1 /*
2   Hatari - sdlgui.c
3 
4   This file is distributed under the GNU General Public License, version 2
5   or at your option any later version. Read the file gpl.txt for details.
6 
7   A tiny graphical user interface for Hatari.
8 */
9 const char SDLGui_fileid[] = "Hatari sdlgui.c : " __DATE__ " " __TIME__;
10 
11 #include <SDL.h>
12 #include <ctype.h>
13 #include <string.h>
14 
15 #include "main.h"
16 #include "sdlgui.h"
17 
18 //RETRO DEF
19 
20 #include "gui-retro.h"
21 
22 extern int touch;
23 int gmx,gmy;
24 int okold=0,boutc=0;
25 
26 extern unsigned short int bmp[1024*1024];
27 #define B ((rgba>> 8)&0xff)>>3
28 #define G ((rgba>>16)&0xff)>>3
29 #define R ((rgba>>24)&0xff)>>3
30 
31 #define RGB565(r, g, b)  (((r) << (5+6)) | ((g) << 6) | (b))
32 
33 extern void Draw_text(unsigned  short *buffer,int x,int y,unsigned  short  fgcol,unsigned  short int bgcol ,int scalex,int scaley , int max,char *string,...);
34 extern void DrawFBoxBmp(unsigned  short  *buffer,int x,int y,int dx,int dy,unsigned  short color);
35 extern void input_gui();
36 
37 static const char *cross[] = {
38   "X                               ",
39   "XX                              ",
40   "X.X                             ",
41   "X..X                            ",
42   "X...X                           ",
43   "X....X                          ",
44   "X.....X                         ",
45   "X......X                        ",
46   "X.......X                       ",
47   "X........X                      ",
48   "X.....XXXXX                     ",
49   "X..X..X                         ",
50   "X.X X..X                        ",
51   "XX  X..X                        ",
52   "X    X..X                       ",
53   "     X..X                       ",
54   "      X..X                      ",
55   "      X..X                      ",
56   "       XX                       ",
57   "                                ",
58 };
59 
draw_cross(int x,int y)60 void draw_cross(int x,int y) {
61 
62 	int i,j,idx;
63 	int dx=32,dy=20;
64 	unsigned  short color;
65 
66 	for(j=y;j<y+dy;j++){
67 		idx=0;
68 		for(i=x;i<x+dx;i++){
69 			if(cross[j-y][idx]=='.')DrawPointBmp(bmp,i,j,0xffff);
70 			else if(cross[j-y][idx]=='X')DrawPointBmp(bmp,i,j,0);
71 			idx++;
72 		}
73 	}
74 }
75 
76 
77 #if 0
78 #include "font5x8.h"
79 #include "font10x16.h"
80 #endif
81 static SDL_Surface *pSdlGuiScrn;            /* Pointer to the actual main SDL screen surface */
82 #if 0
83 static SDL_Surface *pSmallFontGfx = NULL;   /* The small font graphics */
84 static SDL_Surface *pBigFontGfx = NULL;     /* The big font graphics */
85 static SDL_Surface *pFontGfx = NULL;        /* The actual font graphics */
86 #endif
87 
88 static int current_object = 0;				/* Current selected object */
89 
90 int sdlgui_fontwidth;			/* Width of the actual font */
91 int sdlgui_fontheight;			/* Height of the actual font */
92 #if 0
93 /*-----------------------------------------------------------------------*/
94 /**
95  * Load an 1 plane XBM into a 8 planes SDL_Surface.
96  */
97 static SDL_Surface *SDLGui_LoadXBM(int w, int h, const Uint8 *pXbmBits)
98 {
99 	SDL_Surface *bitmap;
100 	Uint8 *dstbits;
101 	const Uint8 *srcbits;
102 	int x, y, srcpitch;
103 	int mask;
104 
105 	srcbits = pXbmBits;
106 
107 	/* Allocate the bitmap */
108 	bitmap = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 8, 0, 0, 0, 0);
109 	if (bitmap == NULL)
110 	{
111 		fprintf(stderr, "Failed to allocate bitmap: %s", SDL_GetError());
112 		return NULL;
113 	}
114 
115 	srcpitch = ((w + 7) / 8);
116 	dstbits = (Uint8 *)bitmap->pixels;
117 	mask = 1;
118 
119 	/* Copy the pixels */
120 	for (y = 0 ; y < h ; y++)
121 	{
122 		for (x = 0 ; x < w ; x++)
123 		{
124 			dstbits[x] = (srcbits[x / 8] & mask) ? 1 : 0;
125 			mask <<= 1;
126 			mask |= (mask >> 8);
127 			mask &= 0xFF;
128 		}
129 		dstbits += bitmap->pitch;
130 		srcbits += srcpitch;
131 	}
132 
133 	return bitmap;
134 }
135 #endif
136 
137 /*-----------------------------------------------------------------------*/
138 /**
139  * Initialize the GUI.
140  */
SDLGui_Init(void)141 int SDLGui_Init(void)
142 {
143 #if 0
144 	SDL_Color blackWhiteColors[2] = {{255, 255, 255, 0}, {0, 0, 0, 0}};
145 
146 	if (pSmallFontGfx && pBigFontGfx)
147 	{
148 		/* already initialized */
149 		return 0;
150 	}
151 
152 	/* Initialize the font graphics: */
153 	pSmallFontGfx = SDLGui_LoadXBM(font5x8_width, font5x8_height, font5x8_bits);
154 	pBigFontGfx = SDLGui_LoadXBM(font10x16_width, font10x16_height, font10x16_bits);
155 	if (pSmallFontGfx == NULL || pBigFontGfx == NULL)
156 	{
157 		fprintf(stderr, "Error: Can not init font graphics!\n");
158 		return -1;
159 	}
160 
161 	/* Set color palette of the font graphics: */
162 	SDL_SetColors(pSmallFontGfx, blackWhiteColors, 0, 2);
163 	SDL_SetColors(pBigFontGfx, blackWhiteColors, 0, 2);
164 
165 	/* Set font color 0 as transparent: */
166 	SDL_SetColorKey(pSmallFontGfx, (SDL_SRCCOLORKEY|SDL_RLEACCEL), 0);
167 	SDL_SetColorKey(pBigFontGfx, (SDL_SRCCOLORKEY|SDL_RLEACCEL), 0);
168 #endif
169 	return 0;
170 }
171 
172 
173 /*-----------------------------------------------------------------------*/
174 /**
175  * Uninitialize the GUI.
176  */
SDLGui_UnInit(void)177 int SDLGui_UnInit(void)
178 {
179 #if 0
180 	if (pSmallFontGfx)
181 	{
182 		SDL_FreeSurface(pSmallFontGfx);
183 		pSmallFontGfx = NULL;
184 	}
185 
186 	if (pBigFontGfx)
187 	{
188 		SDL_FreeSurface(pBigFontGfx);
189 		pBigFontGfx = NULL;
190 	}
191 #endif
192 	return 0;
193 }
194 
195 
196 /*-----------------------------------------------------------------------*/
197 /**
198  * Inform the SDL-GUI about the actual SDL_Surface screen pointer and
199  * prepare the font to suit the actual resolution.
200  */
SDLGui_SetScreen(SDL_Surface * pScrn)201 int SDLGui_SetScreen(SDL_Surface *pScrn)
202 {
203 #if 0
204 	pSdlGuiScrn = pScrn;
205 
206 	/* Decide which font to use - small or big one: */
207 	if (pSdlGuiScrn->w >= 640 && pSdlGuiScrn->h >= 400 && pBigFontGfx != NULL)
208 	{
209 		pFontGfx = pBigFontGfx;
210 	}
211 	else
212 	{
213 		pFontGfx = pSmallFontGfx;
214 	}
215 
216 	if (pFontGfx == NULL)
217 	{
218 		fprintf(stderr, "Error: A problem with the font occurred!\n");
219 		return -1;
220 	}
221 
222 	/* Get the font width and height: */
223 	sdlgui_fontwidth = pFontGfx->w/16;
224 	sdlgui_fontheight = pFontGfx->h/16;
225 
226 	return 0;
227 #else
228 	pSdlGuiScrn = pScrn;
229 	memset(bmp, 0, sizeof(bmp));
230 
231 	sdlgui_fontwidth  = 10;
232 	sdlgui_fontheight = 16;
233 	return 0;
234 #endif
235 }
236 
237 /*-----------------------------------------------------------------------*/
238 /**
239  * Return character size for current font in given arguments.
240  */
SDLGui_GetFontSize(int * width,int * height)241 void SDLGui_GetFontSize(int *width, int *height)
242 {
243 	*width = sdlgui_fontwidth;
244 	*height = sdlgui_fontheight;
245 }
246 
247 /*-----------------------------------------------------------------------*/
248 /**
249  * Center a dialog so that it appears in the middle of the screen.
250  * Note: We only store the coordinates in the root box of the dialog,
251  * all other objects in the dialog are positioned relatively to this one.
252  */
SDLGui_CenterDlg(SGOBJ * dlg)253 void SDLGui_CenterDlg(SGOBJ *dlg)
254 {
255 	dlg[0].x = (pSdlGuiScrn->w/sdlgui_fontwidth-dlg[0].w)/2;
256 	dlg[0].y = (pSdlGuiScrn->h/sdlgui_fontheight-dlg[0].h)/2;
257 }
258 
259 
260 /*-----------------------------------------------------------------------*/
261 /**
262  * Draw a text string.
263  */
SDLGui_Text(int x,int y,const char * txt)264 void SDLGui_Text(int x, int y, const char *txt)
265 {
266 /*
267 	int i;
268 	unsigned char c;
269 	SDL_Rect sr, dr;
270 
271 	for (i=0; txt[i]!=0; i++)
272 	{
273 		c = txt[i];
274 		sr.x=sdlgui_fontwidth*(c%16);
275 		sr.y=sdlgui_fontheight*(c/16);
276 		sr.w=sdlgui_fontwidth;
277 		sr.h=sdlgui_fontheight;
278 		dr.x=x+i*sdlgui_fontwidth;
279 		dr.y=y;
280 		dr.w=sdlgui_fontwidth;
281 		dr.h=sdlgui_fontheight;
282 		SDL_BlitSurface(pFontGfx, &sr, pSdlGuiScrn, &dr);
283 	}
284 */
285 	Draw_text(bmp,x,y,1,0,1,2,40,(char *)txt);
286 }
287 
288 
289 /*-----------------------------------------------------------------------*/
290 /**
291  * Draw a dialog text object.
292  */
SDLGui_DrawText(const SGOBJ * tdlg,int objnum)293 static void SDLGui_DrawText(const SGOBJ *tdlg, int objnum)
294 {
295 	int x, y;
296 	x = (tdlg[0].x+tdlg[objnum].x)*sdlgui_fontwidth;
297 	y = (tdlg[0].y+tdlg[objnum].y)*sdlgui_fontheight;
298 	SDLGui_Text(x, y, tdlg[objnum].txt);
299 }
300 
301 
302 /*-----------------------------------------------------------------------*/
303 /**
304  * Draw a edit field object.
305  */
SDLGui_DrawEditField(const SGOBJ * edlg,int objnum)306 static void SDLGui_DrawEditField(const SGOBJ *edlg, int objnum)
307 {
308 	int x, y;
309 	SDL_Rect rect;
310 
311 	x = (edlg[0].x+edlg[objnum].x)*sdlgui_fontwidth;
312 	y = (edlg[0].y+edlg[objnum].y)*sdlgui_fontheight;
313 	SDLGui_Text(x, y, edlg[objnum].txt);
314 
315 	rect.x = x;
316 	rect.y = y + edlg[objnum].h * sdlgui_fontheight;
317 	rect.w = edlg[objnum].w * sdlgui_fontwidth;
318 	rect.h = 1;
319 	SDL_FillRect(pSdlGuiScrn, &rect, SDL_MapRGB(pSdlGuiScrn->format,160,160,160));
320 }
321 
322 
323 /*-----------------------------------------------------------------------*/
324 /**
325  * Draw a dialog box object.
326  */
SDLGui_DrawBox(const SGOBJ * bdlg,int objnum)327 static void SDLGui_DrawBox(const SGOBJ *bdlg, int objnum)
328 {
329 	SDL_Rect rect;
330 	int x, y, w, h, offset;
331 	Uint32 grey = SDL_MapRGB(pSdlGuiScrn->format,192,192,192);
332 	Uint32 upleftc, downrightc;
333 
334 	x = bdlg[objnum].x*sdlgui_fontwidth;
335 	y = bdlg[objnum].y*sdlgui_fontheight;
336 	if (objnum > 0)                 /* Since the root object is a box, too, */
337 	{
338 		/* we have to look for it now here and only */
339 		x += bdlg[0].x*sdlgui_fontwidth;   /* add its absolute coordinates if we need to */
340 		y += bdlg[0].y*sdlgui_fontheight;
341 	}
342 	w = bdlg[objnum].w*sdlgui_fontwidth;
343 	h = bdlg[objnum].h*sdlgui_fontheight;
344 
345 	if (bdlg[objnum].state & SG_SELECTED)
346 	{
347 		upleftc = SDL_MapRGB(pSdlGuiScrn->format,128,128,128);
348 		downrightc = SDL_MapRGB(pSdlGuiScrn->format,255,255,255);
349 	}
350 	else
351 	{
352 		upleftc = SDL_MapRGB(pSdlGuiScrn->format,255,255,255);
353 		downrightc = SDL_MapRGB(pSdlGuiScrn->format,128,128,128);
354 	}
355 
356 	/* The root box should be bigger than the screen, so we disable the offset there: */
357 	if (objnum != 0)
358 		offset = 1;
359 	else
360 		offset = 0;
361 
362 	/* Draw background: */
363 	rect.x = x;
364 	rect.y = y;
365 	rect.w = w;
366 	rect.h = h;
367 	SDL_FillRect(pSdlGuiScrn, &rect, grey);
368 
369 	/* Draw upper border: */
370 	rect.x = x;
371 	rect.y = y - offset;
372 	rect.w = w;
373 	rect.h = 1;
374 	SDL_FillRect(pSdlGuiScrn, &rect, upleftc);
375 
376 	/* Draw left border: */
377 	rect.x = x - offset;
378 	rect.y = y;
379 	rect.w = 1;
380 	rect.h = h;
381 	SDL_FillRect(pSdlGuiScrn, &rect, upleftc);
382 
383 	/* Draw bottom border: */
384 	rect.x = x;
385 	rect.y = y + h - 1 + offset;
386 	rect.w = w;
387 	rect.h = 1;
388 	SDL_FillRect(pSdlGuiScrn, &rect, downrightc);
389 
390 	/* Draw right border: */
391 	rect.x = x + w - 1 + offset;
392 	rect.y = y;
393 	rect.w = 1;
394 	rect.h = h;
395 	SDL_FillRect(pSdlGuiScrn, &rect, downrightc);
396 }
397 
398 
399 /*-----------------------------------------------------------------------*/
400 /**
401  * Draw a normal button.
402  */
SDLGui_DrawButton(const SGOBJ * bdlg,int objnum)403 static void SDLGui_DrawButton(const SGOBJ *bdlg, int objnum)
404 {
405 	int x,y;
406 
407 	SDLGui_DrawBox(bdlg, objnum);
408 
409 	x = (bdlg[0].x + bdlg[objnum].x + (bdlg[objnum].w-strlen(bdlg[objnum].txt))/2) * sdlgui_fontwidth;
410 	y = (bdlg[0].y + bdlg[objnum].y + (bdlg[objnum].h-1)/2) * sdlgui_fontheight;
411 
412 	if (bdlg[objnum].state & SG_SELECTED)
413 	{
414 		x+=1;
415 		y+=1;
416 	}
417 	SDLGui_Text(x, y, bdlg[objnum].txt);
418 }
419 
420 
421 /*-----------------------------------------------------------------------*/
422 /**
423  * Draw a dialog radio button object.
424  */
SDLGui_DrawRadioButton(const SGOBJ * rdlg,int objnum)425 static void SDLGui_DrawRadioButton(const SGOBJ *rdlg, int objnum)
426 {
427 	char str[80];
428 	int x, y;
429 
430 	x = (rdlg[0].x + rdlg[objnum].x) * sdlgui_fontwidth;
431 	y = (rdlg[0].y + rdlg[objnum].y) * sdlgui_fontheight;
432 
433 	if (rdlg[objnum].state & SG_SELECTED)
434 		str[0]=SGRADIOBUTTON_SELECTED;
435 	else
436 		str[0]=SGRADIOBUTTON_NORMAL;
437 	str[1]=' ';
438 	strcpy(&str[2], rdlg[objnum].txt);
439 
440 	SDLGui_Text(x, y, str);
441 }
442 
443 
444 /*-----------------------------------------------------------------------*/
445 /**
446  * Draw a dialog check box object.
447  */
SDLGui_DrawCheckBox(const SGOBJ * cdlg,int objnum)448 static void SDLGui_DrawCheckBox(const SGOBJ *cdlg, int objnum)
449 {
450 	char str[80];
451 	int x, y;
452 
453 	x = (cdlg[0].x + cdlg[objnum].x) * sdlgui_fontwidth;
454 	y = (cdlg[0].y + cdlg[objnum].y) * sdlgui_fontheight;
455 
456 	if ( cdlg[objnum].state&SG_SELECTED )
457 		str[0]=SGCHECKBOX_SELECTED;
458 	else
459 		str[0]=SGCHECKBOX_NORMAL;
460 	str[1]=' ';
461 	strcpy(&str[2], cdlg[objnum].txt);
462 
463 	SDLGui_Text(x, y, str);
464 }
465 
466 
467 /*-----------------------------------------------------------------------*/
468 /**
469  * Draw a scrollbar button.
470  */
SDLGui_DrawScrollbar(const SGOBJ * bdlg,int objnum)471 static void SDLGui_DrawScrollbar(const SGOBJ *bdlg, int objnum)
472 {
473 	SDL_Rect rect;
474 	int x, y, w, h;
475 	Uint32 grey0 = SDL_MapRGB(pSdlGuiScrn->format,128,128,128);
476 	Uint32 grey1 = SDL_MapRGB(pSdlGuiScrn->format,196,196,196);
477 	Uint32 grey2 = SDL_MapRGB(pSdlGuiScrn->format, 64, 64, 64);
478 
479 	x = bdlg[objnum].x * sdlgui_fontwidth;
480 	y = bdlg[objnum].y * sdlgui_fontheight + bdlg[objnum].h;
481 
482 	x += bdlg[0].x*sdlgui_fontwidth;   /* add mainbox absolute coordinates */
483 	y += bdlg[0].y*sdlgui_fontheight;  /* add mainbox absolute coordinates */
484 
485 	w = 1 * sdlgui_fontwidth;
486 	h = bdlg[objnum].w;
487 
488 	/* Draw background: */
489 	rect.x = x;
490 	rect.y = y;
491 	rect.w = w;
492 	rect.h = h;
493 	SDL_FillRect(pSdlGuiScrn, &rect, grey0);
494 
495 	/* Draw upper border: */
496 	rect.x = x;
497 	rect.y = y;
498 	rect.w = w;
499 	rect.h = 1;
500 	SDL_FillRect(pSdlGuiScrn, &rect, grey1);
501 
502 	/* Draw bottom border: */
503 	rect.x = x;
504 	rect.y = y + h - 1;
505 	rect.w = w;
506 	rect.h = 1;
507 	SDL_FillRect(pSdlGuiScrn, &rect, grey2);
508 
509 }
510 
511 /*-----------------------------------------------------------------------*/
512 /**
513  *  Draw a dialog popup button object.
514  */
SDLGui_DrawPopupButton(const SGOBJ * pdlg,int objnum)515 static void SDLGui_DrawPopupButton(const SGOBJ *pdlg, int objnum)
516 {
517 	int x, y, w;
518 	const char *downstr = "\x02";
519 
520 	SDLGui_DrawBox(pdlg, objnum);
521 
522 	x = (pdlg[0].x + pdlg[objnum].x) * sdlgui_fontwidth;
523 	y = (pdlg[0].y + pdlg[objnum].y) * sdlgui_fontheight;
524 	w = pdlg[objnum].w * sdlgui_fontwidth;
525 
526 	SDLGui_Text(x, y, pdlg[objnum].txt);
527 	SDLGui_Text(x+w-sdlgui_fontwidth, y, downstr);
528 }
529 
530 #if 0
531 /*-----------------------------------------------------------------------*/
532 /**
533  * Let the user insert text into an edit field object.
534  * NOTE: The dlg[objnum].txt must point to an an array that is big enough
535  * for dlg[objnum].w characters!
536  */
537 static void SDLGui_EditField(SGOBJ *dlg, int objnum)
538 {
539 	size_t cursorPos;                   /* Position of the cursor in the edit field */
540 	int blinkState = 0;                 /* Used for cursor blinking */
541 	int bStopEditing = false;           /* true if user wants to exit the edit field */
542 	char *txt;                          /* Shortcut for dlg[objnum].txt */
543 	SDL_Rect rect;
544 	Uint32 grey, cursorCol;
545 	SDL_Event event;
546 	int nOldUnicodeMode;
547 
548 	/* Enable unicode translation to get proper characters with SDL_PollEvent */
549 	nOldUnicodeMode = SDL_EnableUNICODE(true);
550 
551 	grey = SDL_MapRGB(pSdlGuiScrn->format, 192, 192, 192);
552 	cursorCol = SDL_MapRGB(pSdlGuiScrn->format, 128, 128, 128);
553 
554 	rect.x = (dlg[0].x + dlg[objnum].x) * sdlgui_fontwidth;
555 	rect.y = (dlg[0].y + dlg[objnum].y) * sdlgui_fontheight;
556 	rect.w = (dlg[objnum].w + 1) * sdlgui_fontwidth - 1;
557 	rect.h = dlg[objnum].h * sdlgui_fontheight;
558 
559 	txt = dlg[objnum].txt;
560 	cursorPos = strlen(txt);
561 
562 	do
563 	{
564 		/* Look for events */
565 		if (SDL_PollEvent(&event) == 0)
566 		{
567 			/* No event: Wait some time for cursor blinking */
568 			SDL_Delay(250);
569 			blinkState ^= 1;
570 		}
571 		else
572 		{
573 			/* Handle events */
574 			do
575 			{
576 				switch (event.type)
577 				{
578 				 case SDL_QUIT:                     /* User wants to quit */
579 					bQuitProgram = true;
580 					bStopEditing = true;
581 					break;
582 				 case SDL_MOUSEBUTTONDOWN:          /* Mouse pressed -> stop editing */
583 					bStopEditing = true;
584 					break;
585 				 case SDL_KEYDOWN:                  /* Key pressed */
586 					switch (event.key.keysym.sym)
587 					{
588 					 case SDLK_RETURN:
589 					 case SDLK_KP_ENTER:
590 						bStopEditing = true;
591 						break;
592 					 case SDLK_LEFT:
593 						if (cursorPos > 0)
594 							cursorPos -= 1;
595 						break;
596 					 case SDLK_RIGHT:
597 						if (cursorPos < strlen(txt))
598 							cursorPos += 1;
599 						break;
600 					 case SDLK_BACKSPACE:
601 						if (cursorPos > 0)
602 						{
603 							memmove(&txt[cursorPos-1], &txt[cursorPos], strlen(&txt[cursorPos])+1);
604 							cursorPos -= 1;
605 						}
606 						break;
607 					 case SDLK_DELETE:
608 						if (cursorPos < strlen(txt))
609 							memmove(&txt[cursorPos], &txt[cursorPos+1], strlen(&txt[cursorPos+1])+1);
610 						break;
611 					 default:
612 						/* If it is a "good" key then insert it into the text field */
613 						if (event.key.keysym.unicode >= 32 && event.key.keysym.unicode < 128
614 						        && event.key.keysym.unicode != PATHSEP)
615 						{
616 							if (strlen(txt) < (size_t)dlg[objnum].w)
617 							{
618 								memmove(&txt[cursorPos+1], &txt[cursorPos], strlen(&txt[cursorPos])+1);
619 								txt[cursorPos] = event.key.keysym.unicode;
620 								cursorPos += 1;
621 							}
622 						}
623 						break;
624 					}
625 					break;
626 				}
627 			}
628 			while (SDL_PollEvent(&event));
629 
630 			blinkState = 1;
631 		}
632 
633 		/* Redraw the text field: */
634 		SDL_FillRect(pSdlGuiScrn, &rect, grey);  /* Draw background */
635 		/* Draw the cursor: */
636 		if (blinkState && !bStopEditing)
637 		{
638 			SDL_Rect cursorrect;
639 			cursorrect.x = rect.x + cursorPos * sdlgui_fontwidth;
640 			cursorrect.y = rect.y;
641 			cursorrect.w = sdlgui_fontwidth;
642 			cursorrect.h = rect.h;
643 			SDL_FillRect(pSdlGuiScrn, &cursorrect, cursorCol);
644 		}
645 		SDLGui_Text(rect.x, rect.y, dlg[objnum].txt);  /* Draw text */
646 		SDL_UpdateRects(pSdlGuiScrn, 1, &rect);
647 	}
648 	while (!bStopEditing);
649 
650 	SDL_EnableUNICODE(nOldUnicodeMode);
651 }
652 
653 #else
SDLGui_EditField(SGOBJ * dlg,int objnum)654 static void SDLGui_EditField(SGOBJ *dlg, int objnum)
655 {
656 }
657 #endif
658 
659 /*-----------------------------------------------------------------------*/
660 /**
661  * Draw a whole dialog.
662  */
SDLGui_DrawDialog(const SGOBJ * dlg)663 void SDLGui_DrawDialog(const SGOBJ *dlg)
664 {
665 	int i;
666 
667 	memset(bmp, 0, sizeof(bmp));
668 
669 	for (i = 0; dlg[i].type != -1; i++)
670 	{
671 		switch (dlg[i].type)
672 		{
673 		 case SGBOX:
674 			SDLGui_DrawBox(dlg, i);
675 			break;
676 		 case SGTEXT:
677 			SDLGui_DrawText(dlg, i);
678 			break;
679 		 case SGEDITFIELD:
680 			SDLGui_DrawEditField(dlg, i);
681 			break;
682 		 case SGBUTTON:
683 			SDLGui_DrawButton(dlg, i);
684 			break;
685 		 case SGRADIOBUT:
686 			SDLGui_DrawRadioButton(dlg, i);
687 			break;
688 		 case SGCHECKBOX:
689 			SDLGui_DrawCheckBox(dlg, i);
690 			break;
691 		 case SGPOPUP:
692 			SDLGui_DrawPopupButton(dlg, i);
693 			break;
694 		 case SGSCROLLBAR:
695 			SDLGui_DrawScrollbar(dlg, i);
696 			break;
697 		}
698 	}
699 	SDL_UpdateRect(pSdlGuiScrn, 0,0,0,0);
700 }
701 
702 
703 /*-----------------------------------------------------------------------*/
704 /**
705  * Search an object at a certain position.
706  * Return object index or -1 if it wasn't found.
707  */
SDLGui_FindObj(const SGOBJ * dlg,int fx,int fy)708 static int SDLGui_FindObj(const SGOBJ *dlg, int fx, int fy)
709 {
710 	int len, i;
711 	int ob = -1;
712 	int xpos, ypos;
713 
714 	len = 0;
715 	while (dlg[len].type != -1)   len++;
716 
717 	xpos = fx / sdlgui_fontwidth;
718 	ypos = fy / sdlgui_fontheight;
719 	/* Now search for the object: */
720 	for (i = len; i >= 0; i--)
721 	{
722 		/* clicked on a scrollbar ? */
723 		if (dlg[i].type == SGSCROLLBAR) {
724 			if (xpos >= dlg[0].x+dlg[i].x && xpos < dlg[0].x+dlg[i].x+1) {
725 				ypos = dlg[i].y * sdlgui_fontheight + dlg[i].h + dlg[0].y * sdlgui_fontheight;
726 				if (fy >= ypos && fy < ypos + dlg[i].w) {
727 					ob = i;
728 					break;
729 				}
730 			}
731 		}
732 		/* clicked on another object ? */
733 		else if (xpos >= dlg[0].x+dlg[i].x && ypos >= dlg[0].y+dlg[i].y
734 		    && xpos < dlg[0].x+dlg[i].x+dlg[i].w && ypos < dlg[0].y+dlg[i].y+dlg[i].h)
735 		{
736 			ob = i;
737 			break;
738 		}
739 	}
740 
741 	return ob;
742 }
743 
744 
745 /*-----------------------------------------------------------------------*/
746 /**
747  * Search a button with a special flag (e.g. SG_DEFAULT or SG_CANCEL).
748  */
SDLGui_SearchFlaggedButton(const SGOBJ * dlg,int flag)749 static int SDLGui_SearchFlaggedButton(const SGOBJ *dlg, int flag)
750 {
751 	int i = 0;
752 
753 	while (dlg[i].type != -1)
754 	{
755 		if (dlg[i].flags & flag)
756 			return i;
757 		i++;
758 	}
759 
760 	return 0;
761 }
762 
763 
764 /*-----------------------------------------------------------------------*/
765 /**
766  * Show and process a dialog. Returns the button number that has been
767  * pressed or SDLGUI_UNKNOWNEVENT if an unsupported event occurred (will be
768  * stored in parameter pEventOut).
769  */
SDLGui_DoDialog(SGOBJ * dlg,SDL_Event * pEventOut)770 int SDLGui_DoDialog(SGOBJ *dlg, SDL_Event *pEventOut)
771 {
772 	int obj=0;
773 	int oldbutton=0;
774 	int retbutton=0;
775 	int i, j, b;
776 	SDL_Event sdlEvent;
777 	SDL_Rect rct;
778 	Uint32 grey;
779 	SDL_Surface *pBgSurface;
780 	SDL_Rect dlgrect, bgrect;
781 
782 	if (pSdlGuiScrn->h / sdlgui_fontheight < dlg[0].h)
783 	{
784 		fprintf(stderr, "Screen size too small for dialog!\n");
785 		return SDLGUI_ERROR;
786 	}
787 
788 	grey = SDL_MapRGB(pSdlGuiScrn->format,192,192,192);
789 
790 	dlgrect.x = dlg[0].x * sdlgui_fontwidth;
791 	dlgrect.y = dlg[0].y * sdlgui_fontheight;
792 	dlgrect.w = dlg[0].w * sdlgui_fontwidth;
793 	dlgrect.h = dlg[0].h * sdlgui_fontheight;
794 
795 	bgrect.x = bgrect.y = 0;
796 	bgrect.w = dlgrect.w;
797 	bgrect.h = dlgrect.h;
798 
799 #if 0
800 	/* Save background */
801 	pBgSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, dlgrect.w, dlgrect.h, pSdlGuiScrn->format->BitsPerPixel,
802 	                                  pSdlGuiScrn->format->Rmask, pSdlGuiScrn->format->Gmask, pSdlGuiScrn->format->Bmask, pSdlGuiScrn->format->Amask);
803 	if (pSdlGuiScrn->format->palette != NULL)
804 	{
805 		SDL_SetColors(pBgSurface, pSdlGuiScrn->format->palette->colors, 0, pSdlGuiScrn->format->palette->ncolors-1);
806 	}
807 
808 	if (pBgSurface != NULL)
809 	{
810 		SDL_BlitSurface(pSdlGuiScrn,  &dlgrect, pBgSurface, &bgrect);
811 	}
812 	else
813 	{
814 		fprintf(stderr, "SDLGUI_DoDialog: CreateRGBSurface failed: %s\n", SDL_GetError());
815 	}
816 #endif
817 	/* (Re-)draw the dialog */
818 	SDLGui_DrawDialog(dlg);
819 
820 	/* Is the left mouse button still pressed? Yes -> Handle TOUCHEXIT objects here */
821 	//SDL_PumpEvents();
822 	input_gui();
823 	b = SDL_GetMouseState(&i, &j);
824 
825         if(touch!=-1){b=1;boutc=1;}
826 	else {b=0;boutc=0;}
827 
828 	/* If current object is the scrollbar, and mouse is still down, we can scroll it */
829 	/* also if the mouse pointer has left the scrollbar */
830 	if (current_object >= 0 && dlg[current_object].type == SGSCROLLBAR) {
831 		if (b ==1 /*& SDL_BUTTON(1)*/) {
832 			obj = current_object;
833 			dlg[obj].state |= SG_MOUSEDOWN;
834 			oldbutton = obj;
835 			retbutton = obj;
836 		}
837 		else {
838 			obj = current_object;
839 			current_object = 0;
840 			dlg[obj].state &= ~SG_MOUSEDOWN;//SG_MOUSEUP;
841 			//retbutton = obj;
842 			//oldbutton = obj;
843 			okold=1;
844 		}
845 	}
846 	else {
847 		obj = SDLGui_FindObj(dlg, i, j);
848 		current_object = obj;
849 		if (obj > 0 && (dlg[obj].flags&SG_TOUCHEXIT) )
850 		{
851 			oldbutton = obj;
852 			if (b ==1/*& SDL_BUTTON(1)*/)
853 			{
854 				dlg[obj].state |= SG_SELECTED;
855 				retbutton = obj;
856 			}
857 			else{
858                                 dlg[obj].state &= ~SG_SELECTED;
859 			}
860 		}
861 	}
862 
863 
864 	/* The main loop */
865 	while (retbutton == 0 && !bQuitProgram)
866 	{
867 #if 0
868 		if (SDL_WaitEvent(&sdlEvent) == 1)  /* Wait for events */
869 
870 			switch (sdlEvent.type)
871 			{
872 			 case SDL_QUIT:
873 				retbutton = SDLGUI_QUIT;
874 				break;
875 
876 			 case SDL_MOUSEBUTTONDOWN:
877 				if (sdlEvent.button.button != SDL_BUTTON_LEFT)
878 				{
879 					/* Not left mouse button -> unsupported event */
880 					if (pEventOut)
881 						retbutton = SDLGUI_UNKNOWNEVENT;
882 					break;
883 				}
884 #endif
885 
886 		input_gui();
887 
888 		draw_cross(gmx,gmy);
889 
890                 if(touch!=-1 && okold==0 ){
891 
892 			okold=1;
893 
894 				/* It was the left button: Find the object under the mouse cursor */
895 				obj = SDLGui_FindObj(dlg,  gmx, gmy/*sdlEvent.button.x, sdlEvent.button.y*/);
896 				if (obj>0)
897 				{
898 					if (dlg[obj].type==SGBUTTON)
899 					{
900 						dlg[obj].state |= SG_SELECTED;
901 						SDLGui_DrawButton(dlg, obj);
902 				//		SDL_UpdateRect(pSdlGuiScrn, (dlg[0].x+dlg[obj].x)*sdlgui_fontwidth-2, (dlg[0].y+dlg[obj].y)*sdlgui_fontheight-2,						               dlg[obj].w*sdlgui_fontwidth+4, dlg[obj].h*sdlgui_fontheight+4);
903 						oldbutton=obj;
904 					}
905 					if (dlg[obj].type==SGSCROLLBAR)
906 					{
907 						dlg[obj].state |= SG_MOUSEDOWN;
908 						oldbutton=obj;
909 					}
910 					if ( dlg[obj].flags&SG_TOUCHEXIT )
911 					{
912 						dlg[obj].state |= SG_SELECTED;
913 						retbutton = obj;
914 					}
915 				}
916 				//break;
917 #if 0
918 			 case SDL_MOUSEBUTTONUP:
919 				if (sdlEvent.button.button != SDL_BUTTON_LEFT)
920 				{
921 					/* Not left mouse button -> unsupported event */
922 					if (pEventOut)
923 						retbutton = SDLGUI_UNKNOWNEVENT;
924 					break;
925 				}
926 				/* It was the left button: Find the object under the mouse cursor */
927 #endif
928 		}
929 		else if(touch==-1 && okold==1){
930 			okold=0;
931 				obj = SDLGui_FindObj(dlg, gmx,gmy/*sdlEvent.button.x, sdlEvent.button.y*/);
932 				if (obj>0)
933 				{
934 					switch (dlg[obj].type)
935 					{
936 					 case SGBUTTON:
937 						if (oldbutton==obj)
938 							retbutton=obj;
939 						break;
940 					 case SGSCROLLBAR:
941  						dlg[obj].state &= ~SG_MOUSEDOWN;//SG_MOUSEUP;
942 
943 						if (oldbutton==obj)
944 							retbutton=obj;
945 						break;
946 					case SGEDITFIELD:
947 						SDLGui_EditField(dlg, obj);
948 						break;
949 					 case SGRADIOBUT:
950 						for (i = obj-1; i > 0 && dlg[i].type == SGRADIOBUT; i--)
951 						{
952 							dlg[i].state &= ~SG_SELECTED;  /* Deselect all radio buttons in this group */
953 							rct.x = (dlg[0].x+dlg[i].x)*sdlgui_fontwidth;
954 							rct.y = (dlg[0].y+dlg[i].y)*sdlgui_fontheight;
955 							rct.w = sdlgui_fontwidth;
956 							rct.h = sdlgui_fontheight;
957 							SDL_FillRect(pSdlGuiScrn, &rct, grey); /* Clear old */
958 							SDLGui_DrawRadioButton(dlg, i);
959 					//		SDL_UpdateRects(pSdlGuiScrn, 1, &rct);
960 						}
961 						for (i = obj+1; dlg[i].type == SGRADIOBUT; i++)
962 						{
963 							dlg[i].state &= ~SG_SELECTED;  /* Deselect all radio buttons in this group */
964 							rct.x = (dlg[0].x+dlg[i].x)*sdlgui_fontwidth;
965 							rct.y = (dlg[0].y+dlg[i].y)*sdlgui_fontheight;
966 							rct.w = sdlgui_fontwidth;
967 							rct.h = sdlgui_fontheight;
968 							SDL_FillRect(pSdlGuiScrn, &rct, grey); /* Clear old */
969 							SDLGui_DrawRadioButton(dlg, i);
970 					//		SDL_UpdateRects(pSdlGuiScrn, 1, &rct);
971 						}
972 						dlg[obj].state |= SG_SELECTED;  /* Select this radio button */
973 						rct.x = (dlg[0].x+dlg[obj].x)*sdlgui_fontwidth;
974 						rct.y = (dlg[0].y+dlg[obj].y)*sdlgui_fontheight;
975 						rct.w = sdlgui_fontwidth;
976 						rct.h = sdlgui_fontheight;
977 						SDL_FillRect(pSdlGuiScrn, &rct, grey); /* Clear old */
978 						SDLGui_DrawRadioButton(dlg, obj);
979 					//	SDL_UpdateRects(pSdlGuiScrn, 1, &rct);
980 						break;
981 					 case SGCHECKBOX:
982 						dlg[obj].state ^= SG_SELECTED;
983 						rct.x = (dlg[0].x+dlg[obj].x)*sdlgui_fontwidth;
984 						rct.y = (dlg[0].y+dlg[obj].y)*sdlgui_fontheight;
985 						rct.w = sdlgui_fontwidth;
986 						rct.h = sdlgui_fontheight;
987 						SDL_FillRect(pSdlGuiScrn, &rct, grey); /* Clear old */
988 						SDLGui_DrawCheckBox(dlg, obj);
989 					//	SDL_UpdateRects(pSdlGuiScrn, 1, &rct);
990 						break;
991 					 case SGPOPUP:
992 						dlg[obj].state |= SG_SELECTED;
993 						SDLGui_DrawPopupButton(dlg, obj);
994 					//	SDL_UpdateRect(pSdlGuiScrn, (dlg[0].x+dlg[obj].x)*sdlgui_fontwidth-2, (dlg[0].y+dlg[obj].y)*sdlgui_fontheight-2,						               dlg[obj].w*sdlgui_fontwidth+4, dlg[obj].h*sdlgui_fontheight+4);
995 						retbutton=obj;
996 						break;
997 					}
998 				}
999 				if (oldbutton > 0 /*&& dlg[oldbutton].type == SGBUTTON*/)
1000 				{
1001 					dlg[oldbutton].state &= ~SG_SELECTED;
1002 					SDLGui_DrawButton(dlg, oldbutton);
1003 					//SDL_UpdateRect(pSdlGuiScrn, (dlg[0].x+dlg[oldbutton].x)*sdlgui_fontwidth-2, (dlg[0].y+dlg[oldbutton].y)*sdlgui_fontheight-2,					               dlg[oldbutton].w*sdlgui_fontwidth+4, dlg[oldbutton].h*sdlgui_fontheight+4);
1004 					oldbutton = 0;
1005 				}
1006 				if (obj >= 0 && (dlg[obj].flags&SG_EXIT))
1007 				{
1008 						if(dlg[obj].type==SGBUTTON)dlg[obj].state &= ~SG_SELECTED;
1009 					retbutton = obj;
1010 				}
1011 #if 0
1012 				break;
1013 
1014 			 case SDL_JOYAXISMOTION:
1015 			 case SDL_JOYBALLMOTION:
1016 			 case SDL_JOYHATMOTION:
1017 			 case SDL_MOUSEMOTION:
1018 				break;
1019 
1020 			 case SDL_KEYDOWN:                     /* Key pressed */
1021 				if (sdlEvent.key.keysym.sym == SDLK_RETURN
1022 				    || sdlEvent.key.keysym.sym == SDLK_KP_ENTER)
1023 				{
1024 					retbutton = SDLGui_SearchFlaggedButton(dlg, SG_DEFAULT);
1025 				}
1026 				else if (sdlEvent.key.keysym.sym == SDLK_ESCAPE)
1027 				{
1028 					retbutton = SDLGui_SearchFlaggedButton(dlg, SG_CANCEL);
1029 				}
1030 				else if (pEventOut)
1031 				{
1032 					retbutton = SDLGUI_UNKNOWNEVENT;
1033 				}
1034 				break;
1035 
1036 			 default:
1037 				if (pEventOut)
1038 					retbutton = SDLGUI_UNKNOWNEVENT;
1039 				break;
1040 #endif
1041 
1042 		}
1043 
1044 		if(retbutton ==0)retbutton = 1;
1045 	}
1046 
1047 #if 0
1048 	/* Restore background */
1049 	if (pBgSurface)
1050 	{
1051 		SDL_BlitSurface(pBgSurface, &bgrect, pSdlGuiScrn,  &dlgrect);
1052 		SDL_FreeSurface(pBgSurface);
1053 	}
1054 
1055 	/* Copy event data of unsupported events if caller wants to have it */
1056 	if (retbutton == SDLGUI_UNKNOWNEVENT && pEventOut)
1057 		memcpy(pEventOut, &sdlEvent, sizeof(SDL_Event));
1058 #endif
1059 	if (retbutton == SDLGUI_QUIT)
1060 		bQuitProgram = true;
1061 
1062 	return retbutton;
1063 }
1064 
1065