/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
*/

#include "../../SDL_internal.h"

#if SDL_VIDEO_DRIVER_X11

#include "SDL.h"
#include "SDL_x11video.h"
#include "SDL_x11dyn.h"
#include "SDL_assert.h"
#include "SDL_x11messagebox.h"

#include <X11/keysym.h>
#include <locale.h>


#define SDL_FORK_MESSAGEBOX 1
#define SDL_SET_LOCALE      1

#if SDL_FORK_MESSAGEBOX
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <errno.h>
#endif

#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_MessageBoxFontLatin1[] = "-*-*-medium-r-normal--0-120-*-*-p-0-iso8859-1";
static const char g_MessageBoxFont[] = "-*-*-medium-r-normal--*-120-*-*-*-*-*-*";

static const SDL_MessageBoxColor g_default_colors[ SDL_MESSAGEBOX_COLOR_MAX ] = {
    { 56,  54,  53  }, /* SDL_MESSAGEBOX_COLOR_BACKGROUND, */
    { 209, 207, 205 }, /* SDL_MESSAGEBOX_COLOR_TEXT, */
    { 140, 135, 129 }, /* SDL_MESSAGEBOX_COLOR_BUTTON_BORDER, */
    { 105, 102, 99  }, /* SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND, */
    { 205, 202, 53  }, /* SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED, */
};

#define SDL_MAKE_RGB( _r, _g, _b )  ( ( ( Uint32 )( _r ) << 16 ) | \
                                      ( ( Uint32 )( _g ) << 8 ) |  \
                                      ( ( Uint32 )( _b ) ) )

typedef struct SDL_MessageBoxButtonDataX11 {
    int x, y;                           /* Text position */
    int length;                         /* Text length */
    int text_width;                     /* Text width */

    SDL_Rect rect;                      /* Rectangle for entire button */

    const SDL_MessageBoxButtonData *buttondata;   /* Button data from caller */
} SDL_MessageBoxButtonDataX11;

typedef struct TextLineData {
    int width;                          /* Width of this text line */
    int length;                         /* String length of this text line */
    const char *text;                   /* Text for this line */
} TextLineData;

typedef struct SDL_MessageBoxDataX11
{
    Display *display;
    int screen;
    Window window;
#if SDL_VIDEO_DRIVER_X11_XDBE
    XdbeBackBuffer buf;
    SDL_bool xdbe;                      /* Whether Xdbe is present or not */
#endif
    long event_mask;
    Atom wm_protocols;
    Atom wm_delete_message;

    int dialog_width;                   /* Dialog box width. */
    int dialog_height;                  /* Dialog box height. */

    XFontSet font_set;                  /* for UTF-8 systems */
    XFontStruct *font_struct;           /* Latin1 (ASCII) fallback. */
    int xtext, ytext;                   /* Text position to start drawing at. */
    int numlines;                       /* Count of Text lines. */
    int text_height;                    /* Height for text lines. */
    TextLineData linedata[ MAX_TEXT_LINES ];

    int *pbuttonid;                     /* Pointer to user return buttonid value. */

    int button_press_index;             /* Index into buttondata/buttonpos for button which is pressed (or -1). */
    int mouse_over_index;               /* Index into buttondata/buttonpos for button mouse is over (or -1). */

    int numbuttons;                     /* Count of buttons. */
    const SDL_MessageBoxButtonData *buttondata;
    SDL_MessageBoxButtonDataX11 buttonpos[ MAX_BUTTONS ];

    Uint32 color[ SDL_MESSAGEBOX_COLOR_MAX ];

    const SDL_MessageBoxData *messageboxdata;
} SDL_MessageBoxDataX11;

/* Maximum helper for ints. */
static SDL_INLINE int
IntMax( int a, int b )
{
    return ( a > b  ) ? a : b;
}

