comparison src/video/x11/SDL_x11window.c @ 5281:15a71bec4a55

merged
author Eric Wing <ewing . public |-at-| gmail . com>
date Sat, 12 Feb 2011 19:16:09 -0800
parents b530ef003506
children
comparison
equal deleted inserted replaced
5219:adfcdd311ae0 5281:15a71bec4a55
1 /* 1 /*
2 SDL - Simple DirectMedia Layer 2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2010 Sam Lantinga 3 Copyright (C) 1997-2011 Sam Lantinga
4 4
5 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public 6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either 7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version. 8 version 2.1 of the License, or (at your option) any later version.
26 #include "../../events/SDL_keyboard_c.h" 26 #include "../../events/SDL_keyboard_c.h"
27 #include "../../events/SDL_mouse_c.h" 27 #include "../../events/SDL_mouse_c.h"
28 28
29 #include "SDL_x11video.h" 29 #include "SDL_x11video.h"
30 #include "SDL_x11mouse.h" 30 #include "SDL_x11mouse.h"
31 #include "SDL_x11gamma.h"
32 #include "SDL_x11shape.h" 31 #include "SDL_x11shape.h"
33 32
34 #ifdef SDL_VIDEO_DRIVER_PANDORA 33 #ifdef SDL_VIDEO_DRIVER_PANDORA
35 #include "SDL_x11opengles.h" 34 #include "SDL_x11opengles.h"
36 #endif 35 #endif
89 static void 88 static void
90 X11_GetDisplaySize(_THIS, SDL_Window * window, int *w, int *h) 89 X11_GetDisplaySize(_THIS, SDL_Window * window, int *w, int *h)
91 { 90 {
92 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; 91 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
93 SDL_DisplayData *displaydata = 92 SDL_DisplayData *displaydata =
94 (SDL_DisplayData *) window->display->driverdata; 93 (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
95 XWindowAttributes attr; 94 XWindowAttributes attr;
96 95
97 XGetWindowAttributes(data->display, RootWindow(data->display, displaydata->screen), &attr); 96 XGetWindowAttributes(data->display, RootWindow(data->display, displaydata->screen), &attr);
98 if (window->flags & SDL_WINDOW_FULLSCREEN) { 97 if (window->flags & SDL_WINDOW_FULLSCREEN) {
99 /* The bounds when this window is visible is the fullscreen mode */ 98 /* The bounds when this window is visible is the fullscreen mode */
258 int 257 int
259 X11_CreateWindow(_THIS, SDL_Window * window) 258 X11_CreateWindow(_THIS, SDL_Window * window)
260 { 259 {
261 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; 260 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
262 SDL_DisplayData *displaydata = 261 SDL_DisplayData *displaydata =
263 (SDL_DisplayData *) window->display->driverdata; 262 (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
264 Display *display = data->display; 263 Display *display = data->display;
265 int screen = displaydata->screen; 264 int screen = displaydata->screen;
266 Visual *visual; 265 Visual *visual;
267 int depth; 266 int depth;
268 XSetWindowAttributes xattr; 267 XSetWindowAttributes xattr;
324 } else { 323 } else {
325 xattr.override_redirect = False; 324 xattr.override_redirect = False;
326 } 325 }
327 xattr.background_pixel = 0; 326 xattr.background_pixel = 0;
328 xattr.border_pixel = 0; 327 xattr.border_pixel = 0;
329 328 xattr.colormap = XCreateColormap(display, RootWindow(display, screen), visual, AllocNone);
330 if (visual->class == PseudoColor) {
331 printf("asking for PseudoColor\n");
332
333 /* Status status; */
334 XColor *colorcells;
335 Colormap colormap;
336 Sint32 pix;
337 Sint32 ncolors;
338 Sint32 nbits;
339 Sint32 rmax, gmax, bmax;
340 Sint32 rwidth, gwidth, bwidth;
341 Sint32 rmask, gmask, bmask;
342 Sint32 rshift, gshift, bshift;
343 Sint32 r, g, b;
344
345 /* Is the colormap we need already registered in SDL? */
346 if ((colormap =
347 X11_LookupColormap(display, screen, visual->visualid))) {
348 xattr.colormap = colormap;
349 /* printf("found existing colormap\n"); */
350 } else {
351 /* The colormap is not known to SDL so we will create it */
352 colormap = XCreateColormap(display, RootWindow(display, screen),
353 visual, AllocAll);
354 /* printf("colormap = %x\n", colormap); */
355
356 /* If we can't create a colormap, then we must die */
357 if (!colormap) {
358 SDL_SetError
359 ("Couldn't create window: Could not create writable colormap");
360 return -1;
361 }
362
363 /* OK, we got a colormap, now fill it in as best as we can */
364
365 colorcells = SDL_malloc(visual->map_entries * sizeof(XColor));
366 if (NULL == colorcells) {
367 SDL_SetError("out of memory in X11_CreateWindow");
368 return -1;
369 }
370
371 ncolors = visual->map_entries;
372 nbits = visual->bits_per_rgb;
373
374 /* printf("ncolors = %d nbits = %d\n", ncolors, nbits); */
375
376 /* what if ncolors != (1 << nbits)? That can happen on a
377 true PseudoColor display. I'm assuming that we will
378 always have ncolors == (1 << nbits) */
379
380 /* I'm making a lot of assumptions here. */
381
382 /* Compute the width of each field. If there is one extra
383 bit, give it to green. If there are two extra bits give
384 them to red and greed. We can get extra bits when the
385 number of bits per pixel is not a multiple of 3. For
386 example when we have 16 bits per pixel and need a 5/6/5
387 layout for the RGB fields */
388
389 rwidth = (nbits / 3) + (((nbits % 3) == 2) ? 1 : 0);
390 gwidth = (nbits / 3) + (((nbits % 3) >= 1) ? 1 : 0);
391 bwidth = (nbits / 3);
392
393 rshift = gwidth + bwidth;
394 gshift = bwidth;
395 bshift = 0;
396
397 rmax = 1 << rwidth;
398 gmax = 1 << gwidth;
399 bmax = 1 << bwidth;
400
401 rmask = rmax - 1;
402 gmask = gmax - 1;
403 bmask = bmax - 1;
404
405 /* printf("red mask = %4x shift = %4d width = %d\n", rmask, rshift, rwidth); */
406 /* printf("green mask = %4x shift = %4d width = %d\n", gmask, gshift, gwidth); */
407 /* printf("blue mask = %4x shift = %4d width = %d\n", bmask, bshift, bwidth); */
408
409 /* build the color table pixel values */
410 pix = 0;
411 for (r = 0; r < rmax; r++) {
412 for (g = 0; g < gmax; g++) {
413 for (b = 0; b < bmax; b++) {
414 colorcells[pix].pixel =
415 (r << rshift) | (g << gshift) | (b << bshift);
416 colorcells[pix].red = (0xffff * r) / rmask;
417 colorcells[pix].green = (0xffff * g) / gmask;
418 colorcells[pix].blue = (0xffff * b) / bmask;
419 /* printf("%4x:%4x [%4x %4x %4x]\n", */
420 /* pix, */
421 /* colorcells[pix].pixel, */
422 /* colorcells[pix].red, */
423 /* colorcells[pix].green, */
424 /* colorcells[pix].blue); */
425 pix++;
426 }
427 }
428 }
429
430 /* status = */
431 /* XStoreColors(display, colormap, colorcells, ncolors); */
432
433 xattr.colormap = colormap;
434 X11_TrackColormap(display, screen, colormap, visual, NULL);
435
436 SDL_free(colorcells);
437 }
438 } else if (visual->class == DirectColor) {
439 Status status;
440 XColor *colorcells;
441 Colormap colormap;
442 int i;
443 int ncolors;
444 int rmax, gmax, bmax;
445 int rmask, gmask, bmask;
446 int rshift, gshift, bshift;
447
448 /* Is the colormap we need already registered in SDL? */
449 if ((colormap =
450 X11_LookupColormap(display, screen, visual->visualid))) {
451 xattr.colormap = colormap;
452 /* printf("found existing colormap\n"); */
453 } else {
454 /* The colormap is not known to SDL so we will create it */
455 colormap = XCreateColormap(display, RootWindow(display, screen),
456 visual, AllocAll);
457 /* printf("colormap = %x\n", colormap); */
458
459 /* If we can't create a colormap, then we must die */
460 if (!colormap) {
461 SDL_SetError
462 ("Couldn't create window: Could not create writable colormap");
463 return -1;
464 }
465
466 /* OK, we got a colormap, now fill it in as best as we can */
467 colorcells = SDL_malloc(visual->map_entries * sizeof(XColor));
468 if (NULL == colorcells) {
469 SDL_SetError("out of memory in X11_CreateWindow");
470 return -1;
471 }
472 ncolors = visual->map_entries;
473 rmax = 0xffff;
474 gmax = 0xffff;
475 bmax = 0xffff;
476
477 rshift = 0;
478 rmask = visual->red_mask;
479 while (0 == (rmask & 1)) {
480 rshift++;
481 rmask >>= 1;
482 }
483
484 /* printf("rmask = %4x rshift = %4d\n", rmask, rshift); */
485
486 gshift = 0;
487 gmask = visual->green_mask;
488 while (0 == (gmask & 1)) {
489 gshift++;
490 gmask >>= 1;
491 }
492
493 /* printf("gmask = %4x gshift = %4d\n", gmask, gshift); */
494
495 bshift = 0;
496 bmask = visual->blue_mask;
497 while (0 == (bmask & 1)) {
498 bshift++;
499 bmask >>= 1;
500 }
501
502 /* printf("bmask = %4x bshift = %4d\n", bmask, bshift); */
503
504 /* build the color table pixel values */
505 for (i = 0; i < ncolors; i++) {
506 Uint32 red = (rmax * i) / (ncolors - 1);
507 Uint32 green = (gmax * i) / (ncolors - 1);
508 Uint32 blue = (bmax * i) / (ncolors - 1);
509
510 Uint32 rbits = (rmask * i) / (ncolors - 1);
511 Uint32 gbits = (gmask * i) / (ncolors - 1);
512 Uint32 bbits = (bmask * i) / (ncolors - 1);
513
514 Uint32 pix =
515 (rbits << rshift) | (gbits << gshift) | (bbits << bshift);
516
517 colorcells[i].pixel = pix;
518
519 colorcells[i].red = red;
520 colorcells[i].green = green;
521 colorcells[i].blue = blue;
522
523 colorcells[i].flags = DoRed | DoGreen | DoBlue;
524 /* printf("%2d:%4x [%4x %4x %4x]\n", i, pix, red, green, blue); */
525 }
526
527 status =
528 XStoreColors(display, colormap, colorcells, ncolors);
529
530 xattr.colormap = colormap;
531 X11_TrackColormap(display, screen, colormap, visual, colorcells);
532
533 SDL_free(colorcells);
534 }
535 } else {
536 xattr.colormap =
537 XCreateColormap(display, RootWindow(display, screen),
538 visual, AllocNone);
539 }
540 329
541 if (oldstyle_fullscreen 330 if (oldstyle_fullscreen
542 || window->x == SDL_WINDOWPOS_CENTERED) { 331 || SDL_WINDOWPOS_ISCENTERED(window->x)) {
543 X11_GetDisplaySize(_this, window, &x, NULL); 332 X11_GetDisplaySize(_this, window, &x, NULL);
544 x = (x - window->w) / 2; 333 x = (x - window->w) / 2;
545 } else if (window->x == SDL_WINDOWPOS_UNDEFINED) { 334 } else if (SDL_WINDOWPOS_ISUNDEFINED(window->x)) {
546 x = 0; 335 x = 0;
547 } else { 336 } else {
548 x = window->x; 337 x = window->x;
549 } 338 }
550 if (oldstyle_fullscreen 339 if (oldstyle_fullscreen
551 || window->y == SDL_WINDOWPOS_CENTERED) { 340 || SDL_WINDOWPOS_ISCENTERED(window->y)) {
552 X11_GetDisplaySize(_this, window, NULL, &y); 341 X11_GetDisplaySize(_this, window, NULL, &y);
553 y = (y - window->h) / 2; 342 y = (y - window->h) / 2;
554 } else if (window->y == SDL_WINDOWPOS_UNDEFINED) { 343 } else if (SDL_WINDOWPOS_ISUNDEFINED(window->y)) {
555 y = 0; 344 y = 0;
556 } else { 345 } else {
557 y = window->y; 346 y = window->y;
558 } 347 }
559 348
586 sizehints->min_width = sizehints->max_width = window->w; 375 sizehints->min_width = sizehints->max_width = window->w;
587 sizehints->min_height = sizehints->max_height = window->h; 376 sizehints->min_height = sizehints->max_height = window->h;
588 sizehints->flags = PMaxSize | PMinSize; 377 sizehints->flags = PMaxSize | PMinSize;
589 } 378 }
590 if (!oldstyle_fullscreen 379 if (!oldstyle_fullscreen
591 && window->x != SDL_WINDOWPOS_UNDEFINED 380 && !SDL_WINDOWPOS_ISUNDEFINED(window->x)
592 && window->y != SDL_WINDOWPOS_UNDEFINED) { 381 && !SDL_WINDOWPOS_ISUNDEFINED(window->y)) {
593 sizehints->x = x; 382 sizehints->x = x;
594 sizehints->y = y; 383 sizehints->y = y;
595 sizehints->flags |= USPosition; 384 sizehints->flags |= USPosition;
596 } 385 }
597 XSetWMNormalHints(display, w, sizehints); 386 XSetWMNormalHints(display, w, sizehints);
922 711
923 /* ICCCM2.0-compliant window managers can handle fullscreen windows */ 712 /* ICCCM2.0-compliant window managers can handle fullscreen windows */
924 oldstyle_fullscreen = X11_IsWindowOldFullscreen(_this, window); 713 oldstyle_fullscreen = X11_IsWindowOldFullscreen(_this, window);
925 714
926 if (oldstyle_fullscreen 715 if (oldstyle_fullscreen
927 || window->x == SDL_WINDOWPOS_CENTERED) { 716 || SDL_WINDOWPOS_ISCENTERED(window->x)) {
928 X11_GetDisplaySize(_this, window, &x, NULL); 717 X11_GetDisplaySize(_this, window, &x, NULL);
929 x = (x - window->w) / 2; 718 x = (x - window->w) / 2;
930 } else { 719 } else {
931 x = window->x; 720 x = window->x;
932 } 721 }
933 if (oldstyle_fullscreen 722 if (oldstyle_fullscreen
934 || window->y == SDL_WINDOWPOS_CENTERED) { 723 || SDL_WINDOWPOS_ISCENTERED(window->y)) {
935 X11_GetDisplaySize(_this, window, NULL, &y); 724 X11_GetDisplaySize(_this, window, NULL, &y);
936 y = (y - window->h) / 2; 725 y = (y - window->h) / 2;
937 } else { 726 } else {
938 y = window->y; 727 y = window->y;
939 } 728 }
986 static void 775 static void
987 X11_SetWindowMaximized(_THIS, SDL_Window * window, SDL_bool maximized) 776 X11_SetWindowMaximized(_THIS, SDL_Window * window, SDL_bool maximized)
988 { 777 {
989 SDL_WindowData *data = (SDL_WindowData *) window->driverdata; 778 SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
990 SDL_DisplayData *displaydata = 779 SDL_DisplayData *displaydata =
991 (SDL_DisplayData *) window->display->driverdata; 780 (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
992 Display *display = data->videodata->display; 781 Display *display = data->videodata->display;
993 Atom _NET_WM_STATE = data->videodata->_NET_WM_STATE; 782 Atom _NET_WM_STATE = data->videodata->_NET_WM_STATE;
994 Atom _NET_WM_STATE_MAXIMIZED_VERT = data->videodata->_NET_WM_STATE_MAXIMIZED_VERT; 783 Atom _NET_WM_STATE_MAXIMIZED_VERT = data->videodata->_NET_WM_STATE_MAXIMIZED_VERT;
995 Atom _NET_WM_STATE_MAXIMIZED_HORZ = data->videodata->_NET_WM_STATE_MAXIMIZED_HORZ; 784 Atom _NET_WM_STATE_MAXIMIZED_HORZ = data->videodata->_NET_WM_STATE_MAXIMIZED_HORZ;
996 Atom _NET_WM_STATE_FULLSCREEN = data->videodata->_NET_WM_STATE_FULLSCREEN; 785 Atom _NET_WM_STATE_FULLSCREEN = data->videodata->_NET_WM_STATE_FULLSCREEN;
1041 void 830 void
1042 X11_MinimizeWindow(_THIS, SDL_Window * window) 831 X11_MinimizeWindow(_THIS, SDL_Window * window)
1043 { 832 {
1044 SDL_WindowData *data = (SDL_WindowData *) window->driverdata; 833 SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
1045 SDL_DisplayData *displaydata = 834 SDL_DisplayData *displaydata =
1046 (SDL_DisplayData *) window->display->driverdata; 835 (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata;
1047 Display *display = data->videodata->display; 836 Display *display = data->videodata->display;
1048 837
1049 XIconifyWindow(display, data->xwindow, displaydata->screen); 838 XIconifyWindow(display, data->xwindow, displaydata->screen);
1050 XFlush(display); 839 XFlush(display);
1051 } 840 }