src/video/x11/SDL_x11messagebox.c
changeset 6725 a7a99a9d419a
parent 6724 6c5ed0c4cc6d
child 6726 f2898757eaae
equal deleted inserted replaced
6724:6c5ed0c4cc6d 6725:a7a99a9d419a
    17   2. Altered source versions must be plainly marked as such, and must not be
    17   2. Altered source versions must be plainly marked as such, and must not be
    18      misrepresented as being the original software.
    18      misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    20 */
    21 
    21 
    22 /* !!! FIXME: clean up differences in coding style in this file. */
       
    23 
       
    24 #include "SDL_config.h"
    22 #include "SDL_config.h"
    25 
    23 
    26 #if SDL_VIDEO_DRIVER_X11
    24 #if SDL_VIDEO_DRIVER_X11
    27 
    25 
    28 #include "SDL.h"
    26 #include "SDL.h"
    38 #define MIN_DIALOG_HEIGHT       100     /* Minimum dialog height */
    36 #define MIN_DIALOG_HEIGHT       100     /* Minimum dialog height */
    39 
    37 
    40 static const char g_MessageBoxFontLatin1[] = "-*-*-medium-r-normal--0-120-*-*-p-0-iso8859-1";
    38 static const char g_MessageBoxFontLatin1[] = "-*-*-medium-r-normal--0-120-*-*-p-0-iso8859-1";
    41 static const char g_MessageBoxFont[] = "-*-*-*-*-*-*-*-*-*-*-*-*-*-*";
    39 static const char g_MessageBoxFont[] = "-*-*-*-*-*-*-*-*-*-*-*-*-*-*";
    42 
    40 
    43 static const SDL_MessageBoxColor g_default_colors[ SDL_MESSAGEBOX_COLOR_MAX ] =
    41 static const SDL_MessageBoxColor g_default_colors[ SDL_MESSAGEBOX_COLOR_MAX ] = {
    44 {
    42     { 56,  54,  53  }, // SDL_MESSAGEBOX_COLOR_BACKGROUND,
    45     { 56,  54,  53  }, // SDL_MESSAGEBOX_COLOR_BACKGROUND,       
    43     { 209, 207, 205 }, // SDL_MESSAGEBOX_COLOR_TEXT,
    46     { 209, 207, 205 }, // SDL_MESSAGEBOX_COLOR_TEXT,             
    44     { 140, 135, 129 }, // SDL_MESSAGEBOX_COLOR_BUTTON_BORDER,
    47     { 140, 135, 129 }, // SDL_MESSAGEBOX_COLOR_BUTTON_BORDER,    
       
    48     { 105, 102, 99  }, // SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND,
    45     { 105, 102, 99  }, // SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND,
    49     { 205, 202, 53  }, // SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED,  
    46     { 205, 202, 53  }, // SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED,
    50 };
    47 };
    51 
    48 
    52 #define SDL_MAKE_RGB( _r, _g, _b )  ( ( ( Uint32 )( _r ) << 16 ) | \
    49 #define SDL_MAKE_RGB( _r, _g, _b )  ( ( ( Uint32 )( _r ) << 16 ) | \
    53                                       ( ( Uint32 )( _g ) << 8 ) |  \
    50                                       ( ( Uint32 )( _g ) << 8 ) |  \
    54                                       ( ( Uint32 )( _b ) ) )
    51                                       ( ( Uint32 )( _b ) ) )
    55 
    52 
    56 typedef struct SDL_MessageBoxButtonDataX11
    53 typedef struct SDL_MessageBoxButtonDataX11 {
    57 {
       
    58     int x, y;                           /* Text position */
    54     int x, y;                           /* Text position */
    59     int length;                         /* Text length */
    55     int length;                         /* Text length */
    60     int text_width;                     /* Text width */
    56     int text_width;                     /* Text width */
    61 
    57 
    62     SDL_Rect rect;                      /* Rectangle for entire button */
    58     SDL_Rect rect;                      /* Rectangle for entire button */
    63 
    59 
    64     const SDL_MessageBoxButtonData *buttondata;   /* Button data from caller */
    60     const SDL_MessageBoxButtonData *buttondata;   /* Button data from caller */
    65 } SDL_MessageBoxButtonDataX11;
    61 } SDL_MessageBoxButtonDataX11;
    66 
    62 
    67 typedef struct TextLineData
    63 typedef struct TextLineData {
    68 {
       
    69     int width;                          /* Width of this text line */
    64     int width;                          /* Width of this text line */
    70     int length;                         /* String length of this text line */
    65     int length;                         /* String length of this text line */
    71     const char *text;                   /* Text for this line */
    66     const char *text;                   /* Text for this line */
    72 } TextLineData;
    67 } TextLineData;
    73 
    68 
    74 typedef struct SDL_MessageBoxDataX11
    69 typedef struct SDL_MessageBoxDataX11 {
    75 {
       
    76     XFontSet font_set;                  /* for UTF-8 systems */
    70     XFontSet font_set;                  /* for UTF-8 systems */
    77     XFontStruct *font_struct;            /* Latin1 (ASCII) fallback. */
    71     XFontStruct *font_struct;            /* Latin1 (ASCII) fallback. */
    78     Window window;
    72     Window window;
    79     Display *display;
    73     Display *display;
    80     long event_mask;
    74     long event_mask;
   136 {
   130 {
   137     int i;
   131     int i;
   138     int numbuttons = data->numbuttons;
   132     int numbuttons = data->numbuttons;
   139     SDL_MessageBoxButtonDataX11 *buttonpos = data->buttonpos;
   133     SDL_MessageBoxButtonDataX11 *buttonpos = data->buttonpos;
   140 
   134 
   141     for ( i = 0; i < numbuttons; i++ )
   135     for ( i = 0; i < numbuttons; i++ ) {
   142     {
       
   143         SDL_Rect *rect = &buttonpos[ i ].rect;
   136         SDL_Rect *rect = &buttonpos[ i ].rect;
   144 
   137 
   145         if ( ( x >= rect->x ) &&
   138         if ( ( x >= rect->x ) &&
   146             ( x <= ( rect->x + rect->w ) ) &&
   139              ( x <= ( rect->x + rect->w ) ) &&
   147             ( y >= rect->y ) &&
   140              ( y >= rect->y ) &&
   148             ( y <= ( rect->y + rect->h ) ) )
   141              ( y <= ( rect->y + rect->h ) ) ) {
   149         {
       
   150             return i;
   142             return i;
   151         }
   143         }
   152     }
   144     }
   153 
   145 
   154     return -1;
   146     return -1;
   225     int button_text_height = 0;
   217     int button_text_height = 0;
   226     int button_width = MIN_BUTTON_WIDTH;
   218     int button_width = MIN_BUTTON_WIDTH;
   227     const SDL_MessageBoxData *messageboxdata = data->messageboxdata;
   219     const SDL_MessageBoxData *messageboxdata = data->messageboxdata;
   228 
   220 
   229     /* Go over text and break linefeeds into separate lines. */
   221     /* Go over text and break linefeeds into separate lines. */
   230     if ( messageboxdata->message && messageboxdata->message[ 0 ] )
   222     if ( messageboxdata->message && messageboxdata->message[ 0 ] ) {
   231     {
       
   232         const char *text = messageboxdata->message;
   223         const char *text = messageboxdata->message;
   233         TextLineData *plinedata = data->linedata;
   224         TextLineData *plinedata = data->linedata;
   234 
   225 
   235         for ( i = 0; i < MAX_TEXT_LINES; i++, plinedata++ )
   226         for ( i = 0; i < MAX_TEXT_LINES; i++, plinedata++ ) {
   236         {
       
   237             int height;
   227             int height;
   238             char *lf = SDL_strchr( ( char * )text, '\n' );
   228             char *lf = SDL_strchr( ( char * )text, '\n' );
   239 
   229 
   240             data->numlines++;
   230             data->numlines++;
   241 
   231 
   259         /* Bump up the text height slightly. */
   249         /* Bump up the text height slightly. */
   260         data->text_height += 2;
   250         data->text_height += 2;
   261     }
   251     }
   262 
   252 
   263     /* Loop through all buttons and calculate the button widths and height. */
   253     /* Loop through all buttons and calculate the button widths and height. */
   264     for ( i = 0; i < data->numbuttons; i++ )
   254     for ( i = 0; i < data->numbuttons; i++ ) {
   265     {
       
   266         int height;
   255         int height;
   267 
   256 
   268         data->buttonpos[ i ].buttondata = &data->buttondata[ i ];
   257         data->buttonpos[ i ].buttondata = &data->buttondata[ i ];
   269         data->buttonpos[ i ].length = SDL_strlen( data->buttondata[ i ].text );
   258         data->buttonpos[ i ].length = SDL_strlen( data->buttondata[ i ].text );
   270 
   259 
   273 
   262 
   274         button_width = IntMax( button_width, data->buttonpos[ i ].text_width );
   263         button_width = IntMax( button_width, data->buttonpos[ i ].text_width );
   275         button_text_height = IntMax( button_text_height, height );
   264         button_text_height = IntMax( button_text_height, height );
   276     }
   265     }
   277 
   266 
   278     if ( data->numlines )
   267     if ( data->numlines ) {
   279     {
       
   280         /* x,y for this line of text. */
   268         /* x,y for this line of text. */
   281         data->xtext = data->text_height;
   269         data->xtext = data->text_height;
   282         data->ytext = data->text_height + data->text_height;
   270         data->ytext = data->text_height + data->text_height;
   283 
   271 
   284         /* Bump button y down to bottom of text. */
   272         /* Bump button y down to bottom of text. */
   285         ybuttons = 3 * data->ytext / 2 + ( data->numlines - 1 ) * data->text_height;
   273         ybuttons = 3 * data->ytext / 2 + ( data->numlines - 1 ) * data->text_height;
   286 
   274 
   287         /* Bump the dialog box width and height up if needed. */
   275         /* Bump the dialog box width and height up if needed. */
   288         data->dialog_width = IntMax( data->dialog_width, 2 * data->xtext + text_width_max );
   276         data->dialog_width = IntMax( data->dialog_width, 2 * data->xtext + text_width_max );
   289         data->dialog_height = IntMax( data->dialog_height, ybuttons );
   277         data->dialog_height = IntMax( data->dialog_height, ybuttons );
   290     }
   278     } else {
   291     else
       
   292     {
       
   293         /* Button y starts at height of button text. */
   279         /* Button y starts at height of button text. */
   294         ybuttons = button_text_height;
   280         ybuttons = button_text_height;
   295     }
   281     }
   296 
   282 
   297     if ( data->numbuttons )
   283     if ( data->numbuttons ) {
   298     {
       
   299         int x, y;
   284         int x, y;
   300         int width_of_buttons;
   285         int width_of_buttons;
   301         int button_spacing = button_text_height;
   286         int button_spacing = button_text_height;
   302         int button_height = 2 * button_text_height;
   287         int button_height = 2 * button_text_height;
   303 
   288 
   313 
   298 
   314         /* Location for first button. */
   299         /* Location for first button. */
   315         x = ( data->dialog_width - width_of_buttons ) / 2;
   300         x = ( data->dialog_width - width_of_buttons ) / 2;
   316         y = ybuttons + ( data->dialog_height - ybuttons - button_height ) / 2;
   301         y = ybuttons + ( data->dialog_height - ybuttons - button_height ) / 2;
   317 
   302 
   318         for ( i = 0; i < data->numbuttons; i++ )
   303         for ( i = 0; i < data->numbuttons; i++ ) {
   319         {
       
   320             /* Button coordinates. */
   304             /* Button coordinates. */
   321             data->buttonpos[ i ].rect.x = x;
   305             data->buttonpos[ i ].rect.x = x;
   322             data->buttonpos[ i ].rect.y = y;
   306             data->buttonpos[ i ].rect.y = y;
   323             data->buttonpos[ i ].rect.w = button_width;
   307             data->buttonpos[ i ].rect.w = button_width;
   324             data->buttonpos[ i ].rect.h = button_height;
   308             data->buttonpos[ i ].rect.h = button_height;
   337 
   321 
   338 /* Free SDL_MessageBoxData data. */
   322 /* Free SDL_MessageBoxData data. */
   339 static void
   323 static void
   340 X11_MessageBoxShutdown( SDL_MessageBoxDataX11 *data )
   324 X11_MessageBoxShutdown( SDL_MessageBoxDataX11 *data )
   341 {
   325 {
   342     if ( data->font_set != NULL )
   326     if ( data->font_set != NULL ) {
   343     {
       
   344         XFreeFontSet( data->display, data->font_set );
   327         XFreeFontSet( data->display, data->font_set );
   345         data->font_set = NULL;
   328         data->font_set = NULL;
   346     }
   329     }
   347 
   330 
   348     if ( data->font_struct != NULL )
   331     if ( data->font_struct != NULL ) {
   349     {
       
   350         XFreeFont( data->display, data->font_struct );
   332         XFreeFont( data->display, data->font_struct );
   351         data->font_struct = NULL;
   333         data->font_struct = NULL;
   352     }
   334     }
   353 
   335 
   354     if ( data->display )
   336     if ( data->display ) {
   355     {
   337         if ( data->window != None ) {
   356         if ( data->window != None )
       
   357         {
       
   358             XUnmapWindow( data->display, data->window );
   338             XUnmapWindow( data->display, data->window );
   359             XDestroyWindow( data->display, data->window );
   339             XDestroyWindow( data->display, data->window );
   360             data->window = None;
   340             data->window = None;
   361         }
   341         }
   362 
   342 
   379     if ( messageboxdata->window ) {
   359     if ( messageboxdata->window ) {
   380         windowdata = (SDL_WindowData *)messageboxdata->window->driverdata;
   360         windowdata = (SDL_WindowData *)messageboxdata->window->driverdata;
   381     }
   361     }
   382 
   362 
   383     data->event_mask = ExposureMask |
   363     data->event_mask = ExposureMask |
   384         ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask |
   364                        ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask |
   385         StructureNotifyMask | FocusChangeMask | PointerMotionMask;
   365                        StructureNotifyMask | FocusChangeMask | PointerMotionMask;
   386     wnd_attr.event_mask = data->event_mask;
   366     wnd_attr.event_mask = data->event_mask;
   387 
   367 
   388     data->window = XCreateWindow(
   368     data->window = XCreateWindow(
   389                             display, DefaultRootWindow( display ),
   369                        display, DefaultRootWindow( display ),
   390                             0, 0,
   370                        0, 0,
   391                             data->dialog_width, data->dialog_height,
   371                        data->dialog_width, data->dialog_height,
   392                             0, CopyFromParent, InputOutput, CopyFromParent,
   372                        0, CopyFromParent, InputOutput, CopyFromParent,
   393                             CWEventMask, &wnd_attr );
   373                        CWEventMask, &wnd_attr );
   394     if ( data->window == None ) {
   374     if ( data->window == None ) {
   395         SDL_SetError("Couldn't create X window");
   375         SDL_SetError("Couldn't create X window");
   396         return -1;
   376         return -1;
   397     }
   377     }
   398 
   378 
   453 
   433 
   454     XSetForeground( display, ctx, data->color[ SDL_MESSAGEBOX_COLOR_BACKGROUND ] );
   434     XSetForeground( display, ctx, data->color[ SDL_MESSAGEBOX_COLOR_BACKGROUND ] );
   455     XFillRectangle( display, window, ctx, 0, 0, data->dialog_width, data->dialog_height );
   435     XFillRectangle( display, window, ctx, 0, 0, data->dialog_width, data->dialog_height );
   456 
   436 
   457     XSetForeground( display, ctx, data->color[ SDL_MESSAGEBOX_COLOR_TEXT ] );
   437     XSetForeground( display, ctx, data->color[ SDL_MESSAGEBOX_COLOR_TEXT ] );
   458     for ( i = 0; i < data->numlines; i++ )
   438     for ( i = 0; i < data->numlines; i++ ) {
   459     {
       
   460         TextLineData *plinedata = &data->linedata[ i ];
   439         TextLineData *plinedata = &data->linedata[ i ];
   461 
   440 
   462         if (SDL_X11_HAVE_UTF8) {
   441         if (SDL_X11_HAVE_UTF8) {
   463             Xutf8DrawString( display, window, data->font_set, ctx,
   442             Xutf8DrawString( display, window, data->font_set, ctx,
   464                              data->xtext, data->ytext + i * data->text_height,
   443                              data->xtext, data->ytext + i * data->text_height,
   468                          data->xtext, data->ytext + i * data->text_height,
   447                          data->xtext, data->ytext + i * data->text_height,
   469                          plinedata->text, plinedata->length );
   448                          plinedata->text, plinedata->length );
   470         }
   449         }
   471     }
   450     }
   472 
   451 
   473     for ( i = 0; i < data->numbuttons; i++ )
   452     for ( i = 0; i < data->numbuttons; i++ ) {
   474     {
       
   475         SDL_MessageBoxButtonDataX11 *buttondatax11 = &data->buttonpos[ i ];
   453         SDL_MessageBoxButtonDataX11 *buttondatax11 = &data->buttonpos[ i ];
   476         const SDL_MessageBoxButtonData *buttondata = buttondatax11->buttondata;
   454         const SDL_MessageBoxButtonData *buttondata = buttondatax11->buttondata;
   477         int border = ( buttondata->flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT ) ? 2 : 0;
   455         int border = ( buttondata->flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT ) ? 2 : 0;
   478         int offset = ( ( data->mouse_over_index == i ) && ( data->button_press_index == data->mouse_over_index ) ) ? 1 : 0;
   456         int offset = ( ( data->mouse_over_index == i ) && ( data->button_press_index == data->mouse_over_index ) ) ? 1 : 0;
   479 
   457 
   581         case KeyPress:
   559         case KeyPress:
   582             /* Store key press - we make sure in key release that we got both. */
   560             /* Store key press - we make sure in key release that we got both. */
   583             last_key_pressed = XLookupKeysym( &e.xkey, 0 );
   561             last_key_pressed = XLookupKeysym( &e.xkey, 0 );
   584             break;
   562             break;
   585 
   563 
   586         case KeyRelease:
   564         case KeyRelease: {
   587         {
       
   588             Uint32 mask = 0;
   565             Uint32 mask = 0;
   589             KeySym key = XLookupKeysym( &e.xkey, 0 );
   566             KeySym key = XLookupKeysym( &e.xkey, 0 );
   590 
   567 
   591             /* If this is a key release for something we didn't get the key down for, then bail. */
   568             /* If this is a key release for something we didn't get the key down for, then bail. */
   592             if ( key != last_key_pressed )
   569             if ( key != last_key_pressed )