/* Return width and height for a string. */
static void
GetTextWidthHeight( SDL_MessageBoxDataX11 *data, const char *str, int nbytes, int *pwidth, int *pheight )
{
    if (SDL_X11_HAVE_UTF8) {
        XRectangle overall_ink, overall_logical;
        X11_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;
        X11_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. */
static int
GetHitButtonIndex( SDL_MessageBoxDataX11 *data, int x, int y )
{
    int i;
    int numbuttons = data->numbuttons;
    SDL_MessageBoxButtonDataX11 *buttonpos = data->buttonpos;

    for ( i = 0; i < numbuttons; i++ ) {
        SDL_Rect *rect = &buttonpos[ i ].rect;

        if ( ( x >= rect->x ) &&
             ( x <= ( rect->x + rect->w ) ) &&
             ( y >= rect->y ) &&
             ( y <= ( rect->y + rect->h ) ) ) {
            return i;
        }
    }

    return -1;
}

/* Initialize SDL_MessageBoxData structure and Display, etc. */
static int
X11_MessageBoxInit( SDL_MessageBoxDataX11 *data, const SDL_MessageBoxData * messageboxdata, int * pbuttonid )
{
    int i;
    int numbuttons = messageboxdata->numbuttons;
    const SDL_MessageBoxButtonData *buttondata = messageboxdata->buttons;
    const SDL_MessageBoxColor *colorhints;

    if ( numbuttons > MAX_BUTTONS ) {
        return SDL_SetError("Too many buttons (%d max allowed)", MAX_BUTTONS);
    }

    data->dialog_width = MIN_DIALOG_WIDTH;
    data->dialog_height = MIN_DIALOG_HEIGHT;
    data->messageboxdata = messageboxdata;
    data->buttondata = buttondata;
    data->numbuttons = numbuttons;
    data->pbuttonid = pbuttonid;

    data->display = X11_XOpenDisplay( NULL );
    if ( !data->display ) {
        return SDL_SetError("Couldn't open X11 display");
    }

    if (SDL_X11_HAVE_UTF8) {
        char **missing = NULL;
        int num_missing = 0;
        data->font_set = X11_XCreateFontSet(data->display, g_MessageBoxFont,
                                        &missing, &num_missing, NULL);
        if ( missing != NULL ) {
            X11_XFreeStringList(missing);
        }
        if ( data->font_set == NULL ) {
            return SDL_SetError("Couldn't load font %s", g_MessageBoxFont);
        }
    } else {
        data->font_struct = X11_XLoadQueryFont( data->display, g_MessageBoxFontLatin1 );
        if ( data->font_struct == NULL ) {
            return SDL_SetError("Couldn't load font %s", g_MessageBoxFontLatin1);
        }
    }

    if ( messageboxdata->colorScheme ) {
        colorhints = messageboxdata->colorScheme->colors;
    } else {
        colorhints = g_default_colors;
    }

    /* Convert our SDL_MessageBoxColor r,g,b values to packed RGB format. */
    for ( i = 0; i < SDL_MESSAGEBOX_COLOR_MAX; i++ ) {
        data->color[ i ] = SDL_MAKE_RGB( colorhints[ i ].r, colorhints[ i ].g, colorhints[ i ].b );
    }

    return 0;
}

/* Calculate and initialize text and button locations. */
static int
X11_MessageBoxInitPositions( SDL_MessageBoxDataX11 *data )
{
    int i;
    int ybuttons;
    int text_width_max = 0;
    int button_text_height = 0;
    int button_width = MIN_BUTTON_WIDTH;
    const SDL_MessageBoxData *messageboxdata = data->messageboxdata;

    /* Go over text and break linefeeds into separate lines. */
    if ( messageboxdata->message && messageboxdata->message[ 0 ] ) {
        const char *text = messageboxdata->message;
        TextLineData *plinedata = data->linedata;

        for ( i = 0; i < MAX_TEXT_LINES; i++, plinedata++ ) {
            int height;
            char *lf = SDL_strchr( ( char * )text, '\n' );

            data->numlines++;

            /* Only grab length up to lf if it exists and isn't the last line. */
            plinedata->length = ( lf && ( i < MAX_TEXT_LINES - 1 ) ) ? ( lf - text ) : SDL_strlen( text );
            plinedata->text = text;

            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 );
            text_width_max = IntMax( text_width_max, plinedata->width );

            if (lf && (lf > text) && (lf[-1] == '\r')) {
                plinedata->length--;
            }

            text += plinedata->length + 1;

            /* Break if there are no more linefeeds. */
            if ( !lf )
                break;
        }

        /* Bump up the text height slightly. */
        data->text_height += 2;
    }

    /* Loop through all buttons and calculate the button widths and height. */
    for ( i = 0; i < data->numbuttons; i++ ) {
        int height;

        data->buttonpos[ i ].buttondata = &data->buttondata[ i ];
        data->buttonpos[ i ].length = 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 );
        button_text_height = IntMax( button_text_height, height );
    }

    if ( data->numlines ) {
        /* x,y for this line of text. */
        data->xtext = data->text_height;
        data->ytext = data->text_height + data->text_height;

        /* Bump button y down to bottom of text. */
        ybuttons = 3 * data->ytext / 2 + ( data->numlines - 1 ) * data->text_height;

        /* Bump the dialog box width and height up if needed. */
        data->dialog_width = IntMax( data->dialog_width, 2 * data->xtext + text_width_max );
        data->dialog_height = IntMax( data->dialog_height, ybuttons );
    } else {
        /* Button y starts at height of button text. */
        ybuttons = button_text_height;
    }

    if ( data->numbuttons ) {
        int x, y;
        int width_of_buttons;
        int button_spacing = button_text_height;
        int button_height = 2 * button_text_height;

        /* Bump button width up a bit. */
        button_width += button_text_height;

        /* Get width of all buttons lined up. */
        width_of_buttons = data->numbuttons * button_width + ( data->numbuttons - 1 ) * button_spacing;

        /* Bump up dialog width and height if buttons are wider than text. */
        data->dialog_width = IntMax( data->dialog_width, width_of_buttons + 2 * button_spacing );
        data->dialog_height = IntMax( data->dialog_height, ybuttons + 2 * button_height );

        /* Location for first button. */
        x = ( data->dialog_width - width_of_buttons ) / 2;
        y = ybuttons + ( data->dialog_height - ybuttons - button_height ) / 2;

        for ( i = 0; i < data->numbuttons; i++ ) {
            /* Button coordinates. */
            data->buttonpos[ i ].rect.x = x;
            data->buttonpos[ i ].rect.y = y;
            data->buttonpos[ i ].rect.w = button_width;
            data->buttonpos[ i ].rect.h = button_height;

            /* Button text coordinates. */
            data->buttonpos[ i ].x = x + ( button_width - data->buttonpos[ i ].text_width ) / 2;
            data->buttonpos[ i ].y = y + ( button_height - button_text_height - 1 ) / 2 + button_text_height;

            /* Scoot over for next button. */
            x += button_width + button_spacing;
        }
    }

    return 0;
}

