zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_x11messagebox.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 
22 #include "SDL_config.h"
23 
24 #if SDL_VIDEO_DRIVER_X11
25 
26 #include "SDL.h"
27 #include "SDL_x11video.h"
28 #include "SDL_x11dyn.h"
29 #include "SDL_assert.h"
30 
31 #include <locale.h>
32 
33 
34 #define SDL_FORK_MESSAGEBOX 0
35 #define SDL_SET_LOCALE 0
36 
37 #if SDL_FORK_MESSAGEBOX
38 #include <sys/types.h>
39 #include <sys/wait.h>
40 #include <unistd.h>
41 #include <errno.h>
42 #endif
43 
44 #define MAX_BUTTONS 8 /* Maximum number of buttons supported */
45 #define MAX_TEXT_LINES 32 /* Maximum number of text lines supported */
46 #define MIN_BUTTON_WIDTH 64 /* Minimum button width */
47 #define MIN_DIALOG_WIDTH 200 /* Minimum dialog width */
48 #define MIN_DIALOG_HEIGHT 100 /* Minimum dialog height */
49 
50 static const char g_MessageBoxFontLatin1[] = "-*-*-medium-r-normal--0-120-*-*-p-0-iso8859-1";
51 static const char g_MessageBoxFont[] = "-*-*-*-*-*-*-*-*-*-*-*-*-*-*";
52 
53 static const SDL_MessageBoxColor g_default_colors[ SDL_MESSAGEBOX_COLOR_MAX ] = {
54  { 56, 54, 53 }, /* SDL_MESSAGEBOX_COLOR_BACKGROUND, */
55  { 209, 207, 205 }, /* SDL_MESSAGEBOX_COLOR_TEXT, */
56  { 140, 135, 129 }, /* SDL_MESSAGEBOX_COLOR_BUTTON_BORDER, */
57  { 105, 102, 99 }, /* SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND, */
58  { 205, 202, 53 }, /* SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED, */
59 };
60 
61 #define SDL_MAKE_RGB( _r, _g, _b ) ( ( ( Uint32 )( _r ) << 16 ) | \
62  ( ( Uint32 )( _g ) << 8 ) | \
63  ( ( Uint32 )( _b ) ) )
64 
65 typedef struct SDL_MessageBoxButtonDataX11 {
66  int x, y; /* Text position */
67  int length; /* Text length */
68  int text_width; /* Text width */
69 
70  SDL_Rect rect; /* Rectangle for entire button */
71 
72  const SDL_MessageBoxButtonData *buttondata; /* Button data from caller */
73 } SDL_MessageBoxButtonDataX11;
74 
75 typedef struct TextLineData {
76  int width; /* Width of this text line */
77  int length; /* String length of this text line */
78  const char *text; /* Text for this line */
79 } TextLineData;
80 
81 typedef struct SDL_MessageBoxDataX11
82 {
83  Display *display;
84  int screen;
85  Window window;
86  long event_mask;
87  Atom wm_protocols;
88  Atom wm_delete_message;
89 
90  int dialog_width; /* Dialog box width. */
91  int dialog_height; /* Dialog box height. */
92 
93  XFontSet font_set; /* for UTF-8 systems */
94  XFontStruct *font_struct; /* Latin1 (ASCII) fallback. */
95  int xtext, ytext; /* Text position to start drawing at. */
96  int numlines; /* Count of Text lines. */
97  int text_height; /* Height for text lines. */
98  TextLineData linedata[ MAX_TEXT_LINES ];
99 
100  int *pbuttonid; /* Pointer to user return buttonid value. */
101 
102  int button_press_index; /* Index into buttondata/buttonpos for button which is pressed (or -1). */
103  int mouse_over_index; /* Index into buttondata/buttonpos for button mouse is over (or -1). */
104 
105  int numbuttons; /* Count of buttons. */
106  const SDL_MessageBoxButtonData *buttondata;
107  SDL_MessageBoxButtonDataX11 buttonpos[ MAX_BUTTONS ];
108 
110 
111  const SDL_MessageBoxData *messageboxdata;
112 } SDL_MessageBoxDataX11;
113 
114 /* Maximum helper for ints. */
115 static __inline__ int
116 IntMax( int a, int b )
117 {
118  return ( a > b ) ? a : b;
119 }
120 
121 /* Return width and height for a string. */
122 static void
123 GetTextWidthHeight( SDL_MessageBoxDataX11 *data, const char *str, int nbytes, int *pwidth, int *pheight )
124 {
125  if (SDL_X11_HAVE_UTF8) {
126  XRectangle overall_ink, overall_logical;
127  Xutf8TextExtents(data->font_set, str, nbytes, &overall_ink, &overall_logical);
128  *pwidth = overall_logical.width;
129  *pheight = overall_logical.height;
130  } else {
131  XCharStruct text_structure;
132  int font_direction, font_ascent, font_descent;
133  XTextExtents( data->font_struct, str, nbytes,
134  &font_direction, &font_ascent, &font_descent,
135  &text_structure );
136  *pwidth = text_structure.width;
137  *pheight = text_structure.ascent + text_structure.descent;
138  }
139 }
140 
141 /* Return index of button if position x,y is contained therein. */
142 static int
143 GetHitButtonIndex( SDL_MessageBoxDataX11 *data, int x, int y )
144 {
145  int i;
146  int numbuttons = data->numbuttons;
147  SDL_MessageBoxButtonDataX11 *buttonpos = data->buttonpos;
148 
149  for ( i = 0; i < numbuttons; i++ ) {
150  SDL_Rect *rect = &buttonpos[ i ].rect;
151 
152  if ( ( x >= rect->x ) &&
153  ( x <= ( rect->x + rect->w ) ) &&
154  ( y >= rect->y ) &&
155  ( y <= ( rect->y + rect->h ) ) ) {
156  return i;
157  }
158  }
159 
160  return -1;
161 }
162 
163 /* Initialize SDL_MessageBoxData structure and Display, etc. */
164 static int
165 X11_MessageBoxInit( SDL_MessageBoxDataX11 *data, const SDL_MessageBoxData * messageboxdata, int * pbuttonid )
166 {
167  int i;
168  int numbuttons = messageboxdata->numbuttons;
169  const SDL_MessageBoxButtonData *buttondata = messageboxdata->buttons;
170  const SDL_MessageBoxColor *colorhints;
171 
172  if ( numbuttons > MAX_BUTTONS ) {
173  return SDL_SetError("Too many buttons (%d max allowed)", MAX_BUTTONS);
174  }
175 
176  data->dialog_width = MIN_DIALOG_WIDTH;
177  data->dialog_height = MIN_DIALOG_HEIGHT;
178  data->messageboxdata = messageboxdata;
179  data->buttondata = buttondata;
180  data->numbuttons = numbuttons;
181  data->pbuttonid = pbuttonid;
182 
183  data->display = XOpenDisplay( NULL );
184  if ( !data->display ) {
185  return SDL_SetError("Couldn't open X11 display");
186  }
187 
188  if (SDL_X11_HAVE_UTF8) {
189  char **missing = NULL;
190  int num_missing = 0;
191  data->font_set = XCreateFontSet(data->display, g_MessageBoxFont,
192  &missing, &num_missing, NULL);
193  if ( missing != NULL ) {
194  XFreeStringList(missing);
195  }
196  if ( data->font_set == NULL ) {
197  return SDL_SetError("Couldn't load font %s", g_MessageBoxFont);
198  }
199  } else {
200  data->font_struct = XLoadQueryFont( data->display, g_MessageBoxFontLatin1 );
201  if ( data->font_struct == NULL ) {
202  return SDL_SetError("Couldn't load font %s", g_MessageBoxFontLatin1);
203  }
204  }
205 
206  if ( messageboxdata->colorScheme ) {
207  colorhints = messageboxdata->colorScheme->colors;
208  } else {
209  colorhints = g_default_colors;
210  }
211 
212  /* Convert our SDL_MessageBoxColor r,g,b values to packed RGB format. */
213  for ( i = 0; i < SDL_MESSAGEBOX_COLOR_MAX; i++ ) {
214  data->color[ i ] = SDL_MAKE_RGB( colorhints[ i ].r, colorhints[ i ].g, colorhints[ i ].b );
215  }
216 
217  return 0;
218 }
219 
220 /* Calculate and initialize text and button locations. */
221 static int
222 X11_MessageBoxInitPositions( SDL_MessageBoxDataX11 *data )
223 {
224  int i;
225  int ybuttons;
226  int text_width_max = 0;
227  int button_text_height = 0;
228  int button_width = MIN_BUTTON_WIDTH;
229  const SDL_MessageBoxData *messageboxdata = data->messageboxdata;
230 
231  /* Go over text and break linefeeds into separate lines. */
232  if ( messageboxdata->message && messageboxdata->message[ 0 ] ) {
233  const char *text = messageboxdata->message;
234  TextLineData *plinedata = data->linedata;
235 
236  for ( i = 0; i < MAX_TEXT_LINES; i++, plinedata++ ) {
237  int height;
238  char *lf = SDL_strchr( ( char * )text, '\n' );
239 
240  data->numlines++;
241 
242  /* Only grab length up to lf if it exists and isn't the last line. */
243  plinedata->length = ( lf && ( i < MAX_TEXT_LINES - 1 ) ) ? ( lf - text ) : SDL_strlen( text );
244  plinedata->text = text;
245 
246  GetTextWidthHeight( data, text, plinedata->length, &plinedata->width, &height );
247 
248  /* Text and widths are the largest we've ever seen. */
249  data->text_height = IntMax( data->text_height, height );
250  text_width_max = IntMax( text_width_max, plinedata->width );
251 
252  if (lf && (lf > text) && (lf[-1] == '\r')) {
253  plinedata->length--;
254  }
255 
256  text += plinedata->length + 1;
257 
258  /* Break if there are no more linefeeds. */
259  if ( !lf )
260  break;
261  }
262 
263  /* Bump up the text height slightly. */
264  data->text_height += 2;
265  }
266 
267  /* Loop through all buttons and calculate the button widths and height. */
268  for ( i = 0; i < data->numbuttons; i++ ) {
269  int height;
270 
271  data->buttonpos[ i ].buttondata = &data->buttondata[ i ];
272  data->buttonpos[ i ].length = SDL_strlen( data->buttondata[ i ].text );
273 
274  GetTextWidthHeight( data, data->buttondata[ i ].text, SDL_strlen( data->buttondata[ i ].text ),
275  &data->buttonpos[ i ].text_width, &height );
276 
277  button_width = IntMax( button_width, data->buttonpos[ i ].text_width );
278  button_text_height = IntMax( button_text_height, height );
279  }
280 
281  if ( data->numlines ) {
282  /* x,y for this line of text. */
283  data->xtext = data->text_height;
284  data->ytext = data->text_height + data->text_height;
285 
286  /* Bump button y down to bottom of text. */
287  ybuttons = 3 * data->ytext / 2 + ( data->numlines - 1 ) * data->text_height;
288 
289  /* Bump the dialog box width and height up if needed. */
290  data->dialog_width = IntMax( data->dialog_width, 2 * data->xtext + text_width_max );
291  data->dialog_height = IntMax( data->dialog_height, ybuttons );
292  } else {
293  /* Button y starts at height of button text. */
294  ybuttons = button_text_height;
295  }
296 
297  if ( data->numbuttons ) {
298  int x, y;
299  int width_of_buttons;
300  int button_spacing = button_text_height;
301  int button_height = 2 * button_text_height;
302 
303  /* Bump button width up a bit. */
304  button_width += button_text_height;
305 
306  /* Get width of all buttons lined up. */
307  width_of_buttons = data->numbuttons * button_width + ( data->numbuttons - 1 ) * button_spacing;
308 
309  /* Bump up dialog width and height if buttons are wider than text. */
310  data->dialog_width = IntMax( data->dialog_width, width_of_buttons + 2 * button_spacing );
311  data->dialog_height = IntMax( data->dialog_height, ybuttons + 2 * button_height );
312 
313  /* Location for first button. */
314  x = ( data->dialog_width - width_of_buttons ) / 2;
315  y = ybuttons + ( data->dialog_height - ybuttons - button_height ) / 2;
316 
317  for ( i = 0; i < data->numbuttons; i++ ) {
318  /* Button coordinates. */
319  data->buttonpos[ i ].rect.x = x;
320  data->buttonpos[ i ].rect.y = y;
321  data->buttonpos[ i ].rect.w = button_width;
322  data->buttonpos[ i ].rect.h = button_height;
323 
324  /* Button text coordinates. */
325  data->buttonpos[ i ].x = x + ( button_width - data->buttonpos[ i ].text_width ) / 2;
326  data->buttonpos[ i ].y = y + ( button_height - button_text_height - 1 ) / 2 + button_text_height;
327 
328  /* Scoot over for next button. */
329  x += button_width + button_spacing;
330  }
331  }
332 
333  return 0;
334 }
335 
336 /* Free SDL_MessageBoxData data. */
337 static void
338 X11_MessageBoxShutdown( SDL_MessageBoxDataX11 *data )
339 {
340  if ( data->font_set != NULL ) {
341  XFreeFontSet( data->display, data->font_set );
342  data->font_set = NULL;
343  }
344 
345  if ( data->font_struct != NULL ) {
346  XFreeFont( data->display, data->font_struct );
347  data->font_struct = NULL;
348  }
349 
350  if ( data->display ) {
351  if ( data->window != None ) {
352  XWithdrawWindow( data->display, data->window, data->screen );
353  XDestroyWindow( data->display, data->window );
354  data->window = None;
355  }
356 
357  XCloseDisplay( data->display );
358  data->display = NULL;
359  }
360 }
361 
362 /* Create and set up our X11 dialog box indow. */
363 static int
364 X11_MessageBoxCreateWindow( SDL_MessageBoxDataX11 *data )
365 {
366  int x, y;
367  XSizeHints *sizehints;
368  XSetWindowAttributes wnd_attr;
369  Display *display = data->display;
370  SDL_WindowData *windowdata = NULL;
371  const SDL_MessageBoxData *messageboxdata = data->messageboxdata;
372 
373  if ( messageboxdata->window ) {
374  SDL_DisplayData *displaydata =
376  windowdata = (SDL_WindowData *)messageboxdata->window->driverdata;
377  data->screen = displaydata->screen;
378  } else {
379  data->screen = DefaultScreen( display );
380  }
381 
382  data->event_mask = ExposureMask |
383  ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask |
384  StructureNotifyMask | FocusChangeMask | PointerMotionMask;
385  wnd_attr.event_mask = data->event_mask;
386 
387  data->window = XCreateWindow(
388  display, RootWindow(display, data->screen),
389  0, 0,
390  data->dialog_width, data->dialog_height,
391  0, CopyFromParent, InputOutput, CopyFromParent,
392  CWEventMask, &wnd_attr );
393  if ( data->window == None ) {
394  return SDL_SetError("Couldn't create X window");
395  }
396 
397  if ( windowdata ) {
398  /* http://tronche.com/gui/x/icccm/sec-4.html#WM_TRANSIENT_FOR */
399  XSetTransientForHint( display, data->window, windowdata->xwindow );
400  }
401 
402  XStoreName( display, data->window, messageboxdata->title );
403 
404  /* Allow the window to be deleted by the window manager */
405  data->wm_protocols = XInternAtom( display, "WM_PROTOCOLS", False );
406  data->wm_delete_message = XInternAtom( display, "WM_DELETE_WINDOW", False );
407  XSetWMProtocols( display, data->window, &data->wm_delete_message, 1 );
408 
409  if ( windowdata ) {
410  XWindowAttributes attrib;
411  Window dummy;
412 
413  XGetWindowAttributes(display, windowdata->xwindow, &attrib);
414  x = attrib.x + ( attrib.width - data->dialog_width ) / 2;
415  y = attrib.y + ( attrib.height - data->dialog_height ) / 3 ;
416  XTranslateCoordinates(display, windowdata->xwindow, RootWindow(display, data->screen), x, y, &x, &y, &dummy);
417  } else {
418  x = ( DisplayWidth( display, data->screen ) - data->dialog_width ) / 2;
419  y = ( DisplayHeight( display, data->screen ) - data->dialog_height ) / 3 ;
420  }
421  XMoveWindow( display, data->window, x, y );
422 
423  sizehints = XAllocSizeHints();
424  if ( sizehints ) {
425  sizehints->flags = USPosition | USSize | PMaxSize | PMinSize;
426  sizehints->x = x;
427  sizehints->y = y;
428  sizehints->width = data->dialog_width;
429  sizehints->height = data->dialog_height;
430 
431  sizehints->min_width = sizehints->max_width = data->dialog_width;
432  sizehints->min_height = sizehints->max_height = data->dialog_height;
433 
434  XSetWMNormalHints( display, data->window, sizehints );
435 
436  XFree( sizehints );
437  }
438 
439  XMapRaised( display, data->window );
440  return 0;
441 }
442 
443 /* Draw our message box. */
444 static void
445 X11_MessageBoxDraw( SDL_MessageBoxDataX11 *data, GC ctx )
446 {
447  int i;
448  Window window = data->window;
449  Display *display = data->display;
450 
451  XSetForeground( display, ctx, data->color[ SDL_MESSAGEBOX_COLOR_BACKGROUND ] );
452  XFillRectangle( display, window, ctx, 0, 0, data->dialog_width, data->dialog_height );
453 
454  XSetForeground( display, ctx, data->color[ SDL_MESSAGEBOX_COLOR_TEXT ] );
455  for ( i = 0; i < data->numlines; i++ ) {
456  TextLineData *plinedata = &data->linedata[ i ];
457 
458  if (SDL_X11_HAVE_UTF8) {
459  Xutf8DrawString( display, window, data->font_set, ctx,
460  data->xtext, data->ytext + i * data->text_height,
461  plinedata->text, plinedata->length );
462  } else {
463  XDrawString( display, window, ctx,
464  data->xtext, data->ytext + i * data->text_height,
465  plinedata->text, plinedata->length );
466  }
467  }
468 
469  for ( i = 0; i < data->numbuttons; i++ ) {
470  SDL_MessageBoxButtonDataX11 *buttondatax11 = &data->buttonpos[ i ];
471  const SDL_MessageBoxButtonData *buttondata = buttondatax11->buttondata;
472  int border = ( buttondata->flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT ) ? 2 : 0;
473  int offset = ( ( data->mouse_over_index == i ) && ( data->button_press_index == data->mouse_over_index ) ) ? 1 : 0;
474 
475  XSetForeground( display, ctx, data->color[ SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND ] );
476  XFillRectangle( display, window, ctx,
477  buttondatax11->rect.x - border, buttondatax11->rect.y - border,
478  buttondatax11->rect.w + 2 * border, buttondatax11->rect.h + 2 * border );
479 
480  XSetForeground( display, ctx, data->color[ SDL_MESSAGEBOX_COLOR_BUTTON_BORDER ] );
481  XDrawRectangle( display, window, ctx,
482  buttondatax11->rect.x, buttondatax11->rect.y,
483  buttondatax11->rect.w, buttondatax11->rect.h );
484 
485  XSetForeground( display, ctx, ( data->mouse_over_index == i ) ?
486  data->color[ SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED ] :
487  data->color[ SDL_MESSAGEBOX_COLOR_TEXT ] );
488 
489  if (SDL_X11_HAVE_UTF8) {
490  Xutf8DrawString( display, window, data->font_set, ctx,
491  buttondatax11->x + offset,
492  buttondatax11->y + offset,
493  buttondata->text, buttondatax11->length );
494  } else {
495  XDrawString( display, window, ctx,
496  buttondatax11->x + offset, buttondatax11->y + offset,
497  buttondata->text, buttondatax11->length );
498  }
499  }
500 }
501 
502 /* Loop and handle message box event messages until something kills it. */
503 static int
504 X11_MessageBoxLoop( SDL_MessageBoxDataX11 *data )
505 {
506  GC ctx;
507  XGCValues ctx_vals;
508  SDL_bool close_dialog = SDL_FALSE;
509  SDL_bool has_focus = SDL_TRUE;
510  KeySym last_key_pressed = XK_VoidSymbol;
511  unsigned long gcflags = GCForeground | GCBackground;
512 
513  SDL_zero(ctx_vals);
514  ctx_vals.foreground = data->color[ SDL_MESSAGEBOX_COLOR_BACKGROUND ];
515  ctx_vals.background = data->color[ SDL_MESSAGEBOX_COLOR_BACKGROUND ];
516 
517  if (!SDL_X11_HAVE_UTF8) {
518  gcflags |= GCFont;
519  ctx_vals.font = data->font_struct->fid;
520  }
521 
522  ctx = XCreateGC( data->display, data->window, gcflags, &ctx_vals );
523  if ( ctx == None ) {
524  return SDL_SetError("Couldn't create graphics context");
525  }
526 
527  data->button_press_index = -1; /* Reset what button is currently depressed. */
528  data->mouse_over_index = -1; /* Reset what button the mouse is over. */
529 
530  while( !close_dialog ) {
531  XEvent e;
532  SDL_bool draw = SDL_TRUE;
533 
534  XWindowEvent( data->display, data->window, data->event_mask, &e );
535 
536  /* If XFilterEvent returns True, then some input method has filtered the
537  event, and the client should discard the event. */
538  if ( ( e.type != Expose ) && XFilterEvent( &e, None ) )
539  continue;
540 
541  switch( e.type ) {
542  case Expose:
543  if ( e.xexpose.count > 0 ) {
544  draw = SDL_FALSE;
545  }
546  break;
547 
548  case FocusIn:
549  /* Got focus. */
550  has_focus = SDL_TRUE;
551  break;
552 
553  case FocusOut:
554  /* lost focus. Reset button and mouse info. */
555  has_focus = SDL_FALSE;
556  data->button_press_index = -1;
557  data->mouse_over_index = -1;
558  break;
559 
560  case MotionNotify:
561  if ( has_focus ) {
562  /* Mouse moved... */
563  data->mouse_over_index = GetHitButtonIndex( data, e.xbutton.x, e.xbutton.y );
564  }
565  break;
566 
567  case ClientMessage:
568  if ( e.xclient.message_type == data->wm_protocols &&
569  e.xclient.format == 32 &&
570  e.xclient.data.l[ 0 ] == data->wm_delete_message ) {
571  close_dialog = SDL_TRUE;
572  }
573  break;
574 
575  case KeyPress:
576  /* Store key press - we make sure in key release that we got both. */
577  last_key_pressed = XLookupKeysym( &e.xkey, 0 );
578  break;
579 
580  case KeyRelease: {
581  Uint32 mask = 0;
582  KeySym key = XLookupKeysym( &e.xkey, 0 );
583 
584  /* If this is a key release for something we didn't get the key down for, then bail. */
585  if ( key != last_key_pressed )
586  break;
587 
588  if ( key == XK_Escape )
590  else if ( ( key == XK_Return ) || ( key == XK_KP_Enter ) )
592 
593  if ( mask ) {
594  int i;
595 
596  /* Look for first button with this mask set, and return it if found. */
597  for ( i = 0; i < data->numbuttons; i++ ) {
598  SDL_MessageBoxButtonDataX11 *buttondatax11 = &data->buttonpos[ i ];
599 
600  if ( buttondatax11->buttondata->flags & mask ) {
601  *data->pbuttonid = buttondatax11->buttondata->buttonid;
602  close_dialog = SDL_TRUE;
603  break;
604  }
605  }
606  }
607  break;
608  }
609 
610  case ButtonPress:
611  data->button_press_index = -1;
612  if ( e.xbutton.button == Button1 ) {
613  /* Find index of button they clicked on. */
614  data->button_press_index = GetHitButtonIndex( data, e.xbutton.x, e.xbutton.y );
615  }
616  break;
617 
618  case ButtonRelease:
619  /* If button is released over the same button that was clicked down on, then return it. */
620  if ( ( e.xbutton.button == Button1 ) && ( data->button_press_index >= 0 ) ) {
621  int button = GetHitButtonIndex( data, e.xbutton.x, e.xbutton.y );
622 
623  if ( data->button_press_index == button ) {
624  SDL_MessageBoxButtonDataX11 *buttondatax11 = &data->buttonpos[ button ];
625 
626  *data->pbuttonid = buttondatax11->buttondata->buttonid;
627  close_dialog = SDL_TRUE;
628  }
629  }
630  data->button_press_index = -1;
631  break;
632  }
633 
634  if ( draw ) {
635  /* Draw our dialog box. */
636  X11_MessageBoxDraw( data, ctx );
637  }
638  }
639 
640  XFreeGC( data->display, ctx );
641  return 0;
642 }
643 
644 static int
645 X11_ShowMessageBoxImpl(const SDL_MessageBoxData *messageboxdata, int *buttonid)
646 {
647  int ret;
648  SDL_MessageBoxDataX11 data;
649 #if SDL_SET_LOCALE
650  char *origlocale;
651 #endif
652 
653  SDL_zero(data);
654 
655  if ( !SDL_X11_LoadSymbols() )
656  return -1;
657 
658 #if SDL_SET_LOCALE
659  origlocale = setlocale(LC_ALL, NULL);
660  if (origlocale != NULL) {
661  origlocale = SDL_strdup(origlocale);
662  if (origlocale == NULL) {
663  return SDL_OutOfMemory();
664  }
665  setlocale(LC_ALL, "");
666  }
667 #endif
668 
669  /* This code could get called from multiple threads maybe? */
670  XInitThreads();
671 
672  /* Initialize the return buttonid value to -1 (for error or dialogbox closed). */
673  *buttonid = -1;
674 
675  /* Init and display the message box. */
676  ret = X11_MessageBoxInit( &data, messageboxdata, buttonid );
677  if ( ret != -1 ) {
678  ret = X11_MessageBoxInitPositions( &data );
679  if ( ret != -1 ) {
680  ret = X11_MessageBoxCreateWindow( &data );
681  if ( ret != -1 ) {
682  ret = X11_MessageBoxLoop( &data );
683  }
684  }
685  }
686 
687  X11_MessageBoxShutdown( &data );
688 
689 #if SDL_SET_LOCALE
690  if (origlocale) {
691  setlocale(LC_ALL, origlocale);
692  SDL_free(origlocale);
693  }
694 #endif
695 
696  return ret;
697 }
698 
699 /* Display an x11 message box. */
700 int
701 X11_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
702 {
703 #if SDL_FORK_MESSAGEBOX
704  /* Use a child process to protect against setlocale(). Annoying. */
705  pid_t pid;
706  int fds[2];
707  int status = 0;
708 
709  /* Need to flush here in case someone has turned grab off and it hasn't gone through yet, etc. */
710  XFlush(data->display);
711 
712  if (pipe(fds) == -1) {
713  return X11_ShowMessageBoxImpl(messageboxdata, buttonid); /* oh well. */
714  }
715 
716  pid = fork();
717  if (pid == -1) { /* failed */
718  close(fds[0]);
719  close(fds[1]);
720  return X11_ShowMessageBoxImpl(messageboxdata, buttonid); /* oh well. */
721  } else if (pid == 0) { /* we're the child */
722  int exitcode = 0;
723  close(fds[0]);
724  status = X11_ShowMessageBoxImpl(messageboxdata, buttonid);
725  if (write(fds[1], &status, sizeof (int)) != sizeof (int))
726  exitcode = 1;
727  else if (write(fds[1], buttonid, sizeof (int)) != sizeof (int))
728  exitcode = 1;
729  close(fds[1]);
730  _exit(exitcode); /* don't run atexit() stuff, static destructors, etc. */
731  } else { /* we're the parent */
732  pid_t rc;
733  close(fds[1]);
734  do {
735  rc = waitpid(pid, &status, 0);
736  } while ((rc == -1) && (errno == EINTR));
737 
738  SDL_assert(rc == pid); /* not sure what to do if this fails. */
739 
740  if ((rc == -1) || (!WIFEXITED(status)) || (WEXITSTATUS(status) != 0)) {
741  return SDL_SetError("msgbox child process failed");
742  }
743 
744  if (read(fds[0], &status, sizeof (int)) != sizeof (int))
745  status = -1;
746  else if (read(fds[0], buttonid, sizeof (int)) != sizeof (int))
747  status = -1;
748  close(fds[0]);
749 
750  return status;
751  }
752 #else
753  return X11_ShowMessageBoxImpl(messageboxdata, buttonid);
754 #endif
755 }
756 #endif /* SDL_VIDEO_DRIVER_X11 */
757 
758 /* vi: set ts=4 sw=4 expandtab: */
const char * message
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer retur XCloseDisplay)
Definition: SDL_x11sym.h:34
#define __inline__
Definition: begin_code.h:119
GLuint color
Definition: glew.h:7185
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int int return Display Window Cursor return Display Window return Display Drawable GC int int unsigned int unsigned int return Display Drawable GC int int _Xconst char int return Display Drawable GC int int unsigned int unsigned int return Display return Display Cursor return Display GC return XModifierKeymap return char Display Window int return Display return Display Atom return Display Window XWindowAttributes return Display Window return Display XEvent Bool(*) XPointer return Display Window Bool unsigned int int int Window Cursor Time return Display Window int return KeySym return Display _Xconst char Bool return Display _Xconst char return XKeyEvent char int KeySym XComposeStatus return Display int int int XVisualInfo return Display Window int int retur XOpenDisplay)
Definition: SDL_x11sym.h:92
const char * title
SDL_Window * window
GLboolean GLboolean g
Definition: glew.h:8736
#define NULL
Definition: ftobjs.h:61
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int int return Display Window Cursor return Display Window return Display Drawable GC int int unsigned int unsigned int return Display Drawable GC int int _Xconst char int return Display Drawable GC int int unsigned int unsigned int retur XFlush)
Definition: SDL_x11sym.h:54
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int int return Display Window Cursor return Display Window return Display Drawable GC int int unsigned int unsigned int return Display Drawable GC int int _Xconst char int retur XFillRectangle)
Definition: SDL_x11sym.h:52
SDL_bool
Definition: SDL_stdinc.h:116
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int int return Display Window Cursor return Display Window return Display Drawable GC int int unsigned int unsigned int return Display Drawable GC int int _Xconst char int return Display Drawable GC int int unsigned int unsigned int return Display return Display Cursor return Display GC return XModifierKeymap retur XFreeStringList)
Definition: SDL_x11sym.h:62
EGLSurface EGLint x
Definition: eglext.h:293
return Display return Display Bool Bool int int e
Definition: SDL_x11sym.h:30
DECLSPEC void SDLCALL SDL_free(void *mem)
EGLSurface EGLint EGLint EGLint EGLint height
Definition: eglext.h:293
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:8736
char * display
Definition: visualinfo.c:85
DECLSPEC char *SDLCALL SDL_strchr(const char *str, int c)
Definition: SDL_string.c:575
#define SDL_X11_HAVE_UTF8
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int int return Display Window Cursor return Display Window retur XDrawRectangle)
Definition: SDL_x11sym.h:48
ret
Definition: glew_str_glx.c:2
RGB value used in a message box color scheme.
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int int return Display Window Cursor return Display Window return Display Drawable GC int int unsigned int unsigned int return Display Drawable GC int int _Xconst char int return Display Drawable GC int int unsigned int unsigned int return Display return Display Cursor return Display GC return XModifierKeymap return char Display Window int return Display return Display Atom return Display Window XWindowAttributes return Display Window return Display XEvent Bool(*) XPointer return Display Window Bool unsigned int int int Window Cursor Time return Display Window int return KeySym return Display _Xconst char Bool return Display _Xconst char return XKeyEvent char int KeySym XComposeStatus return Display int int int XVisualInfo return Display Window int int return _Xconst char return Display XEvent return Display Drawable GC XImage int int int int unsigned int unsigned int return Display Window Window Window int int int int unsigned int return Display Window Window int int return Display Window unsigned int unsigned int return Display Window Bool long XEvent return Display GC unsigned long return Display Window int Time retur XSetTransientForHint)
Definition: SDL_x11sym.h:110
Individual button data.
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int int return Display Window Cursor return Display Window return Display Drawable GC int int unsigned int unsigned int return Display Drawable GC int int _Xconst char int return Display Drawable GC int int unsigned int unsigned int return Display return Display Cursor return Display GC return XModifierKeymap return char Display Window int return Display return Display Atom return Display Window XWindowAttributes return Display Window return Display XEvent Bool(*) XPointer return Display Window Bool unsigned int int int Window Cursor Time return Display Window int return KeySym return Display _Xconst char Bool retur XLoadQueryFont)
Definition: SDL_x11sym.h:84
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:145
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int int return Display Window Cursor return Display Window return Display Drawable GC int int unsigned int unsigned int return Display Drawable GC int int _Xconst char int return Display Drawable GC int int unsigned int unsigned int return Display return Display Cursor return Display GC return XModifierKeymap return char Display Window int return Display return Display Atom return Display Window XWindowAttributes return Display Window return Display XEvent Bool(*) XPointer return Display Window Bool unsigned int int int Window Cursor Time return Display Window int return KeySym retur XInternAtom)
Definition: SDL_x11sym.h:82
#define XK_VoidSymbol
GLsizei GLsizei * length
Definition: gl2ext.h:792
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl2ext.h:848
EGLSurface EGLint EGLint EGLint width
Definition: eglext.h:293
DECLSPEC char *SDLCALL SDL_strdup(const char *str)
Definition: SDL_string.c:511
int SDL_X11_LoadSymbols(void)
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
Definition: SDL_error.c:53
#define XK_Escape
GLint GLenum GLsizei GLsizei GLsizei GLint border
Definition: gl2ext.h:845
int x
Definition: SDL_rect.h:65
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int int return Display Window Cursor return Display Window return Display Drawable GC int int unsigned int unsigned int return Display Drawable GC int int _Xconst char int return Display Drawable GC int int unsigned int unsigned int return Display return Display Cursor return Display GC return XModifierKeymap return char Display Window int return Display return Display Atom retur XGetWindowAttributes)
Definition: SDL_x11sym.h:70
const SDL_MessageBoxButtonData * buttons
int w
Definition: SDL_rect.h:66
MessageBox structure containing title, text, window, etc.
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int int return Display Window Cursor return Display Window return Display Drawable GC int int unsigned int unsigned int return Display Drawable GC int int _Xconst char int return Display Drawable GC int int unsigned int unsigned int return Display return Display Cursor return Display GC return XModifierKeymap return char Display Window int return Display return Display Atom return Display Window XWindowAttributes return Display Window return Display XEvent Bool(*) XPointer return Display Window Bool unsigned int int int Window Cursor Time return Display Window int return KeySym return Display _Xconst char Bool return Display _Xconst char return XKeyEvent char int KeySym XComposeStatus return Display int int int XVisualInfo return Display Window int int return _Xconst char return Display XEvent return Display Drawable GC XImage int int int int unsigned int unsigned int return Display Window Window Window int int int int unsigned int return Display Window Window int int return Display Window unsigned int unsigned int return Display Window Bool long XEvent retur XSetForeground)
Definition: SDL_x11sym.h:106
#define SDL_assert(condition)
Definition: SDL_assert.h:159
DECLSPEC size_t SDLCALL SDL_strlen(const char *str)
Definition: SDL_string.c:389
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int retur XCreateFontSet)
Definition: SDL_x11sym.h:40
EGLSurface EGLint EGLint y
Definition: eglext.h:293
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
GLintptr offset
Definition: glew.h:1668
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
Definition: SDL_video.c:996
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int int return Display Window Cursor return Display Window return Display Drawable GC int int unsigned int unsigned int retur XDrawString)
Definition: SDL_x11sym.h:50
int h
Definition: SDL_rect.h:66
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
Definition: gl2ext.h:961
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int int return Display Window Cursor return Display Window return Display Drawable GC int int unsigned int unsigned int return Display Drawable GC int int _Xconst char int return Display Drawable GC int int unsigned int unsigned int return Display return Display Cursor return Display GC return XModifierKeymap return char Display Window int return Display return Display Atom return Display Window XWindowAttributes return Display Window return Display XEvent Bool(*) XPointer return Display Window Bool unsigned int int int Window Cursor Time return Display Window int return KeySym return Display _Xconst char Bool return Display _Xconst char return XKeyEvent char int KeySym XComposeStatus return Display int int int XVisualInfo return Display Window int int return _Xconst char return Display XEvent return Display Drawable GC XImage int int int int unsigned int unsigned int return Display Window Window Window int int int int unsigned int return Display Window Window int int return Display Window unsigned int unsigned int return Display Window Bool long XEvent return Display GC unsigned long return Display Window int Time return Display Window Window return Display Window unsigned long return Display Window XSizeHints Display Colormap XColor int return char int XTextProperty retur XTextExtents)
Definition: SDL_x11sym.h:120
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int int return Display Window Cursor return Display Window return Display Drawable GC int int unsigned int unsigned int return Display Drawable GC int int _Xconst char int return Display Drawable GC int int unsigned int unsigned int return Display return Display Cursor return Display GC return XModifierKeymap return char Display Window int return Display return Display Atom return Display Window XWindowAttributes return Display Window return Display XEvent Bool(*) XPointer return Display Window Bool unsigned int int int Window Cursor Time return Display Window int return KeySym return Display _Xconst char Bool return Display _Xconst char return XKeyEvent char int KeySym XComposeStatus return Display int int int XVisualInfo return Display Window int int return _Xconst char return Display XEvent return Display Drawable GC XImage int int int int unsigned int unsigned int return Display Window Window Window int int int int unsigned int return Display Window Window int int return Display Window unsigned int unsigned int return Display Window Bool long XEvent return Display GC unsigned long return Display Window int Time return Display Window Window return Display Window unsigned long return Display Window XSizeHints Display Colormap XColor int return char int XTextProperty return XFontStruct _Xconst char int int int int XCharStruct return Display Window return Display Time return Display Colormap return Display Window Window int int unsigned int unsigned int int int retur XWithdrawWindow)
Definition: SDL_x11sym.h:130
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int int return Display Window Cursor return Display Window return Display Drawable GC int int unsigned int unsigned int return Display Drawable GC int int _Xconst char int return Display Drawable GC int int unsigned int unsigned int return Display return Display Cursor return Display GC return XModifierKeymap return char Display Window int return Display return Display Atom return Display Window XWindowAttributes return Display Window return Display XEvent Bool(*) XPointer return Display Window Bool unsigned int int int Window Cursor Time return Display Window int return KeySym return Display _Xconst char Bool return Display _Xconst char return XKeyEvent char int KeySym XComposeStatus return Display int int int XVisualInfo return Display Window int int return _Xconst char return Display XEvent return Display Drawable GC XImage int int int int unsigned int unsigned int return Display Window Window Window int int int int unsigned int return Display Window Window int int return Display Window unsigned int unsigned int return Display Window Bool long XEvent return Display GC unsigned long return Display Window int Time return Display Window Window return Display Window unsigned long retur XSetWMNormalHints)
Definition: SDL_x11sym.h:114
GLdouble GLdouble GLdouble r
Definition: glew.h:1392
GLdouble GLdouble GLdouble b
Definition: glew.h:8383
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int int return Display Window Cursor retur XDestroyWindow)
Definition: SDL_x11sym.h:46
#define str(s)
#define SDL_zero(x)
Definition: SDL_stdinc.h:254
void * driverdata
Definition: SDL_sysvideo.h:99
int i
Definition: pngrutil.c:1377
#define XK_KP_Enter
const SDL_MessageBoxColorScheme * colorScheme
SDL_MessageBoxColor colors[SDL_MESSAGEBOX_COLOR_MAX]
#define XK_Return
int y
Definition: SDL_rect.h:65
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int int return Display Window Cursor return Display Window return Display Drawable GC int int unsigned int unsigned int return Display Drawable GC int int _Xconst char int return Display Drawable GC int int unsigned int unsigned int return Display return Display Cursor retur XFreeGC)
Definition: SDL_x11sym.h:58
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:63
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int int return Display Window Cursor return Display Window return Display Drawable GC int int unsigned int unsigned int return Display Drawable GC int int _Xconst char int return Display Drawable GC int int unsigned int unsigned int return Display return Display Cursor return Display GC return XModifierKeymap return char Display Window int return Display return Display Atom return Display Window XWindowAttributes return Display Window return Display XEvent Bool(*) XPointer return Display Window Bool unsigned int int int Window Cursor Time return Display Window int return KeySym return Display _Xconst char Bool return Display _Xconst char return XKeyEvent char int KeySym XComposeStatus return Display int int int XVisualInfo retur XMoveWindow)
Definition: SDL_x11sym.h:90
EGLContext ctx
Definition: eglext.h:87