/* 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; }
/* 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; 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 ); /* 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 { 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 ); return 0; }