src/video/x11/SDL_x11window.c
author Bob Pendleton <bob@pendleton.com>
Tue, 04 Mar 2008 23:09:28 +0000
changeset 2321 c5feceb0395e
parent 2214 e7164a4dac62
child 2322 c25d45b7add3
permissions -rw-r--r--
SetupWindowData in SDL_X11window.c was realloc()ing the display window list and incrementing numwindows even though those are being updated in functions that call
this function. The result is that it is possible to get the same window added to the list twice.
slouken@1951
     1
/*
slouken@1951
     2
    SDL - Simple DirectMedia Layer
slouken@1951
     3
    Copyright (C) 1997-2006 Sam Lantinga
slouken@1951
     4
slouken@1951
     5
    This library is free software; you can redistribute it and/or
slouken@1951
     6
    modify it under the terms of the GNU Lesser General Public
slouken@1951
     7
    License as published by the Free Software Foundation; either
slouken@1951
     8
    version 2.1 of the License, or (at your option) any later version.
slouken@1951
     9
slouken@1951
    10
    This library is distributed in the hope that it will be useful,
slouken@1951
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@1951
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@1951
    13
    Lesser General Public License for more details.
slouken@1951
    14
slouken@1951
    15
    You should have received a copy of the GNU Lesser General Public
slouken@1951
    16
    License along with this library; if not, write to the Free Software
slouken@1951
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@1951
    18
slouken@1951
    19
    Sam Lantinga
slouken@1951
    20
    slouken@libsdl.org
slouken@1951
    21
*/
slouken@1951
    22
#include "SDL_config.h"
slouken@1951
    23
slouken@1951
    24
#include "SDL_syswm.h"
slouken@1951
    25
#include "../SDL_sysvideo.h"
slouken@1951
    26
#include "../../events/SDL_keyboard_c.h"
slouken@1951
    27
slouken@1951
    28
#include "SDL_x11video.h"
bob@2185
    29
#include "../Xext/extensions/StdCmap.h"
slouken@1951
    30
slouken@1951
    31
static int
slouken@1951
    32
