src/video/x11/SDL_x11messagebox.c
changeset 6723 7c464a9ecf48
parent 6615 d7a463bde4d7
child 6724 6c5ed0c4cc6d
     1.1 --- a/src/video/x11/SDL_x11messagebox.c	Fri Dec 07 19:59:30 2012 -0500
     1.2 +++ b/src/video/x11/SDL_x11messagebox.c	Fri Dec 07 20:00:42 2012 -0500
     1.3 @@ -18,6 +18,9 @@
     1.4       misrepresented as being the original software.
     1.5    3. This notice may not be removed or altered from any source distribution.
     1.6  */
     1.7 +
     1.8 +/* !!! FIXME: clean up differences in coding style in this file. */
     1.9 +
    1.10  #include "SDL_config.h"
    1.11  
    1.12  #if SDL_VIDEO_DRIVER_X11
    1.13 @@ -26,13 +29,16 @@
    1.14  #include "SDL_x11video.h"
    1.15  #include "SDL_x11dyn.h"
    1.16  
    1.17 +#include <locale.h>
    1.18 +
    1.19  #define MAX_BUTTONS             8       /* Maximum number of buttons supported */
    1.20  #define MAX_TEXT_LINES          32      /* Maximum number of text lines supported */
    1.21  #define MIN_BUTTON_WIDTH        64      /* Minimum button width */
    1.22  #define MIN_DIALOG_WIDTH        200     /* Minimum dialog width */
    1.23  #define MIN_DIALOG_HEIGHT       100     /* Minimum dialog height */
    1.24  
    1.25 -static const char g_MessageBoxFont[] = "-*-*-medium-r-normal--0-120-*-*-p-0-iso8859-1";
    1.26 +static const char g_MessageBoxFontLatin1[] = "-*-*-medium-r-normal--0-120-*-*-p-0-iso8859-1";
    1.27 +static const char g_MessageBoxFont[] = "-*-*-*-*-*-*-*-*-*-*-*-*-*-*";
    1.28  
    1.29  static const SDL_MessageBoxColor g_default_colors[ SDL_MESSAGEBOX_COLOR_MAX ] =
    1.30  {
    1.31 @@ -67,7 +73,8 @@
    1.32  
    1.33  typedef struct SDL_MessageBoxDataX11
    1.34  {
    1.35 -    Font hfont;
    1.36 +    XFontSet font_set;                  /* for UTF-8 systems */
    1.37 +    XFontStruct *font_struct;            /* Latin1 (ASCII) fallback. */
    1.38      Window window;
    1.39      Display *display;
    1.40      long event_mask;
    1.41 @@ -105,17 +112,22 @@
    1.42  
    1.43  /* Return width and height for a string. */
    1.44  static void
    1.45 -GetTextWidthHeight( XFontStruct *font_struct, const char *str, int nchars, int *pwidth, int *pheight )
    1.46 +GetTextWidthHeight( SDL_MessageBoxDataX11 *data, const char *str, int nbytes, int *pwidth, int *pheight )
    1.47  {
    1.48 -    XCharStruct text_structure;
    1.49 -    int font_direction, font_ascent, font_descent;
    1.50 -
    1.51 -    XTextExtents( font_struct, str, nchars,
    1.52 -                     &font_direction, &font_ascent, &font_descent,
    1.53 -                     &text_structure );
    1.54 -
    1.55 -    *pwidth = text_structure.width;
    1.56 -    *pheight = text_structure.ascent + text_structure.descent;
    1.57 +    if (SDL_X11_HAVE_UTF8) {
    1.58 +        XRectangle overall_ink, overall_logical;
    1.59 +        Xutf8TextExtents(data->font_set, str, nbytes, &overall_ink, &overall_logical);
    1.60 +        *pwidth = overall_logical.width;
    1.61 +        *pheight = overall_logical.height;
    1.62 +    } else {
    1.63 +        XCharStruct text_structure;
    1.64 +        int font_direction, font_ascent, font_descent;
    1.65 +        XTextExtents( data->font_struct, str, nbytes,
    1.66 +                      &font_direction, &font_ascent, &font_descent,
    1.67 +                      &text_structure );
    1.68 +        *pwidth = text_structure.width;
    1.69 +        *pheight = text_structure.ascent + text_structure.descent;
    1.70 +    }
    1.71  }
    1.72  
    1.73  /* Return index of button if position x,y is contained therein. */
    1.74 @@ -169,10 +181,24 @@
    1.75          return -1;
    1.76      }
    1.77  
    1.78 -    data->hfont = XLoadFont( data->display, g_MessageBoxFont );
    1.79 -    if ( data->hfont == None ) {
    1.80 -        SDL_SetError("Couldn't load font %s", g_MessageBoxFont);
    1.81 -        return -1;
    1.82 +    if (SDL_X11_HAVE_UTF8) {
    1.83 +        char **missing = NULL;
    1.84 +        int num_missing = 0;
    1.85 +        data->font_set = XCreateFontSet(data->display, g_MessageBoxFont,
    1.86 +                                        &missing, &num_missing, NULL);
    1.87 +        if ( missing != NULL ) {
    1.88 +            XFreeStringList(missing);
    1.89 +        }
    1.90 +        if ( data->font_set == NULL ) {
    1.91 +            SDL_SetError("Couldn't load font %s", g_MessageBoxFont);
    1.92 +            return -1;
    1.93 +        }
    1.94 +    } else {
    1.95 +        data->font_struct = XLoadQueryFont( data->display, g_MessageBoxFontLatin1 );
    1.96 +        if ( data->font_struct == NULL ) {
    1.97 +            SDL_SetError("Couldn't load font %s", g_MessageBoxFontLatin1);
    1.98 +            return -1;
    1.99 +        }
   1.100      }
   1.101  
   1.102      if ( messageboxdata->colorScheme ) {
   1.103 @@ -200,12 +226,6 @@
   1.104      int button_width = MIN_BUTTON_WIDTH;
   1.105      const SDL_MessageBoxData *messageboxdata = data->messageboxdata;
   1.106  
   1.107 -    XFontStruct *fontinfo = XQueryFont( data->display, data->hfont );
   1.108 -    if ( !fontinfo ) {
   1.109 -        SDL_SetError("Couldn't get font info");
   1.110 -        return -1;
   1.111 -    }
   1.112 -
   1.113      /* Go over text and break linefeeds into separate lines. */
   1.114      if ( messageboxdata->message && messageboxdata->message[ 0 ] )
   1.115      {
   1.116 @@ -223,7 +243,7 @@
   1.117              plinedata->length = ( lf && ( i < MAX_TEXT_LINES - 1 ) ) ? ( lf - text ) : SDL_strlen( text );
   1.118              plinedata->text = text;
   1.119  
   1.120 -            GetTextWidthHeight( fontinfo, text, plinedata->length, &plinedata->width, &height );
   1.121 +            GetTextWidthHeight( data, text, plinedata->length, &plinedata->width, &height );
   1.122  
   1.123              /* Text and widths are the largest we've ever seen. */
   1.124              data->text_height = IntMax( data->text_height, height );
   1.125 @@ -248,7 +268,7 @@
   1.126          data->buttonpos[ i ].buttondata = &data->buttondata[ i ];
   1.127          data->buttonpos[ i ].length = SDL_strlen( data->buttondata[ i ].text );
   1.128  
   1.129 -        GetTextWidthHeight( fontinfo, data->buttondata[ i ].text, SDL_strlen( data->buttondata[ i ].text ),
   1.130 +        GetTextWidthHeight( data, data->buttondata[ i ].text, SDL_strlen( data->buttondata[ i ].text ),
   1.131                              &data->buttonpos[ i ].text_width, &height );
   1.132  
   1.133          button_width = IntMax( button_width, data->buttonpos[ i ].text_width );
   1.134 @@ -312,7 +332,6 @@
   1.135          }
   1.136      }
   1.137  
   1.138 -    XFreeFontInfo( NULL, fontinfo, 1 );
   1.139      return 0;
   1.140  }
   1.141  
   1.142 @@ -320,10 +339,16 @@
   1.143  static void
   1.144  X11_MessageBoxShutdown( SDL_MessageBoxDataX11 *data )
   1.145  {
   1.146 -    if ( data->hfont != None )
   1.147 +    if ( data->font_set != NULL )
   1.148      {
   1.149 -        XUnloadFont( data->display, data->hfont );
   1.150 -        data->hfont = None;
   1.151 +        XFreeFontSet( data->display, data->font_set );
   1.152 +        data->font_set = NULL;
   1.153 +    }
   1.154 +
   1.155 +    if ( data->font_struct != NULL )
   1.156 +    {
   1.157 +        XFreeFont( data->display, data->font_struct );
   1.158 +        data->font_struct = NULL;
   1.159      }
   1.160  
   1.161      if ( data->display )
   1.162 @@ -434,9 +459,15 @@
   1.163      {
   1.164          TextLineData *plinedata = &data->linedata[ i ];
   1.165  
   1.166 -        XDrawString( display, window, ctx,
   1.167 -                     data->xtext, data->ytext + i * data->text_height,
   1.168 -                     plinedata->text, plinedata->length );
   1.169 +        if (SDL_X11_HAVE_UTF8) {
   1.170 +            Xutf8DrawString( display, window, data->font_set, ctx,
   1.171 +                             data->xtext, data->ytext + i * data->text_height,
   1.172 +                             plinedata->text, plinedata->length );
   1.173 +        } else {
   1.174 +            XDrawString( display, window, ctx,
   1.175 +                         data->xtext, data->ytext + i * data->text_height,
   1.176 +                         plinedata->text, plinedata->length );
   1.177 +        }
   1.178      }
   1.179  
   1.180      for ( i = 0; i < data->numbuttons; i++ )
   1.181 @@ -459,9 +490,17 @@
   1.182          XSetForeground( display, ctx, ( data->mouse_over_index == i ) ?
   1.183                          data->color[ SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED ] :
   1.184                          data->color[ SDL_MESSAGEBOX_COLOR_TEXT ] );
   1.185 -        XDrawString( display, window, ctx,
   1.186 -            buttondatax11->x + offset, buttondatax11->y + offset,
   1.187 -            buttondata->text, buttondatax11->length );
   1.188 +
   1.189 +        if (SDL_X11_HAVE_UTF8) {
   1.190 +            Xutf8DrawString( display, window, data->font_set, ctx,
   1.191 +                             buttondatax11->x + offset,
   1.192 +                             buttondatax11->y + offset,
   1.193 +                             buttondata->text, buttondatax11->length );
   1.194 +        } else {
   1.195 +            XDrawString( display, window, ctx,
   1.196 +                         buttondatax11->x + offset, buttondatax11->y + offset,
   1.197 +                         buttondata->text, buttondatax11->length );
   1.198 +        }
   1.199      }
   1.200  }
   1.201  
   1.202 @@ -474,12 +513,18 @@
   1.203      SDL_bool close_dialog = SDL_FALSE;
   1.204      SDL_bool has_focus = SDL_TRUE;
   1.205      KeySym last_key_pressed = XK_VoidSymbol;
   1.206 +    unsigned long gcflags = GCForeground | GCBackground;
   1.207  
   1.208 -    ctx_vals.font = data->hfont;
   1.209 +    SDL_zero(ctx_vals);
   1.210      ctx_vals.foreground = data->color[ SDL_MESSAGEBOX_COLOR_BACKGROUND ];
   1.211      ctx_vals.background = data->color[ SDL_MESSAGEBOX_COLOR_BACKGROUND ];
   1.212  
   1.213 -    ctx = XCreateGC( data->display, data->window, GCForeground | GCBackground | GCFont, &ctx_vals );
   1.214 +    if (!SDL_X11_HAVE_UTF8) {
   1.215 +        gcflags |= GCFont;
   1.216 +        ctx_vals.font = data->font_struct->fid;
   1.217 +    }
   1.218 +
   1.219 +    ctx = XCreateGC( data->display, data->window, gcflags, &ctx_vals );
   1.220      if ( ctx == None ) {
   1.221          SDL_SetError("Couldn't create graphics context");
   1.222          return -1;
   1.223 @@ -610,7 +655,9 @@
   1.224      int ret;
   1.225      SDL_MessageBoxDataX11 data;
   1.226  
   1.227 -    SDL_memset( &data, 0, sizeof( data ) );
   1.228 +    SDL_zero(data);
   1.229 +
   1.230 +    setlocale(LC_ALL, "");
   1.231  
   1.232      if ( !SDL_X11_LoadSymbols() )
   1.233          return -1;