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