SetupWindowData(_THIS, SDL_Window * window, Window w, BOOL created)
slouken@1951
    33
{
slouken@1951
    34
    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
slouken@1951
    35
    SDL_WindowData *data;
slouken@1951
    36
    int numwindows = videodata->numwindows;
slouken@1951
    37
    SDL_WindowData **windowlist = videodata->windowlist;
slouken@1951
    38
slouken@1951
    39
    /* Allocate the window data */
slouken@1951
    40
    data = (SDL_WindowData *) SDL_malloc(sizeof(*data));
slouken@1951
    41
    if (!data) {
slouken@1951
    42
        SDL_OutOfMemory();
slouken@1951
    43
        return -1;
slouken@1951
    44
    }
slouken@1951
    45
    data->windowID = window->id;
slouken@1951
    46
    data->window = w;
slouken@1951
    47
#ifdef X_HAVE_UTF8_STRING
slouken@1951
    48
    if (SDL_X11_HAVE_UTF8) {
slouken@1951
    49
        data->ic =
slouken@1951
    50
            pXCreateIC(videodata->im, XNClientWindow, w, XNFocusWindow, w,
slouken@1951
    51
                       XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
slouken@1951
    52
                       XNResourceName, videodata->classname, XNResourceClass,
slouken@1951
    53
                       videodata->classname, NULL);
slouken@1951
    54
    }
slouken@1951
    55
#endif
slouken@1951
    56
    data->created = created;
slouken@1951
    57
    data->videodata = videodata;
slouken@1951
    58
slouken@1951
    59
    /* Associate the data with the window */
slouken@1951
    60
    windowlist =
slouken@1951
    61
        (SDL_WindowData **) SDL_realloc(windowlist,
slouken@1951
    62
                                        (numwindows +
slouken@1951
    63
                                         1) * sizeof(*windowlist));
slouken@1951
    64
    if (!windowlist) {
slouken@1951
    65
        SDL_OutOfMemory();
slouken@1951
    66
        SDL_free(data);
slouken@1951
    67
        return -1;
slouken@1951
    68
    }
slouken@1951
    69
    windowlist[numwindows++] = data;
slouken@1951
    70
    videodata->numwindows = numwindows;
slouken@1951
    71
    videodata->windowlist = windowlist;
slouken@1951
    72
slouken@1951
    73
    /* Fill in the SDL window with the window data */
slouken@1951
    74
    {
slouken@1951
    75
        XWindowAttributes attrib;
slouken@1951
    76
slouken@1951
    77
        XGetWindowAttributes(data->videodata->display, w, &attrib);
slouken@1951
    78
        window->x = attrib.x;
slouken@1951
    79
        window->y = attrib.y;
slouken@1951
    80
        window->w = attrib.width;
slouken@1951
    81
        window->h = attrib.height;
slouken@1951
    82
        if (attrib.map_state != IsUnmapped) {
slouken@1951
    83
            window->flags |= SDL_WINDOW_SHOWN;
slouken@1951
    84
        } else {
slouken@1951
    85
            window->flags &= ~SDL_WINDOW_SHOWN;
slouken@1951
    86
        }
slouken@1951
    87
    }
slouken@1951
    88
    /* FIXME: How can I tell?
slouken@1951
    89
       {
slouken@1951
    90
       DWORD style = GetWindowLong(hwnd, GWL_STYLE);
slouken@1951
    91
       if (style & WS_VISIBLE) {
slouken@1951
    92
       if (style & (WS_BORDER | WS_THICKFRAME)) {
slouken@1951
    93
       window->flags &= ~SDL_WINDOW_BORDERLESS;
slouken@1951
    94
       } else {
slouken@1951
    95
       window->flags |= SDL_WINDOW_BORDERLESS;
slouken@1951
    96
       }
slouken@1951
    97
       if (style & WS_THICKFRAME) {
slouken@1951
    98
       window->flags |= SDL_WINDOW_RESIZABLE;
slouken@1951
    99
       } else {
slouken@1951
   100
       window->flags &= ~SDL_WINDOW_RESIZABLE;
slouken@1951
   101
       }
slouken@1951
   102
       if (style & WS_MAXIMIZE) {
slouken@1951
   103
       window->flags |= SDL_WINDOW_MAXIMIZED;
slouken@1951
   104
       } else {
slouken@1951
   105
       window->flags &= ~SDL_WINDOW_MAXIMIZED;
slouken@1951
   106
       }
slouken@1951
   107
       if (style & WS_MINIMIZE) {
slouken@1951
   108
       window->flags |= SDL_WINDOW_MINIMIZED;
slouken@1951
   109
       } else {
slouken@1951
   110
       window->flags &= ~SDL_WINDOW_MINIMIZED;
slouken@1951
   111
       }
slouken@1951
   112
       }
slouken@1951
   113
       if (GetFocus() == hwnd) {
slouken@1951
   114
       int index = data->videodata->keyboard;
slouken@1951
   115
       window->flags |= SDL_WINDOW_INPUT_FOCUS;
slouken@1951
   116
       SDL_SetKeyboardFocus(index, data->windowID);
slouken@1951
   117
slouken@1951
   118
       if (window->flags & SDL_WINDOW_INPUT_GRABBED) {
slouken@1951
   119
       RECT rect;
slouken@1951
   120
       GetClientRect(hwnd, &rect);
slouken@1951
   121
       ClientToScreen(hwnd, (LPPOINT) & rect);
slouken@1951
   122
       ClientToScreen(hwnd, (LPPOINT) & rect + 1);
slouken@1951
   123
       ClipCursor(&rect);
slouken@1951
   124
       }
slouken@1951
   125
       }
slouken@1951
   126
     */
slouken@1951
   127
slouken@1951
   128
    /* All done! */
slouken@1951
   129
    window->driverdata = data;
slouken@1951
   130
    return 0;
slouken@1951
   131
}
slouken@1951
   132
slouken@1951
   133
int
slouken@1951
   134