/* Free SDL_MessageBoxData data. */
static void
X11_MessageBoxShutdown( SDL_MessageBoxDataX11 *data )
{
    if ( data->font_set != NULL ) {
        X11_XFreeFontSet( data->display, data->font_set );
        data->font_set = NULL;
    }

    if ( data->font_struct != NULL ) {
        X11_XFreeFont( data->display, data->font_struct );
        data->font_struct = NULL;
    }

#if SDL_VIDEO_DRIVER_X11_XDBE
    if ( SDL_X11_HAVE_XDBE && data->xdbe ) {
        X11_XdbeDeallocateBackBufferName(data->display, data->buf);
    }
#endif

    if ( data->display ) {
        if ( data->window != None ) {
            X11_XWithdrawWindow( data->display, data->window, data->screen );
            X11_XDestroyWindow( data->display, data->window );
            data->window = None;
        }

        X11_XCloseDisplay( data->display );
        data->display = NULL;
    }
}

/* Create and set up our X11 dialog box indow. */
static int
X11_MessageBoxCreateWindow( SDL_MessageBoxDataX11 *data )
{
    int x, y;
    XSizeHints *sizehints;
    XSetWindowAttributes wnd_attr;
    Atom _NET_WM_WINDOW_TYPE, _NET_WM_WINDOW_TYPE_DIALOG, _NET_WM_NAME, UTF8_STRING;
    Display *display = data->display;
    SDL_WindowData *windowdata = NULL;
    const SDL_MessageBoxData *messageboxdata = data->messageboxdata;

    if ( messageboxdata->window ) {
        SDL_DisplayData *displaydata =
            (SDL_DisplayData *) SDL_GetDisplayForWindow(messageboxdata->window)->driverdata;
        windowdata = (SDL_WindowData *)messageboxdata->window->driverdata;
        data->screen = displaydata->screen;
    } else {
        data->screen = DefaultScreen( display );
    }

    data->event_mask = ExposureMask |
                       ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask |
                       StructureNotifyMask | FocusChangeMask | PointerMotionMask;
    wnd_attr.event_mask = data->event_mask;

    data->window = X11_XCreateWindow(
                       display, RootWindow(display, data->screen),
                       0, 0,
                       data->dialog_width, data->dialog_height,
                       0, CopyFromParent, InputOutput, CopyFromParent,
                       CWEventMask, &wnd_attr );
    if ( data->window == None ) {
        return SDL_SetError("Couldn't create X window");
    }

    if ( windowdata ) {
        /* http://tronche.com/gui/x/icccm/sec-4.html#WM_TRANSIENT_FOR */
        X11_XSetTransientForHint( display, data->window, windowdata->xwindow );
    }

    X11_XStoreName( display, data->window, messageboxdata->title );
    _NET_WM_NAME = X11_XInternAtom(display, "_NET_WM_NAME", False);
    UTF8_STRING = X11_XInternAtom(display, "UTF8_STRING", False);
    X11_XChangeProperty(display, data->window, _NET_WM_NAME, UTF8_STRING, 8,
                    PropModeReplace, (unsigned char *) messageboxdata->title,
                    strlen(messageboxdata->title) + 1 );

    /* Let the window manager know this is a dialog box */
    _NET_WM_WINDOW_TYPE = X11_XInternAtom(display, "_NET_WM_WINDOW_TYPE", False);
    _NET_WM_WINDOW_TYPE_DIALOG = X11_XInternAtom(display, "_NET_WM_WINDOW_TYPE_DIALOG", False);
    X11_XChangeProperty(display, data->window, _NET_WM_WINDOW_TYPE, XA_ATOM, 32,
                    PropModeReplace,
                    (unsigned char *)&_NET_WM_WINDOW_TYPE_DIALOG, 1);

    /* Allow the window to be deleted by the window manager */
    data->wm_protocols = X11_XInternAtom( display, "WM_PROTOCOLS", False );
    data->wm_delete_message = X11_XInternAtom( display, "WM_DELETE_WINDOW", False );
    X11_XSetWMProtocols( display, data->window, &data->wm_delete_message, 1 );

    if ( windowdata ) {
        XWindowAttributes attrib;
        Window dummy;

        X11_XGetWindowAttributes(display, windowdata->xwindow, &attrib);
        x = attrib.x + ( attrib.width - data->dialog_width ) / 2;
        y = attrib.y + ( attrib.height - data->dialog_height ) / 3 ;
        X11_XTranslateCoordinates(display, windowdata->xwindow, RootWindow(display, data->screen), x, y, &x, &y, &dummy);
    } else {
        const SDL_VideoDevice *dev = SDL_GetVideoDevice();
        if ((dev) && (dev->displays) && (dev->num_displays > 0)) {
            const SDL_VideoDisplay *dpy = &dev->displays[0];
            const SDL_DisplayData *dpydata = (SDL_DisplayData *) dpy->driverdata;
            x = dpydata->x + (( dpy->current_mode.w - data->dialog_width ) / 2);
            y = dpydata->y + (( dpy->current_mode.h - data->dialog_height ) / 3);
        } else {   /* oh well. This will misposition on a multi-head setup. Init first next time. */
            x = ( DisplayWidth( display, data->screen ) - data->dialog_width ) / 2;
            y = ( DisplayHeight( display, data->screen ) - data->dialog_height ) / 3 ;
        }
    }
    X11_XMoveWindow( display, data->window, x, y );

    sizehints = X11_XAllocSizeHints();
    if ( sizehints ) {
        sizehints->flags = USPosition | USSize | PMaxSize | PMinSize;
        sizehints->x = x;
        sizehints->y = y;
        sizehints->width = data->dialog_width;
        sizehints->height = data->dialog_height;

        sizehints->min_width = sizehints->max_width = data->dialog_width;
        sizehints->min_height = sizehints->max_height = data->dialog_height;

        X11_XSetWMNormalHints( display, data->window, sizehints );

        X11_XFree( sizehints );
    }

    X11_XMapRaised( display, data->window );

#if SDL_VIDEO_DRIVER_X11_XDBE
    /* Initialise a back buffer for double buffering */
    if (SDL_X11_HAVE_XDBE) {
        int xdbe_major, xdbe_minor;
        if (X11_XdbeQueryExtension(display, &xdbe_major, &xdbe_minor) != 0) {
            data->xdbe = SDL_TRUE;
            data->buf = X11_XdbeAllocateBackBufferName(display, data->window, XdbeUndefined);
        } else {
            data->xdbe = SDL_FALSE;
        }
    }
#endif

    return 0;
}

/* Draw our message box. */
static void
X11_MessageBoxDraw( SDL_MessageBoxDataX11 *data, GC ctx )
{
    int i;
    Drawable window = data->window;
    Display *display = data->display;

#if SDL_VIDEO_DRIVER_X11_XDBE
    if (SDL_X11_HAVE_XDBE && data->xdbe) {
        window = data->buf;
        X11_XdbeBeginIdiom(data->display);
    }
#endif

    X11_XSetForeground( display, ctx, data->color[ SDL_MESSAGEBOX_COLOR_BACKGROUND ] );
    X11_XFillRectangle( display, window, ctx, 0, 0, data->dialog_width, data->dialog_height );

    X11_XSetForeground( display, ctx, data->color[ SDL_MESSAGEBOX_COLOR_TEXT ] );
    for ( i = 0; i < data->numlines; i++ ) {
        TextLineData *plinedata = &data->linedata[ i ];

        if (SDL_X11_HAVE_UTF8) {
            X11_Xutf8DrawString( display, window, data->font_set, ctx,
                             data->xtext, data->ytext + i * data->text_height,
                             plinedata->text, plinedata->length );
        } else {
            X11_XDrawString( display, window, ctx,
                         data->xtext, data->ytext + i * data->text_height,
                         plinedata->text, plinedata->length );
        }
    }

    for ( i = 0; i < data->numbuttons; i++ ) {
        SDL_MessageBoxButtonDataX11 *buttondatax11 = &data->buttonpos[ i ];
        const SDL_MessageBoxButtonData *buttondata = buttondatax11->buttondata;
        int border = ( buttondata->flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT ) ? 2 : 0;
        int offset = ( ( data->mouse_over_index == i ) && ( data->button_press_index == data->mouse_over_index ) ) ? 1 : 0;

        X11_XSetForeground( display, ctx, data->color[ SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND ] );
        X11_XFillRectangle( display, window, ctx,
                        buttondatax11->rect.x - border, buttondatax11->rect.y - border,
                        buttondatax11->rect.w + 2 * border, buttondatax11->rect.h + 2 * border );

        X11_XSetForeground( display, ctx, data->color[ SDL_MESSAGEBOX_COLOR_BUTTON_BORDER ] );
        X11_XDrawRectangle( display, window, ctx,
                        buttondatax11->rect.x, buttondatax11->rect.y,
                        buttondatax11->rect.w, buttondatax11->rect.h );

        X11_XSetForeground( display, ctx, ( data->mouse_over_index == i ) ?
                        data->color[ SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED ] :
                        data->color[ SDL_MESSAGEBOX_COLOR_TEXT ] );

        if (SDL_X11_HAVE_UTF8) {
            X11_Xutf8DrawString( display, window, data->font_set, ctx,
                             buttondatax11->x + offset,
                             buttondatax11->y + offset,
                             buttondata->text, buttondatax11->length );
        } else {
            X11_XDrawString( display, window, ctx,
                         buttondatax11->x + offset, buttondatax11->y + offset,
                         buttondata->text, buttondatax11->length );
        }
    }

#if SDL_VIDEO_DRIVER_X11_XDBE
    if (SDL_X11_HAVE_XDBE && data->xdbe) {
        XdbeSwapInfo swap_info;
        swap_info.swap_window = data->window;
        swap_info.swap_action = XdbeUndefined;
        X11_XdbeSwapBuffers(data->display, &swap_info, 1);
        X11_XdbeEndIdiom(data->display);
    }
#endif
}

