libpayload: Add PDCurses and ncurses' libform/libmenu
[coreboot.git] / payloads / libpayload / curses / PDCurses-3.4 / os2 / pdcscrn.c
1 /* Public Domain Curses */
2
3 #include "pdcos2.h"
4
5 RCSID("$Id: pdcscrn.c,v 1.76 2008/07/14 04:24:51 wmcbrine Exp $")
6
7 #ifdef CHTYPE_LONG
8 # define PDC_OFFSET 32
9 #else
10 # define PDC_OFFSET  8
11 #endif
12
13 /* COLOR_PAIR to attribute encoding table. */
14
15 unsigned char *pdc_atrtab = (unsigned char *)NULL;
16
17 int pdc_font;  /* default font size */
18
19 static short curstoreal[16], realtocurs[16] =
20 {
21     COLOR_BLACK, COLOR_BLUE, COLOR_GREEN, COLOR_CYAN, COLOR_RED,
22     COLOR_MAGENTA, COLOR_YELLOW, COLOR_WHITE, COLOR_BLACK + 8,
23     COLOR_BLUE + 8, COLOR_GREEN + 8, COLOR_CYAN + 8, COLOR_RED + 8,
24     COLOR_MAGENTA + 8, COLOR_YELLOW + 8, COLOR_WHITE + 8
25 };
26
27 #ifdef EMXVIDEO
28 static unsigned char *saved_screen = NULL;
29 static int saved_lines = 0;
30 static int saved_cols = 0;
31 #else
32 # ifdef PDCTHUNK
33 #  ifdef __EMX__
34 #   define THUNKEDVIO VIOCOLORREG
35 #  else
36
37 typedef struct {
38     USHORT cb;
39     USHORT type;
40     USHORT firstcolorreg;
41     USHORT numcolorregs;
42     ptr_16 colorregaddr;
43 } THUNKEDVIO;
44
45 #  endif
46 # endif
47
48 static PCH saved_screen = NULL;
49 static USHORT saved_lines = 0;
50 static USHORT saved_cols = 0;
51 static VIOMODEINFO scrnmode;    /* default screen mode  */
52 static VIOMODEINFO saved_scrnmode[3];
53 static int saved_font[3];
54 static bool can_change = FALSE;
55
56 static int _get_font(void)
57 {
58     VIOMODEINFO modeInfo = {0};
59
60     modeInfo.cb = sizeof(modeInfo);
61
62     VioGetMode(&modeInfo, 0);
63     return (modeInfo.vres / modeInfo.row);
64 }
65
66 static void _set_font(int size)
67 {
68     VIOMODEINFO modeInfo = {0};
69
70     if (pdc_font != size)
71     {
72         modeInfo.cb = sizeof(modeInfo);
73
74         /* set most parameters of modeInfo */
75
76         VioGetMode(&modeInfo, 0);
77         modeInfo.cb = 8;    /* ignore horiz an vert resolution */
78         modeInfo.row = modeInfo.vres / size;
79         VioSetMode(&modeInfo, 0);
80     }
81
82     curs_set(SP->visibility);
83
84     pdc_font = _get_font();
85 }
86
87 #endif
88
89 /* close the physical screen -- may restore the screen to its state
90    before PDC_scr_open(); miscellaneous cleanup */
91
92 void PDC_scr_close(void)
93 {
94     PDC_LOG(("PDC_scr_close() - called\n"));
95
96     if (saved_screen && getenv("PDC_RESTORE_SCREEN"))
97     {
98 #ifdef EMXVIDEO
99         v_putline(saved_screen, 0, 0, saved_lines * saved_cols);
100 #else
101         VioWrtCellStr(saved_screen, saved_lines * saved_cols * 2,
102             0, 0, (HVIO)NULL);
103 #endif
104         free(saved_screen);
105         saved_screen = NULL;
106     }
107
108     reset_shell_mode();
109
110     if (SP->visibility != 1)
111         curs_set(1);
112
113     /* Position cursor to the bottom left of the screen. */
114
115     PDC_gotoyx(PDC_get_rows() - 2, 0);
116 }
117
118 void PDC_scr_free(void)
119 {
120     if (SP)
121         free(SP);
122     if (pdc_atrtab)
123         free(pdc_atrtab);
124
125     pdc_atrtab = (unsigned char *)NULL;
126 }
127
128 /* open the physical screen -- allocate SP, miscellaneous intialization,
129    and may save the existing screen for later restoration */
130
131 int PDC_scr_open(int argc, char **argv)
132 {
133 #ifdef EMXVIDEO
134     int adapter;
135 #else
136     USHORT totchars;
137 #endif
138     int i;
139     short r, g, b;
140
141     PDC_LOG(("PDC_scr_open() - called\n"));
142
143     SP = calloc(1, sizeof(SCREEN));
144     pdc_atrtab = calloc(PDC_COLOR_PAIRS * PDC_OFFSET, 1);
145
146     if (!SP || !pdc_atrtab)
147         return ERR;
148
149     for (i = 0; i < 16; i++)
150         curstoreal[realtocurs[i]] = i;
151
152 #ifdef EMXVIDEO
153     v_init();
154 #endif
155     SP->orig_attr = FALSE;
156
157 #ifdef EMXVIDEO
158     adapter = v_hardware();
159     SP->mono = (adapter == V_MONOCHROME);
160
161     pdc_font = SP->mono ? 14 : (adapter == V_COLOR_8) ? 8 : 12;
162 #else
163     VioGetMode(&scrnmode, 0);
164     PDC_get_keyboard_info();
165
166     pdc_font = _get_font();
167 #endif
168     SP->lines = PDC_get_rows();
169     SP->cols = PDC_get_columns();
170
171     SP->mouse_wait = PDC_CLICK_PERIOD;
172     SP->audible = TRUE;
173
174     /* This code for preserving the current screen */
175
176     if (getenv("PDC_RESTORE_SCREEN"))
177     {
178         saved_lines = SP->lines;
179         saved_cols = SP->cols;
180
181         saved_screen = malloc(2 * saved_lines * saved_cols);
182
183         if (!saved_screen)
184         {
185             SP->_preserve = FALSE;
186             return OK;
187         }
188 #ifdef EMXVIDEO
189         v_getline(saved_screen, 0, 0, saved_lines * saved_cols);
190 #else
191         totchars = saved_lines * saved_cols * 2;
192         VioReadCellStr((PCH)saved_screen, &totchars, 0, 0, (HVIO)NULL);
193 #endif
194     }
195
196     SP->_preserve = (getenv("PDC_PRESERVE_SCREEN") != NULL);
197
198     can_change = (PDC_color_content(0, &r, &g, &b) == OK);
199
200     return OK;
201 }
202
203 /* the core of resize_term() */
204
205 int PDC_resize_screen(int nlines, int ncols)
206 {
207 #ifndef EMXVIDEO
208     VIOMODEINFO modeInfo = {0};
209     USHORT result;
210 #endif
211
212     PDC_LOG(("PDC_resize_screen() - called. Lines: %d Cols: %d\n",
213               nlines, ncols));
214
215 #ifdef EMXVIDEO
216     return ERR;
217 #else
218     modeInfo.cb = sizeof(modeInfo);
219
220     /* set most parameters of modeInfo */
221
222     VioGetMode(&modeInfo, 0);
223     modeInfo.fbType = 1;
224     modeInfo.row = nlines;
225     modeInfo.col = ncols;
226     result = VioSetMode(&modeInfo, 0);
227
228     LINES = PDC_get_rows();
229     COLS = PDC_get_columns();
230
231     return (result == 0) ? OK : ERR;
232 #endif
233 }
234
235 void PDC_reset_prog_mode(void)
236 {
237     PDC_LOG(("PDC_reset_prog_mode() - called.\n"));
238
239 #ifndef EMXVIDEO
240     PDC_set_keyboard_binary(TRUE);
241 #endif
242 }
243
244 void PDC_reset_shell_mode(void)
245 {
246     PDC_LOG(("PDC_reset_shell_mode() - called.\n"));
247
248 #ifndef EMXVIDEO
249     PDC_set_keyboard_default();
250 #endif
251 }
252
253 #ifndef EMXVIDEO
254
255 static bool _screen_mode_equals(VIOMODEINFO *oldmode)
256 {
257     VIOMODEINFO current = {0};
258
259     VioGetMode(&current, 0);
260
261     return ((current.cb == oldmode->cb) &&
262             (current.fbType == oldmode->fbType) &&
263             (current.color == oldmode->color) && 
264             (current.col == oldmode->col) &&
265             (current.row == oldmode->row) && 
266             (current.hres == oldmode->vres) &&
267             (current.vres == oldmode->vres));
268 }
269
270 #endif
271
272 void PDC_restore_screen_mode(int i)
273 {
274 #ifndef EMXVIDEO
275     if (i >= 0 && i <= 2)
276     {
277         pdc_font = _get_font();
278         _set_font(saved_font[i]);
279
280         if (!_screen_mode_equals(&saved_scrnmode[i]))
281             if (VioSetMode(&saved_scrnmode[i], 0) != 0)
282             {
283                 pdc_font = _get_font();
284                 scrnmode = saved_scrnmode[i];
285                 LINES = PDC_get_rows();
286                 COLS = PDC_get_columns();
287             }
288     }
289 #endif
290 }
291
292 void PDC_save_screen_mode(int i)
293 {
294 #ifndef EMXVIDEO
295     if (i >= 0 && i <= 2)
296     {
297         saved_font[i] = pdc_font;
298         saved_scrnmode[i] = scrnmode;
299     }
300 #endif
301 }
302
303 void PDC_init_pair(short pair, short fg, short bg)
304 {
305     unsigned char att, temp_bg;
306     chtype i;
307
308     fg = curstoreal[fg];
309     bg = curstoreal[bg];
310
311     for (i = 0; i < PDC_OFFSET; i++)
312     {
313         att = fg | (bg << 4);
314
315         if (i & (A_REVERSE >> PDC_ATTR_SHIFT))
316             att = bg | (fg << 4);
317         if (i & (A_UNDERLINE >> PDC_ATTR_SHIFT))
318             att = 1;
319         if (i & (A_INVIS >> PDC_ATTR_SHIFT))
320         {
321             temp_bg = att >> 4;
322             att = temp_bg << 4 | temp_bg;
323         }
324         if (i & (A_BOLD >> PDC_ATTR_SHIFT))
325             att |= 8;
326         if (i & (A_BLINK >> PDC_ATTR_SHIFT))
327             att |= 128;
328
329         pdc_atrtab[pair * PDC_OFFSET + i] = att;
330     }
331 }
332
333 int PDC_pair_content(short pair, short *fg, short *bg)
334 {
335     *fg = realtocurs[pdc_atrtab[pair * PDC_OFFSET] & 0x0F];
336     *bg = realtocurs[(pdc_atrtab[pair * PDC_OFFSET] & 0xF0) >> 4];
337
338     return OK;
339 }
340
341 bool PDC_can_change_color(void)
342 {
343     return can_change;
344 }
345
346 int PDC_color_content(short color, short *red, short *green, short *blue)
347 {
348 #ifdef PDCTHUNK
349     THUNKEDVIO vcr;
350     USHORT palbuf[4];
351     unsigned char pal[3];
352     int rc;
353
354     /* Read single DAC register */
355
356     palbuf[0] = 8;
357     palbuf[1] = 0;
358     palbuf[2] = curstoreal[color];
359
360     rc = VioGetState(&palbuf, 0);
361     if (rc)
362         return ERR;
363
364     vcr.cb = sizeof(vcr);
365     vcr.type = 3;
366     vcr.firstcolorreg = palbuf[3];
367     vcr.numcolorregs = 1;
368     vcr.colorregaddr = PDCTHUNK(pal);
369
370     rc = VioGetState(&vcr, 0);
371     if (rc)
372         return ERR;
373
374     /* Scale and store */
375
376     *red = DIVROUND((unsigned)(pal[0]) * 1000, 63);
377     *green = DIVROUND((unsigned)(pal[1]) * 1000, 63);
378     *blue = DIVROUND((unsigned)(pal[2]) * 1000, 63);
379
380     return OK;
381 #else
382     return ERR;
383 #endif
384 }
385
386 int PDC_init_color(short color, short red, short green, short blue)
387 {
388 #ifdef PDCTHUNK
389     THUNKEDVIO vcr;
390     USHORT palbuf[4];
391     unsigned char pal[3];
392     int rc;
393
394     /* Scale */
395
396     pal[0] = DIVROUND((unsigned)red * 63, 1000);
397     pal[1] = DIVROUND((unsigned)green * 63, 1000);
398     pal[2] = DIVROUND((unsigned)blue * 63, 1000);
399
400     /* Set single DAC register */
401
402     palbuf[0] = 8;
403     palbuf[1] = 0;
404     palbuf[2] = curstoreal[color];
405
406     rc = VioGetState(&palbuf, 0);
407     if (rc)
408         return ERR;
409
410     vcr.cb = sizeof(vcr);
411     vcr.type = 3;
412     vcr.firstcolorreg = palbuf[3];
413     vcr.numcolorregs = 1;
414     vcr.colorregaddr = PDCTHUNK(pal);
415
416     rc = VioSetState(&vcr, 0);
417
418     return rc ? ERR : OK;
419 #else
420     return ERR;
421 #endif
422 }