X11_CreateWindow(_THIS, SDL_Window * window)
slouken@1951
   135
{
slouken@1951
   136
    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
slouken@1951
   137
    SDL_DisplayData *displaydata =
slouken@1952
   138
        (SDL_DisplayData *) SDL_GetDisplayFromWindow(window)->driverdata;
slouken@1951
   139
    Visual *visual;
slouken@1951
   140
    int depth;
slouken@1951
   141
    XSetWindowAttributes xattr;
slouken@1951
   142
    int x, y;
slouken@1951
   143
    Window w;
slouken@1951
   144
    XSizeHints *sizehints;
slouken@1951
   145
    XWMHints *wmhints;
slouken@1951
   146
    XClassHint *classhints;
slouken@1951
   147
slouken@1951
   148
#if SDL_VIDEO_DRIVER_X11_XINERAMA
slouken@1951
   149
/* FIXME
slouken@1951
   150
    if ( use_xinerama ) {
slouken@1951
   151
        x = xinerama_info.x_org;
slouken@1951
   152
        y = xinerama_info.y_org;
slouken@1951
   153
    }
slouken@1951
   154
*/
slouken@1951
   155
#endif
slouken@1952
   156
#ifdef SDL_VIDEO_OPENGL_GLX
slouken@1951
   157
    if (window->flags & SDL_WINDOW_OPENGL) {
slouken@1952
   158
        XVisualInfo *vinfo;
slouken@1952
   159
slouken@1952
   160
        if (X11_GL_Initialize(_this) < 0) {
slouken@1952
   161
            return -1;
slouken@1952
   162
        }
slouken@1952
   163
        vinfo = X11_GL_GetVisual(_this, data->display, displaydata->screen);
slouken@1952
   164
        if (!vinfo) {
slouken@1952
   165
            return -1;
slouken@1952
   166
        }
slouken@1952
   167
        visual = vinfo->visual;
slouken@1952
   168
        depth = vinfo->depth;
slouken@1952
   169
        XFree(vinfo);
slouken@1952
   170
    } else
slouken@1952
   171
#endif
slouken@1952
   172
    {
slouken@1951
   173
        visual = displaydata->visual;
slouken@1951
   174
        depth = displaydata->depth;
slouken@1951
   175
    }
slouken@1951
   176
slouken@1951
   177
    if (window->flags & SDL_WINDOW_FULLSCREEN) {
slouken@1951
   178
        xattr.override_redirect = True;
slouken@1951
   179
    } else {
slouken@1951
   180
        xattr.override_redirect = False;
slouken@1951
   181
    }
slouken@1951
   182
    xattr.background_pixel = 0;
slouken@1951
   183
    xattr.border_pixel = 0;
bob@2214
   184
bob@2211
   185
    if (visual->class == DirectColor || visual->class == PseudoColor) {
bob@2185
   186
        int nmaps;
bob@2214
   187
        XStandardColormap cmap;
bob@2185
   188
        XStandardColormap *stdmaps;
bob@2214
   189
        XColor *colorcells;
bob@2214
   190
        Colormap colormap;
bob@2185
   191
        Bool found = False;
bob@2214
   192
        int i;
bob@2214
   193
        int ncolors;
bob@2214
   194
        int rmax, gmax, bmax;
bob@2214
   195
        int rmul, gmul, bmul;
bob@2185
   196
bob@2214
   197
        if (colormap =
bob@2214
   198
            X11_LookupColormap(data->display, displaydata->screen,
bob@2214
   199
                               visual->visualid)) {
bob@2214
   200
            xattr.colormap = colormap;
bob@2214
   201
        } else {
bob@2214
   202
            /* check to see if the colormap we need already exists */
bob@2214
   203
            if (0 != XGetRGBColormaps(data->display,
bob@2214
   204
                                      RootWindow(data->display,
bob@2214
   205
                                                 displaydata->screen),
bob@2214
   206
                                      &stdmaps, &nmaps, XA_RGB_BEST_MAP)) {
bob@2214
   207
                for (i = 0; i < nmaps; i++) {
bob@2214
   208
                    if (stdmaps[i].visualid == visual->visualid) {
bob@2214
   209
                        SDL_memcpy(&cmap, &stdmaps[i],
bob@2214
   210
                                   sizeof(XStandardColormap));
bob@2214
   211
                        found = True;
bob@2214
   212
                        break;
bob@2214
   213
                    }
bob@2185
   214
                }
bob@2214
   215
                XFree(stdmaps);
bob@2185
   216
            }
bob@2213
   217
bob@2214
   218
            /* it doesn't exist, so create it */
bob@2214
   219
            if (!found) {
bob@2214
   220
                int max = visual->map_entries - 1;
bob@2214
   221
                stdmaps =
bob@2214
   222
                    XmuStandardColormap(data->display, displaydata->screen,
bob@2214
   223
                                        visual->visualid, depth,
bob@2214
   224
                                        XA_RGB_BEST_MAP, None, max, max, max);
bob@2214
   225
                if (NULL == stdmaps || stdmaps->visualid != visual->visualid) {
bob@2214
   226
                    SDL_SetError
bob@2214
   227
                        ("Couldn't create window:XA_RGB_BEST_MAP not found and could not be created");
bob@2214
   228
                    return -1;
bob@2214
   229
                }
bob@2214
   230
                SDL_memcpy(&cmap, stdmaps, sizeof(XStandardColormap));
bob@2214
   231
            }
bob@2214
   232
bob@2214
   233
            /* OK, we have the best color map, now copy it for use by the
bob@2214
   234
               program */
bob@2214
   235
bob@2214
   236
            colorcells = SDL_malloc(visual->map_entries * sizeof(XColor));
bob@2214
   237
            if (NULL == colorcells) {
bob@2214
   238
                SDL_SetError("out of memory in X11_CreateWindow");
bob@2185
   239
                return -1;
bob@2185
   240
            }
bob@2214
   241
            ncolors = visual->map_entries;
bob@2214
   242
            rmax = cmap.red_max + 1;
bob@2214
   243
            gmax = cmap.blue_max + 1;
bob@2214
   244
            bmax = cmap.green_max + 1;
bob@2214
   245
bob@2214
   246
            rmul = cmap.red_mult;
bob@2214
   247
            gmul = cmap.blue_mult;
bob@2214
   248
            bmul = cmap.green_mult;
bob@2214
   249
bob@2214
   250
            /* build the color table pixel values */
bob@2214
   251
            for (i = 0; i < ncolors; i++) {
bob@2214
   252
                Uint32 red = (rmax * i) / ncolors;
bob@2214
   253
                Uint32 green = (gmax * i) / ncolors;
bob@2214
   254
                Uint32 blue = (bmax * i) / ncolors;
bob@2214
   255
bob@2214
   256
                colorcells[i].pixel =
bob@2214
   257
                    (red * rmul) | (green * gmul) | (blue * bmul);
bob@2214
   258
            }
bob@2214
   259
            XQueryColors(data->display, cmap.colormap, colorcells, ncolors);
bob@2214
   260
            colormap = XCreateColormap(data->display,
bob@2214
   261
                                       RootWindow(data->display,
bob@2214
   262
                                                  displaydata->screen),
bob@2214
   263
                                       visual, AllocAll);
bob@2214
   264
            XStoreColors(data->display, colormap, colorcells, ncolors);
bob@2214
   265
            SDL_free(colorcells);
bob@2214
   266
bob@2214
   267
            xattr.colormap = colormap;
bob@2214
   268
            X11_TrackColormap(data->display, displaydata->screen, colormap,
bob@2214
   269
                              &cmap, visual);
bob@2185
   270
        }
slouken@1951
   271
    } else {
slouken@1951
   272
        xattr.colormap =
slouken@1951
   273
            XCreateColormap(data->display,
slouken@1951
   274
                            RootWindow(data->display, displaydata->screen),
slouken@1951
   275
                            visual, AllocNone);
slouken@1951
   276
    }
slouken@1951
   277
slouken@1956
   278
    if (window->x == SDL_WINDOWPOS_CENTERED) {
slouken@1951
   279
        x = (DisplayWidth(data->display, displaydata->screen) -
slouken@1951
   280
             window->w) / 2;
slouken@1951
   281
    } else if (window->x == SDL_WINDOWPOS_UNDEFINED) {
slouken@1951
   282
        x = 0;
slouken@1951
   283
    } else {
slouken@1951
   284
        x = window->x;
slouken@1951
   285
    }
slouken@1956
   286
    if (window->y == SDL_WINDOWPOS_CENTERED) {
slouken@1951
   287
        y = (DisplayHeight(data->display, displaydata->screen) -
slouken@1951
   288
             window->h) / 2;
slouken@1951
   289
    } else if (window->y == SDL_WINDOWPOS_UNDEFINED) {
slouken@1951
   290
        y = 0;
slouken@1951
   291
    } else {
slouken@1951
   292
        y = window->y;
slouken@1951
   293
    }
slouken@1951
   294
slouken@1951
   295
    w = XCreateWindow(data->display,
slouken@1951
   296
                      RootWindow(data->display, displaydata->screen), x, y,
slouken@1951
   297
                      window->w, window->h, 0, depth, InputOutput, visual,
slouken@1951
   298
                      (CWOverrideRedirect | CWBackPixel | CWBorderPixel |
slouken@1951
   299
                       CWColormap), &xattr);
slouken@1952
   300
    if (!w) {
slouken@1952
   301
#ifdef SDL_VIDEO_OPENGL_GLX
slouken@1952
   302
        if (window->flags & SDL_WINDOW_OPENGL) {
slouken@1952
   303
            X11_GL_Shutdown(_this);
slouken@1952
   304
        }
slouken@1952
   305
#endif
slouken@1952
   306
        SDL_SetError("Couldn't create window");
slouken@1952
   307
        return -1;
slouken@1952
   308
    }
slouken@1951
   309
slouken@1951
   310
    sizehints = XAllocSizeHints();
slouken@1951
   311
    if (sizehints) {
slouken@1951
   312
        if (window->flags & SDL_WINDOW_RESIZABLE) {
slouken@1951
   313
            sizehints->min_width = 32;
slouken@1951
   314
            sizehints->min_height = 32;
slouken@1951
   315
            sizehints->max_height = 4096;
slouken@1951
   316
            sizehints->max_width = 4096;
slouken@1951
   317
        } else {
slouken@1951
   318
            sizehints->min_width = sizehints->max_width = window->w;
slouken@1951
   319
            sizehints->min_height = sizehints->max_height = window->h;
slouken@1951
   320
        }
slouken@1951
   321
        sizehints->flags = PMaxSize | PMinSize;
slouken@1951
   322
        if (!(window->flags & SDL_WINDOW_FULLSCREEN)
slouken@1951
   323
            && window->x != SDL_WINDOWPOS_UNDEFINED
slouken@1951
   324
            && window->y != SDL_WINDOWPOS_UNDEFINED) {
slouken@1951
   325
            sizehints->x = x;
slouken@1951
   326
            sizehints->y = y;
slouken@1951
   327
            sizehints->flags |= USPosition;
slouken@1951
   328
        }
slouken@1951
   329
        XSetWMNormalHints(data->display, w, sizehints);
slouken@1951
   330
        XFree(sizehints);
slouken@1951
   331
    }
slouken@1951
   332
slouken@1951
   333
    if (window->flags & SDL_WINDOW_BORDERLESS) {
slouken@1951
   334
        SDL_bool set;
slouken@1951
   335
        Atom WM_HINTS;
slouken@1951
   336
slouken@1951
   337
        /* We haven't modified the window manager hints yet */
slouken@1951
   338
        set = SDL_FALSE;
slouken@1951
   339
slouken@1951
   340
        /* First try to set MWM hints */
slouken@1951
   341
        WM_HINTS = XInternAtom(data->display, "_MOTIF_WM_HINTS", True);
slouken@1951
   342
        if (WM_HINTS != None) {
slouken@1951
   343
            /* Hints used by Motif compliant window managers */
slouken@1951
   344
            struct
slouken@1951
   345
            {
slouken@1951
   346
                unsigned long flags;
slouken@1951
   347
                unsigned long functions;
slouken@1951
   348
                unsigned long decorations;
slouken@1951
   349
                long input_mode;
slouken@1951
   350
                unsigned long status;
slouken@1951
   351
            } MWMHints = {
slouken@1951
   352
            (1L << 1), 0, 0, 0, 0};
slouken@1951
   353
slouken@1951
   354
            XChangeProperty(data->display, w, WM_HINTS, WM_HINTS, 32,
slouken@1951
   355
                            PropModeReplace, (unsigned char *) &MWMHints,
slouken@1951
   356
                            sizeof(MWMHints) / sizeof(long));
slouken@1951
   357
            set = SDL_TRUE;
slouken@1951
   358
        }
slouken@1951
   359
        /* Now try to set KWM hints */
slouken@1951
   360
        WM_HINTS = XInternAtom(data->display, "KWM_WIN_DECORATION", True);
slouken@1951
   361
        if (WM_HINTS != None) {
slouken@1951
   362
            long KWMHints = 0;
slouken@1951
   363
slouken@1951
   364
            XChangeProperty(data->display, w,
slouken@1951
   365
                            WM_HINTS, WM_HINTS, 32,
slouken@1951
   366
                            PropModeReplace,
slouken@1951
   367
                            (unsigned char *) &KWMHints,
slouken@1951
   368
                            sizeof(KWMHints) / sizeof(long));
slouken@1951
   369
            set = SDL_TRUE;
slouken@1951
   370
        }
slouken@1951
   371
        /* Now try to set GNOME hints */
slouken@1951
   372
        WM_HINTS = XInternAtom(data->display, "_WIN_HINTS", True);
slouken@1951
   373
        if (WM_HINTS != None) {
slouken@1951
   374
            long GNOMEHints = 0;
slouken@1951
   375
slouken@1951
   376
            XChangeProperty(data->display, w,
slouken@1951
   377
                            WM_HINTS, WM_HINTS, 32,
slouken@1951
   378
                            PropModeReplace,
slouken@1951
   379
                            (unsigned char *) &GNOMEHints,
slouken@1951
   380
                            sizeof(GNOMEHints) / sizeof(long));
slouken@1951
   381
            set = SDL_TRUE;
slouken@1951
   382
        }
slouken@1951
   383
        /* Finally set the transient hints if necessary */
slouken@1951
   384
        if (!set) {
slouken@1951
   385
            XSetTransientForHint(data->display, w,
slouken@1951
   386
                                 RootWindow(data->display,
slouken@1951
   387
                                            displaydata->screen));
slouken@1951
   388
        }
slouken@1951
   389
    } else {
slouken@1951
   390
        SDL_bool set;
slouken@1951
   391
        Atom WM_HINTS;
slouken@1951
   392
slouken@1951
   393
        /* We haven't modified the window manager hints yet */
slouken@1951
   394
        set = SDL_FALSE;
slouken@1951
   395
slouken@1951
   396
        /* First try to unset MWM hints */
slouken@1951
   397
        WM_HINTS = XInternAtom(data->display, "_MOTIF_WM_HINTS", True);
slouken@1951
   398
        if (WM_HINTS != None) {
slouken@1951
   399
            XDeleteProperty(data->display, w, WM_HINTS);
slouken@1951
   400
            set = SDL_TRUE;
slouken@1951
   401
        }
slouken@1951
   402
        /* Now try to unset KWM hints */
slouken@1951
   403
        WM_HINTS = XInternAtom(data->display, "KWM_WIN_DECORATION", True);
slouken@1951
   404
        if (WM_HINTS != None) {
slouken@1951
   405
            XDeleteProperty(data->display, w, WM_HINTS);
slouken@1951
   406
            set = SDL_TRUE;
slouken@1951
   407
        }
slouken@1951
   408
        /* Now try to unset GNOME hints */
slouken@1951
   409
        WM_HINTS = XInternAtom(data->display, "_WIN_HINTS", True);
slouken@1951
   410
        if (WM_HINTS != None) {
slouken@1951
   411
            XDeleteProperty(data->display, w, WM_HINTS);
slouken@1951
   412
            set = SDL_TRUE;
slouken@1951
   413
        }
slouken@1951
   414
        /* Finally unset the transient hints if necessary */
slouken@1951
   415
        if (!set) {
slouken@1951
   416
            /* NOTE: Does this work? */
slouken@1951
   417
            XSetTransientForHint(data->display, w, None);
slouken@1951
   418
        }
slouken@1951
   419
    }
slouken@1951
   420
slouken@1951
   421
    /* Tell KDE to keep fullscreen windows on top */
slouken@1951
   422
    if (window->flags & SDL_WINDOW_FULLSCREEN) {
slouken@1951
   423
        XEvent ev;
slouken@1951
   424
        long mask;
slouken@1951
   425
slouken@1951
   426
        SDL_zero(ev);
slouken@1951
   427
        ev.xclient.type = ClientMessage;
slouken@1951
   428
        ev.xclient.window = RootWindow(data->display, displaydata->screen);
slouken@1951
   429
        ev.xclient.message_type =
slouken@1951
   430
            XInternAtom(data->display, "KWM_KEEP_ON_TOP", False);
slouken@1951
   431
        ev.xclient.format = 32;
slouken@1951
   432
        ev.xclient.data.l[0] = w;
slouken@1951
   433
        ev.xclient.data.l[1] = CurrentTime;
slouken@1951
   434
        XSendEvent(data->display,
slouken@1951
   435
                   RootWindow(data->display, displaydata->screen), False,
slouken@1951
   436
                   SubstructureRedirectMask, &ev);
slouken@1951
   437
    }
slouken@1951
   438
slouken@1951
   439
    /* Set the input hints so we get keyboard input */
slouken@1951
   440
    wmhints = XAllocWMHints();
slouken@1951
   441
    if (wmhints) {
slouken@1951
   442
        wmhints->input = True;
slouken@1956
   443
        wmhints->flags = InputHint;
slouken@1951
   444
        XSetWMHints(data->display, w, wmhints);
slouken@1951
   445
        XFree(wmhints);
slouken@1951
   446
    }
slouken@1951
   447
slouken@1951
   448
    XSelectInput(data->display, w,
slouken@1951
   449
                 (FocusChangeMask | EnterWindowMask | LeaveWindowMask |
slouken@1951
   450
                  ExposureMask | ButtonPressMask | ButtonReleaseMask |
slouken@1951
   451
                  PointerMotionMask | KeyPressMask | KeyReleaseMask |
slouken@1951
   452
                  PropertyChangeMask | StructureNotifyMask |
slouken@1951
   453
                  KeymapStateMask));
slouken@1951
   454
slouken@1951
   455
    /* Set the class hints so we can get an icon (AfterStep) */
slouken@1951
   456
    classhints = XAllocClassHint();
slouken@1951
   457
    if (classhints != NULL) {
slouken@1951
   458
        classhints->res_name = data->classname;
slouken@1951
   459
        classhints->res_class = data->classname;
slouken@1951
   460
        XSetClassHint(data->display, w, classhints);
slouken@1951
   461
        XFree(classhints);
slouken@1951
   462
    }
slouken@1951
   463
slouken@1951
   464
    /* Allow the window to be deleted by the window manager */
slouken@1951
   465
    XSetWMProtocols(data->display, w, &data->WM_DELETE_WINDOW, 1);
slouken@1951
   466
slouken@1951
   467
    if (SetupWindowData(_this, window, w, SDL_TRUE) < 0) {
slouken@1952
   468
#ifdef SDL_VIDEO_OPENGL_GLX
slouken@1952
   469
        if (window->flags & SDL_WINDOW_OPENGL) {
slouken@1952
   470
            X11_GL_Shutdown(_this);
slouken@1952
   471
        }
slouken@1952
   472
#endif
slouken@1951
   473
        XDestroyWindow(data->display, w);
slouken@1951
   474
        return -1;
slouken@1951
   475
    }
slouken@1951
   476
    return 0;
slouken@1951
   477
}
slouken@1951
   478
