1 /**
2  ** gfaz.c ---- Mini GUI for GRX
3  **
4  ** Copyright (C) 2000,2001 Mariano Alvarez Fernandez
5  ** [e-mail: malfer@teleline.es]
6  **
7  ** This is a test/demo file of the GRX graphics library.
8  ** You can use GRX test/demo files as you want.
9  **
10  ** The GRX graphics library is free software; you can redistribute it
11  ** and/or modify it under some conditions; see the "copying.grx" file
12  ** for details.
13  **
14  ** This library is distributed in the hope that it will be useful,
15  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17  **
18  **/
19 
20 #include <stdlib.h>
21 #include <string.h>
22 #include <grx20.h>
23 #include <grxkeys.h>
24 #include "gfaz.h"
25 
26 GrColor *egacolors;
27 
28 static int mouse_found = 0;
29 static int mouse_count = 0;
30 
31 #define MAX_EVQUEUE 10
32 
33 static Event evqueue[MAX_EVQUEUE];
34 static int num_evqueue = 0;
35 
36 static void (*hook_input_event)( Event * ) = NULL;
37 
38 /* Internal routines */
39 
40 static int read_input( void );
41 static void input_event_queue( Event *ev );
42 static int coord_into( int x, int y, int xo, int yo, int xl, int yl );
43 
44 /**************************************************************************/
45 
gfaz_ini(int width,int height,int bpp)46 int gfaz_ini( int width, int height, int bpp )
47 {
48 /*  __djgpp_set_ctrl_c( 0 );*/
49 /*  _go32_want_ctrl_break( 1 );*/
50 /*  GrSetMode( GR_default_graphics );*/
51 
52   GrSetMode( GR_width_height_bpp_graphics,width,height,bpp );
53 
54   egacolors = GrAllocEgaColors();
55 
56   if( GrMouseDetect() ){
57     mouse_found = 1;
58     GrMouseInit();
59     GrMouseSetColors( GrWhite(),GrBlack() );
60     show_mouse();
61     }
62   GrMouseEventEnable( 1,mouse_found );
63 
64   return 0;
65 }
66 
67 /**************************************************************************/
68 
gfaz_fin(void)69 int gfaz_fin( void )
70 {
71   if( mouse_found ){
72     hide_mouse();
73     GrMouseUnInit();
74     }
75 
76   GrSetMode( GR_default_text );
77 
78   return 0;
79 }
80 
81 /**************************************************************************/
82 
event_read(Event * ev)83 void event_read( Event *ev )
84 {
85   while( 1 ){
86     if( num_evqueue > 0 ){
87       num_evqueue--;
88       *ev = evqueue[num_evqueue];
89       return;
90       }
91     if( read_input() ){
92       continue;
93       }
94     ev->type = EV_NULL;
95     ev->p1 = 0;
96     ev->p2 = 0;
97     ev->p3 = 0;
98     return;
99     }
100 }
101 
102 /**************************************************************************/
103 
event_wait(Event * ev)104 void event_wait( Event *ev )
105 {
106   while( 1 ){
107     event_read( ev );
108     if( ev->type != EV_NULL )
109       return;
110     }
111 }
112 
113 /**************************************************************************/
114 
event_queue(Event * ev)115 void event_queue( Event *ev )
116 {
117   if( num_evqueue < MAX_EVQUEUE )
118     evqueue[num_evqueue++] = *ev;
119 }
120 
121 /**************************************************************************/
122 
par_event_queue(int type,long p1,long p2,long p3)123 void par_event_queue( int type, long p1, long p2, long p3 )
124 {
125   Event ev;
126 
127   ev.type = type;
128   ev.p1 = p1;
129   ev.p2 = p2;
130   ev.p3 = p3;
131   event_queue( &ev );
132 }
133 
134 /**************************************************************************/
135 
set_hook_input_event(void (* fn)(Event *))136 void set_hook_input_event( void (*fn)( Event * ) )
137 {
138   hook_input_event = fn;
139 }
140 
141 /**************************************************************************/
142 
input_event_queue(Event * ev)143 static void input_event_queue( Event *ev )
144 {
145   if( hook_input_event != NULL )
146     hook_input_event( ev );
147   else
148     event_queue( ev );
149 }
150 
151 /************************************************************************/
152 
read_input(void)153 static int read_input( void )
154 {
155   GrMouseEvent evt;
156   Event evaux;
157 
158   GrMouseGetEventT( GR_M_EVENT,&evt,10L );
159   if( evt.dtime == -1 ) return 0;
160 
161   if( evt.flags & GR_M_KEYPRESS ){
162     evaux.type = EV_KEY;
163     evaux.p1 = evt.key;
164     evaux.p2 = 0;
165     evaux.p3 = 0;
166     input_event_queue( &evaux );
167     }
168   evaux.type = EV_MOUSE;
169   evaux.p2 = evt.x;
170   evaux.p3 = evt.y;
171   if( evt.flags & GR_M_LEFT_DOWN ){
172     evaux.p1 = MOUSE_LB_PRESSED;
173     input_event_queue( &evaux );
174     }
175   if( evt.flags & GR_M_RIGHT_DOWN ){
176     evaux.p1 = MOUSE_RB_PRESSED;
177     input_event_queue( &evaux );
178     }
179   if( evt.flags & GR_M_LEFT_UP ){
180     evaux.p1 = MOUSE_LB_RELEASED;
181     input_event_queue( &evaux );
182     }
183   if( evt.flags & GR_M_RIGHT_UP ){
184     evaux.p1 = MOUSE_RB_RELEASED;
185     input_event_queue( &evaux );
186     }
187   return 1;
188 }
189 
190 /**************************************************************************/
191 
show_mouse(void)192 void show_mouse( void )
193 {
194   if( (mouse_count == 0) && mouse_found )
195     GrMouseDisplayCursor();
196 
197   mouse_count++;
198 }
199 
200 /************************************************************************/
201 
hide_mouse(void)202 void hide_mouse( void )
203 {
204   mouse_count--;
205 
206   if( (mouse_count == 0) && mouse_found )
207     GrMouseEraseCursor();
208 }
209 
210 /**************************************************************************/
211 
dboton(int x,int y,int an,int al,GrColor c,GrColor ct,char * s,int t)212 void dboton( int x, int y, int an, int al,
213              GrColor c, GrColor ct, char * s, int t )
214 
215 //   x, y posici�n de la esquina izquierda
216 //   an, al ancho y alto
217 //   c, ct color del fondo y del texto
218 //   t, tipo bit 0 0=normal, 1=apretado
219 //           bit 1 0=no selec, 1=seleccionado
220 
221 {
222   int pol[7][2], prof, pulsd, selec, despl;
223   GrTextOption grt;
224   GrLineOption glo;
225   int mouseblock;
226 
227   prof = (t & 0x1) ? 2 : 4;
228   pulsd = (t & 0x1) ? 1 : 0;
229   selec = (t & 0x2) ? 1 : 0;
230   despl = (t & 0x1) ? 1 : 0;
231 
232   mouseblock = GrMouseBlock( NULL,x,y,x+an-1,y+al-1 );
233   GrBox( x,y,x+an-1,y+al-1,BLACK );
234   x = x + 1; y = y + 1;
235   an = an - 2; al = al - 2;
236 
237   pol[0][0] = x;                 pol[0][1] = y;
238   pol[1][0] = x + an - 1;        pol[1][1] = y;
239   pol[2][0] = x + an - 2 - prof; pol[2][1] = y + 1 + prof;
240   pol[3][0] = x + 1 + prof;      pol[3][1] = y + 1 + prof;
241   pol[4][0] = x + 1 + prof;      pol[4][1] = y + al - 2 - prof;
242   pol[5][0] = x;                 pol[5][1] = y + al - 1;
243   pol[6][0] = pol[0][0];         pol[6][1] = pol[0][1];
244   GrFilledPolygon( 7,pol,pulsd ? DARKGRAY : LIGHTGRAY );
245   GrPolygon( 7,pol,BLACK );
246   GrLine( pol[0][0],pol[0][1],pol[3][0],pol[3][1],BLACK );
247   pol[0][0] = x + an - 1;        pol[0][1] = y + al - 1;
248   pol[3][0] = x + an - 2 - prof; pol[3][1] = y + al - 2 - prof;
249   pol[6][0] = pol[0][0];         pol[6][1] = pol[0][1];
250   GrFilledPolygon( 7,pol,pulsd ? LIGHTGRAY : DARKGRAY );
251   GrPolygon( 7,pol,BLACK );
252   GrLine( pol[0][0],pol[0][1],pol[3][0],pol[3][1],BLACK );
253   GrFilledBox( x+2+prof,y+2+prof,x+an-3-prof,y+al-3-prof,c );
254 
255   grt.txo_font = &GrFont_PC8x14;
256   grt.txo_fgcolor.v = ct;
257   grt.txo_bgcolor.v = GrNOCOLOR;
258   grt.txo_direct = GR_TEXT_RIGHT;
259   grt.txo_xalign = GR_ALIGN_CENTER;
260   grt.txo_yalign = GR_ALIGN_CENTER;
261   grt.txo_chrtype = GR_BYTE_TEXT;
262   if( despl )
263     GrDrawString( s,strlen( s ),x+an/2+1,y+al/2+1,&grt );
264   else
265     GrDrawString( s,strlen( s ),x+an/2,y+al/2,&grt );
266 
267   if( selec ){
268     glo.lno_color = ct;
269     glo.lno_width = 1;
270     glo.lno_pattlen = 2;
271     glo.lno_dashpat = "\2\1";
272     GrCustomBox( x+8,y+al/2-6,x+an-8,y+al/2+5,&glo );
273     }
274 
275   GrMouseUnBlock( mouseblock );
276 }
277 
278 /**************************************************************************/
279 
paint_button(int x,int y,Button * b)280 void paint_button( int x, int y, Button *b )
281 {
282   dboton( x+b->x,y+b->y,b->wide,b->high,
283           egacolors[b->tbcolor],egacolors[b->tfcolor],
284           b->text,b->status );
285 }
286 
287 /**************************************************************************/
288 
paint_button_group(Button_Group * bg)289 void paint_button_group( Button_Group *bg )
290 {
291   int i;
292 
293   for( i=0; i<bg->nb; i++ )
294     paint_button( bg->x,bg->y,&(bg->b[i]) );
295 }
296 
297 /**************************************************************************/
298 
pev_button_group(Event * ev,Button_Group * bg)299 int pev_button_group( Event *ev, Button_Group *bg )
300 {
301   int i;
302 
303   if( ev->type == EV_MOUSE ){
304     if( ev->p1 == MOUSE_LB_PRESSED ){
305       for( i=0; i<bg->nb; i++ )
306         if( coord_into( ev->p2,ev->p3,
307                         bg->x+bg->b[i].x,bg->y+bg->b[i].y,
308                         bg->b[i].wide,bg->b[i].high ) ){
309           bg->b[bg->pb].status &= ~BSTATUS_SELECTED;
310           paint_button( bg->x,bg->y,&(bg->b[bg->pb]) );
311           bg->b[i].status |= BSTATUS_PRESSED | BSTATUS_SELECTED;
312           paint_button( bg->x,bg->y,&(bg->b[i]) );
313           bg->pb = i;
314           bg->abp = 1;
315           par_event_queue( EV_SELECT,bg->b[i].bid,0,0 );
316           return 1;
317           }
318       }
319     if( ev->p1 == MOUSE_LB_RELEASED ){
320       if( bg->abp ){
321         i = bg->pb;
322         bg->b[i].status &= ~BSTATUS_PRESSED;
323         paint_button( bg->x,bg->y,&(bg->b[i]) );
324         bg->abp = 0;
325         if( coord_into( ev->p2,ev->p3,
326                         bg->x+bg->b[i].x,bg->y+bg->b[i].y,
327                         bg->b[i].wide,bg->b[i].high ) ){
328           par_event_queue( EV_COMMAND,bg->b[i].bid,0,0 );
329           }
330         return 1;
331         }
332       }
333     }
334   else if( ev->type == EV_KEY ){
335     if( ev->p1 == GrKey_Right ||
336         ev->p1 == GrKey_Down ||
337         ev->p1 == GrKey_Tab ){
338       if( bg->pb < bg->nb-1 ){
339         bg->b[bg->pb].status &= ~BSTATUS_SELECTED;
340         paint_button( bg->x,bg->y,&(bg->b[bg->pb]) );
341         bg->pb++;
342         bg->b[bg->pb].status |= BSTATUS_SELECTED;
343         paint_button( bg->x,bg->y,&(bg->b[bg->pb]) );
344         par_event_queue( EV_SELECT,bg->b[bg->pb].bid,0,0 );
345         }
346       return 1;
347       }
348     else if( ev->p1 == GrKey_Left ||
349              ev->p1 == GrKey_Up ||
350              ev->p1 == GrKey_BackTab ){
351       if( bg->pb > 0 ){
352         bg->b[bg->pb].status &= ~BSTATUS_SELECTED;
353         paint_button( bg->x,bg->y,&(bg->b[bg->pb]) );
354         bg->pb--;
355         bg->b[bg->pb].status |= BSTATUS_SELECTED;
356         paint_button( bg->x,bg->y,&(bg->b[bg->pb]) );
357         par_event_queue( EV_SELECT,bg->b[bg->pb].bid,0,0 );
358         }
359       return 1;
360       }
361     else if( ev->p1 == GrKey_Return ){
362       par_event_queue( EV_COMMAND,bg->b[bg->pb].bid,0,0 );
363       return 1;
364       }
365     }
366 
367   return 0;
368 }
369 
370 /**************************************************************************/
371 
coord_into(int x,int y,int xo,int yo,int xl,int yl)372 static int coord_into( int x, int y, int xo, int yo, int xl, int yl )
373 {
374   if( x < xo ) return 0;
375   if( x >= xo+xl ) return 0;
376   if( y < yo ) return 0;
377   if( y >= yo+yl ) return 0;
378   return 1;
379 }
380 
381 /**************************************************************************/
382 
paint_board(Board * b)383 void paint_board( Board *b )
384 {
385   int x1, y1, x2, y2;
386 
387   x1 = b->x;
388   y1 = b->y;
389   x2 = b->x + b->wide - 1;
390   y2 = b->y + b->high - 1;
391 
392   GrBox( x1,y1,x2,y2,egacolors[b->lcolor] );
393   GrBox( x1+1,y1+1,x2-1,y2-1,egacolors[b->bcolor] );
394   GrBox( x1+2,y1+2,x2-2,y2-2,egacolors[b->bcolor] );
395   GrBox( x1+3,y1+3,x2-3,y2-3,egacolors[b->lcolor] );
396   GrFilledBox( x1+4,y1+4,x2-4,y2-4,egacolors[b->color] );
397 }
398 
399