コード例 #1
0
ファイル: SDL_x11messagebox.c プロジェクト: abakobo/monkey2
/* 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;
}
コード例 #2
0
ファイル: SDL_x11framebuffer.c プロジェクト: Daft-Freak/vogl
int
X11_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format,
                            void ** pixels, int *pitch)
{
    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
    Display *display = data->videodata->display;
    XGCValues gcv;
    XVisualInfo vinfo;

    /* Free the old framebuffer surface */
    X11_DestroyWindowFramebuffer(_this, window);

    /* Create the graphics context for drawing */
    gcv.graphics_exposures = False;
    data->gc = X11_XCreateGC(display, data->xwindow, GCGraphicsExposures, &gcv);
    if (!data->gc) {
        return SDL_SetError("Couldn't create graphics context");
    }

    /* Find out the pixel format and depth */
    if (X11_GetVisualInfoFromVisual(display, data->visual, &vinfo) < 0) {
        return SDL_SetError("Couldn't get window visual information");
    }

    *format = X11_GetPixelFormatFromVisualInfo(display, &vinfo);
    if (*format == SDL_PIXELFORMAT_UNKNOWN) {
        return SDL_SetError("Unknown window pixel format");
    }

    /* Calculate pitch */
    *pitch = (((window->w * SDL_BYTESPERPIXEL(*format)) + 3) & ~3);

    /* Create the actual image */
#ifndef NO_SHARED_MEMORY
    if (have_mitshm()) {
        XShmSegmentInfo *shminfo = &data->shminfo;

        shminfo->shmid = shmget(IPC_PRIVATE, window->h*(*pitch), IPC_CREAT | 0777);
        if ( shminfo->shmid >= 0 ) {
            shminfo->shmaddr = (char *)shmat(shminfo->shmid, 0, 0);
            shminfo->readOnly = False;
            if ( shminfo->shmaddr != (char *)-1 ) {
                shm_error = False;
                X_handler = X11_XSetErrorHandler(shm_errhandler);
                X11_XShmAttach(display, shminfo);
                X11_XSync(display, True);
                X11_XSetErrorHandler(X_handler);
                if ( shm_error )
                    shmdt(shminfo->shmaddr);
            } else {
                shm_error = True;
            }
            shmctl(shminfo->shmid, IPC_RMID, NULL);
        } else {
            shm_error = True;
        }
        if (!shm_error) {
            data->ximage = X11_XShmCreateImage(display, data->visual,
                             vinfo.depth, ZPixmap,
                             shminfo->shmaddr, shminfo,
                             window->w, window->h);
            if (!data->ximage) {
                X11_XShmDetach(display, shminfo);
                X11_XSync(display, False);
                shmdt(shminfo->shmaddr);
            } else {
                /* Done! */
                data->use_mitshm = SDL_TRUE;
                *pixels = shminfo->shmaddr;
                return 0;
            }
        }
    }
#endif /* not NO_SHARED_MEMORY */

    *pixels = SDL_malloc(window->h*(*pitch));
    if (*pixels == NULL) {
        return SDL_OutOfMemory();
    }

    data->ximage = X11_XCreateImage(display, data->visual,
                      vinfo.depth, ZPixmap, 0, (char *)(*pixels),
                      window->w, window->h, 32, 0);
    if (!data->ximage) {
        SDL_free(*pixels);
        return SDL_SetError("Couldn't create XImage");
    }
    return 0;
}