slouken@1951
   479
int
bob@2321
   480
X11_CreateWindowFrom(_THIS, SDL_Window *window, const void *data)
slouken@1951
   481
{
slouken@1951
   482
    Window w = (Window) data;
slouken@1951
   483
slouken@1951
   484
    /* FIXME: Query the title from the existing window */
slouken@1951
   485
slouken@1951
   486
    if (SetupWindowData(_this, window, w, SDL_FALSE) < 0) {
slouken@1951
   487
        return -1;
slouken@1951
   488
    }
slouken@1951
   489
    return 0;
slouken@1951
   490
}
slouken@1951
   491
slouken@1951
   492
void
slouken@1951
   493
X11_SetWindowTitle(_THIS, SDL_Window * window)
slouken@1951
   494
{
slouken@1951
   495
    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
slouken@1951
   496
    Display *display = data->videodata->display;
slouken@1951
   497
    XTextProperty titleprop, iconprop;
slouken@1951
   498
    Status status;
slouken@1951
   499
    const char *title = window->title;
slouken@1951
   500
    const char *icon = NULL;
slouken@1951
   501
slouken@1951
   502
#ifdef X_HAVE_UTF8_STRING
slouken@1951
   503
    Atom _NET_WM_NAME = 0;
slouken@1951
   504
    Atom _NET_WM_ICON_NAME = 0;
slouken@1951
   505
slouken@1951
   506
    /* Look up some useful Atoms */
slouken@1951
   507
    if (SDL_X11_HAVE_UTF8) {
slouken@1951
   508
        _NET_WM_NAME = XInternAtom(display, "_NET_WM_NAME", False);
slouken@1951
   509
        _NET_WM_ICON_NAME = XInternAtom(display, "_NET_WM_ICON_NAME", False);
slouken@1951
   510
    }
slouken@1951
   511
#endif
slouken@1951
   512
slouken@1951
   513
    if (title != NULL) {
slouken@2143
   514
        char *title_locale = SDL_iconv_utf8_locale(title);
slouken@2143
   515
        if (!title_locale) {
slouken@1951
   516
            SDL_OutOfMemory();
slouken@1951
   517
            return;
slouken@1951
   518
        }
slouken@2143
   519
        status = XStringListToTextProperty(&title_locale, 1, &titleprop);
slouken@2143
   520
        SDL_free(title_locale);
slouken@1951
   521
        if (status) {
slouken@1951
   522
            XSetTextProperty(display, data->window, &titleprop, XA_WM_NAME);
slouken@1951
   523
            XFree(titleprop.value);
slouken@1951
   524
        }
slouken@1951
   525
#ifdef X_HAVE_UTF8_STRING
slouken@1951
   526
        if (SDL_X11_HAVE_UTF8) {
slouken@1951
   527
            status =
slouken@1951
   528
                Xutf8TextListToTextProperty(display, (char **) &title, 1,
slouken@1951
   529
                                            XUTF8StringStyle, &titleprop);
slouken@1951
   530
            if (status == Success) {
slouken@1951
   531
                XSetTextProperty(display, data->window, &titleprop,
slouken@1951
   532
                                 _NET_WM_NAME);
slouken@1951
   533
                XFree(titleprop.value);
slouken@1951
   534
            }
slouken@1951
   535
        }
slouken@1951
   536
#endif
slouken@1951
   537
    }
slouken@1951
   538
    if (icon != NULL) {
slouken@2143
   539
        char *icon_locale = SDL_iconv_utf8_locale(icon);
slouken@2143
   540
        if (!icon_locale) {
slouken@1951
   541
            SDL_OutOfMemory();
slouken@1951
   542
            return;
slouken@1951
   543
        }
slouken@2143
   544
        status = XStringListToTextProperty(&icon_locale, 1, &iconprop);
slouken@2143
   545
        SDL_free(icon_locale);
slouken@1951
   546
        if (status) {
slouken@1951
   547
            XSetTextProperty(display, data->window, &iconprop,
slouken@1951
   548
                             XA_WM_ICON_NAME);
slouken@1951
   549
            XFree(iconprop.value);
slouken@1951
   550
        }
slouken@1951
   551
#ifdef X_HAVE_UTF8_STRING
slouken@1951
   552
        if (SDL_X11_HAVE_UTF8) {
slouken@1951
   553
            status =
slouken@1951
   554
                Xutf8TextListToTextProperty(display, (char **) &icon, 1,
slouken@1951
   555
                                            XUTF8StringStyle, &iconprop);
slouken@1951
   556
            if (status == Success) {
slouken@1951
   557
                XSetTextProperty(display, data->window, &iconprop,
slouken@1951
   558
                                 _NET_WM_ICON_NAME);
slouken@1951
   559
                XFree(iconprop.value);
slouken@1951
   560
            }
slouken@1951
   561
        }
slouken@1951
   562
#endif
slouken@1951
   563
    }
slouken@1951
   564
}
slouken@1951
   565
slouken@1951
   566
void
slouken@1951
   567
X11_SetWindowPosition(_THIS, SDL_Window * window)
slouken@1951
   568
{
slouken@1951
   569
    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
slouken@1951
   570
    SDL_DisplayData *displaydata =
slouken@1952
   571
        (SDL_DisplayData *) SDL_GetDisplayFromWindow(window)->driverdata;
slouken@1951
   572
    Display *display = data->videodata->display;
slouken@1951
   573
slouken@1956
   574
    XMoveWindow(display, data->window, window->x, window->y);
slouken@1951
   575
}
slouken@1951
   576
slouken@1951
   577
void
slouken@1951
   578
X11_SetWindowSize(_THIS, SDL_Window * window)
slouken@1951
   579
{
slouken@1951
   580
    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
slouken@1951
   581
    Display *display = data->videodata->display;
slouken@1951
   582
slouken@1951
   583
    XMoveWindow(display, data->window, window->w, window->h);
slouken@1951
   584
}
slouken@1951
   585
slouken@1951
   586
void
slouken@1951
   587
X11_ShowWindow(_THIS, SDL_Window * window)
slouken@1951
   588
{
slouken@1951
   589
    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
slouken@1951
   590
    Display *display = data->videodata->display;
slouken@1951
   591
slouken@1951
   592
    XMapRaised(display, data->window);
slouken@1951
   593
}
slouken@1951
   594
slouken@1951
   595
void
slouken@1951
   596
X11_HideWindow(_THIS, SDL_Window * window)
slouken@1951
   597
{
slouken@1951
   598
    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
slouken@1951
   599
    Display *display = data->videodata->display;
slouken@1951
   600
slouken@1951
   601
    XUnmapWindow(display, data->window);
slouken@1951
   602
}
slouken@1951
   603
slouken@1951
   604
void
slouken@1951
   605
X11_RaiseWindow(_THIS, SDL_Window * window)
slouken@1951
   606
{
slouken@1951
   607
    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
slouken@1951
   608
    Display *display = data->videodata->display;
slouken@1951
   609
slouken@1951
   610
    XRaiseWindow(display, data->window);
slouken@1951
   611
}
slouken@1951
   612
slouken@1951
   613
void
slouken@1951
   614
X11_MaximizeWindow(_THIS, SDL_Window * window)
slouken@1951
   615
{
slouken@1951
   616
    /* FIXME: is this even possible? */
slouken@1951
   617
}
slouken@1951
   618
slouken@1951
   619
void
slouken@1951
   620
X11_MinimizeWindow(_THIS, SDL_Window * window)
slouken@1951
   621
{
slouken@1951
   622
    X11_HideWindow(_this, window);
slouken@1951
   623
}
slouken@1951
   624
slouken@1951
   625
void
slouken@1951
   626
X11_RestoreWindow(_THIS, SDL_Window * window)
slouken@1951
   627
{
slouken@1951
   628
    X11_ShowWindow(_this, window);
slouken@1951
   629
}
slouken@1951
   630
slouken@1951
   631
void
slouken@1951
   632
X11_SetWindowGrab(_THIS, SDL_Window * window)
slouken@1951
   633
{
slouken@1951
   634
    /* FIXME */
slouken@1951
   635
}
slouken@1951
   636
slouken@1951
   637
void
slouken@1951
   638
X11_DestroyWindow(_THIS, SDL_Window * window)
slouken@1951
   639
{
slouken@1951
   640
    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
slouken@1951
   641
slouken@1951
   642
    if (data) {
slouken@1951
   643
        Display *display = data->videodata->display;
slouken@1952
   644
#ifdef SDL_VIDEO_OPENGL_GLX
slouken@1952
   645
        if (window->flags & SDL_WINDOW_OPENGL) {
slouken@1952
   646
            X11_GL_Shutdown(_this);
slouken@1952
   647
        }
slouken@1951
   648
#endif
slouken@1951
   649
#ifdef X_HAVE_UTF8_STRING
slouken@1951
   650
        if (data->ic) {
slouken@1951
   651
            XDestroyIC(data->ic);
slouken@1951
   652
        }
slouken@1951
   653
#endif
slouken@1951
   654
        if (data->created) {
slouken@1951
   655
            XDestroyWindow(display, data->window);
slouken@1951
   656
        }
slouken@1951
   657
        SDL_free(data);
slouken@1951
   658
    }
slouken@1951
   659
}
slouken@1951
   660
slouken@1951
   661
SDL_bool
slouken@1951
   662
X11_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
slouken@1951
   663
{
slouken@1951
   664
    if (info->version.major <= SDL_MAJOR_VERSION) {
slouken@1951
   665
        /* FIXME! */
slouken@1951
   666
        return SDL_TRUE;
slouken@1951
   667
    } else {
slouken@1951
   668
        SDL_SetError("Application not compiled with SDL %d.%d\n",
slouken@1951
   669
                     SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
slouken@1951
   670
        return SDL_FALSE;
slouken@1951
   671
    }
slouken@1951
   672
}
slouken@1951
   673
slouken@1951
   674
/* vi: set ts=4 sw=4 expandtab: */