Example #1
0
void
X11_DestroyWindowFramebuffer(_THIS, SDL_Window * window)
{
    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
    Display *display;

    if (!data) {
        /* The window wasn't fully initialized */
        return;
    }

    display = data->videodata->display;

    if (data->ximage) {
        XDestroyImage(data->ximage);

#ifndef NO_SHARED_MEMORY
        if (data->use_mitshm) {
            X11_XShmDetach(display, &data->shminfo);
            X11_XSync(display, False);
            shmdt(data->shminfo.shmaddr);
            data->use_mitshm = SDL_FALSE;
        }
#endif /* !NO_SHARED_MEMORY */

        data->ximage = NULL;
    }
    if (data->gc) {
        X11_XFreeGC(display, data->gc);
        data->gc = NULL;
    }
}
Example #2
0
/* 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;
}