1 /****************************************************************************
2 * window.c
3 * Text mode window engine
4 *
5 * Written by Neil Bradley (neil@synthcom.com)
6 * Heavily modified by Juergen Buchmueller (pullmoll@t-online.de)
7 *
8 * Designed to fit the needs of the new MAME debugger (a bit more ;)
9 *
10 * Warning: This code is still buggy!
11 * Some of the changes I made were contrary to the original design,
12 * so expect 'assertions' for every non common case (ie. window too
13 * big, hanging out of the screen etc.)
14 ****************************************************************************/
15 #include <stdio.h>
16
17 #ifdef MAME_DEBUG
18
19 #include <stdlib.h>
20 #include <string.h>
21 #include <stdarg.h>
22 #include <assert.h>
23 #include "window.h"
24
25 /*
26 * These standard definition functions are macro'd so they can easily be
27 * redefined to other custom procedures.
28 */
29
30 #define ASSERT(expr) assert(expr)
31
MyMalloc(UINT32 size,const char * function)32 static INLINE void *MyMalloc( UINT32 size, const char *function )
33 {
34 void *p = malloc( size );
35 ASSERT( p );
36 memset( p, 0, size );
37 return p;
38 }
39
MyReAlloc(void * p,UINT32 size,const char * function)40 static INLINE void *MyReAlloc( void *p, UINT32 size, const char *function )
41 {
42 p = realloc( p, size );
43 ASSERT( p );
44 return p;
45 }
46
MyFree(void ** p,const char * function)47 static INLINE void MyFree( void **p, const char *function )
48 {
49 if( *p )
50 {
51 free(*p);
52 *p = NULL;
53 }
54 }
55
56 /* Forward references for circular function calls */
57
58 void win_set_cursor_char(UINT32 idx, UINT32 state, UINT32 state_old);
59
60 /* Global windowing data we need */
61
62 UINT32 screen_w = 80; /* Our screen's size in characters X */
63 UINT32 screen_h = 50; /* Our screen's size in characters Y */
64
65 static struct sWindow *p_windows = NULL;
66 static UINT8 *p_prio_map = NULL;
67 static UINT8 *p_shadow_map = NULL;
68 static UINT8 *p_text = NULL;
69 static UINT8 *p_attr = NULL;
70
71 /************************************************************************
72 *
73 * Name : win_out
74 *
75 * Entry: Character, attribute and X/Y position of char to place
76 *
77 * Exit : None
78 *
79 * Description:
80 *
81 * This routine will place a character at a given video position.
82 *
83 ************************************************************************/
84
win_out(UINT8 bChar,UINT8 bAttr,UINT32 x,UINT32 y,UINT32 idx)85 static INLINE void win_out(UINT8 bChar, UINT8 bAttr, UINT32 x, UINT32 y, UINT32 idx)
86 {
87 UINT32 offs = (y * screen_w) + x;
88
89 ASSERT(idx < MAX_WINDOWS);
90
91 if( x >= screen_w || y >= screen_h )
92 return;
93
94 idx = p_windows[idx].prio;
95
96 /* If we're under the influence of a Window's shadow, change the attribute */
97 if( idx > p_shadow_map[offs] )
98 bAttr = ( bAttr & 0x08 ) ? bAttr & 0x07 : 0x08;
99
100 /* If it's different */
101 if( bChar != p_text[offs] || bAttr != p_attr[offs] )
102 {
103 /* Put it in our video map */
104 p_text[offs] = bChar;
105 p_attr[offs] = bAttr;
106
107 /* Here's where we draw the character */
108 dbg_put_screen_char(bChar, bAttr, x, y);
109 }
110 }
111
112 /************************************************************************
113 *
114 * Name : win_update_map
115 *
116 * Entry: Nothing
117 *
118 * Exit : Nothing
119 *
120 * Description:
121 *
122 * This routine will update the window priority map and
123 * will recompute all windows.
124 *
125 ************************************************************************/
126
win_update_map(void)127 static void win_update_map(void)
128 {
129 INT32 prio, i;
130 UINT32 yadd, xadd, x, y;
131 struct sWindow *pwin;
132
133 ASSERT(p_prio_map); /* This had better not be null */
134 ASSERT(p_windows); /* This either */
135
136 memset(p_prio_map, 0xff, screen_w * screen_h);
137
138 for( prio = 0xff; prio >= 0; prio-- )
139 {
140 for( i = 0, pwin = p_windows; i < MAX_WINDOWS; i++, pwin++ )
141 {
142 if ( pwin->prio == prio && pwin->text && !(pwin->flags & HIDDEN) )
143 break;
144 }
145
146 if( i != MAX_WINDOWS && pwin->x < screen_w )
147 {
148 UINT32 w;
149 xadd = 0;
150 yadd = 0;
151
152 if( pwin->flags & BORDER_LEFT ) ++xadd;
153 if( pwin->flags & BORDER_RIGHT ) ++xadd;
154 if( pwin->flags & BORDER_TOP ) ++yadd;
155 if( pwin->flags & BORDER_BOTTOM ) ++yadd;
156
157 w = pwin->w + xadd;
158 if( w > screen_w )
159 w = screen_w - pwin->x;
160
161 for( y = pwin->y; y < screen_h && y < pwin->y + pwin->h + yadd; y++ )
162 memset(&p_prio_map[y * screen_w + pwin->x], prio, w);
163 }
164 }
165
166 /* Now create a shadow region (if applicable) */
167
168 memset(p_shadow_map, 0xff, screen_w * screen_h);
169
170 for( pwin = &p_windows[MAX_WINDOWS-1], i = MAX_WINDOWS-1; i >= 0; --i, --pwin )
171 {
172 /* Let's figure out if we should be doing a shadow */
173
174 if( pwin->text && (pwin->flags & SHADOW) && !(pwin->flags & HIDDEN) )
175 {
176 yadd = pwin->y + pwin->h;
177 xadd = pwin->x + pwin->w;
178
179 /* If we have additional borders, extend it! */
180 if( pwin->flags & BORDER_TOP ) ++yadd;
181 if( pwin->flags & BORDER_BOTTOM ) ++yadd;
182 if( pwin->flags & BORDER_LEFT ) ++xadd;
183 if( pwin->flags & BORDER_RIGHT ) ++xadd;
184
185 /* If the line is still within range, go figure it! */
186
187 if( (yadd + 1) < screen_h )
188 {
189 for( x = pwin->x + 1; x < screen_w && x < (xadd + 1); x++ )
190 {
191 if( pwin->prio < p_shadow_map[x + (yadd * screen_w)] )
192 p_shadow_map[x + (yadd * screen_w)] = pwin->prio;
193 }
194 }
195
196 /* Now let's draw us a vertical shadow line */
197 if( (xadd + 1) < screen_w )
198 {
199 for( y = pwin->y + 1; y < yadd; y++ )
200 {
201 if( pwin->prio < p_shadow_map[xadd + (y * screen_w)] )
202 p_shadow_map[xadd + (y * screen_w)] = pwin->prio;
203 }
204 }
205 }
206 }
207 }
208
209 /************************************************************************
210 *
211 * Name : win_update_shadow
212 *
213 * Entry: Window #, pointer to an array of bytes for affected windows
214 *
215 * Exit : Nothing
216 *
217 * Description:
218 *
219 * This routine will find all windows that are affected by a
220 * shadow of a given window. Not actual updates are done.
221 *
222 ************************************************************************/
223
win_update_shadow(UINT32 idx,UINT8 * affected)224 static void win_update_shadow(UINT32 idx, UINT8 *affected)
225 {
226 struct sWindow *pwin = &p_windows[idx];
227 UINT32 x, y, xadd, yadd;
228 UINT8 bMap = 0;
229
230 xadd = pwin->w;
231 yadd = pwin->h;
232
233 if( pwin->flags & BORDER_LEFT ) ++xadd;
234 if( pwin->flags & BORDER_RIGHT ) ++xadd;
235 if( pwin->flags & BORDER_TOP ) ++yadd;
236 if( pwin->flags & BORDER_BOTTOM ) ++yadd;
237
238 /* Now check to see if we need to update anything because of the shadow */
239
240 if( pwin->flags & SHADOW )
241 {
242 /* Check out the shadow on the bottom and see if we need */
243 /* to update a window below. */
244 y = yadd + pwin->y;
245 if( y < screen_h )
246 {
247 for( x = pwin->x + 2; x < (pwin->x + xadd + 2); x++ )
248 {
249 if( x < screen_w )
250 {
251 bMap = p_prio_map[(y * screen_w) + x];
252 if( 0xff != bMap )
253 affected[bMap] = 1;
254 }
255 }
256 }
257
258 /* And now down the right side */
259 for( y = pwin->y + 1; y < screen_h && y < pwin->y + yadd + 1; y++ )
260 {
261 for( x = xadd + pwin->x; x < (xadd + pwin->x + 2); x++ )
262 {
263 if( x < screen_w )
264 {
265 bMap = p_prio_map[(y * screen_w) + x];
266 if( 0xff != bMap )
267 affected[bMap] = 1;
268 }
269 }
270 }
271 }
272 }
273
274 /************************************************************************
275 *
276 * Name : win_update
277 *
278 * Entry: Window # to update
279 *
280 * Exit : Nothing
281 *
282 * Description:
283 *
284 * This routine will update a given window on the screen.
285 *
286 ************************************************************************/
287
win_update(UINT32 idx)288 void win_update(UINT32 idx)
289 {
290 struct sWindow *pwin = &p_windows[idx];
291 UINT8 affected[MAX_WINDOWS];
292 UINT32 x0, y0, x, y, win_offs, scr_offs;
293 UINT8 ch, color;
294
295 ASSERT(idx < MAX_WINDOWS); /* This had better be in range */
296 ASSERT(p_windows); /* And this had better be initialized */
297
298 memset( affected, 0, sizeof(affected) );
299
300 /* If this isn't a valid window or it's hidden, just bail out */
301
302 if( NULL == pwin->text || (pwin->flags & HIDDEN) )
303 return;
304
305 /* Let's whip through and draw the whole stinking window, shall we? */
306
307 x0 = pwin->x;
308 y0 = pwin->y;
309
310 if( pwin->flags & BORDER_LEFT ) ++x0;
311 if( pwin->flags & BORDER_TOP ) ++y0;
312
313 color = pwin->co_frame;
314
315 /* See if we need a character in the upper left hand corner of our window */
316 if( (pwin->flags & BORDER_TOP) && (pwin->flags & BORDER_LEFT) )
317 {
318 if( pwin->x < screen_w && pwin->y < screen_h )
319 if( p_prio_map[pwin->x + (pwin->y * screen_w)] >= pwin->prio )
320 win_out(FRAME_TL, color, pwin->x, pwin->y, idx);
321 }
322
323 /* See if we need a character in the lower left hand corner of our window */
324 if( (pwin->flags & BORDER_BOTTOM) && (pwin->flags & BORDER_LEFT) )
325 {
326 if( pwin->x < screen_w && pwin->y + y0 < screen_h )
327 if( p_prio_map[pwin->x + ((y0 + pwin->h) * screen_w)] >= pwin->prio )
328 win_out(FRAME_BL, color, pwin->x, pwin->h + y0, idx);
329 }
330
331 /* See if we need a character in the upper right hand corner of our window */
332 if( (pwin->flags & BORDER_TOP) && (pwin->flags & BORDER_RIGHT) )
333 {
334 if( pwin->x + x0 < screen_w && pwin->y < screen_h )
335 if( p_prio_map[pwin->w + x0 + (pwin->y * screen_w)] >= pwin->prio )
336 win_out(FRAME_TR, color, pwin->w + x0, pwin->y, idx);
337 }
338
339 /* See if we need a character in the lower right hand corner of our window */
340 if( (pwin->flags & BORDER_BOTTOM) && (pwin->flags & BORDER_RIGHT) )
341 {
342 if( pwin->x + x0 < screen_w && pwin->y + y0 < screen_h )
343 if( p_prio_map[pwin->w + x0 + ((pwin->h + y0) * screen_w)] >= pwin->prio )
344 win_out(FRAME_BR, color, pwin->w + x0, pwin->h + y0, idx);
345 }
346
347 /* Let's go through and draw the frame for the window (if any) */
348 if( pwin->flags & BORDER_LEFT ) /* Here we have a left border */
349 {
350 for( y = y0; y < (y0 + pwin->h); y++ )
351 {
352 if( p_prio_map[pwin->x + (y * screen_w)] >= pwin->prio )
353 win_out(FRAME_V, color, pwin->x, y, idx);
354 }
355 }
356
357 /* Let's draw the right side of the window (if any) */
358 if( pwin->flags & BORDER_RIGHT ) /* Here we have a right border */
359 {
360 if( pwin->w + x0 < screen_w )
361 for( y = y0; y < screen_h && y < (y0 + pwin->h); y++ )
362 {
363 if( p_prio_map[pwin->w + x0 + (y * screen_w)] >= pwin->prio )
364 win_out(FRAME_V, color, x0 + pwin->w, y, idx);
365 }
366 }
367
368 /* Let's draw the bottom side of the window (if any) */
369 if( pwin->flags & BORDER_BOTTOM )
370 {
371 if( pwin->h + y0 < screen_h )
372 for( x = x0; x < (x0 + pwin->w); x++ )
373 {
374 if( p_prio_map[((y0 + pwin->h) * screen_w) + x] >= pwin->prio )
375 win_out(FRAME_H, color, x, y0 + pwin->h, idx);
376 }
377 }
378
379 /* And now the top! */
380 if( pwin->flags & BORDER_TOP )
381 {
382 /* If we've got a title, let's put that in, too... */
383 if( pwin->title )
384 {
385 UINT32 i, j, length1, length2;
386 char *p = strchr(pwin->title, '\t');
387
388 /* If the title contains a tab, split it into two parts */
389 if( p )
390 {
391 i = 0;
392 j = 1;
393 length1 = (UINT32)(p - pwin->title);
394 length2 = strlen(p + j);
395
396 for( x = x0; x < screen_w && x < (x0 + pwin->w); x++ )
397 {
398 if( p_prio_map[x + (pwin->y * screen_w)] < pwin->prio )
399 continue;
400 color = pwin->co_frame;
401 if( x < (x0 + 1) )
402 {
403 ch = FRAME_H;
404 }
405 else
406 if( x > (x0 + 1 + length1 + 1) )
407 {
408 if( x < (x0 + pwin->w - 1 - length2 - 1) )
409 {
410 ch = FRAME_H;
411 }
412 else
413 {
414 if( x == (x0 + pwin->w - 1) )
415 ch = CAPTION_R;
416 else
417 if( x == (x0 + pwin->w - 1 - length2 - 1) )
418 ch = CAPTION_L;
419 else
420 {
421 color = pwin->co_title;
422 ch = p[j++];
423 }
424 }
425 }
426 else
427 {
428 if( x == (x0 + 1) )
429 ch = CAPTION_L;
430 else
431 if( x == (x0 + 1 + length1 + 1) )
432 ch = CAPTION_R;
433 else
434 {
435 color = pwin->co_title;
436 ch = pwin->title[i++];
437 }
438 }
439 win_out(ch, color, x, pwin->y, idx);
440 }
441 }
442 else
443 {
444 /* Draw a top border with a title in the left part */
445 length1 = strlen(pwin->title);
446 i = 0;
447 for( x = x0; x < screen_w && x < (x0 + pwin->w); x++ )
448 {
449 if( p_prio_map[x + (pwin->y * screen_w)] < pwin->prio )
450 continue;
451 color = pwin->co_frame;
452 if( x < (x0 + 1) || x > (x0 + 1 + length1 + 1) )
453 {
454 ch = FRAME_H;
455 }
456 else
457 {
458 if( x == (x0 + 1) )
459 ch = CAPTION_L;
460 else
461 if( x == (x0 + 1 + length1 + 1) )
462 ch = CAPTION_R;
463 else
464 {
465 color = pwin->co_title;
466 ch = pwin->title[i++];
467 }
468 }
469 win_out(ch, color, x, pwin->y, idx);
470 }
471 }
472 }
473 else
474 {
475 for( x = x0; x < screen_w && x < (x0 + pwin->w); x++ )
476 {
477 if( p_prio_map[(pwin->y * screen_w) + x] >= pwin->prio )
478 win_out(FRAME_H, color, x, pwin->y, idx);
479 }
480 }
481
482 }
483
484 /* Loop through our existing window and update it on the screen */
485 for( y = 0; y < pwin->h; y++ )
486 {
487 win_offs = y * screen_w;
488 scr_offs = (y0 + y) * screen_w + x0;
489 for( x = 0; x < pwin->w; x++ )
490 {
491 if( p_prio_map[scr_offs] >= pwin->prio )
492 {
493 ch = pwin->text[win_offs];
494 color = pwin->attr[win_offs];
495 win_out(ch, color, x0 + x, y0 + y, idx);
496 }
497 win_offs++;
498 scr_offs++;
499 }
500 }
501 }
502
503 /************************************************************************
504 *
505 * Name : win_erase
506 *
507 * Entry: Window index # to erase
508 *
509 * Exit : Nothing
510 *
511 * Description:
512 *
513 * This routine will erase a window from the physical display (including
514 * borders if applicable)
515 *
516 ************************************************************************/
517
win_erase(UINT32 idx)518 void win_erase(UINT32 idx)
519 {
520 struct sWindow *pwin = &p_windows[idx];
521 UINT8 affected[MAX_WINDOWS];
522 UINT32 i = 0;
523 UINT32 flags_old;
524 UINT8 bMap = 0;
525 UINT32 x, y;
526 UINT32 xadd = 0;
527 UINT32 yadd = 0;
528
529 ASSERT(idx < MAX_WINDOWS); /* This had better be in range */
530 ASSERT(p_windows); /* And this had better be initialized */
531
532 if( NULL == pwin->text )
533 return;
534
535 memset( affected, 0, sizeof(affected) );
536
537 /* Let's fake like the window is gone */
538
539 flags_old = pwin->flags;
540 pwin->flags |= HIDDEN;
541
542 /* Recompute the display matrix */
543
544 win_update_map();
545
546 xadd = pwin->w;
547 yadd = pwin->h;
548
549 if( pwin->flags & BORDER_LEFT ) ++xadd;
550 if( pwin->flags & BORDER_RIGHT ) ++xadd;
551 if( pwin->flags & BORDER_TOP ) ++yadd;
552 if( pwin->flags & BORDER_BOTTOM ) ++yadd;
553
554 win_set_cursor_char(idx, 0, pwin->flags & CURSOR_ON);
555
556 /* Go see if we need to do anything about our shadows */
557 for( y = pwin->y; y < screen_h && y < (pwin->y + yadd); y++ )
558 {
559 for( x = pwin->x; x < screen_w && x < (pwin->x + xadd); x++ )
560 {
561 bMap = p_prio_map[(y * screen_w) + x];
562 if( 0xff == bMap )
563 win_out(WIN_EMPTY, WIN_WHITE, x, y, idx);
564 else
565 affected[bMap] = 1;
566 }
567 }
568
569 win_update_shadow(idx, affected);
570
571 /* Now that we've erased the residuals, let's go update */
572 /* the windows that need it */
573
574 for( i = 0; i < MAX_WINDOWS; i++ )
575 {
576 if( affected[i] || (i != idx) )
577 {
578 win_update(i);
579 win_set_cursor_char(i, p_windows[i].flags & CURSOR_ON, 0);
580 }
581 }
582
583 pwin->flags = flags_old;
584 }
585
586 /************************************************************************
587 *
588 * Name : win_set_cursor_char
589 *
590 * Entry: Window # to set cursor state, and state of cursor
591 *
592 * Exit : Nothing
593 *
594 * Description:
595 *
596 * This routine will either turn on/off the cursor in a given window.
597 *
598 ************************************************************************/
599
win_set_cursor_char(UINT32 idx,UINT32 state,UINT32 state_old)600 void win_set_cursor_char(UINT32 idx, UINT32 state, UINT32 state_old)
601 {
602 struct sWindow *pwin = &p_windows[idx];
603 UINT32 x0, y0, win_offs;
604
605 if( INVALID == idx )
606 return;
607
608 if( NULL == pwin->text )
609 return;
610
611 if( pwin->flags & HIDDEN )
612 return;
613
614 if( pwin->flags & NO_WRAP )
615 {
616 if( pwin->x >= pwin->w )
617 return;
618 if( pwin->y >= pwin->h )
619 return;
620 }
621
622 x0 = pwin->x + pwin->cx;
623 y0 = pwin->y + pwin->cy;
624
625 if( pwin->flags & BORDER_LEFT ) ++x0;
626 if( pwin->flags & BORDER_TOP ) ++y0;
627
628 /* If we are outside of the physical screen, just exit */
629 if( x0 >= screen_w || y0 >= screen_h )
630 return;
631
632 win_offs = y0 * screen_w + x0;
633
634 if( p_prio_map[win_offs] < pwin->prio )
635 return;
636
637 if( state )
638 {
639 pwin->saved_text = p_text[win_offs];
640 pwin->saved_attr = p_attr[win_offs];
641 win_out(CHAR_CURSORON, WIN_BRIGHT_WHITE, x0, y0, idx);
642 }
643 else
644 {
645 if( 0 != state_old )
646 win_out(pwin->saved_text, pwin->saved_attr, x0, y0, idx);
647 }
648 }
649
650 /************************************************************************
651 *
652 * Name : win_is_initalized()
653 *
654 * Entry: Nothing
655 *
656 * Exit : TRUE if a window is already initialized
657 *
658 * Description:
659 *
660 * This routine returns the initialization status of a window
661 *
662 ************************************************************************/
663
win_is_initalized(UINT32 idx)664 UINT32 win_is_initalized(UINT32 idx)
665 {
666 struct sWindow *pwin = &p_windows[idx];
667
668 if( !p_windows )
669 return FALSE;
670
671 if( idx >= MAX_WINDOWS )
672 return FALSE;
673 if( pwin->text == NULL )
674 return FALSE;
675 if( pwin->attr == NULL )
676 return FALSE;
677
678 return TRUE;
679 }
680
681 /************************************************************************
682 *
683 * Name : win_init_engine()
684 *
685 * Entry: Nothing
686 *
687 * Exit : Nothing
688 *
689 * Description:
690 *
691 * This routine will initialize all variables needed for the windowing
692 * engine to start.
693 *
694 ************************************************************************/
695
win_init_engine(UINT32 w,UINT32 h)696 UINT32 win_init_engine(UINT32 w, UINT32 h)
697 {
698 UINT32 x, y;
699
700 /* Uninitialize if we are currently initialized */
701
702 win_exit_engine(); /* Just in case! */
703
704 screen_w = w;
705 screen_h = h;
706
707 /* Allocate memory for some things */
708
709 p_text = MyMalloc(screen_w * screen_h, "win_init_engine()");
710 p_attr = MyMalloc(screen_w * screen_h, "win_init_engine()");
711 p_windows = MyMalloc(sizeof(struct sWindow) * MAX_WINDOWS, "win_init_engine()");
712 p_prio_map = MyMalloc(screen_w * screen_h, "win_init_engine()");
713 p_shadow_map = MyMalloc(screen_w * screen_h, "win_init_engine()");
714
715 win_update_map();
716
717 for (y = 0; y < screen_h; y++)
718 for (x = 0; x < screen_w; x++)
719 win_out(WIN_EMPTY, WIN_WHITE, x, y, 0);
720
721 return(TRUE);
722 }
723
724 /************************************************************************
725 *
726 * Name : win_exit_engine
727 *
728 * Entry: Nothing
729 *
730 * Exit : Nothing
731 *
732 * Description:
733 *
734 * This routine will shut down the windowing engine
735 *
736 ************************************************************************/
737
win_exit_engine(void)738 void win_exit_engine(void)
739 {
740 UINT32 x, y, i;
741
742 /* Clear the screen. This *MUST* be before the shadow map is freed! */
743
744 if( p_windows )
745 {
746 if( p_text )
747 {
748 for (y = 0; y < screen_h; y++)
749 for (x = 0; x < screen_w; x++)
750 win_out(' ', WIN_WHITE, x, y, 0);
751 }
752
753 for (i = 0; i < MAX_WINDOWS; i++)
754 {
755 if( p_windows[i].text )
756 MyFree((void **) &p_windows[i].text, "win_exit_engine()");
757 if( p_windows[i].attr )
758 MyFree((void **) &p_windows[i].attr, "win_exit_engine()");
759 }
760 }
761
762 if( p_windows )
763 MyFree((void **) &p_windows, "InitWindowEngine()");
764 if( p_prio_map )
765 MyFree((void **) &p_prio_map, "InitWindowEngine()");
766 if( p_shadow_map )
767 MyFree((void **) &p_shadow_map, "InitWindowEngine()");
768 if( p_text )
769 MyFree((void **) &p_text, "InitWindowEngine()");
770 if( p_attr )
771 MyFree((void **) &p_attr, "InitWindowEngine()");
772 }
773
774 /************************************************************************
775 *
776 * Name : win_open
777 *
778 * Entry: Window structure, and priority desired
779 *
780 * Exit : FALSE If couldn't be opened, or TRUE if successful
781 *
782 * Description:
783 *
784 * This routine will allow one to open a window.
785 *
786 ************************************************************************/
787
win_open(UINT32 idx,struct sWindow * psWin)788 UINT32 win_open(UINT32 idx, struct sWindow *psWin)
789 {
790 struct sWindow *pwin = &p_windows[idx];
791 UINT8 affected[MAX_WINDOWS];
792 UINT32 xadd, yadd, i;
793 UINT8 ch = 0, color = 0;
794
795 ASSERT(idx < MAX_WINDOWS); /* This had better be in range */
796 ASSERT(p_windows); /* And this had better be initialized */
797 ASSERT(psWin); /* This, too. */
798
799 memset( affected, 0, sizeof(affected) );
800
801 /* Is the window already open? Return FALSE if so */
802
803 if( pwin->text )
804 return(FALSE);
805
806 xadd = 0;
807 yadd = 0;
808
809 if( psWin->flags & BORDER_LEFT )
810 ++xadd;
811 if( psWin->flags & BORDER_RIGHT )
812 ++xadd;
813 if( psWin->flags & BORDER_TOP )
814 ++yadd;
815 if( psWin->flags & BORDER_BOTTOM )
816 ++yadd;
817
818 /* ASSERT((psWin->x + psWin->w + xadd) <= screen_w);*/
819 /* ASSERT((psWin->y + psWin->h + yadd) <= screen_h);*/
820
821 psWin->text = MyMalloc( screen_w * (yadd + psWin->h), "win_open()" );
822 psWin->attr = MyMalloc( screen_w * (yadd + psWin->h), "win_open()" );
823 psWin->title = MyMalloc( screen_w + 1, "win_open()" );
824
825 /* This is our fill character */
826 ch = psWin->filler;
827 color = psWin->co_text;
828
829 for (i = 0; i < screen_w * (yadd + psWin->h); i++)
830 {
831 psWin->text[i] = ch;
832 psWin->attr[i] = color;
833 }
834
835 psWin->cx = 0;
836 psWin->cy = 0;
837
838 /* Copy it into the regular structure, update the window map and show */
839 /* the window (if it's not hidden) */
840
841 memcpy(pwin, psWin, sizeof(struct sWindow));
842
843 win_update_map();
844 win_update_shadow(idx, affected);
845
846 /* Now that we've erased the residuals, let's go update the windows */
847 /* that need it */
848
849 for (i = 0; i < MAX_WINDOWS; i++)
850 {
851 if( affected[i] || (i == idx) )
852 {
853 win_update(i);
854 win_set_cursor_char(i, p_windows[i].flags & CURSOR_ON, 0);
855 }
856 }
857
858 pwin->saved_text = ch;
859 pwin->saved_attr = color;
860 win_set_cursor_char(idx, pwin->flags & CURSOR_ON, 0);
861
862 /* Now that the window is opened, if there's a resize handler available, */
863 /* call it! */
864
865 if( pwin->Resize )
866 pwin->Resize(idx, pwin);
867
868 return(TRUE);
869 }
870
871 /************************************************************************
872 *
873 * Name : win_close
874 *
875 * Entry: Window #
876 *
877 * Exit : Nothing
878 *
879 * Description:
880 *
881 * This routine will close down a currently opened window and erase it from
882 * the visual screen.
883 *
884 ************************************************************************/
885
win_close(UINT32 idx)886 void win_close(UINT32 idx)
887 {
888 struct sWindow *pwin = &p_windows[idx];
889
890 ASSERT(idx < MAX_WINDOWS); /* This had better be in range */
891 ASSERT(p_windows); /* And this had better be initialized */
892
893 if( NULL == pwin->text )
894 return;
895
896 /* Call the shutdown client if applicable */
897
898 if( pwin->Close )
899 {
900 if( FALSE == pwin->Close(idx, pwin) )
901 return;
902 }
903
904 /* Erase the window from the screen */
905
906 win_erase(idx);
907
908 /* Delete all we've allocated */
909
910 MyFree((void **) &pwin->text, "win_close()"); /* Free our video data */
911 MyFree((void **) &pwin->attr, "win_close()"); /* Free our video data */
912 MyFree((void **) &pwin->title, "win_close()"); /* Free our video data */
913 }
914
915 /************************************************************************
916 *
917 * Name : win_scroll
918 *
919 * Entry: Window # to scroll
920 *
921 * Exit : Window is scrolled and updated (if currently visible)
922 *
923 * Description:
924 *
925 * This routine will scroll a window
926 *
927 ************************************************************************/
928
win_scroll(UINT32 idx)929 UINT32 win_scroll(UINT32 idx)
930 {
931 struct sWindow *pwin = &p_windows[idx];
932 UINT32 i;
933 UINT8 *ptext, *pattr, color;
934
935 ASSERT(idx < MAX_WINDOWS); /* This had better be in range */
936 ASSERT(p_windows); /* And this had better be initialized */
937
938 /* Is the window already open? Return FALSE if so */
939
940 if( NULL == pwin->text )
941 return(FALSE);
942
943 /* If we don't scroll it, don't scroll it! */
944
945 if( pwin->flags & NO_SCROLL )
946 return(FALSE);
947
948 /* Let's do the scroll */
949
950 ptext = pwin->text;
951 pattr = pwin->attr;
952
953 if( pwin->h != 1 )
954 {
955 memcpy( ptext, ptext + screen_w, screen_w * (pwin->h - 1) );
956 memcpy( pattr, pattr + screen_w, screen_w * (pwin->h - 1) );
957 }
958
959 /* Now that we've done the scroll, let's clear out the bottom line */
960
961 color = pwin->co_text;
962 for (i = 0; i < pwin->w; i++)
963 {
964 *ptext++ = ' ';
965 *pattr++ = color;
966 }
967
968 win_update(idx);
969 return(TRUE);
970 }
971
972 /************************************************************************
973 *
974 * Name : win_internal_putchar
975 *
976 * Entry: Character to display
977 *
978 * Exit : relative offset of the cursor after the output
979 *
980 * Description:
981 *
982 * This routine will put a character to the currently active window. This
983 * routine does not take into account the cursor! Use win_putc or win_printf
984 * instead!
985 *
986 ************************************************************************/
987
win_internal_putchar(UINT32 idx,UINT8 ch)988 INT32 win_internal_putchar(UINT32 idx, UINT8 ch)
989 {
990 struct sWindow *pwin = &p_windows[idx];
991 INT32 rel = 0;
992 UINT32 x0, y0;
993 UINT8 color;
994
995 if( NULL == pwin->text )
996 return 0;
997
998 color = pwin->co_text;
999
1000 switch( ch )
1001 {
1002 case '\b': /* Backspace? */
1003 if( pwin->cx )
1004 {
1005 pwin->cx--;
1006 rel--;
1007 }
1008 break;
1009
1010 case '\r': /* Carriage return */
1011 rel = - pwin->cx;
1012 pwin->cx = 0;
1013 break;
1014
1015 case '\n': /* Newline or linefeed? */
1016 #if NEWLINE_ERASE_EOL
1017 win_erase_eol( idx, ' ' );
1018 #endif
1019 rel = - pwin->cx;
1020 pwin->cx = 0;
1021 pwin->cy++;
1022 if( pwin->cy >= pwin->h )
1023 {
1024 pwin->cy--;
1025 win_scroll(idx);
1026 }
1027 break;
1028
1029 case '\t': /* Tab? */
1030 do
1031 {
1032 rel += win_internal_putchar( idx, ' ');
1033 } while( pwin->cx % TAB_STOP );
1034 break;
1035
1036 default:
1037 x0 = pwin->x + pwin->cx;
1038 y0 = pwin->y + pwin->cy;
1039
1040 if( pwin->flags & BORDER_LEFT )
1041 ++x0;
1042 if( pwin->flags & BORDER_TOP )
1043 ++y0;
1044
1045 /* Sanity check */
1046 if( x0 < screen_w && y0 < screen_h )
1047 {
1048 pwin->text[pwin->cy * screen_w + pwin->cx] = ch;
1049 pwin->attr[pwin->cy * screen_w + pwin->cx] = color;
1050 if( pwin->cx < pwin->w )
1051 {
1052 if( p_prio_map[y0 * screen_w + x0] >= pwin->prio && !(pwin->flags & HIDDEN) )
1053 win_out(ch, color, x0, y0, idx);
1054 }
1055 }
1056
1057 rel++;
1058 pwin->cx++;
1059 if( pwin->cx >= pwin->w )
1060 {
1061 /* If we do not wrap at the right side, just exit */
1062 if( pwin->flags & NO_WRAP )
1063 return rel;
1064 pwin->cx = 0;
1065 pwin->cy++;
1066 if( pwin->cy >= pwin->h )
1067 {
1068 win_scroll(idx);
1069 pwin->cy--;
1070 }
1071 }
1072 }
1073 return rel;
1074 }
1075
1076 /************************************************************************
1077 *
1078 * Name : win_putc
1079 *
1080 * Entry: Character to print
1081 *
1082 * Exit : relative offset of the cursor after the output
1083 *
1084 * Description:
1085 *
1086 * This routine will put a character to the currently defined window.
1087 *
1088 ************************************************************************/
1089
win_putc(UINT32 idx,UINT8 bChar)1090 INT32 win_putc(UINT32 idx, UINT8 bChar)
1091 {
1092 struct sWindow *pwin = &p_windows[idx];
1093 INT32 rel;
1094
1095 ASSERT(idx < MAX_WINDOWS); /* This had better be in range */
1096 ASSERT(p_windows); /* And this had better be initialized */
1097
1098 if( NULL == pwin->text )
1099 return 0;
1100
1101 if( pwin->flags & CURSOR_ON )
1102 win_set_cursor_char(idx, 0, pwin->flags);
1103
1104 rel = win_internal_putchar(idx, bChar);
1105
1106 if( pwin->flags & CURSOR_ON )
1107 win_set_cursor_char(idx, 1, 0);
1108
1109 return rel;
1110 }
1111
1112 /************************************************************************
1113 *
1114 * Name : win_erase_eol
1115 *
1116 * Entry: Window # and character to fill with
1117 *
1118 * Exit : None
1119 *
1120 * Description:
1121 *
1122 * This routine will fill a character to the end of the line
1123 *
1124 ************************************************************************/
1125
win_erase_eol(UINT32 idx,UINT8 ch)1126 void win_erase_eol(UINT32 idx, UINT8 ch)
1127 {
1128 struct sWindow *pwin = &p_windows[idx];
1129 UINT32 i, x, y;
1130 UINT32 flags_old;
1131
1132 ASSERT(idx < MAX_WINDOWS); /* This had better be in range */
1133 ASSERT(p_windows); /* And this had better be initialized */
1134
1135 if( NULL == pwin->text )
1136 return;
1137
1138 flags_old = pwin->flags;
1139 pwin->flags |= NO_SCROLL;
1140
1141 if( pwin->flags & CURSOR_ON )
1142 win_set_cursor_char(idx, 0, pwin->flags);
1143
1144 /* Do the fill! */
1145
1146 x = pwin->cx;
1147 y = pwin->cy;
1148 for( i = x; i < pwin->w ; i++ )
1149 win_internal_putchar(idx, ch);
1150
1151 pwin->cx = x;
1152 pwin->cy = y;
1153 pwin->flags = flags_old;
1154
1155 if( pwin->flags & CURSOR_ON )
1156 win_set_cursor_char(idx, 1, 0);
1157 }
1158
1159 /************************************************************************
1160 *
1161 * Name : win_set_curpos
1162 *
1163 * Entry: Window # and x/y coordinates within the window
1164 *
1165 * Exit : Nothing
1166 *
1167 * Description:
1168 *
1169 * This routine will position the cursor within the Window.
1170 *
1171 ************************************************************************/
1172
win_set_curpos(UINT32 idx,UINT32 x,UINT32 y)1173 void win_set_curpos(UINT32 idx, UINT32 x, UINT32 y)
1174 {
1175 struct sWindow *pwin = &p_windows[idx];
1176
1177 ASSERT(idx < MAX_WINDOWS); /* This had better be in range */
1178 ASSERT(p_windows); /* And this had better be initialized */
1179
1180 if( NULL == pwin->text )
1181 return;
1182
1183 /* Make sure we're in range */
1184
1185 /* If we do not wrap at the right side, just exit */
1186 if( !(pwin->flags & NO_WRAP) )
1187 {
1188 if( x >= pwin->w )
1189 return;
1190 if( y >= pwin->h )
1191 return;
1192 }
1193
1194 win_set_cursor_char(idx, 0, pwin->flags & CURSOR_ON);
1195
1196 /* Now put the cursor there */
1197
1198 pwin->cx = x;
1199 pwin->cy = y;
1200 win_set_cursor_char(idx, pwin->flags & CURSOR_ON, 0);
1201 }
1202
1203 static char tmp_text[450];
1204
1205 /************************************************************************
1206 *
1207 * Name : win_vprintf
1208 *
1209 * Entry: window # to and format (with optional arguments) to print
1210 *
1211 * Exit : Nothing
1212 *
1213 * Description:
1214 *
1215 * This routine will send a null terminated string to a window
1216 *
1217 ************************************************************************/
1218
win_vprintf(UINT32 idx,const char * fmt,va_list arg)1219 INT32 win_vprintf(UINT32 idx, const char *fmt, va_list arg)
1220 {
1221 struct sWindow *pwin = &p_windows[idx];
1222 char *src = tmp_text;
1223 int length = 0;
1224
1225 ASSERT(idx < MAX_WINDOWS); /* This had better be in range */
1226 ASSERT(p_windows); /* And this had better be initialized */
1227
1228 if( NULL == pwin->text )
1229 return length;
1230
1231 if( pwin->flags & CURSOR_ON )
1232 win_set_cursor_char(idx, 0, pwin->flags & CURSOR_ON);
1233
1234 length = vsprintf(tmp_text, fmt, arg);
1235
1236 while( *src )
1237 win_internal_putchar( idx, *src++ );
1238
1239 if( pwin->flags & CURSOR_ON )
1240 win_set_cursor_char(idx, 1, 0);
1241
1242 return length;
1243 }
1244
1245
1246 /************************************************************************
1247 *
1248 * Name : win_printf
1249 *
1250 * Entry: window # to and format (with optional arguments) to print
1251 *
1252 * Exit : Nothing
1253 *
1254 * Description:
1255 *
1256 * This routine will send a null terminated string to a window
1257 *
1258 ************************************************************************/
1259
win_printf(UINT32 idx,const char * fmt,...)1260 INT32 DECL_SPEC win_printf(UINT32 idx, const char *fmt, ...)
1261 {
1262 struct sWindow *pwin = &p_windows[idx];
1263 char *src = tmp_text;
1264 int length = 0;
1265 va_list arg;
1266
1267 ASSERT(idx < MAX_WINDOWS); /* This had better be in range */
1268 ASSERT(p_windows); /* And this had better be initialized */
1269
1270 if( NULL == pwin->text )
1271 return length;
1272
1273 if( pwin->flags & CURSOR_ON )
1274 win_set_cursor_char(idx, 0, pwin->flags & CURSOR_ON);
1275
1276 va_start(arg, fmt);
1277 length = vsprintf(tmp_text, fmt, arg);
1278 va_end(arg);
1279
1280 while( *src )
1281 win_internal_putchar( idx, *src++ );
1282
1283 if( pwin->flags & CURSOR_ON )
1284 win_set_cursor_char(idx, 1, 0);
1285
1286 return length;
1287 }
1288
1289 /************************************************************************
1290 *
1291 * Name : win_set_color
1292 *
1293 * Entry: Window # and color
1294 *
1295 * Exit : Nothing
1296 *
1297 * Description:
1298 *
1299 * This routine sets the fore- and background colors for
1300 * subsequent text outputs (win_putc and win_printf)
1301 *
1302 ************************************************************************/
1303
win_set_color(UINT32 idx,UINT32 color)1304 void win_set_color(UINT32 idx, UINT32 color)
1305 {
1306 struct sWindow *pwin = &p_windows[idx];
1307
1308 ASSERT(idx < MAX_WINDOWS); /* This had better be in range */
1309 ASSERT(p_windows); /* And this had better be initialized */
1310
1311 if( NULL == pwin->text )
1312 return;
1313
1314 pwin->co_text = color;
1315 }
1316
1317 /************************************************************************
1318 *
1319 * Name : win_set_title_color
1320 *
1321 * Entry: Window # and new title color
1322 *
1323 * Exit : Nothing
1324 *
1325 * Description:
1326 *
1327 * This routine sets the color for title of a window
1328 *
1329 ************************************************************************/
1330
win_set_title_color(UINT32 idx,UINT32 color)1331 void win_set_title_color(UINT32 idx, UINT32 color)
1332 {
1333 struct sWindow *pwin = &p_windows[idx];
1334
1335 ASSERT(idx < MAX_WINDOWS); /* This had better be in range */
1336 ASSERT(p_windows); /* And this had better be initialized */
1337
1338 if( NULL == pwin->text )
1339 return;
1340
1341 pwin->co_title = color;
1342 win_update( idx );
1343 }
1344
1345 /************************************************************************
1346 *
1347 * Name : win_set_frame_color
1348 *
1349 * Entry: Window # and new frame color
1350 *
1351 * Exit : Nothing
1352 *
1353 * Description:
1354 *
1355 * This routine sets the color for title of a window
1356 *
1357 ************************************************************************/
1358
win_set_frame_color(UINT32 idx,UINT32 color)1359 void win_set_frame_color(UINT32 idx, UINT32 color)
1360 {
1361 struct sWindow *pwin = &p_windows[idx];
1362
1363 ASSERT(idx < MAX_WINDOWS); /* This had better be in range */
1364 ASSERT(p_windows); /* And this had better be initialized */
1365
1366 if( NULL == pwin->text )
1367 return;
1368
1369 pwin->co_frame = color;
1370 win_update( idx );
1371 }
1372
1373 /************************************************************************
1374 *
1375 * Name : win_set_cursor
1376 *
1377 * Entry: Window # and cursor state
1378 *
1379 * Exit : Nothing
1380 *
1381 * Description:
1382 *
1383 * This routine sets the cursor state to on (non zero) or off (zero)
1384 *
1385 ************************************************************************/
1386
win_set_cursor(UINT32 idx,UINT32 state)1387 void win_set_cursor(UINT32 idx, UINT32 state)
1388 {
1389 struct sWindow *pwin = &p_windows[idx];
1390 UINT32 cursor;
1391
1392 ASSERT(idx < MAX_WINDOWS); /* This had better be in range */
1393 ASSERT(p_windows); /* And this had better be initialized */
1394
1395 if( NULL == pwin->text )
1396 return;
1397
1398 if( state )
1399 cursor = pwin->flags |= CURSOR_ON;
1400 else
1401 cursor = pwin->flags &= ~CURSOR_ON;
1402
1403 win_set_cursor_char(idx, state, pwin->flags & CURSOR_ON);
1404
1405 pwin->flags = cursor;
1406 }
1407
1408 /************************************************************************
1409 *
1410 * Name : win_hide
1411 *
1412 * Entry: Window # to hide
1413 *
1414 * Exit : Nothing
1415 *
1416 * Description:
1417 *
1418 * This routine will hide a window.
1419 *
1420 ************************************************************************/
1421
win_hide(UINT32 idx)1422 void win_hide(UINT32 idx)
1423 {
1424 struct sWindow *pwin = &p_windows[idx];
1425
1426 ASSERT(idx < MAX_WINDOWS); /* This had better be in range */
1427 ASSERT(p_windows); /* And this had better be initialized */
1428
1429 /* If it's already hidden, don't hide it again! */
1430
1431 if( pwin->flags & HIDDEN )
1432 return;
1433
1434 /* Otherwise, hide it */
1435
1436 win_erase(idx);
1437 pwin->flags |= HIDDEN;
1438 }
1439
1440 /************************************************************************
1441 *
1442 * Name : win_show
1443 *
1444 * Entry: Window # to show
1445 *
1446 * Exit : Nothing
1447 *
1448 * Description:
1449 *
1450 * This routine will show a window.
1451 *
1452 ************************************************************************/
1453
win_show(UINT32 idx)1454 void win_show(UINT32 idx)
1455 {
1456 struct sWindow *pwin = &p_windows[idx];
1457
1458 ASSERT(idx < MAX_WINDOWS); /* This had better be in range */
1459 ASSERT(p_windows); /* And this had better be initialized */
1460
1461 /* Don't redraw the window if it's already shown */
1462
1463 if( pwin->flags & HIDDEN )
1464 {
1465 pwin->flags &= ~HIDDEN;
1466 win_update_map();
1467 }
1468
1469 /* But update them */
1470 win_update(idx);
1471 }
1472
1473 /************************************************************************
1474 *
1475 * Name : win_set_title
1476 *
1477 * Entry: Window # and new title
1478 *
1479 * Exit :
1480 *
1481 * Description:
1482 *
1483 * Changes the title of a window and updates the screen
1484 *
1485 ************************************************************************/
1486
win_set_title(UINT32 idx,const char * fmt,...)1487 UINT32 DECL_SPEC win_set_title(UINT32 idx, const char *fmt, ... )
1488 {
1489 struct sWindow *pwin = &p_windows[idx];
1490 va_list arg;
1491
1492 ASSERT(idx < MAX_WINDOWS); /* This had better be in range */
1493 ASSERT(p_windows); /* And this had better be initialized */
1494
1495 /* If BORDER_TOP is not set, changing a title makes no sense */
1496 if( (pwin->flags & BORDER_TOP) == 0 )
1497 return FALSE;
1498
1499 va_start(arg, fmt);
1500 vsprintf(tmp_text, fmt, arg);
1501 va_end(arg);
1502
1503 /* If a title is there and did not change, just exit */
1504 if( pwin->title && !strcmp(pwin->title, tmp_text) )
1505 return TRUE;
1506
1507 strncpy( pwin->title, tmp_text, screen_w );
1508
1509 win_update(idx);
1510 return TRUE;
1511 }
1512
1513 /************************************************************************
1514 *
1515 * Name : win_get_cx
1516 *
1517 * Entry: Window #
1518 *
1519 * Exit : Cursor X
1520 *
1521 * Description:
1522 *
1523 * Returns the cursor X coordinate for a window
1524 *
1525 ************************************************************************/
1526
win_get_cx(UINT32 idx)1527 UINT32 win_get_cx(UINT32 idx)
1528 {
1529 struct sWindow *pwin = &p_windows[idx];
1530
1531 ASSERT(idx < MAX_WINDOWS); /* This had better be in range */
1532 ASSERT(p_windows); /* And this had better be initialized */
1533
1534 return pwin->cx;
1535 }
1536
1537 /************************************************************************
1538 *
1539 * Name : win_get_cy
1540 *
1541 * Entry: Window #
1542 *
1543 * Exit : Cursor Y
1544 *
1545 * Description:
1546 *
1547 * Returns the cursor Y coordinate for a window
1548 *
1549 ************************************************************************/
1550
win_get_cy(UINT32 idx)1551 UINT32 win_get_cy(UINT32 idx)
1552 {
1553 struct sWindow *pwin = &p_windows[idx];
1554
1555 ASSERT(idx < MAX_WINDOWS); /* This had better be in range */
1556 ASSERT(p_windows); /* And this had better be initialized */
1557
1558 return pwin->cy;
1559 }
1560
1561 /************************************************************************
1562 *
1563 * Name : win_get_cx_abs
1564 *
1565 * Entry: Window #
1566 *
1567 * Exit : Cursor X
1568 *
1569 * Description:
1570 *
1571 * Returns the screen (absolute) Cursor X coordinate for a window
1572 *
1573 ************************************************************************/
1574
win_get_cx_abs(UINT32 idx)1575 UINT32 win_get_cx_abs(UINT32 idx)
1576 {
1577 struct sWindow *pwin = &p_windows[idx];
1578 UINT32 x;
1579
1580 ASSERT(idx < MAX_WINDOWS); /* This had better be in range */
1581 ASSERT(p_windows); /* And this had better be initialized */
1582
1583 x = pwin->x + pwin->cx;
1584 if( pwin->flags & BORDER_LEFT )
1585 x++;
1586
1587 return x;
1588 }
1589
1590 /************************************************************************
1591 *
1592 * Name : win_get_cy_abs
1593 *
1594 * Entry: Window #
1595 *
1596 * Exit : Cursor Y
1597 *
1598 * Description:
1599 *
1600 * Returns the screen (absolute) Cursor Y coordinate for a window
1601 *
1602 ************************************************************************/
1603
win_get_cy_abs(UINT32 idx)1604 UINT32 win_get_cy_abs(UINT32 idx)
1605 {
1606 struct sWindow *pwin = &p_windows[idx];
1607 UINT32 y;
1608
1609 ASSERT(idx < MAX_WINDOWS); /* This had better be in range */
1610 ASSERT(p_windows); /* And this had better be initialized */
1611
1612 y = pwin->y + pwin->cy;
1613 if( pwin->flags & BORDER_TOP )
1614 y++;
1615
1616 return y;
1617 }
1618
1619 /************************************************************************
1620 *
1621 * Name : win_get_x_abs
1622 *
1623 * Entry: Window #
1624 *
1625 * Exit : AbsX
1626 *
1627 * Description:
1628 *
1629 * Returns the screen (absolute) X coordinate for a window
1630 *
1631 ************************************************************************/
1632
win_get_x_abs(UINT32 idx)1633 UINT32 win_get_x_abs(UINT32 idx)
1634 {
1635 struct sWindow *pwin = &p_windows[idx];
1636 UINT32 x;
1637
1638 ASSERT(idx < MAX_WINDOWS); /* This had better be in range */
1639 ASSERT(p_windows); /* And this had better be initialized */
1640
1641 x = pwin->x;
1642 if( pwin->flags & BORDER_LEFT )
1643 x++;
1644
1645 return x;
1646 }
1647
1648 /************************************************************************
1649 *
1650 * Name : win_get_y_abs
1651 *
1652 * Entry: Window #
1653 *
1654 * Exit : AbsY
1655 *
1656 * Description:
1657 *
1658 * Returns the screen (absolute) Y coordinate for a window
1659 *
1660 ************************************************************************/
1661
win_get_y_abs(UINT32 idx)1662 UINT32 win_get_y_abs(UINT32 idx)
1663 {
1664 struct sWindow *pwin = &p_windows[idx];
1665 UINT32 y;
1666
1667 ASSERT(idx < MAX_WINDOWS); /* This had better be in range */
1668 ASSERT(p_windows); /* And this had better be initialized */
1669
1670 y = pwin->y;
1671 if( pwin->flags & BORDER_TOP )
1672 y++;
1673
1674 return y;
1675 }
1676
1677 /************************************************************************
1678 *
1679 * Name : win_get_w
1680 *
1681 * Entry: Window #
1682 *
1683 * Exit : Width
1684 *
1685 * Description:
1686 *
1687 * Returns the width of a window
1688 *
1689 ************************************************************************/
1690
win_get_w(UINT32 idx)1691 UINT32 win_get_w(UINT32 idx)
1692 {
1693 struct sWindow *pwin = &p_windows[idx];
1694
1695 ASSERT(idx < MAX_WINDOWS); /* This had better be in range */
1696 ASSERT(p_windows); /* And this had better be initialized */
1697
1698 return pwin->w;
1699 }
1700
1701 /************************************************************************
1702 *
1703 * Name : win_get_h
1704 *
1705 * Entry: Window #
1706 *
1707 * Exit : Height
1708 *
1709 * Description:
1710 *
1711 * Returns the height of a window
1712 *
1713 ************************************************************************/
1714
win_get_h(UINT32 idx)1715 UINT32 win_get_h(UINT32 idx)
1716 {
1717 struct sWindow *pwin = &p_windows[idx];
1718
1719 ASSERT(idx < MAX_WINDOWS); /* This had better be in range */
1720 ASSERT(p_windows); /* And this had better be initialized */
1721
1722 return pwin->h;
1723 }
1724
1725 /************************************************************************
1726 *
1727 * Name : win_set_w
1728 *
1729 * Entry: Window # and new width
1730 *
1731 * Exit : Nothing
1732 *
1733 * Description:
1734 *
1735 * Changes the width of a window
1736 *
1737 ************************************************************************/
1738
win_set_w(UINT32 idx,UINT32 w)1739 void win_set_w(UINT32 idx, UINT32 w)
1740 {
1741 struct sWindow *pwin = &p_windows[idx];
1742
1743 ASSERT(idx < MAX_WINDOWS); /* This had better be in range */
1744 ASSERT(p_windows); /* And this had better be initialized */
1745
1746 win_erase(idx);
1747 pwin->w = w;
1748 win_update_map();
1749 win_update(idx);
1750 }
1751
1752 /************************************************************************
1753 *
1754 * Name : win_set_h
1755 *
1756 * Entry: Window # and new height
1757 *
1758 * Exit : Nothing
1759 *
1760 * Description:
1761 *
1762 * Changes the height of a window
1763 *
1764 ************************************************************************/
1765
win_set_h(UINT32 idx,UINT32 h)1766 void win_set_h(UINT32 idx, UINT32 h)
1767 {
1768 struct sWindow *pwin = &p_windows[idx];
1769 UINT32 yadd;
1770 ASSERT(idx < MAX_WINDOWS); /* This had better be in range */
1771 ASSERT(p_windows); /* And this had better be initialized */
1772
1773 yadd = 0;
1774
1775 if( pwin->flags & BORDER_TOP )
1776 ++yadd;
1777 if( pwin->flags & BORDER_BOTTOM )
1778 ++yadd;
1779
1780 win_erase(idx);
1781 pwin->text = MyReAlloc(pwin->text, screen_w * (h + yadd), "win_set_h()");
1782 pwin->attr = MyReAlloc(pwin->attr, screen_w * (h + yadd), "win_set_h()");
1783 pwin->h = h;
1784 if( pwin->cy >= pwin->h )
1785 pwin->cy = pwin->h - 1;
1786 win_update_map();
1787 win_update(idx);
1788 }
1789
1790 /************************************************************************
1791 *
1792 * Name : win_get_prio
1793 *
1794 * Entry: Window #
1795 *
1796 * Exit : Priority of window
1797 *
1798 * Description:
1799 *
1800 * Returns the current priority of a window
1801 *
1802 ************************************************************************/
1803
win_get_prio(UINT32 idx)1804 UINT8 win_get_prio(UINT32 idx)
1805 {
1806 struct sWindow *pwin = &p_windows[idx];
1807
1808 ASSERT(idx < MAX_WINDOWS); /* This had better be in range */
1809 ASSERT(p_windows); /* And this had better be initialized */
1810
1811 return pwin->prio;
1812 }
1813
1814 /************************************************************************
1815 *
1816 * Name : win_set_prio
1817 *
1818 * Entry: Window # and new priority
1819 *
1820 * Exit : Nothing
1821 *
1822 * Description:
1823 *
1824 * Changes the priority of a window
1825 *
1826 ************************************************************************/
1827
win_set_prio(UINT32 idx,UINT8 prio)1828 void win_set_prio(UINT32 idx, UINT8 prio)
1829 {
1830 struct sWindow *pwin = &p_windows[idx];
1831
1832 ASSERT(idx < MAX_WINDOWS); /* This had better be in range */
1833 ASSERT(p_windows); /* And this had better be initialized */
1834
1835 if( pwin->prio == prio )
1836 return;
1837
1838 win_erase(idx);
1839 pwin->prio = prio;
1840 win_update_map();
1841 win_update(idx);
1842 }
1843
1844 /************************************************************************
1845 *
1846 * Name : win_move
1847 *
1848 * Entry: Window #, new x and y coordinates
1849 *
1850 * Exit :
1851 *
1852 * Description:
1853 *
1854 * Moves a window to a new position
1855 *
1856 ************************************************************************/
1857
win_move(UINT32 idx,UINT32 x,UINT32 y)1858 void win_move(UINT32 idx, UINT32 x, UINT32 y)
1859 {
1860 struct sWindow *pwin = &p_windows[idx];
1861
1862 ASSERT(idx < MAX_WINDOWS); /* This had better be in range */
1863 ASSERT(p_windows); /* And this had better be initialized */
1864 win_erase(idx);
1865 pwin->x = x;
1866 pwin->y = y;
1867 win_update_map();
1868 win_update(idx);
1869 }
1870
1871 /************************************************************************
1872 *
1873 * Name : win_invalidate_video
1874 *
1875 * Entry: Nothing
1876 *
1877 * Exit : Nothing
1878 *
1879 * Description:
1880 *
1881 * Invalidates the video memory (eg. after a switch to graphics mode)
1882 *
1883 ************************************************************************/
1884
win_invalidate_video(void)1885 void win_invalidate_video(void)
1886 {
1887
1888 if( p_text == NULL || p_attr == NULL )
1889 return;
1890
1891 memset( p_text, 0xff, screen_w * screen_h );
1892 memset( p_attr, 0xff, screen_w * screen_h );
1893 }
1894
1895 #endif
1896