static Bool
X11_MessageBoxEventTest(Display *display, XEvent *event, XPointer arg)
{
    const SDL_MessageBoxDataX11 *data = (const SDL_MessageBoxDataX11 *) arg;
    return ((event->xany.display == data->display) && (event->xany.window == data->window)) ? True : False;
}

/* Loop and handle message box event messages until something kills it. */
static int
X11_MessageBoxLoop( SDL_MessageBoxDataX11 *data )
{
    GC ctx;
    XGCValues ctx_vals;
    SDL_bool close_dialog = SDL_FALSE;
    SDL_bool has_focus = SDL_TRUE;
    KeySym last_key_pressed = XK_VoidSymbol;
    unsigned long gcflags = GCForeground | GCBackground;

    SDL_zero(ctx_vals);
    ctx_vals.foreground = data->color[ SDL_MESSAGEBOX_COLOR_BACKGROUND ];
    ctx_vals.background = data->color[ SDL_MESSAGEBOX_COLOR_BACKGROUND ];

    if (!SDL_X11_HAVE_UTF8) {
        gcflags |= GCFont;
        ctx_vals.font = data->font_struct->fid;
    }

    ctx = X11_XCreateGC( data->display, data->window, gcflags, &ctx_vals );
    if ( ctx == None ) {
        return SDL_SetError("Couldn't create graphics context");
    }

    data->button_press_index = -1;  /* Reset what button is currently depressed. */
    data->mouse_over_index = -1;    /* Reset what button the mouse is over. */

    while( !close_dialog ) {
        XEvent e;
        SDL_bool draw = SDL_TRUE;

        /* can't use XWindowEvent() because it can't handle ClientMessage events. */
        /* can't use XNextEvent() because we only want events for this window. */
        X11_XIfEvent( data->display, &e, X11_MessageBoxEventTest, (XPointer) data );

        /* If X11_XFilterEvent returns True, then some input method has filtered the
           event, and the client should discard the event. */
        if ( ( e.type != Expose ) && X11_XFilterEvent( &e, None ) )
            continue;

        switch( e.type ) {
        case Expose:
            if ( e.xexpose.count > 0 ) {
                draw = SDL_FALSE;
            }
            break;

        case FocusIn:
            /* Got focus. */
            has_focus = SDL_TRUE;
            break;

        case FocusOut:
            /* lost focus. Reset button and mouse info. */
            has_focus = SDL_FALSE;
            data->button_press_index = -1;
            data->mouse_over_index = -1;
            break;

        case MotionNotify:
            if ( has_focus ) {
                /* Mouse moved... */
                const int previndex = data->mouse_over_index;
                data->mouse_over_index = GetHitButtonIndex( data, e.xbutton.x, e.xbutton.y );
                if (data->mouse_over_index == previndex) {
                    draw = SDL_FALSE;
                }
            }
            break;

        case ClientMessage:
            if ( e.xclient.message_type == data->wm_protocols &&
                 e.xclient.format == 32 &&
                 e.xclient.data.l[ 0 ] == data->wm_delete_message ) {
                close_dialog = SDL_TRUE;
            }
            break;

        case KeyPress:
            /* Store key press - we make sure in key release that we got both. */
            last_key_pressed = X11_XLookupKeysym( &e.xkey, 0 );
            break;

        case KeyRelease: {
            Uint32 mask = 0;
            KeySym key = X11_XLookupKeysym( &e.xkey, 0 );

            /* If this is a key release for something we didn't get the key down for, then bail. */
            if ( key != last_key_pressed )
                break;

            if ( key == XK_Escape )
                mask = SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT;
            else if ( ( key == XK_Return ) || ( key == XK_KP_Enter ) )
                mask = SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT;

            if ( mask ) {
                int i;

                /* Look for first button with this mask set, and return it if found. */
                for ( i = 0; i < data->numbuttons; i++ ) {
                    SDL_MessageBoxButtonDataX11 *buttondatax11 = &data->buttonpos[ i ];

                    if ( buttondatax11->buttondata->flags & mask ) {
                        *data->pbuttonid = buttondatax11->buttondata->buttonid;
                        close_dialog = SDL_TRUE;
                        break;
                    }
                }
            }
            break;
        }

        case ButtonPress:
            data->button_press_index = -1;
            if ( e.xbutton.button == Button1 ) {
                /* Find index of button they clicked on. */
                data->button_press_index = GetHitButtonIndex( data, e.xbutton.x, e.xbutton.y );
            }
            break;

        case ButtonRelease:
            /* If button is released over the same button that was clicked down on, then return it. */
            if ( ( e.xbutton.button == Button1 ) && ( data->button_press_index >= 0 ) ) {
                int button = GetHitButtonIndex( data, e.xbutton.x, e.xbutton.y );

                if ( data->button_press_index == button ) {
                    SDL_MessageBoxButtonDataX11 *buttondatax11 = &data->buttonpos[ button ];

                    *data->pbuttonid = buttondatax11->buttondata->buttonid;
                    close_dialog = SDL_TRUE;
                }
            }
            data->button_press_index = -1;
            break;
        }

        if ( draw ) {
            /* Draw our dialog box. */
            X11_MessageBoxDraw( data, ctx );
        }
    }

    X11_XFreeGC( data->display, ctx );
    return 0;
}

static int
X11_ShowMessageBoxImpl(const SDL_MessageBoxData *messageboxdata, int *buttonid)
{
    int ret;
    SDL_MessageBoxDataX11 data;
#if SDL_SET_LOCALE
    char *origlocale;
#endif

    SDL_zero(data);

    if ( !SDL_X11_LoadSymbols() )
        return -1;

#if SDL_SET_LOCALE
    origlocale = setlocale(LC_ALL, NULL);
    if (origlocale != NULL) {
        origlocale = SDL_strdup(origlocale);
        if (origlocale == NULL) {
            return SDL_OutOfMemory();
        }
        setlocale(LC_ALL, "");
    }
#endif

    /* This code could get called from multiple threads maybe? */
    X11_XInitThreads();

    /* Initialize the return buttonid value to -1 (for error or dialogbox closed). */
    *buttonid = -1;

    /* Init and display the message box. */
    ret = X11_MessageBoxInit( &data, messageboxdata, buttonid );
    if ( ret != -1 ) {
        ret = X11_MessageBoxInitPositions( &data );
        if ( ret != -1 ) {
            ret = X11_MessageBoxCreateWindow( &data );
            if ( ret != -1 ) {
                ret = X11_MessageBoxLoop( &data );
            }
        }
    }

    X11_MessageBoxShutdown( &data );

#if SDL_SET_LOCALE
    if (origlocale) {
        setlocale(LC_ALL, origlocale);
        SDL_free(origlocale);
    }
#endif

    return ret;
}

