X11 message boxes should work with UTF-8 strings if possible.
This commit is contained in:
parent
60a837b5aa
commit
2c1f08ae4b
2 changed files with 91 additions and 40 deletions
|
@ -18,6 +18,9 @@
|
|||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
/* !!! FIXME: clean up differences in coding style in this file. */
|
||||
|
||||
#include "SDL_config.h"
|
||||
|
||||
#if SDL_VIDEO_DRIVER_X11
|
||||
|
@ -26,13 +29,16 @@
|
|||
#include "SDL_x11video.h"
|
||||
#include "SDL_x11dyn.h"
|
||||
|
||||
#include <locale.h>
|
||||
|
||||
#define MAX_BUTTONS 8 /* Maximum number of buttons supported */
|
||||
#define MAX_TEXT_LINES 32 /* Maximum number of text lines supported */
|
||||
#define MIN_BUTTON_WIDTH 64 /* Minimum button width */
|
||||
#define MIN_DIALOG_WIDTH 200 /* Minimum dialog width */
|
||||
#define MIN_DIALOG_HEIGHT 100 /* Minimum dialog height */
|
||||
|
||||
static const char g_MessageBoxFont[] = "-*-*-medium-r-normal--0-120-*-*-p-0-iso8859-1";
|
||||
static const char g_MessageBoxFontLatin1[] = "-*-*-medium-r-normal--0-120-*-*-p-0-iso8859-1";
|
||||
static const char g_MessageBoxFont[] = "-*-*-*-*-*-*-*-*-*-*-*-*-*-*";
|
||||
|
||||
static const SDL_MessageBoxColor g_default_colors[ SDL_MESSAGEBOX_COLOR_MAX ] =
|
||||
{
|
||||
|
@ -67,7 +73,8 @@ typedef struct TextLineData
|
|||
|
||||
typedef struct SDL_MessageBoxDataX11
|
||||
{
|
||||
Font hfont;
|
||||
XFontSet font_set; /* for UTF-8 systems */
|
||||
XFontStruct *font_struct; /* Latin1 (ASCII) fallback. */
|
||||
Window window;
|
||||
Display *display;
|
||||
long event_mask;
|
||||
|
@ -105,17 +112,22 @@ IntMax( int a, int b )
|
|||
|
||||
/* Return width and height for a string. */
|
||||
static void
|
||||
GetTextWidthHeight( XFontStruct *font_struct, const char *str, int nchars, int *pwidth, int *pheight )
|
||||
GetTextWidthHeight( SDL_MessageBoxDataX11 *data, const char *str, int nbytes, int *pwidth, int *pheight )
|
||||
{
|
||||
XCharStruct text_structure;
|
||||
int font_direction, font_ascent, font_descent;
|
||||
|
||||
XTextExtents( font_struct, str, nchars,
|
||||
&font_direction, &font_ascent, &font_descent,
|
||||
&text_structure );
|
||||
|
||||
*pwidth = text_structure.width;
|
||||
*pheight = text_structure.ascent + text_structure.descent;
|
||||
if (SDL_X11_HAVE_UTF8) {
|
||||
XRectangle overall_ink, overall_logical;
|
||||
Xutf8TextExtents(data->font_set, str, nbytes, &overall_ink, &overall_logical);
|
||||
*pwidth = overall_logical.width;
|
||||
*pheight = overall_logical.height;
|
||||
} else {
|
||||
XCharStruct text_structure;
|
||||
int font_direction, font_ascent, font_descent;
|
||||
XTextExtents( data->font_struct, str, nbytes,
|
||||
&font_direction, &font_ascent, &font_descent,
|
||||
&text_structure );
|
||||
*pwidth = text_structure.width;
|
||||
*pheight = text_structure.ascent + text_structure.descent;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return index of button if position x,y is contained therein. */
|
||||
|
@ -169,10 +181,24 @@ X11_MessageBoxInit( SDL_MessageBoxDataX11 *data, const SDL_MessageBoxData * mess
|
|||
return -1;
|
||||
}
|
||||
|
||||
data->hfont = XLoadFont( data->display, g_MessageBoxFont );
|
||||
if ( data->hfont == None ) {
|
||||
SDL_SetError("Couldn't load font %s", g_MessageBoxFont);
|
||||
return -1;
|
||||
if (SDL_X11_HAVE_UTF8) {
|
||||
char **missing = NULL;
|
||||
int num_missing = 0;
|
||||
data->font_set = XCreateFontSet(data->display, g_MessageBoxFont,
|
||||
&missing, &num_missing, NULL);
|
||||
if ( missing != NULL ) {
|
||||
XFreeStringList(missing);
|
||||
}
|
||||
if ( data->font_set == NULL ) {
|
||||
SDL_SetError("Couldn't load font %s", g_MessageBoxFont);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
data->font_struct = XLoadQueryFont( data->display, g_MessageBoxFontLatin1 );
|
||||
if ( data->font_struct == NULL ) {
|
||||
SDL_SetError("Couldn't load font %s", g_MessageBoxFontLatin1);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( messageboxdata->colorScheme ) {
|
||||
|
@ -200,12 +226,6 @@ X11_MessageBoxInitPositions( SDL_MessageBoxDataX11 *data )
|
|||
int button_width = MIN_BUTTON_WIDTH;
|
||||
const SDL_MessageBoxData *messageboxdata = data->messageboxdata;
|
||||
|
||||
XFontStruct *fontinfo = XQueryFont( data->display, data->hfont );
|
||||
if ( !fontinfo ) {
|
||||
SDL_SetError("Couldn't get font info");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Go over text and break linefeeds into separate lines. */
|
||||
if ( messageboxdata->message && messageboxdata->message[ 0 ] )
|
||||
{
|
||||
|
@ -223,7 +243,7 @@ X11_MessageBoxInitPositions( SDL_MessageBoxDataX11 *data )
|
|||
plinedata->length = ( lf && ( i < MAX_TEXT_LINES - 1 ) ) ? ( lf - text ) : SDL_strlen( text );
|
||||
plinedata->text = text;
|
||||
|
||||
GetTextWidthHeight( fontinfo, text, plinedata->length, &plinedata->width, &height );
|
||||
GetTextWidthHeight( data, text, plinedata->length, &plinedata->width, &height );
|
||||
|
||||
/* Text and widths are the largest we've ever seen. */
|
||||
data->text_height = IntMax( data->text_height, height );
|
||||
|
@ -248,7 +268,7 @@ X11_MessageBoxInitPositions( SDL_MessageBoxDataX11 *data )
|
|||
data->buttonpos[ i ].buttondata = &data->buttondata[ i ];
|
||||
data->buttonpos[ i ].length = SDL_strlen( data->buttondata[ i ].text );
|
||||
|
||||
GetTextWidthHeight( fontinfo, data->buttondata[ i ].text, SDL_strlen( data->buttondata[ i ].text ),
|
||||
GetTextWidthHeight( data, data->buttondata[ i ].text, SDL_strlen( data->buttondata[ i ].text ),
|
||||
&data->buttonpos[ i ].text_width, &height );
|
||||
|
||||
button_width = IntMax( button_width, data->buttonpos[ i ].text_width );
|
||||
|
@ -312,7 +332,6 @@ X11_MessageBoxInitPositions( SDL_MessageBoxDataX11 *data )
|
|||
}
|
||||
}
|
||||
|
||||
XFreeFontInfo( NULL, fontinfo, 1 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -320,10 +339,16 @@ X11_MessageBoxInitPositions( SDL_MessageBoxDataX11 *data )
|
|||
static void
|
||||
X11_MessageBoxShutdown( SDL_MessageBoxDataX11 *data )
|
||||
{
|
||||
if ( data->hfont != None )
|
||||
if ( data->font_set != NULL )
|
||||
{
|
||||
XUnloadFont( data->display, data->hfont );
|
||||
data->hfont = None;
|
||||
XFreeFontSet( data->display, data->font_set );
|
||||
data->font_set = NULL;
|
||||
}
|
||||
|
||||
if ( data->font_struct != NULL )
|
||||
{
|
||||
XFreeFont( data->display, data->font_struct );
|
||||
data->font_struct = NULL;
|
||||
}
|
||||
|
||||
if ( data->display )
|
||||
|
@ -434,9 +459,15 @@ X11_MessageBoxDraw( SDL_MessageBoxDataX11 *data, GC ctx )
|
|||
{
|
||||
TextLineData *plinedata = &data->linedata[ i ];
|
||||
|
||||
XDrawString( display, window, ctx,
|
||||
data->xtext, data->ytext + i * data->text_height,
|
||||
plinedata->text, plinedata->length );
|
||||
if (SDL_X11_HAVE_UTF8) {
|
||||
Xutf8DrawString( display, window, data->font_set, ctx,
|
||||
data->xtext, data->ytext + i * data->text_height,
|
||||
plinedata->text, plinedata->length );
|
||||
} else {
|
||||
XDrawString( display, window, ctx,
|
||||
data->xtext, data->ytext + i * data->text_height,
|
||||
plinedata->text, plinedata->length );
|
||||
}
|
||||
}
|
||||
|
||||
for ( i = 0; i < data->numbuttons; i++ )
|
||||
|
@ -459,9 +490,17 @@ X11_MessageBoxDraw( SDL_MessageBoxDataX11 *data, GC ctx )
|
|||
XSetForeground( display, ctx, ( data->mouse_over_index == i ) ?
|
||||
data->color[ SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED ] :
|
||||
data->color[ SDL_MESSAGEBOX_COLOR_TEXT ] );
|
||||
XDrawString( display, window, ctx,
|
||||
buttondatax11->x + offset, buttondatax11->y + offset,
|
||||
buttondata->text, buttondatax11->length );
|
||||
|
||||
if (SDL_X11_HAVE_UTF8) {
|
||||
Xutf8DrawString( display, window, data->font_set, ctx,
|
||||
buttondatax11->x + offset,
|
||||
buttondatax11->y + offset,
|
||||
buttondata->text, buttondatax11->length );
|
||||
} else {
|
||||
XDrawString( display, window, ctx,
|
||||
buttondatax11->x + offset, buttondatax11->y + offset,
|
||||
buttondata->text, buttondatax11->length );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -474,12 +513,18 @@ X11_MessageBoxLoop( SDL_MessageBoxDataX11 *data )
|
|||
SDL_bool close_dialog = SDL_FALSE;
|
||||
SDL_bool has_focus = SDL_TRUE;
|
||||
KeySym last_key_pressed = XK_VoidSymbol;
|
||||
unsigned long gcflags = GCForeground | GCBackground;
|
||||
|
||||
ctx_vals.font = data->hfont;
|
||||
SDL_zero(ctx_vals);
|
||||
ctx_vals.foreground = data->color[ SDL_MESSAGEBOX_COLOR_BACKGROUND ];
|
||||
ctx_vals.background = data->color[ SDL_MESSAGEBOX_COLOR_BACKGROUND ];
|
||||
|
||||
ctx = XCreateGC( data->display, data->window, GCForeground | GCBackground | GCFont, &ctx_vals );
|
||||
if (!SDL_X11_HAVE_UTF8) {
|
||||
gcflags |= GCFont;
|
||||
ctx_vals.font = data->font_struct->fid;
|
||||
}
|
||||
|
||||
ctx = XCreateGC( data->display, data->window, gcflags, &ctx_vals );
|
||||
if ( ctx == None ) {
|
||||
SDL_SetError("Couldn't create graphics context");
|
||||
return -1;
|
||||
|
@ -610,7 +655,9 @@ X11_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
|
|||
int ret;
|
||||
SDL_MessageBoxDataX11 data;
|
||||
|
||||
SDL_memset( &data, 0, sizeof( data ) );
|
||||
SDL_zero(data);
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
|
||||
if ( !SDL_X11_LoadSymbols() )
|
||||
return -1;
|
||||
|
|
|
@ -37,6 +37,7 @@ SDL_X11_SYM(Pixmap,XCreateBitmapFromData,(Display *dpy,Drawable d,_Xconst char *
|
|||
SDL_X11_SYM(Colormap,XCreateColormap,(Display* a,Window b,Visual* c,int d),(a,b,c,d),return)
|
||||
SDL_X11_SYM(Cursor,XCreatePixmapCursor,(Display* a,Pixmap b,Pixmap c,XColor* d,XColor* e,unsigned int f,unsigned int g),(a,b,c,d,e,f,g),return)
|
||||
SDL_X11_SYM(Cursor,XCreateFontCursor,(Display* a,unsigned int b),(a,b),return)
|
||||
SDL_X11_SYM(XFontSet,XCreateFontSet,(Display* a, _Xconst char* b, char*** c, int* d, char** e),(a,b,c,d,e),return)
|
||||
SDL_X11_SYM(GC,XCreateGC,(Display* a,Drawable b,unsigned long c,XGCValues* d),(a,b,c,d),return)
|
||||
SDL_X11_SYM(XImage*,XCreateImage,(Display* a,Visual* b,unsigned int c,int d,int e,char* f,unsigned int g,unsigned int h,int i,int j),(a,b,c,d,e,f,g,h,i,j),return)
|
||||
SDL_X11_SYM(Window,XCreateWindow,(Display* a,Window b,int c,int d,unsigned int e,unsigned int f,unsigned int g,int h,unsigned int i,Visual* j,unsigned long k,XSetWindowAttributes* l),(a,b,c,d,e,f,g,h,i,j,k,l),return)
|
||||
|
@ -53,10 +54,12 @@ SDL_X11_SYM(Bool,XFilterEvent,(XEvent *event,Window w),(event,w),return)
|
|||
SDL_X11_SYM(int,XFlush,(Display* a),(a),return)
|
||||
SDL_X11_SYM(int,XFree,(void*a),(a),return)
|
||||
SDL_X11_SYM(int,XFreeCursor,(Display* a,Cursor b),(a,b),return)
|
||||
SDL_X11_SYM(void,XFreeFontSet,(Display* a, XFontSet b),(a,b),)
|
||||
SDL_X11_SYM(int,XFreeGC,(Display* a,GC b),(a,b),return)
|
||||
SDL_X11_SYM(int,XFreeFontInfo,(char** a,XFontStruct* b,int c),(a,b,c),return)
|
||||
SDL_X11_SYM(int,XFreeFont,(Display* a, XFontStruct* b),(a,b),return)
|
||||
SDL_X11_SYM(int,XFreeModifiermap,(XModifierKeymap* a),(a),return)
|
||||
SDL_X11_SYM(int,XFreePixmap,(Display* a,Pixmap b),(a,b),return)
|
||||
SDL_X11_SYM(void,XFreeStringList,(char** a),(a),)
|
||||
SDL_X11_SYM(char*,XGetAtomName,(Display *a,Atom b),(a,b),return)
|
||||
SDL_X11_SYM(int,XGetInputFocus,(Display *a,Window *b,int *c),(a,b,c),return)
|
||||
SDL_X11_SYM(int,XGetErrorDatabaseText,(Display* a,_Xconst char* b,_Xconst char* c,_Xconst char* d,char* e,int f),(a,b,c,d,e,f),return)
|
||||
|
@ -78,7 +81,7 @@ SDL_X11_SYM(char*,XKeysymToString,(KeySym a),(a),return)
|
|||
SDL_X11_SYM(int,XInstallColormap,(Display* a,Colormap b),(a,b),return)
|
||||
SDL_X11_SYM(Atom,XInternAtom,(Display* a,_Xconst char* b,Bool c),(a,b,c),return)
|
||||
SDL_X11_SYM(XPixmapFormatValues*,XListPixmapFormats,(Display* a,int* b),(a,b),return)
|
||||
SDL_X11_SYM(Font,XLoadFont,(Display* a,_Xconst char* b),(a,b),return)
|
||||
SDL_X11_SYM(XFontStruct*,XLoadQueryFont,(Display* a,_Xconst char* b),(a,b),return)
|
||||
SDL_X11_SYM(KeySym,XLookupKeysym,(XKeyEvent* a,int b),(a,b),return)
|
||||
SDL_X11_SYM(int,XLookupString,(XKeyEvent* a,char* b,int c,KeySym* d,XComposeStatus* e),(a,b,c,d,e),return)
|
||||
SDL_X11_SYM(int,XMapRaised,(Display* a,Window b),(a,b),return)
|
||||
|
@ -91,7 +94,6 @@ SDL_X11_SYM(Status,XInitThreads,(void),(),return)
|
|||
SDL_X11_SYM(int,XPeekEvent,(Display* a,XEvent* b),(a,b),return)
|
||||
SDL_X11_SYM(int,XPending,(Display* a),(a),return)
|
||||
SDL_X11_SYM(int,XPutImage,(Display* a,Drawable b,GC c,XImage* d,int e,int f,int g,int h,unsigned int i,unsigned int j),(a,b,c,d,e,f,g,h,i,j),return)
|
||||
SDL_X11_SYM(XFontStruct*,XQueryFont,(Display* a,XID b),(a,b),return)
|
||||
SDL_X11_SYM(int,XQueryKeymap,(Display* a,char *b),(a,b),return)
|
||||
SDL_X11_SYM(Bool,XQueryPointer,(Display* a,Window b,Window* c,Window* d,int* e,int* f,int* g,int* h,unsigned int* i),(a,b,c,d,e,f,g,h,i),return)
|
||||
SDL_X11_SYM(int,XRaiseWindow,(Display* a,Window b),(a,b),return)
|
||||
|
@ -181,6 +183,8 @@ SDL_X11_SYM(void,XSetICFocus,(XIC a),(a),)
|
|||
SDL_X11_SYM(void,XUnsetICFocus,(XIC a),(a),)
|
||||
SDL_X11_SYM(XIM,XOpenIM,(Display* a,struct _XrmHashBucketRec* b,char* c,char* d),(a,b,c,d),return)
|
||||
SDL_X11_SYM(Status,XCloseIM,(XIM a),(a),return)
|
||||
SDL_X11_SYM(void,Xutf8DrawString,(Display *a, Drawable b, XFontSet c, GC d, int e, int f, _Xconst char *g, int h),(a,b,c,d,e,f,g,h),)
|
||||
SDL_X11_SYM(int,Xutf8TextExtents,(XFontSet a, _Xconst char* b, int c, XRectangle* d, XRectangle* e),(a,b,c,d,e),return)
|
||||
#endif
|
||||
|
||||
#ifndef NO_SHARED_MEMORY
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue