src/video/x11/SDL_x11window.c
author Sunny Sachanandani <sunnysachanandani@gmail.com>
Fri, 09 Jul 2010 21:36:41 +0530
changeset 4590 1ad70fb49fcb
parent 3697 f7b03b6838cb
child 4591 1e998db9b597
permissions -rw-r--r--
Fix so many things that there is little place in this column to list them all but the result is that blending modes just work now for drawing primitives.

Fixes involved:
1. Fix handling of alpha channel when SDL_BLENDMODE_NONE is set.
2. Make xrendercolor use floating-point values for color channels and then convert to 16 bit ints.
3. Fix handling of visuals in SDL_x11modes.c so that a 32 bit ARGB visual is used.
4. Fix the background pixel value in SDL_x11window.c so that the window background has an alpha value of 0xFF and not 0.
slouken@1951
     1
/*
slouken@1951
     2
    SDL - Simple DirectMedia Layer
slouken@3697
     3
    Copyright (C) 1997-2010 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_sysvideo.h"
slouken@1951
    25
#include "../../events/SDL_keyboard_c.h"
slouken@2940
    26
#include "../../events/SDL_mouse_c.h"
slouken@1951
    27
slouken@1951
    28
#include "SDL_x11video.h"
slouken@2940
    29
#include "SDL_x11mouse.h"
bob@3009
    30
#include "SDL_x11gamma.h"
bob@2185
    31
#include "../Xext/extensions/StdCmap.h"
slouken@1951
    32
slouken@3161
    33
#ifdef SDL_VIDEO_DRIVER_PANDORA
slouken@3161
    34
#include "SDL_x11opengles.h"
slouken@3161
    35
#endif
slouken@3161
    36
slouken@3241
    37
#include "SDL_syswm.h"
slouken@3241
    38
slouken@3077
    39
#define _NET_WM_STATE_REMOVE    0l
slouken@3077
    40
#define _NET_WM_STATE_ADD       1l
slouken@3077
    41
#define _NET_WM_STATE_TOGGLE    2l
slouken@3077
    42
slouken@2931
    43
static void
slouken@2931
    44
X11_GetDisplaySize(_THIS, SDL_Window * window, int *w, int *h)
slouken@2931
    45
{
slouken@2931
    46
    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
slouken@2931
    47
    SDL_DisplayData *displaydata =
slouken@3685
    48
        (SDL_DisplayData *) window->display->driverdata;
slouken@2931
    49
    XWindowAttributes attr;
slouken@2931
    50
slouken@2931
    51
    XGetWindowAttributes(data->display, RootWindow(data->display,
slouken@2931
    52
                                                   displaydata->screen),
slouken@2931
    53
                         &attr);
slouken@2931
    54
    if (w) {
slouken@2931
    55
        *w = attr.width;
slouken@2931
    56
    }
slouken@2931
    57
    if (h) {
slouken@2931
    58
        *h = attr.height;
slouken@2931
    59
    }
slouken@2931
    60
}
slouken@2931
    61
slouken@1951
    62
static int
slouken@1951
    63
SetupWindowData(_THIS, SDL_Window * window, Window w, BOOL created)
slouken@1951
    64
{
slouken@1951
    65
    SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
slouken@1951
    66
    SDL_WindowData *data;
slouken@1951
    67
    int numwindows = videodata->numwindows;
bob@2324
    68
    int windowlistlength = videodata->windowlistlength;
slouken@1951
    69
    SDL_WindowData **windowlist = videodata->windowlist;
bob@2323
    70
    int index;
slouken@1951
    71
slouken@1951
    72
    /* Allocate the window data */
bob@2323
    73
    data = (SDL_WindowData *) SDL_calloc(1, sizeof(*data));
slouken@1951
    74
    if (!data) {
slouken@1951
    75
        SDL_OutOfMemory();
slouken@1951
    76
        return -1;
slouken@1951
    77
    }
slouken@3685
    78
    data->window = window;
slouken@3685
    79
    data->xwindow = w;
slouken@1951
    80
#ifdef X_HAVE_UTF8_STRING
slouken@1951
    81
    if (SDL_X11_HAVE_UTF8) {
slouken@1951
    82
        data->ic =
slouken@1951
    83
            pXCreateIC(videodata->im, XNClientWindow, w, XNFocusWindow, w,
slouken@1951
    84
                       XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
slouken@1951
    85
                       XNResourceName, videodata->classname, XNResourceClass,
slouken@1951
    86
                       videodata->classname, NULL);
slouken@1951
    87
    }
slouken@1951
    88
#endif
slouken@1951
    89
    data->created = created;
slouken@1951
    90
    data->videodata = videodata;
slouken@1951
    91
bob@2323
    92
    /* Associate the data with the window */
bob@2324
    93
bob@2324
    94
    if (numwindows < windowlistlength) {
bob@2324
    95
        windowlist[numwindows] = data;
bob@2324
    96
        videodata->numwindows++;
bob@2324
    97
    } else {
bob@2324
    98
        windowlist =
bob@2324
    99
            (SDL_WindowData **) SDL_realloc(windowlist,
bob@2324
   100
                                            (numwindows +
bob@2324
   101
                                             1) * sizeof(*windowlist));
bob@2324
   102
        if (!windowlist) {
bob@2324
   103
            SDL_OutOfMemory();
bob@2324
   104
            SDL_free(data);
bob@2324
   105
            return -1;
bob@2323
   106
        }
bob@2324
   107
        windowlist[numwindows] = data;
bob@2324
   108
        videodata->numwindows++;
bob@2324
   109
        videodata->windowlistlength++;
bob@2324
   110
        videodata->windowlist = windowlist;
bob@2323
   111
    }
bob@2323
   112
slouken@1951
   113
    /* Fill in the SDL window with the window data */
slouken@1951
   114
    {
slouken@1951
   115
        XWindowAttributes attrib;
slouken@1951
   116
slouken@1951
   117
        XGetWindowAttributes(data->videodata->display, w, &attrib);
slouken@1951
   118
        window->x = attrib.x;
slouken@1951
   119
        window->y = attrib.y;
slouken@1951
   120
        window->w = attrib.width;
slouken@1951
   121
        window->h = attrib.height;
slouken@1951
   122
        if (attrib.map_state != IsUnmapped) {
slouken@1951
   123
            window->flags |= SDL_WINDOW_SHOWN;
slouken@1951
   124
        } else {
slouken@1951
   125
            window->flags &= ~SDL_WINDOW_SHOWN;
slouken@1951
   126
        }
slouken@1951
   127
    }
slouken@3077
   128
slouken@3077
   129
    {
slouken@3078
   130
        Atom _NET_WM_STATE =
slouken@3078
   131
            XInternAtom(data->videodata->display, "_NET_WM_STATE", False);
slouken@3078
   132
        Atom _NET_WM_STATE_MAXIMIZED_VERT =
slouken@3078
   133
            XInternAtom(data->videodata->display,
slouken@3078
   134
                        "_NET_WM_STATE_MAXIMIZED_VERT", False);
slouken@3078
   135
        Atom _NET_WM_STATE_MAXIMIZED_HORZ =
slouken@3078
   136
            XInternAtom(data->videodata->display,
slouken@3078
   137
                        "_NET_WM_STATE_MAXIMIZED_HORZ", False);
slouken@3077
   138
        Atom actualType;
slouken@3077
   139
        int actualFormat;
slouken@3077
   140
        unsigned long i, numItems, bytesAfter;
slouken@3077
   141
        unsigned char *propertyValue = NULL;
slouken@3077
   142
        long maxLength = 1024;
slouken@3077
   143
slouken@3077
   144
        if (XGetWindowProperty(data->videodata->display, w, _NET_WM_STATE,
slouken@3078
   145
                               0l, maxLength, False, XA_ATOM, &actualType,
slouken@3078
   146
                               &actualFormat, &numItems, &bytesAfter,
slouken@3078
   147
                               &propertyValue) == Success) {
slouken@3078
   148
            Atom *atoms = (Atom *) propertyValue;
slouken@3077
   149
            int maximized = 0;
slouken@3077
   150
slouken@3077
   151
            for (i = 0; i < numItems; ++i) {
slouken@3077
   152
                if (atoms[i] == _NET_WM_STATE_MAXIMIZED_VERT) {
slouken@3077
   153
                    maximized |= 1;
slouken@3077
   154
                } else if (atoms[i] == _NET_WM_STATE_MAXIMIZED_HORZ) {
slouken@3077
   155
                    maximized |= 2;
slouken@3077
   156
                }
slouken@3077
   157
                /* Might also want to check the following properties:
slouken@3077
   158
                   _NET_WM_STATE_ABOVE, _NET_WM_STATE_FULLSCREEN
slouken@3078
   159
                 */
slouken@3077
   160
            }
slouken@3077
   161
            if (maximized == 3) {
slouken@3077
   162
                window->flags |= SDL_WINDOW_MAXIMIZED;
slouken@3077
   163
            }
slouken@3077
   164
            XFree(propertyValue);
slouken@3077
   165
        }
slouken@3077
   166
    }
slouken@3077
   167
slouken@1951
   168
    /* FIXME: How can I tell?
slouken@1951
   169
       {
slouken@1951
   170
       DWORD style = GetWindowLong(hwnd, GWL_STYLE);
slouken@1951
   171
       if (style & WS_VISIBLE) {
slouken@1951
   172
       if (style & (WS_BORDER | WS_THICKFRAME)) {
slouken@1951
   173
       window->flags &= ~SDL_WINDOW_BORDERLESS;
slouken@1951
   174
       } else {
slouken@1951
   175
       window->flags |= SDL_WINDOW_BORDERLESS;
slouken@1951
   176
       }
slouken@1951
   177
       if (style & WS_THICKFRAME) {
slouken@1951
   178
       window->flags |= SDL_WINDOW_RESIZABLE;
slouken@1951
   179
       } else {
slouken@1951
   180
       window->flags &= ~SDL_WINDOW_RESIZABLE;
slouken@1951
   181
       }
slouken@1951
   182
       if (style & WS_MAXIMIZE) {
slouken@1951
   183
       window->flags |= SDL_WINDOW_MAXIMIZED;
slouken@1951
   184
       } else {
slouken@1951
   185
       window->flags &= ~SDL_WINDOW_MAXIMIZED;
slouken@1951
   186
       }
slouken@1951
   187
       if (style & WS_MINIMIZE) {
slouken@1951
   188
       window->flags |= SDL_WINDOW_MINIMIZED;
slouken@1951
   189
       } else {
slouken@1951
   190
       window->flags &= ~SDL_WINDOW_MINIMIZED;
slouken@1951
   191
       }
slouken@1951
   192
       }
slouken@1951
   193
       if (GetFocus() == hwnd) {
slouken@1951
   194
       int index = data->videodata->keyboard;
slouken@1951
   195
       window->flags |= SDL_WINDOW_INPUT_FOCUS;
slouken@3685
   196
       SDL_SetKeyboardFocus(index, data->window);
slouken@1951
   197
slouken@1951
   198
       if (window->flags & SDL_WINDOW_INPUT_GRABBED) {
slouken@1951
   199
       RECT rect;
slouken@1951
   200
       GetClientRect(hwnd, &rect);
slouken@1951
   201
       ClientToScreen(hwnd, (LPPOINT) & rect);
slouken@1951
   202
       ClientToScreen(hwnd, (LPPOINT) & rect + 1);
slouken@1951
   203
       ClipCursor(&rect);
slouken@1951
   204
       }
slouken@1951
   205
       }
slouken@1951
   206
     */
slouken@1951
   207
slouken@1951
   208
    /* All done! */
slouken@1951
   209
    window->driverdata = data;
slouken@1951
   210
    return 0;
slouken@1951
   211
}
slouken@1951
   212
slouken@1951
   213
int
slouken@1951
   214
X11_CreateWindow(_THIS, SDL_Window * window)
slouken@1951
   215
{
slouken@1951
   216
    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
slouken@1951
   217
    SDL_DisplayData *displaydata =
slouken@3685
   218
        (SDL_DisplayData *) window->display->driverdata;
slouken@1951
   219
    Visual *visual;
slouken@1951
   220
    int depth;
slouken@1951
   221
    XSetWindowAttributes xattr;
slouken@1951
   222
    int x, y;
slouken@1951
   223
    Window w;
slouken@1951
   224
    XSizeHints *sizehints;
slouken@1951
   225
    XWMHints *wmhints;
slouken@1951
   226
    XClassHint *classhints;
slouken@1951
   227
slouken@1951
   228
#if SDL_VIDEO_DRIVER_X11_XINERAMA
slouken@1951
   229
/* FIXME
slouken@1951
   230
    if ( use_xinerama ) {
slouken@1951
   231
        x = xinerama_info.x_org;
slouken@1951
   232
        y = xinerama_info.y_org;
slouken@1951
   233
    }
slouken@1951
   234
*/
slouken@1951
   235
#endif
slouken@1952
   236
#ifdef SDL_VIDEO_OPENGL_GLX
slouken@1951
   237
    if (window->flags & SDL_WINDOW_OPENGL) {
slouken@1952
   238
        XVisualInfo *vinfo;
slouken@1952
   239
slouken@1952
   240
        vinfo = X11_GL_GetVisual(_this, data->display, displaydata->screen);
slouken@1952
   241
        if (!vinfo) {
slouken@1952
   242
            return -1;
slouken@1952
   243
        }
slouken@1952
   244
        visual = vinfo->visual;
slouken@1952
   245
        depth = vinfo->depth;
slouken@1952
   246
        XFree(vinfo);
slouken@1952
   247
    } else
slouken@1952
   248
#endif
slouken@3161
   249
#ifdef SDL_VIDEO_DRIVER_PANDORA
slouken@3161
   250
    if (window->flags & SDL_WINDOW_OPENGL) {
slouken@3161
   251
        XVisualInfo *vinfo;
slouken@3161
   252
slouken@3161
   253
        vinfo = X11_GLES_GetVisual(_this, data->display, displaydata->screen);
slouken@3161
   254
        if (!vinfo) {
slouken@3161
   255
            return -1;
slouken@3161
   256
        }
slouken@3161
   257
        visual = vinfo->visual;
slouken@3161
   258
        depth = vinfo->depth;
slouken@3161
   259
        XFree(vinfo);
slouken@3161
   260
    } else
slouken@3161
   261
#endif
slouken@1952
   262
    {
slouken@1951
   263
        visual = displaydata->visual;
slouken@1951
   264
        depth = displaydata->depth;
slouken@1951
   265
    }
slouken@1951
   266
slouken@1951
   267
    if (window->flags & SDL_WINDOW_FULLSCREEN) {
slouken@1951
   268
        xattr.override_redirect = True;
slouken@1951
   269
    } else {
slouken@1951
   270
        xattr.override_redirect = False;
slouken@1951
   271
    }
slouken@1951
   272
    xattr.background_pixel = 0;
slouken@1951
   273
    xattr.border_pixel = 0;
bob@2214
   274
slouken@2945
   275
    if (visual->class == PseudoColor) {
bob@3044
   276
        printf("asking for PseudoColor\n");
bob@3044
   277
bob@3044
   278
        Status status;
bob@2214
   279
        XStandardColormap cmap;
bob@2214
   280
        XColor *colorcells;
bob@2214
   281
        Colormap colormap;
slouken@3052
   282
        Sint32 pix;
bob@3044
   283
        Sint32 ncolors;
bob@3044
   284
        Sint32 nbits;
bob@3044
   285
        Sint32 rmax, gmax, bmax;
slouken@3052
   286
        Sint32 rwidth, gwidth, bwidth;
bob@3044
   287
        Sint32 rmask, gmask, bmask;
bob@3044
   288
        Sint32 rshift, gshift, bshift;
slouken@3052
   289
        Sint32 r, g, b;
bob@2185
   290
bob@3044
   291
        /* Is the colormap we need already registered in SDL? */
bob@2214
   292
        if (colormap =
bob@3044
   293
            X11_LookupColormap(data->display,
bob@3044
   294
                               displaydata->screen, visual->visualid)) {
bob@2214
   295
            xattr.colormap = colormap;
bob@3044
   296
/*             printf("found existing colormap\n"); */
bob@2214
   297
        } else {
bob@3044
   298
            /* The colormap is not known to SDL so we will create it */
bob@3044
   299
            colormap = XCreateColormap(data->display,
bob@3044
   300
                                       RootWindow(data->display,
bob@3044
   301
                                                  displaydata->screen),
bob@3044
   302
                                       visual, AllocAll);
bob@3044
   303
/*             printf("colormap = %x\n", colormap); */
bob@3044
   304
bob@3044
   305
            /* If we can't create a colormap, then we must die */
bob@3044
   306
            if (!colormap) {
bob@3044
   307
                SDL_SetError
bob@3044
   308
                    ("Couldn't create window: Could not create writable colormap");
bob@3044
   309
                return -1;
bob@2185
   310
            }
bob@2213
   311
bob@3044
   312
            /* OK, we got a colormap, now fill it in as best as we can */
bob@2214
   313
bob@2214
   314
            colorcells = SDL_malloc(visual->map_entries * sizeof(XColor));
bob@2214
   315
            if (NULL == colorcells) {
bob@2214
   316
                SDL_SetError("out of memory in X11_CreateWindow");
bob@2185
   317
                return -1;
bob@2185
   318
            }
bob@3044
   319
bob@2214
   320
            ncolors = visual->map_entries;
slouken@3052
   321
            nbits = visual->bits_per_rgb;
bob@2214
   322
bob@3044
   323
/* 	    printf("ncolors = %d nbits = %d\n", ncolors, nbits); */
bob@3044
   324
slouken@3052
   325
            /* what if ncolors != (1 << nbits)? That can happen on a
slouken@3052
   326
               true PseudoColor display.  I'm assuming that we will
slouken@3052
   327
               always have ncolors == (1 << nbits) */
bob@3044
   328
slouken@3052
   329
            /* I'm making a lot of assumptions here. */
bob@3044
   330
slouken@3052
   331
            /* Compute the width of each field. If there is one extra
slouken@3052
   332
               bit, give it to green. If there are two extra bits give
slouken@3052
   333
               them to red and greed.  We can get extra bits when the
slouken@3052
   334
               number of bits per pixel is not a multiple of 3. For
slouken@3052
   335
               example when we have 16 bits per pixel and need a 5/6/5
slouken@3052
   336
               layout for the RGB fields */
slouken@3052
   337
slouken@3052
   338
            rwidth = (nbits / 3) + (((nbits % 3) == 2) ? 1 : 0);
slouken@3052
   339
            gwidth = (nbits / 3) + (((nbits % 3) >= 1) ? 1 : 0);
slouken@3052
   340
            bwidth = (nbits / 3);
bob@3044
   341
bob@3044
   342
            rshift = gwidth + bwidth;
bob@3044
   343
            gshift = bwidth;
bob@3044
   344
            bshift = 0;
bob@3044
   345
bob@3044
   346
            rmax = 1 << rwidth;
bob@3044
   347
            gmax = 1 << gwidth;
bob@3044
   348
            bmax = 1 << bwidth;
bob@3044
   349
bob@3044
   350
            rmask = rmax - 1;
bob@3044
   351
            gmask = gmax - 1;
bob@3044
   352
            bmask = bmax - 1;
bob@3044
   353
bob@3044
   354
/*             printf("red   mask = %4x shift = %4d width = %d\n", rmask, rshift, rwidth); */
bob@3044
   355
/*             printf("green mask = %4x shift = %4d width = %d\n", gmask, gshift, gwidth); */
bob@3044
   356
/*             printf("blue  mask = %4x shift = %4d width = %d\n", bmask, bshift, bwidth); */
bob@2214
   357
bob@2214
   358
            /* build the color table pixel values */
slouken@3052
   359
            pix = 0;
slouken@3052
   360
            for (r = 0; r < rmax; r++) {
slouken@3052
   361
                for (g = 0; g < gmax; g++) {
slouken@3052
   362
                    for (b = 0; b < bmax; b++) {
slouken@3052
   363
                        colorcells[pix].pixel =
slouken@3052
   364
                            (r << rshift) | (g << gshift) | (b << bshift);
slouken@3052
   365
                        colorcells[pix].red = (0xffff * r) / rmask;
slouken@3052
   366
                        colorcells[pix].green = (0xffff * g) / gmask;
slouken@3052
   367
                        colorcells[pix].blue = (0xffff * b) / bmask;
bob@3044
   368
/* 		  printf("%4x:%4x [%4x %4x %4x]\n",  */
bob@3044
   369
/* 			 pix,  */
bob@3044
   370
/* 			 colorcells[pix].pixel, */
bob@3044
   371
/* 			 colorcells[pix].red, */
bob@3044
   372
/* 			 colorcells[pix].green, */
bob@3044
   373
/* 			 colorcells[pix].blue); */
slouken@3052
   374
                        pix++;
slouken@3052
   375
                    }
slouken@3052
   376
                }
slouken@3052
   377
            }
bob@2214
   378
bob@3044
   379
/*             status = */
bob@3044
   380
/*                 XStoreColors(data->display, colormap, colorcells, ncolors); */
bob@2214
   381
bob@2214
   382
            xattr.colormap = colormap;
bob@3044
   383
            X11_TrackColormap(data->display, displaydata->screen,
bob@3044
   384
                              colormap, visual, NULL);
bob@3044
   385
bob@3009
   386
            SDL_free(colorcells);
bob@2185
   387
        }
slouken@2945
   388
    } else if (visual->class == DirectColor) {
bob@3009
   389
        Status status;
bob@3009
   390
        XStandardColormap cmap;
bob@3009
   391
        XColor *colorcells;
bob@3009
   392
        Colormap colormap;
bob@3009
   393
        int i;
bob@3009
   394
        int ncolors;
bob@3009
   395
        int rmax, gmax, bmax;
bob@3009
   396
        int rmask, gmask, bmask;
bob@3009
   397
        int rshift, gshift, bshift;
bob@3009
   398
bob@3009
   399
        /* Is the colormap we need already registered in SDL? */
bob@3009
   400
        if (colormap =
bob@3009
   401
            X11_LookupColormap(data->display,
bob@3009
   402
                               displaydata->screen, visual->visualid)) {
bob@3009
   403
            xattr.colormap = colormap;
bob@3009
   404
/*             printf("found existing colormap\n"); */
bob@3009
   405
        } else {
bob@3009
   406
            /* The colormap is not known to SDL so we will create it */
bob@3009
   407
            colormap = XCreateColormap(data->display,
bob@3009
   408
                                       RootWindow(data->display,
bob@3009
   409
                                                  displaydata->screen),
bob@3009
   410
                                       visual, AllocAll);
bob@3009
   411
/*             printf("colormap = %x\n", colormap); */
bob@3009
   412
bob@3009
   413
            /* If we can't create a colormap, then we must die */
bob@3009
   414
            if (!colormap) {
bob@3009
   415
                SDL_SetError
bob@3044
   416
                    ("Couldn't create window: Could not create writable colormap");
bob@3009
   417
                return -1;
bob@3009
   418
            }
bob@3009
   419
bob@3009
   420
            /* OK, we got a colormap, now fill it in as best as we can */
bob@3009
   421
bob@3009
   422
            colorcells = SDL_malloc(visual->map_entries * sizeof(XColor));
bob@3009
   423
            if (NULL == colorcells) {
bob@3009
   424
                SDL_SetError("out of memory in X11_CreateWindow");
bob@3009
   425
                return -1;
bob@3009
   426
            }
bob@3009
   427
            ncolors = visual->map_entries;
bob@3009
   428
            rmax = 0xffff;
bob@3009
   429
            gmax = 0xffff;
bob@3009
   430
            bmax = 0xffff;
bob@3009
   431
bob@3009
   432
            rshift = 0;
bob@3009
   433
            rmask = visual->red_mask;
bob@3009
   434
            while (0 == (rmask & 1)) {
bob@3009
   435
                rshift++;
bob@3009
   436
                rmask >>= 1;
bob@3009
   437
            }
bob@3009
   438
bob@3009
   439
/*             printf("rmask = %4x rshift = %4d\n", rmask, rshift); */
bob@3009
   440
bob@3009
   441
            gshift = 0;
bob@3009
   442
            gmask = visual->green_mask;
bob@3009
   443
            while (0 == (gmask & 1)) {
bob@3009
   444
                gshift++;
bob@3009
   445
                gmask >>= 1;
bob@3009
   446
            }
bob@3009
   447
bob@3009
   448
/*             printf("gmask = %4x gshift = %4d\n", gmask, gshift); */
bob@3009
   449
bob@3009
   450
            bshift = 0;
bob@3009
   451
            bmask = visual->blue_mask;
bob@3009
   452
            while (0 == (bmask & 1)) {
bob@3009
   453
                bshift++;
bob@3009
   454
                bmask >>= 1;
bob@3009
   455
            }
bob@3009
   456
bob@3009
   457
/*             printf("bmask = %4x bshift = %4d\n", bmask, bshift); */
bob@3009
   458
bob@3009
   459
            /* build the color table pixel values */
bob@3009
   460
            for (i = 0; i < ncolors; i++) {
bob@3009
   461
                Uint32 red = (rmax * i) / (ncolors - 1);
bob@3009
   462
                Uint32 green = (gmax * i) / (ncolors - 1);
bob@3009
   463
                Uint32 blue = (bmax * i) / (ncolors - 1);
bob@3009
   464
bob@3009
   465
                Uint32 rbits = (rmask * i) / (ncolors - 1);
bob@3009
   466
                Uint32 gbits = (gmask * i) / (ncolors - 1);
bob@3009
   467
                Uint32 bbits = (bmask * i) / (ncolors - 1);
bob@3009
   468
bob@3009
   469
                Uint32 pix =
bob@3009
   470
                    (rbits << rshift) | (gbits << gshift) | (bbits << bshift);
bob@3009
   471
bob@3009
   472
                colorcells[i].pixel = pix;
bob@3009
   473
bob@3009
   474
                colorcells[i].red = red;
bob@3009
   475
                colorcells[i].green = green;
bob@3009
   476
                colorcells[i].blue = blue;
bob@3009
   477
bob@3009
   478
                colorcells[i].flags = DoRed | DoGreen | DoBlue;
bob@3009
   479
/* 		printf("%2d:%4x [%4x %4x %4x]\n", i, pix, red, green, blue); */
bob@3009
   480
            }
bob@3009
   481
bob@3009
   482
            status =
bob@3009
   483
                XStoreColors(data->display, colormap, colorcells, ncolors);
bob@3009
   484
bob@3009
   485
            xattr.colormap = colormap;
bob@3009
   486
            X11_TrackColormap(data->display, displaydata->screen,
bob@3009
   487
                              colormap, visual, colorcells);
bob@3009
   488
bob@3009
   489
            SDL_free(colorcells);
bob@3009
   490
        }
slouken@1951
   491
    } else {
slouken@1951
   492
        xattr.colormap =
slouken@1951
   493
            XCreateColormap(data->display,
slouken@1951
   494
                            RootWindow(data->display, displaydata->screen),
slouken@1951
   495
                            visual, AllocNone);
slouken@1951
   496
    }
slouken@1951
   497
slouken@2876
   498
    if ((window->flags & SDL_WINDOW_FULLSCREEN)
slouken@2876
   499
        || window->x == SDL_WINDOWPOS_CENTERED) {
slouken@2931
   500
        X11_GetDisplaySize(_this, window, &x, NULL);
slouken@2931
   501
        x = (x - window->w) / 2;
slouken@1951
   502
    } else if (window->x == SDL_WINDOWPOS_UNDEFINED) {
slouken@1951
   503
        x = 0;
slouken@1951
   504
    } else {
slouken@1951
   505
        x = window->x;
slouken@1951
   506
    }
slouken@2876
   507
    if ((window->flags & SDL_WINDOW_FULLSCREEN)
slouken@2876
   508
        || window->y == SDL_WINDOWPOS_CENTERED) {
slouken@2931
   509
        X11_GetDisplaySize(_this, window, NULL, &y);
slouken@2931
   510
        y = (y - window->h) / 2;
slouken@1951
   511
    } else if (window->y == SDL_WINDOWPOS_UNDEFINED) {
slouken@1951
   512
        y = 0;
slouken@1951
   513
    } else {
slouken@1951
   514
        y = window->y;
slouken@1951
   515
    }
sunnysachanandani@4590
   516
#ifdef SDL_VIDEO_DRIVER_X11_XRENDER
sunnysachanandani@4590
   517
    xattr.background_pixel = 0xFF000000;
sunnysachanandani@4590
   518
#endif
slouken@1951
   519
slouken@1951
   520
    w = XCreateWindow(data->display,
slouken@1951
   521
                      RootWindow(data->display, displaydata->screen), x, y,
slouken@1951
   522
                      window->w, window->h, 0, depth, InputOutput, visual,
slouken@1951
   523
                      (CWOverrideRedirect | CWBackPixel | CWBorderPixel |
slouken@1951
   524
                       CWColormap), &xattr);
slouken@1952
   525
    if (!w) {
slouken@1952
   526
        SDL_SetError("Couldn't create window");
slouken@1952
   527
        return -1;
slouken@1952
   528
    }
slouken@3161
   529
#if SDL_VIDEO_DRIVER_PANDORA
slouken@3161
   530
    /* Create the GLES window surface */
slouken@3161
   531
    _this->gles_data->egl_surface =
slouken@3161
   532
        _this->gles_data->eglCreateWindowSurface(_this->gles_data->
slouken@3161
   533
                                                 egl_display,
slouken@3161
   534
                                                 _this->gles_data->egl_config,
slouken@3161
   535
                                                 (NativeWindowType) w, NULL);
slouken@3161
   536
slouken@3161
   537
    if (_this->gles_data->egl_surface == EGL_NO_SURFACE) {
slouken@3161
   538
        SDL_SetError("Could not create GLES window surface");
slouken@3161
   539
        return -1;
slouken@3161
   540
    }
slouken@3161
   541
#endif
slouken@1951
   542
slouken@1951
   543
    sizehints = XAllocSizeHints();
slouken@1951
   544
    if (sizehints) {
slouken@3225
   545
        if (!(window->flags & SDL_WINDOW_RESIZABLE)
slouken@3225
   546
            || (window->flags & SDL_WINDOW_FULLSCREEN)) {
slouken@1951
   547
            sizehints->min_width = sizehints->max_width = window->w;
slouken@1951
   548
            sizehints->min_height = sizehints->max_height = window->h;
slouken@3225
   549
            sizehints->flags = PMaxSize | PMinSize;
slouken@1951
   550
        }
slouken@1951
   551
        if (!(window->flags & SDL_WINDOW_FULLSCREEN)
slouken@1951
   552
            && window->x != SDL_WINDOWPOS_UNDEFINED
slouken@1951
   553
            && window->y != SDL_WINDOWPOS_UNDEFINED) {
slouken@1951
   554
            sizehints->x = x;
slouken@1951
   555
            sizehints->y = y;
slouken@1951
   556
            sizehints->flags |= USPosition;
slouken@1951
   557
        }
slouken@1951
   558
        XSetWMNormalHints(data->display, w, sizehints);
slouken@1951
   559
        XFree(sizehints);
slouken@1951
   560
    }
slouken@1951
   561
slouken@2876
   562
    if (window->flags & (SDL_WINDOW_BORDERLESS | SDL_WINDOW_FULLSCREEN)) {
slouken@1951
   563
        SDL_bool set;
slouken@1951
   564
        Atom WM_HINTS;
slouken@1951
   565
slouken@1951
   566
        /* We haven't modified the window manager hints yet */
slouken@1951
   567
        set = SDL_FALSE;
slouken@1951
   568
slouken@1951
   569
        /* First try to set MWM hints */
slouken@1951
   570
        WM_HINTS = XInternAtom(data->display, "_MOTIF_WM_HINTS", True);
slouken@1951
   571
        if (WM_HINTS != None) {
slouken@1951
   572
            /* Hints used by Motif compliant window managers */
slouken@1951
   573
            struct
slouken@1951
   574
            {
slouken@1951
   575
                unsigned long flags;
slouken@1951
   576
                unsigned long functions;
slouken@1951
   577
                unsigned long decorations;
slouken@1951
   578
                long input_mode;
slouken@1951
   579
                unsigned long status;
slouken@1951
   580
            } MWMHints = {
slouken@1951
   581
            (1L << 1), 0, 0, 0, 0};
slouken@1951
   582
slouken@1951
   583
            XChangeProperty(data->display, w, WM_HINTS, WM_HINTS, 32,
slouken@1951
   584
                            PropModeReplace, (unsigned char *) &MWMHints,
slouken@1951
   585
                            sizeof(MWMHints) / sizeof(long));
slouken@1951
   586
            set = SDL_TRUE;
slouken@1951
   587
        }
slouken@1951
   588
        /* Now try to set KWM hints */
slouken@1951
   589
        WM_HINTS = XInternAtom(data->display, "KWM_WIN_DECORATION", True);
slouken@1951
   590
        if (WM_HINTS != None) {
slouken@1951
   591
            long KWMHints = 0;
slouken@1951
   592
slouken@1951
   593
            XChangeProperty(data->display, w,
slouken@1951
   594
                            WM_HINTS, WM_HINTS, 32,
slouken@1951
   595
                            PropModeReplace,
slouken@1951
   596
                            (unsigned char *) &KWMHints,
slouken@1951
   597
                            sizeof(KWMHints) / sizeof(long));
slouken@1951
   598
            set = SDL_TRUE;
slouken@1951
   599
        }
slouken@1951
   600
        /* Now try to set GNOME hints */
slouken@1951
   601
        WM_HINTS = XInternAtom(data->display, "_WIN_HINTS", True);
slouken@1951
   602
        if (WM_HINTS != None) {
slouken@1951
   603
            long GNOMEHints = 0;
slouken@1951
   604
slouken@1951
   605
            XChangeProperty(data->display, w,
slouken@1951
   606
                            WM_HINTS, WM_HINTS, 32,
slouken@1951
   607
                            PropModeReplace,
slouken@1951
   608
                            (unsigned char *) &GNOMEHints,
slouken@1951
   609
                            sizeof(GNOMEHints) / sizeof(long));
slouken@1951
   610
            set = SDL_TRUE;
slouken@1951
   611
        }
slouken@1951
   612
        /* Finally set the transient hints if necessary */
slouken@1951
   613
        if (!set) {
slouken@1951
   614
            XSetTransientForHint(data->display, w,
slouken@1951
   615
                                 RootWindow(data->display,
slouken@1951
   616
                                            displaydata->screen));
slouken@1951
   617
        }
slouken@1951
   618
    } else {
slouken@1951
   619
        SDL_bool set;
slouken@1951
   620
        Atom WM_HINTS;
slouken@1951
   621
slouken@1951
   622
        /* We haven't modified the window manager hints yet */
slouken@1951
   623
        set = SDL_FALSE;
slouken@1951
   624
slouken@1951
   625
        /* First try to unset MWM hints */
slouken@1951
   626
        WM_HINTS = XInternAtom(data->display, "_MOTIF_WM_HINTS", True);
slouken@1951
   627
        if (WM_HINTS != None) {
slouken@1951
   628
            XDeleteProperty(data->display, w, WM_HINTS);
slouken@1951
   629
            set = SDL_TRUE;
slouken@1951
   630
        }
slouken@1951
   631
        /* Now try to unset KWM hints */
slouken@1951
   632
        WM_HINTS = XInternAtom(data->display, "KWM_WIN_DECORATION", True);
slouken@1951
   633
        if (WM_HINTS != None) {
slouken@1951
   634
            XDeleteProperty(data->display, w, WM_HINTS);
slouken@1951
   635
            set = SDL_TRUE;
slouken@1951
   636
        }
slouken@1951
   637
        /* Now try to unset GNOME hints */
slouken@1951
   638
        WM_HINTS = XInternAtom(data->display, "_WIN_HINTS", True);
slouken@1951
   639
        if (WM_HINTS != None) {
slouken@1951
   640
            XDeleteProperty(data->display, w, WM_HINTS);
slouken@1951
   641
            set = SDL_TRUE;
slouken@1951
   642
        }
slouken@1951
   643
        /* Finally unset the transient hints if necessary */
slouken@1951
   644
        if (!set) {
slouken@1951
   645
            /* NOTE: Does this work? */
slouken@1951
   646
            XSetTransientForHint(data->display, w, None);
slouken@1951
   647
        }
slouken@1951
   648
    }
slouken@1951
   649
slouken@1951
   650
    /* Tell KDE to keep fullscreen windows on top */
slouken@1951
   651
    if (window->flags & SDL_WINDOW_FULLSCREEN) {
slouken@1951
   652
        XEvent ev;
slouken@1951
   653
        long mask;
slouken@1951
   654
slouken@1951
   655
        SDL_zero(ev);
slouken@1951
   656
        ev.xclient.type = ClientMessage;
slouken@1951
   657
        ev.xclient.window = RootWindow(data->display, displaydata->screen);
slouken@1951
   658
        ev.xclient.message_type =
slouken@1951
   659
            XInternAtom(data->display, "KWM_KEEP_ON_TOP", False);
slouken@1951
   660
        ev.xclient.format = 32;
slouken@1951
   661
        ev.xclient.data.l[0] = w;
slouken@1951
   662
        ev.xclient.data.l[1] = CurrentTime;
slouken@1951
   663
        XSendEvent(data->display,
slouken@1951
   664
                   RootWindow(data->display, displaydata->screen), False,
slouken@1951
   665
                   SubstructureRedirectMask, &ev);
slouken@1951
   666
    }
slouken@1951
   667
slouken@1951
   668
    /* Set the input hints so we get keyboard input */
slouken@1951
   669
    wmhints = XAllocWMHints();
slouken@1951
   670
    if (wmhints) {
slouken@1951
   671
        wmhints->input = True;
slouken@1956
   672
        wmhints->flags = InputHint;
slouken@1951
   673
        XSetWMHints(data->display, w, wmhints);
slouken@1951
   674
        XFree(wmhints);
slouken@1951
   675
    }
slouken@1951
   676
slouken@1951
   677
    /* Set the class hints so we can get an icon (AfterStep) */
slouken@1951
   678
    classhints = XAllocClassHint();
slouken@1951
   679
    if (classhints != NULL) {
slouken@1951
   680
        classhints->res_name = data->classname;
slouken@1951
   681
        classhints->res_class = data->classname;
slouken@1951
   682
        XSetClassHint(data->display, w, classhints);
slouken@1951
   683
        XFree(classhints);
slouken@1951
   684
    }
slouken@1951
   685
slouken@1951
   686
    /* Allow the window to be deleted by the window manager */
slouken@1951
   687
    XSetWMProtocols(data->display, w, &data->WM_DELETE_WINDOW, 1);
slouken@1951
   688
slouken@1951
   689
    if (SetupWindowData(_this, window, w, SDL_TRUE) < 0) {
slouken@1951
   690
        XDestroyWindow(data->display, w);
slouken@1951
   691
        return -1;
slouken@1951
   692
    }
bob@2325
   693
#ifdef X_HAVE_UTF8_STRING
bob@2325
   694
    {
bob@2325
   695
        Uint32 fevent = 0;
bob@2325
   696
        pXGetICValues(((SDL_WindowData *) window->driverdata)->ic,
bob@2325
   697
                      XNFilterEvents, &fevent, NULL);
bob@2325
   698
        XSelectInput(data->display, w,
bob@2325
   699
                     (FocusChangeMask | EnterWindowMask | LeaveWindowMask |
bob@2325
   700
                      ExposureMask | ButtonPressMask | ButtonReleaseMask |
bob@2325
   701
                      PointerMotionMask | KeyPressMask | KeyReleaseMask |
bob@2325
   702
                      PropertyChangeMask | StructureNotifyMask |
bob@2325
   703
                      KeymapStateMask | fevent));
bob@2325
   704
    }
bob@2325
   705
#else
kazeuser@2718
   706
    {
kazeuser@2718
   707
        XSelectInput(data->display, w,
slouken@2725
   708
                     (FocusChangeMask | EnterWindowMask | LeaveWindowMask |
slouken@2725
   709
                      ExposureMask | ButtonPressMask | ButtonReleaseMask |
slouken@2725
   710
                      PointerMotionMask | KeyPressMask | KeyReleaseMask |
slouken@2725
   711
                      PropertyChangeMask | StructureNotifyMask |
slouken@2725
   712
                      KeymapStateMask));
kazeuser@2718
   713
    }
bob@2325
   714
#endif
bob@2325
   715
slouken@2940
   716
#if SDL_VIDEO_DRIVER_X11_XINPUT
slouken@2710
   717
    /* we're informing the display what extension events we want to receive from it */
slouken@2940
   718
    {
slouken@2940
   719
        int i, j, n = 0;
slouken@2940
   720
        XEventClass xevents[256];
slouken@2940
   721
slouken@2940
   722
        for (i = 0; i < SDL_GetNumMice(); ++i) {
slouken@2940
   723
            SDL_Mouse *mouse;
slouken@2940
   724
            X11_MouseData *data;
slouken@2940
   725
slouken@2940
   726
            mouse = SDL_GetMouse(i);
slouken@2942
   727
            data = (X11_MouseData *) mouse->driverdata;
slouken@2940
   728
            if (!data) {
slouken@2940
   729
                continue;
slouken@2940
   730
            }
slouken@2940
   731
slouken@2940
   732
            for (j = 0; j < data->num_xevents; ++j) {
slouken@2940
   733
                xevents[n++] = data->xevents[j];
slouken@2940
   734
            }
slouken@2940
   735
        }
slouken@2940
   736
        if (n > 0) {
slouken@2940
   737
            XSelectExtensionEvent(data->display, w, xevents, n);
slouken@2940
   738
        }
slouken@2940
   739
    }
slouken@2940
   740
#endif
slouken@2710
   741
slouken@1951
   742
    return 0;
slouken@1951
   743
}
slouken@1951
   744
