Initial commit (from git)
This commit is contained in:
@@ -0,0 +1,286 @@
|
||||
/* c_screen.cpp -- screen driver console output
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2000 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2000 Laszlo Molnar
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus.oberhumer@jk.uni-linz.ac.at ml1050@cdata.tvnet.hu
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
|
||||
#if defined(USE_SCREEN)
|
||||
|
||||
#include "screen.h"
|
||||
|
||||
#define mask_fg 0x0f
|
||||
#define mask_bg 0xf0
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
static screen_t *do_construct(screen_t *s, int fd)
|
||||
{
|
||||
if (!s)
|
||||
return NULL;
|
||||
if (s->init(s,fd) != 0)
|
||||
{
|
||||
s->destroy(s);
|
||||
return NULL;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
static screen_t *screen = NULL;
|
||||
|
||||
static void do_destroy(void)
|
||||
{
|
||||
if (screen)
|
||||
{
|
||||
screen->destroy(screen);
|
||||
screen = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int mode = -1;
|
||||
static int init_fg = -1;
|
||||
static int init_bg = -1;
|
||||
static int cur_fg = -1;
|
||||
static int cur_bg = -1;
|
||||
|
||||
|
||||
static int init(FILE *f, int o, int now)
|
||||
{
|
||||
int fd = fileno(f);
|
||||
int n = CON_INIT;
|
||||
|
||||
UNUSED(now);
|
||||
assert(screen == NULL);
|
||||
atexit(do_destroy);
|
||||
#if defined(__DJGPP__)
|
||||
if (!screen)
|
||||
screen = do_construct(screen_djgpp2_construct(),fd);
|
||||
#endif
|
||||
#if defined(__MFX_WIN32)
|
||||
if (!screen)
|
||||
screen = do_construct(screen_win32_construct(),fd);
|
||||
#endif
|
||||
#if defined(USE_SCREEN_VCSA)
|
||||
if (!screen)
|
||||
screen = do_construct(screen_vcsa_construct(),fd);
|
||||
#endif
|
||||
#if defined(USE_SCREEN_CURSES)
|
||||
if (!screen && o == CON_SCREEN)
|
||||
screen = do_construct(screen_curses_construct(),fd);
|
||||
#endif
|
||||
if (!screen)
|
||||
return CON_INIT;
|
||||
mode = screen->getMode(screen);
|
||||
init_fg = cur_fg = screen->getFg(screen);
|
||||
init_bg = cur_bg = screen->getBg(screen);
|
||||
if (screen->isMono(screen))
|
||||
cur_fg = -1;
|
||||
if (screen->getCols(screen) < 80 || screen->getCols(screen) > 256)
|
||||
return CON_INIT;
|
||||
if (screen->getRows(screen) < 24)
|
||||
return CON_INIT;
|
||||
if (cur_fg == (cur_bg >> 4))
|
||||
return CON_INIT;
|
||||
if (cur_bg != BG_BLACK)
|
||||
if (!screen->isMono(screen))
|
||||
{
|
||||
/* return CON_ANSI_MONO; */ /* we could emulate ANSI mono */
|
||||
return CON_INIT;
|
||||
}
|
||||
|
||||
if (o == CON_SCREEN)
|
||||
n = CON_SCREEN;
|
||||
if (o == CON_INIT) /* use by default */
|
||||
n = CON_SCREEN;
|
||||
if (o == CON_ANSI_COLOR) /* can emulate ANSI color */
|
||||
n = CON_ANSI_COLOR;
|
||||
if (o == CON_ANSI_MONO) /* can emulate ANSI mono */
|
||||
n = CON_ANSI_MONO;
|
||||
|
||||
if (screen->atExit)
|
||||
atexit(screen->atExit);
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
static int set_fg(FILE *f, int fg)
|
||||
{
|
||||
const int last_fg = cur_fg;
|
||||
int f1 = fg & mask_fg;
|
||||
int f2 = init_fg & mask_fg;
|
||||
|
||||
UNUSED(f);
|
||||
cur_fg = fg;
|
||||
if (screen->isMono(screen))
|
||||
{
|
||||
const int b = (init_bg & mask_bg) >> 4;
|
||||
if (fg == -1) /* restore startup fg */
|
||||
f1 = f2;
|
||||
else if (b == 0)
|
||||
f1 = (f2 <= 8) ? 15 : 8;
|
||||
else if (b <= 8)
|
||||
f1 = (f2 == 0) ? 15 : 0;
|
||||
else
|
||||
f1 = (f2 == 0) ? 8 : 0;
|
||||
}
|
||||
else if (con_mode == CON_ANSI_MONO && f1 != f2)
|
||||
{
|
||||
f1 = f2 ^ 0x08;
|
||||
}
|
||||
|
||||
screen->setFg(screen,f1 & mask_fg);
|
||||
return last_fg;
|
||||
}
|
||||
|
||||
|
||||
static void print0(FILE *f, const char *ss)
|
||||
{
|
||||
int cx, cy;
|
||||
int c_cx, c_cy;
|
||||
char p[256+1];
|
||||
int pi = 0, px = -1, py = -1;
|
||||
const int sx = screen->getCols(screen);
|
||||
const int sy = screen->getRows(screen);
|
||||
int pass;
|
||||
|
||||
// Note:
|
||||
// We use 2 passes to avoid unnecessary system calls because
|
||||
// scrollScreen() under Win32 is *extremely* slow.
|
||||
UNUSED(f);
|
||||
screen->getCursor(screen,&cx,&cy);
|
||||
c_cx = cx; c_cy = cy;
|
||||
for (pass = 0; pass < 2; pass++)
|
||||
{
|
||||
const char *s = ss;
|
||||
int scroll_y = 0;
|
||||
while (*s)
|
||||
{
|
||||
for ( ; *s; s++)
|
||||
{
|
||||
if (*s == '\n')
|
||||
{
|
||||
c_cy++;
|
||||
c_cx = 0;
|
||||
}
|
||||
else if (*s == '\r')
|
||||
{
|
||||
c_cx = 0;
|
||||
#if 1
|
||||
if (pass > 0 && c_cy < sy)
|
||||
screen->clearLine(screen,c_cy);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (c_cx >= sx)
|
||||
{
|
||||
c_cy++;
|
||||
c_cx = 0;
|
||||
}
|
||||
if (pass > 0 && pi > 0 && py != c_cy)
|
||||
{
|
||||
screen->putString(screen,p,px,py);
|
||||
pi = 0;
|
||||
}
|
||||
if (c_cy >= sy)
|
||||
{
|
||||
int l = c_cy - sy + 1;
|
||||
if (pass > 0)
|
||||
c_cy -= screen->scrollUp(screen,l);
|
||||
else
|
||||
{
|
||||
scroll_y += l;
|
||||
c_cy -= l;
|
||||
}
|
||||
if (c_cy < 0)
|
||||
c_cy = 0;
|
||||
c_cx = 0;
|
||||
}
|
||||
if (*s)
|
||||
{
|
||||
if (pass > 0)
|
||||
{
|
||||
if (pi == 0)
|
||||
px = c_cx, py = c_cy;
|
||||
p[pi++] = *s;
|
||||
p[pi] = 0;
|
||||
}
|
||||
c_cx++;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
if (pass == 0)
|
||||
{
|
||||
c_cx = cx;
|
||||
if (scroll_y > 0)
|
||||
{
|
||||
c_cy -= screen->scrollUp(screen,scroll_y);
|
||||
if (c_cy < 0)
|
||||
c_cy = 0;
|
||||
}
|
||||
else
|
||||
c_cy = cy;
|
||||
}
|
||||
}
|
||||
if (pi > 0)
|
||||
screen->putString(screen,p,px,py);
|
||||
screen->setCursor(screen,c_cx,c_cy);
|
||||
screen->refresh(screen);
|
||||
}
|
||||
|
||||
|
||||
static upx_bool intro(FILE *f)
|
||||
{
|
||||
UNUSED(f);
|
||||
#if defined(USE_FRAMES)
|
||||
if (screen->intro)
|
||||
return screen->intro(screen,screen_show_frames);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
console_t console_screen =
|
||||
{
|
||||
init,
|
||||
set_fg,
|
||||
print0,
|
||||
intro
|
||||
};
|
||||
|
||||
|
||||
#endif /* USE_SCREEN */
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user