/* Display an x11 message box. */
int
X11_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
{
#if SDL_FORK_MESSAGEBOX
    /* Use a child process to protect against setlocale(). Annoying. */
    pid_t pid;
    int fds[2];
    int status = 0;

    if (pipe(fds) == -1) {
        return X11_ShowMessageBoxImpl(messageboxdata, buttonid); /* oh well. */
    }

    pid = fork();
    if (pid == -1) {  /* failed */
        close(fds[0]);
        close(fds[1]);
        return X11_ShowMessageBoxImpl(messageboxdata, buttonid); /* oh well. */
    } else if (pid == 0) {  /* we're the child */
        int exitcode = 0;
        close(fds[0]);
        status = X11_ShowMessageBoxImpl(messageboxdata, buttonid);
        if (write(fds[1], &status, sizeof (int)) != sizeof (int))
            exitcode = 1;
        else if (write(fds[1], buttonid, sizeof (int)) != sizeof (int))
            exitcode = 1;
        close(fds[1]);
        _exit(exitcode);  /* don't run atexit() stuff, static destructors, etc. */
    } else {  /* we're the parent */
        pid_t rc;
        close(fds[1]);
        do {
            rc = waitpid(pid, &status, 0);
        } while ((rc == -1) && (errno == EINTR));

        SDL_assert(rc == pid);  /* not sure what to do if this fails. */

        if ((rc == -1) || (!WIFEXITED(status)) || (WEXITSTATUS(status) != 0)) {
            return SDL_SetError("msgbox child process failed");
        }

        if (read(fds[0], &status, sizeof (int)) != sizeof (int))
            status = -1;
        else if (read(fds[0], buttonid, sizeof (int)) != sizeof (int))
            status = -1;
        close(fds[0]);

        return status;
    }
#else
    return X11_ShowMessageBoxImpl(messageboxdata, buttonid);
#endif
}
#endif /* SDL_VIDEO_DRIVER_X11 */

/* vi: set ts=4 sw=4 expandtab: */