slouken@1951
   745
int
bob@2324
   746
X11_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
slouken@1951
   747
{
slouken@1951
   748
    Window w = (Window) data;
slouken@1951
   749
slouken@1951
   750
    /* FIXME: Query the title from the existing window */
slouken@1951
   751
slouken@1951
   752
    if (SetupWindowData(_this, window, w, SDL_FALSE) < 0) {
slouken@1951
   753
        return -1;
slouken@1951
   754
    }
slouken@1951
   755
    return 0;
slouken@1951
   756
}
slouken@1951
   757
slouken@1951
   758
void
slouken@1951
   759
X11_SetWindowTitle(_THIS, SDL_Window * window)
slouken@1951
   760
{
slouken@1951
   761
    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
slouken@1951
   762
    Display *display = data->videodata->display;
slouken@1951
   763
    XTextProperty titleprop, iconprop;
slouken@1951
   764
    Status status;
slouken@1951
   765
    const char *title = window->title;
slouken@1951
   766
    const char *icon = NULL;
slouken@1951
   767
slouken@1951
   768
#ifdef X_HAVE_UTF8_STRING
slouken@1951
   769
    Atom _NET_WM_NAME = 0;
slouken@1951
   770
    Atom _NET_WM_ICON_NAME = 0;
slouken@1951
   771
slouken@1951
   772
    /* Look up some useful Atoms */
slouken@1951
   773
    if (SDL_X11_HAVE_UTF8) {
slouken@1951
   774
        _NET_WM_NAME = XInternAtom(display, "_NET_WM_NAME", False);
slouken@1951
   775
        _NET_WM_ICON_NAME = XInternAtom(display, "_NET_WM_ICON_NAME", False);
slouken@1951
   776
    }
slouken@1951
   777
#endif
slouken@1951
   778
slouken@1951
   779
    if (title != NULL) {
slouken@2143
   780
        char *title_locale = SDL_iconv_utf8_locale(title);
slouken@2143
   781
        if (!title_locale) {
slouken@1951
   782
            SDL_OutOfMemory();
slouken@1951
   783
            return;
slouken@1951
   784
        }
slouken@2143
   785
        status = XStringListToTextProperty(&title_locale, 1, &titleprop);
slouken@2143
   786
        SDL_free(title_locale);
slouken@1951
   787
        if (status) {
slouken@3685
   788
            XSetTextProperty(display, data->xwindow, &titleprop, XA_WM_NAME);
slouken@1951
   789
            XFree(titleprop.value);
slouken@1951
   790
        }
slouken@1951
   791
#ifdef X_HAVE_UTF8_STRING
slouken@1951
   792
        if (SDL_X11_HAVE_UTF8) {
slouken@1951
   793
            status =
slouken@1951
   794
                Xutf8TextListToTextProperty(display, (char **) &title, 1,
slouken@1951
   795
                                            XUTF8StringStyle, &titleprop);
slouken@1951
   796
            if (status == Success) {
slouken@3685
   797
                XSetTextProperty(display, data->xwindow, &titleprop,
slouken@1951
   798
                                 _NET_WM_NAME);
slouken@1951
   799
                XFree(titleprop.value);
slouken@1951
   800
            }
slouken@1951
   801
        }
slouken@1951
   802
#endif
slouken@1951
   803
    }
slouken@1951
   804
    if (icon != NULL) {
slouken@2143
   805
        char *icon_locale = SDL_iconv_utf8_locale(icon);
slouken@2143
   806
        if (!icon_locale) {
slouken@1951
   807
            SDL_OutOfMemory();
slouken@1951
   808
            return;
slouken@1951
   809
        }
slouken@2143
   810
        status = XStringListToTextProperty(&icon_locale, 1, &iconprop);
slouken@2143
   811
        SDL_free(icon_locale);
slouken@1951
   812
        if (status) {
slouken@3685
   813
            XSetTextProperty(display, data->xwindow, &iconprop,
slouken@1951
   814
                             XA_WM_ICON_NAME);
slouken@1951
   815
            XFree(iconprop.value);
slouken@1951
   816
        }
slouken@1951
   817
#ifdef X_HAVE_UTF8_STRING
slouken@1951
   818
        if (SDL_X11_HAVE_UTF8) {
slouken@1951
   819
            status =
slouken@1951
   820
                Xutf8TextListToTextProperty(display, (char **) &icon, 1,
slouken@1951
   821
                                            XUTF8StringStyle, &iconprop);
slouken@1951
   822
            if (status == Success) {
slouken@3685
   823
                XSetTextProperty(display, data->xwindow, &iconprop,
slouken@1951
   824
                                 _NET_WM_ICON_NAME);
slouken@1951
   825
                XFree(iconprop.value);
slouken@1951
   826
            }
slouken@1951
   827
        }
slouken@1951
   828
#endif
slouken@1951
   829
    }
slouken@1951
   830
}
slouken@1951
   831
slouken@1951
   832
void
slouken@2967
   833
X11_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
slouken@2967
   834
{
slouken@2967
   835
    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
slouken@2967
   836
    Display *display = data->videodata->display;
slouken@2967
   837
    Atom _NET_WM_ICON = XInternAtom(display, "_NET_WM_ICON", False);
slouken@2967
   838
slouken@2967
   839
    if (icon) {
slouken@2967
   840
        SDL_PixelFormat format;
slouken@2967
   841
        SDL_Surface *surface;
slouken@2967
   842
        int propsize;
slouken@2967
   843
        Uint32 *propdata;
slouken@2967
   844
slouken@2967
   845
        /* Convert the icon to ARGB for modern window managers */
slouken@2990
   846
        SDL_InitFormat(&format, 32, 0x00FF0000, 0x0000FF00, 0x000000FF,
slouken@2990
   847
                       0xFF000000);
slouken@2967
   848
        surface = SDL_ConvertSurface(icon, &format, 0);
slouken@2967
   849
        if (!surface) {
slouken@2967
   850
            return;
slouken@2967
   851
        }
slouken@2967
   852
slouken@2967
   853
        /* Set the _NET_WM_ICON property */
slouken@2990
   854
        propsize = 2 + (icon->w * icon->h);
slouken@2967
   855
        propdata = SDL_malloc(propsize * sizeof(Uint32));
slouken@2967
   856
        if (propdata) {
slouken@2967
   857
            propdata[0] = icon->w;
slouken@2967
   858
            propdata[1] = icon->h;
slouken@2990
   859
            SDL_memcpy(&propdata[2], surface->pixels,
slouken@2990
   860
                       surface->h * surface->pitch);
slouken@3685
   861
            XChangeProperty(display, data->xwindow, _NET_WM_ICON, XA_CARDINAL,
slouken@2990
   862
                            32, PropModeReplace, (unsigned char *) propdata,
slouken@2990
   863
                            propsize);
slouken@2967
   864
        }
slouken@2967
   865
        SDL_FreeSurface(surface);
slouken@2967
   866
    } else {
slouken@3685
   867
        XDeleteProperty(display, data->xwindow, _NET_WM_ICON);
slouken@2967
   868
    }
slouken@2967
   869
}
slouken@2967
   870
