1 /* Public Domain Curses */
5 RCSID("$Id: pdcscrn.c,v 1.76 2008/07/14 04:24:51 wmcbrine Exp $")
13 /* COLOR_PAIR to attribute encoding table. */
15 unsigned char *pdc_atrtab
= (unsigned char *)NULL
;
17 int pdc_font
; /* default font size */
19 static short curstoreal
[16], realtocurs
[16] =
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
28 static unsigned char *saved_screen
= NULL
;
29 static int saved_lines
= 0;
30 static int saved_cols
= 0;
34 # define THUNKEDVIO VIOCOLORREG
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
;
56 static int _get_font(void)
58 VIOMODEINFO modeInfo
= {0};
60 modeInfo
.cb
= sizeof(modeInfo
);
62 VioGetMode(&modeInfo
, 0);
63 return (modeInfo
.vres
/ modeInfo
.row
);
66 static void _set_font(int size
)
68 VIOMODEINFO modeInfo
= {0};
72 modeInfo
.cb
= sizeof(modeInfo
);
74 /* set most parameters of modeInfo */
76 VioGetMode(&modeInfo
, 0);
77 modeInfo
.cb
= 8; /* ignore horiz an vert resolution */
78 modeInfo
.row
= modeInfo
.vres
/ size
;
79 VioSetMode(&modeInfo
, 0);
82 curs_set(SP
->visibility
);
84 pdc_font
= _get_font();
89 /* close the physical screen -- may restore the screen to its state
90 before PDC_scr_open(); miscellaneous cleanup */
92 void PDC_scr_close(void)
94 PDC_LOG(("PDC_scr_close() - called\n"));
96 if (saved_screen
&& getenv("PDC_RESTORE_SCREEN"))
99 v_putline(saved_screen
, 0, 0, saved_lines
* saved_cols
);
101 VioWrtCellStr(saved_screen
, saved_lines
* saved_cols
* 2,
110 if (SP
->visibility
!= 1)
113 /* Position cursor to the bottom left of the screen. */
115 PDC_gotoyx(PDC_get_rows() - 2, 0);
118 void PDC_scr_free(void)
125 pdc_atrtab
= (unsigned char *)NULL
;
128 /* open the physical screen -- allocate SP, miscellaneous intialization,
129 and may save the existing screen for later restoration */
131 int PDC_scr_open(int argc
, char **argv
)
141 PDC_LOG(("PDC_scr_open() - called\n"));
143 SP
= calloc(1, sizeof(SCREEN
));
144 pdc_atrtab
= calloc(PDC_COLOR_PAIRS
* PDC_OFFSET
, 1);
146 if (!SP
|| !pdc_atrtab
)
149 for (i
= 0; i
< 16; i
++)
150 curstoreal
[realtocurs
[i
]] = i
;
155 SP
->orig_attr
= FALSE
;
158 adapter
= v_hardware();
159 SP
->mono
= (adapter
== V_MONOCHROME
);
161 pdc_font
= SP
->mono
? 14 : (adapter
== V_COLOR_8
) ? 8 : 12;
163 VioGetMode(&scrnmode
, 0);
164 PDC_get_keyboard_info();
166 pdc_font
= _get_font();
168 SP
->lines
= PDC_get_rows();
169 SP
->cols
= PDC_get_columns();
171 SP
->mouse_wait
= PDC_CLICK_PERIOD
;
174 /* This code for preserving the current screen */
176 if (getenv("PDC_RESTORE_SCREEN"))
178 saved_lines
= SP
->lines
;
179 saved_cols
= SP
->cols
;
181 saved_screen
= malloc(2 * saved_lines
* saved_cols
);
185 SP
->_preserve
= FALSE
;
189 v_getline(saved_screen
, 0, 0, saved_lines
* saved_cols
);
191 totchars
= saved_lines
* saved_cols
* 2;
192 VioReadCellStr((PCH
)saved_screen
, &totchars
, 0, 0, (HVIO
)NULL
);
196 SP
->_preserve
= (getenv("PDC_PRESERVE_SCREEN") != NULL
);
198 can_change
= (PDC_color_content(0, &r
, &g
, &b
) == OK
);
203 /* the core of resize_term() */
205 int PDC_resize_screen(int nlines
, int ncols
)
208 VIOMODEINFO modeInfo
= {0};
212 PDC_LOG(("PDC_resize_screen() - called. Lines: %d Cols: %d\n",
218 modeInfo
.cb
= sizeof(modeInfo
);
220 /* set most parameters of modeInfo */
222 VioGetMode(&modeInfo
, 0);
224 modeInfo
.row
= nlines
;
225 modeInfo
.col
= ncols
;
226 result
= VioSetMode(&modeInfo
, 0);
228 LINES
= PDC_get_rows();
229 COLS
= PDC_get_columns();
231 return (result
== 0) ? OK
: ERR
;
235 void PDC_reset_prog_mode(void)
237 PDC_LOG(("PDC_reset_prog_mode() - called.\n"));
240 PDC_set_keyboard_binary(TRUE
);
244 void PDC_reset_shell_mode(void)
246 PDC_LOG(("PDC_reset_shell_mode() - called.\n"));
249 PDC_set_keyboard_default();
255 static bool _screen_mode_equals(VIOMODEINFO
*oldmode
)
257 VIOMODEINFO current
= {0};
259 VioGetMode(¤t
, 0);
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
));
272 void PDC_restore_screen_mode(int i
)
275 if (i
>= 0 && i
<= 2)
277 pdc_font
= _get_font();
278 _set_font(saved_font
[i
]);
280 if (!_screen_mode_equals(&saved_scrnmode
[i
]))
281 if (VioSetMode(&saved_scrnmode
[i
], 0) != 0)
283 pdc_font
= _get_font();
284 scrnmode
= saved_scrnmode
[i
];
285 LINES
= PDC_get_rows();
286 COLS
= PDC_get_columns();
292 void PDC_save_screen_mode(int i
)
295 if (i
>= 0 && i
<= 2)
297 saved_font
[i
] = pdc_font
;
298 saved_scrnmode
[i
] = scrnmode
;
303 void PDC_init_pair(short pair
, short fg
, short bg
)
305 unsigned char att
, temp_bg
;
311 for (i
= 0; i
< PDC_OFFSET
; i
++)
313 att
= fg
| (bg
<< 4);
315 if (i
& (A_REVERSE
>> PDC_ATTR_SHIFT
))
316 att
= bg
| (fg
<< 4);
317 if (i
& (A_UNDERLINE
>> PDC_ATTR_SHIFT
))
319 if (i
& (A_INVIS
>> PDC_ATTR_SHIFT
))
322 att
= temp_bg
<< 4 | temp_bg
;
324 if (i
& (A_BOLD
>> PDC_ATTR_SHIFT
))
326 if (i
& (A_BLINK
>> PDC_ATTR_SHIFT
))
329 pdc_atrtab
[pair
* PDC_OFFSET
+ i
] = att
;
333 int PDC_pair_content(short pair
, short *fg
, short *bg
)
335 *fg
= realtocurs
[pdc_atrtab
[pair
* PDC_OFFSET
] & 0x0F];
336 *bg
= realtocurs
[(pdc_atrtab
[pair
* PDC_OFFSET
] & 0xF0) >> 4];
341 bool PDC_can_change_color(void)
346 int PDC_color_content(short color
, short *red
, short *green
, short *blue
)
351 unsigned char pal
[3];
354 /* Read single DAC register */
358 palbuf
[2] = curstoreal
[color
];
360 rc
= VioGetState(&palbuf
, 0);
364 vcr
.cb
= sizeof(vcr
);
366 vcr
.firstcolorreg
= palbuf
[3];
367 vcr
.numcolorregs
= 1;
368 vcr
.colorregaddr
= PDCTHUNK(pal
);
370 rc
= VioGetState(&vcr
, 0);
374 /* Scale and store */
376 *red
= DIVROUND((unsigned)(pal
[0]) * 1000, 63);
377 *green
= DIVROUND((unsigned)(pal
[1]) * 1000, 63);
378 *blue
= DIVROUND((unsigned)(pal
[2]) * 1000, 63);
386 int PDC_init_color(short color
, short red
, short green
, short blue
)
391 unsigned char pal
[3];
396 pal
[0] = DIVROUND((unsigned)red
* 63, 1000);
397 pal
[1] = DIVROUND((unsigned)green
* 63, 1000);
398 pal
[2] = DIVROUND((unsigned)blue
* 63, 1000);
400 /* Set single DAC register */
404 palbuf
[2] = curstoreal
[color
];
406 rc
= VioGetState(&palbuf
, 0);
410 vcr
.cb
= sizeof(vcr
);
412 vcr
.firstcolorreg
= palbuf
[3];
413 vcr
.numcolorregs
= 1;
414 vcr
.colorregaddr
= PDCTHUNK(pal
);
416 rc
= VioSetState(&vcr
, 0);
418 return rc
? ERR
: OK
;