slouken@2967
   871
void
slouken@1951
   872
X11_SetWindowPosition(_THIS, SDL_Window * window)
slouken@1951
   873
{
slouken@1951
   874
    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
slouken@1951
   875
    SDL_DisplayData *displaydata =
slouken@3685
   876
        (SDL_DisplayData *) window->display->driverdata;
slouken@1951
   877
    Display *display = data->videodata->display;
slouken@2875
   878
    int x, y;
slouken@1951
   879
slouken@2876
   880
    if ((window->flags & SDL_WINDOW_FULLSCREEN)
slouken@2876
   881
        || window->x == SDL_WINDOWPOS_CENTERED) {
slouken@2931
   882
        X11_GetDisplaySize(_this, window, &x, NULL);
slouken@2931
   883
        x = (x - window->w) / 2;
slouken@2875
   884
    } else {
slouken@2875
   885
        x = window->x;
slouken@2875
   886
    }
slouken@2876
   887
    if ((window->flags & SDL_WINDOW_FULLSCREEN)
slouken@2876
   888
        || window->y == SDL_WINDOWPOS_CENTERED) {
slouken@2931
   889
        X11_GetDisplaySize(_this, window, NULL, &y);
slouken@2931
   890
        y = (y - window->h) / 2;
slouken@2875
   891
    } else {
slouken@2875
   892
        y = window->y;
slouken@2875
   893
    }
slouken@3685
   894
    XMoveWindow(display, data->xwindow, x, y);
slouken@1951
   895
}
slouken@1951
   896
slouken@1951
   897
void
slouken@1951
   898
X11_SetWindowSize(_THIS, SDL_Window * window)
slouken@1951
   899
{
slouken@1951
   900
    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
slouken@1951
   901
    Display *display = data->videodata->display;
slouken@1951
   902
slouken@3685
   903
    XResizeWindow(display, data->xwindow, window->w, window->h);
slouken@1951
   904
}
slouken@1951
   905
slouken@1951
   906
void
slouken@1951
   907
X11_ShowWindow(_THIS, SDL_Window * window)
slouken@1951
   908
{
slouken@1951
   909
    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
slouken@1951
   910
    Display *display = data->videodata->display;
slouken@1951
   911
slouken@3685
   912
    XMapRaised(display, data->xwindow);
slouken@1951
   913
}
slouken@1951
   914
slouken@1951
   915
void
slouken@1951
   916
X11_HideWindow(_THIS, SDL_Window * window)
slouken@1951
   917
{
slouken@1951
   918
    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
slouken@1951
   919
    Display *display = data->videodata->display;
slouken@1951
   920
slouken@3685
   921
    XUnmapWindow(display, data->xwindow);
slouken@1951
   922
}
slouken@1951
   923
slouken@1951
   924
void
slouken@1951
   925
X11_RaiseWindow(_THIS, SDL_Window * window)
slouken@1951
   926
{
slouken@1951
   927
    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
slouken@1951
   928
    Display *display = data->videodata->display;
slouken@1951
   929
slouken@3685
   930
    XRaiseWindow(display, data->xwindow);
slouken@1951
   931
}
slouken@1951
   932
slouken@3077
   933
static void
slouken@3077
   934
X11_SetWindowMaximized(_THIS, SDL_Window * window, SDL_bool maximized)
slouken@3077
   935
{
slouken@3077
   936
    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
slouken@3077
   937
    SDL_DisplayData *displaydata =
slouken@3685
   938
        (SDL_DisplayData *) window->display->driverdata;
slouken@3077
   939
    Display *display = data->videodata->display;
slouken@3077
   940
    Atom _NET_WM_STATE = XInternAtom(display, "_NET_WM_STATE", False);
slouken@3078
   941
    Atom _NET_WM_STATE_MAXIMIZED_VERT =
slouken@3078
   942
        XInternAtom(display, "_NET_WM_STATE_MAXIMIZED_VERT", False);
slouken@3078
   943
    Atom _NET_WM_STATE_MAXIMIZED_HORZ =
slouken@3078
   944
        XInternAtom(display, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
slouken@3077
   945
    XEvent e;
slouken@3077
   946
slouken@3077
   947
    e.xany.type = ClientMessage;
slouken@3685
   948
    e.xany.window = data->xwindow;
slouken@3077
   949
    e.xclient.message_type = _NET_WM_STATE;
slouken@3077
   950
    e.xclient.format = 32;
slouken@3078
   951
    e.xclient.data.l[0] =
slouken@3078
   952
        maximized ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
slouken@3077
   953
    e.xclient.data.l[1] = _NET_WM_STATE_MAXIMIZED_VERT;
slouken@3077
   954
    e.xclient.data.l[2] = _NET_WM_STATE_MAXIMIZED_HORZ;
slouken@3077
   955
    e.xclient.data.l[3] = 0l;
slouken@3077
   956
    e.xclient.data.l[4] = 0l;
slouken@3077
   957
slouken@3077
   958
    XSendEvent(display, RootWindow(display, displaydata->screen), 0,
slouken@3078
   959
               SubstructureNotifyMask | SubstructureRedirectMask, &e);
slouken@3077
   960
}
slouken@3077
   961
slouken@1951
   962
void
slouken@1951
   963
X11_MaximizeWindow(_THIS, SDL_Window * window)
slouken@1951
   964
{
slouken@3077
   965
    X11_SetWindowMaximized(_this, window, SDL_TRUE);
slouken@1951
   966
}
slouken@1951
   967
slouken@1951
   968
void
slouken@1951
   969
X11_MinimizeWindow(_THIS, SDL_Window * window)
slouken@1951
   970
{
slouken@1951
   971
    X11_HideWindow(_this, window);
slouken@1951
   972
}
slouken@1951
   973
slouken@1951
   974
void
slouken@1951
   975
X11_RestoreWindow(_THIS, SDL_Window * window)
slouken@1951
   976
{
slouken@3077
   977
    X11_SetWindowMaximized(_this, window, SDL_FALSE);
slouken@1951
   978
    X11_ShowWindow(_this, window);
slouken@1951
   979
}
slouken@1951
   980
slouken@1951
   981
void
slouken@1951
   982
X11_SetWindowGrab(_THIS, SDL_Window * window)
slouken@1951
   983
{
slouken@2875
   984
    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
slouken@2875
   985
    Display *display = data->videodata->display;
slouken@2875
   986
slouken@2876
   987
    if ((window->flags & (SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_FULLSCREEN))
slouken@2876
   988
        && (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
slouken@2875
   989
        /* Try to grab the mouse */
slouken@2876
   990
        for (;;) {
slouken@2876
   991
            int result =
slouken@3685
   992
                XGrabPointer(display, data->xwindow, True, 0, GrabModeAsync,
slouken@3685
   993
                             GrabModeAsync, data->xwindow, None, CurrentTime);
slouken@2876
   994
            if (result == GrabSuccess) {
slouken@2875
   995
                break;
slouken@2875
   996
            }
slouken@2875
   997
            SDL_Delay(100);
slouken@2875
   998
        }
slouken@2875
   999
slouken@2875
  1000
        /* Raise the window if we grab the mouse */
slouken@3685
  1001
        XRaiseWindow(display, data->xwindow);
slouken@2875
  1002
slouken@2875
  1003
        /* Now grab the keyboard */
slouken@3685
  1004
        XGrabKeyboard(display, data->xwindow, True, GrabModeAsync,
slouken@2876
  1005
                      GrabModeAsync, CurrentTime);
slouken@2875
  1006
    } else {
slouken@2875
  1007
        XUngrabPointer(display, CurrentTime);
slouken@2875
  1008
        XUngrabKeyboard(display, CurrentTime);
slouken@2875
  1009
    }
slouken@1951
  1010
}
slouken@1951
  1011
slouken@1951
  1012
void
slouken@1951
  1013
X11_DestroyWindow(_THIS, SDL_Window * window)
slouken@1951
  1014
{
slouken@1951
  1015
    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
bob@2323
  1016
    window->driverdata = NULL;
slouken@1951
  1017
slouken@1951
  1018
    if (data) {
bob@2323
  1019
        SDL_VideoData *videodata = (SDL_VideoData *) data->videodata;
bob@2323
  1020
        Display *display = videodata->display;
bob@2323
  1021
        int numwindows = videodata->numwindows;
bob@2323
  1022
        SDL_WindowData **windowlist = videodata->windowlist;
bob@2323
  1023
        int i;
bob@2323
  1024
bob@2323
  1025
        if (windowlist) {
bob@2324
  1026
            for (i = 0; i < numwindows; ++i) {
slouken@3685
  1027
                if (windowlist[i] && (windowlist[i]->window == window)) {
bob@2324
  1028
                    windowlist[i] = windowlist[numwindows - 1];
bob@2324
  1029
                    windowlist[numwindows - 1] = NULL;
bob@2324
  1030
                    videodata->numwindows--;
bob@2324
  1031
                    break;
bob@2324
  1032
                }
bob@2323
  1033
            }
bob@2323
  1034
        }
slouken@1951
  1035
#ifdef X_HAVE_UTF8_STRING
slouken@1951
  1036
        if (data->ic) {
slouken@1951
  1037
            XDestroyIC(data->ic);
slouken@1951
  1038
        }
slouken@1951
  1039
#endif
slouken@1951
  1040
        if (data->created) {
slouken@3685
  1041
            XDestroyWindow(display, data->xwindow);
slouken@1951
  1042
        }
slouken@1951
  1043
        SDL_free(data);
slouken@1951
  1044
    }
slouken@1951
  1045
}
slouken@1951
  1046
slouken@1951
  1047
SDL_bool
slouken@1951
  1048
X11_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
slouken@1951
  1049
{
slouken@1951
  1050
    if (info->version.major <= SDL_MAJOR_VERSION) {
slouken@1951
  1051
        /* FIXME! */
slouken@1951
  1052
        return SDL_TRUE;
slouken@1951
  1053
    } else {
slouken@1951
  1054
        SDL_SetError("Application not compiled with SDL %d.%d\n",
slouken@1951
  1055
                     SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
slouken@1951
  1056
        return SDL_FALSE;
slouken@1951
  1057
    }
slouken@1951
  1058
}
slouken@1951
  1059
slouken@1951
  1060
/* vi: set ts=4 sw=4 expandtab: */