comparison src/video/x11/SDL_x11window.c @ 4521:50125e8aab94

Let the window manager know we're a "normal" window
author Sam Lantinga <slouken@libsdl.org>
date Wed, 14 Jul 2010 00:28:15 -0700
parents 0c67c4328678
children a4da6b906abb
comparison
equal deleted inserted replaced
4520:0c67c4328678 4521:50125e8aab94
222 X11_CreateWindow(_THIS, SDL_Window * window) 222 X11_CreateWindow(_THIS, SDL_Window * window)
223 { 223 {
224 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; 224 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
225 SDL_DisplayData *displaydata = 225 SDL_DisplayData *displaydata =
226 (SDL_DisplayData *) window->display->driverdata; 226 (SDL_DisplayData *) window->display->driverdata;
227 Display *display = data->display;
228 int screen = displaydata->screen;
227 Visual *visual; 229 Visual *visual;
228 int depth; 230 int depth;
229 XSetWindowAttributes xattr; 231 XSetWindowAttributes xattr;
230 int x, y; 232 int x, y;
231 Window w; 233 Window w;
232 XSizeHints *sizehints; 234 XSizeHints *sizehints;
233 XWMHints *wmhints; 235 XWMHints *wmhints;
234 XClassHint *classhints; 236 XClassHint *classhints;
235 SDL_bool oldstyle_fullscreen; 237 SDL_bool oldstyle_fullscreen;
238 Atom _NET_WM_WINDOW_TYPE;
239 Atom _NET_WM_WINDOW_TYPE_NORMAL;
236 240
237 /* ICCCM2.0-compliant window managers can handle fullscreen windows */ 241 /* ICCCM2.0-compliant window managers can handle fullscreen windows */
238 if ((window->flags & SDL_WINDOW_FULLSCREEN) && !data->net_wm) { 242 if ((window->flags & SDL_WINDOW_FULLSCREEN) && !data->net_wm) {
239 oldstyle_fullscreen = SDL_TRUE; 243 oldstyle_fullscreen = SDL_TRUE;
240 } else { 244 } else {
251 #endif 255 #endif
252 #ifdef SDL_VIDEO_OPENGL_GLX 256 #ifdef SDL_VIDEO_OPENGL_GLX
253 if (window->flags & SDL_WINDOW_OPENGL) { 257 if (window->flags & SDL_WINDOW_OPENGL) {
254 XVisualInfo *vinfo; 258 XVisualInfo *vinfo;
255 259
256 vinfo = X11_GL_GetVisual(_this, data->display, displaydata->screen); 260 vinfo = X11_GL_GetVisual(_this, display, screen);
257 if (!vinfo) { 261 if (!vinfo) {
258 return -1; 262 return -1;
259 } 263 }
260 visual = vinfo->visual; 264 visual = vinfo->visual;
261 depth = vinfo->depth; 265 depth = vinfo->depth;
264 #endif 268 #endif
265 #ifdef SDL_VIDEO_DRIVER_PANDORA 269 #ifdef SDL_VIDEO_DRIVER_PANDORA
266 if (window->flags & SDL_WINDOW_OPENGL) { 270 if (window->flags & SDL_WINDOW_OPENGL) {
267 XVisualInfo *vinfo; 271 XVisualInfo *vinfo;
268 272
269 vinfo = X11_GLES_GetVisual(_this, data->display, displaydata->screen); 273 vinfo = X11_GLES_GetVisual(_this, display, screen);
270 if (!vinfo) { 274 if (!vinfo) {
271 return -1; 275 return -1;
272 } 276 }
273 visual = vinfo->visual; 277 visual = vinfo->visual;
274 depth = vinfo->depth; 278 depth = vinfo->depth;
303 Sint32 rshift, gshift, bshift; 307 Sint32 rshift, gshift, bshift;
304 Sint32 r, g, b; 308 Sint32 r, g, b;
305 309
306 /* Is the colormap we need already registered in SDL? */ 310 /* Is the colormap we need already registered in SDL? */
307 if ((colormap = 311 if ((colormap =
308 X11_LookupColormap(data->display, 312 X11_LookupColormap(display, screen, visual->visualid))) {
309 displaydata->screen, visual->visualid))) {
310 xattr.colormap = colormap; 313 xattr.colormap = colormap;
311 /* printf("found existing colormap\n"); */ 314 /* printf("found existing colormap\n"); */
312 } else { 315 } else {
313 /* The colormap is not known to SDL so we will create it */ 316 /* The colormap is not known to SDL so we will create it */
314 colormap = XCreateColormap(data->display, 317 colormap = XCreateColormap(display, RootWindow(display, screen),
315 RootWindow(data->display,
316 displaydata->screen),
317 visual, AllocAll); 318 visual, AllocAll);
318 /* printf("colormap = %x\n", colormap); */ 319 /* printf("colormap = %x\n", colormap); */
319 320
320 /* If we can't create a colormap, then we must die */ 321 /* If we can't create a colormap, then we must die */
321 if (!colormap) { 322 if (!colormap) {
390 } 391 }
391 } 392 }
392 } 393 }
393 394
394 /* status = */ 395 /* status = */
395 /* XStoreColors(data->display, colormap, colorcells, ncolors); */ 396 /* XStoreColors(display, colormap, colorcells, ncolors); */
396 397
397 xattr.colormap = colormap; 398 xattr.colormap = colormap;
398 X11_TrackColormap(data->display, displaydata->screen, 399 X11_TrackColormap(display, screen, colormap, visual, NULL);
399 colormap, visual, NULL);
400 400
401 SDL_free(colorcells); 401 SDL_free(colorcells);
402 } 402 }
403 } else if (visual->class == DirectColor) { 403 } else if (visual->class == DirectColor) {
404 Status status; 404 Status status;
410 int rmask, gmask, bmask; 410 int rmask, gmask, bmask;
411 int rshift, gshift, bshift; 411 int rshift, gshift, bshift;
412 412
413 /* Is the colormap we need already registered in SDL? */ 413 /* Is the colormap we need already registered in SDL? */
414 if ((colormap = 414 if ((colormap =
415 X11_LookupColormap(data->display, 415 X11_LookupColormap(display, screen, visual->visualid))) {
416 displaydata->screen, visual->visualid))) {
417 xattr.colormap = colormap; 416 xattr.colormap = colormap;
418 /* printf("found existing colormap\n"); */ 417 /* printf("found existing colormap\n"); */
419 } else { 418 } else {
420 /* The colormap is not known to SDL so we will create it */ 419 /* The colormap is not known to SDL so we will create it */
421 colormap = XCreateColormap(data->display, 420 colormap = XCreateColormap(display, RootWindow(display, screen),
422 RootWindow(data->display,
423 displaydata->screen),
424 visual, AllocAll); 421 visual, AllocAll);
425 /* printf("colormap = %x\n", colormap); */ 422 /* printf("colormap = %x\n", colormap); */
426 423
427 /* If we can't create a colormap, then we must die */ 424 /* If we can't create a colormap, then we must die */
428 if (!colormap) { 425 if (!colormap) {
491 colorcells[i].flags = DoRed | DoGreen | DoBlue; 488 colorcells[i].flags = DoRed | DoGreen | DoBlue;
492 /* printf("%2d:%4x [%4x %4x %4x]\n", i, pix, red, green, blue); */ 489 /* printf("%2d:%4x [%4x %4x %4x]\n", i, pix, red, green, blue); */
493 } 490 }
494 491
495 status = 492 status =
496 XStoreColors(data->display, colormap, colorcells, ncolors); 493 XStoreColors(display, colormap, colorcells, ncolors);
497 494
498 xattr.colormap = colormap; 495 xattr.colormap = colormap;
499 X11_TrackColormap(data->display, displaydata->screen, 496 X11_TrackColormap(display, screen, colormap, visual, colorcells);
500 colormap, visual, colorcells);
501 497
502 SDL_free(colorcells); 498 SDL_free(colorcells);
503 } 499 }
504 } else { 500 } else {
505 xattr.colormap = 501 xattr.colormap =
506 XCreateColormap(data->display, 502 XCreateColormap(display, RootWindow(display, screen),
507 RootWindow(data->display, displaydata->screen),
508 visual, AllocNone); 503 visual, AllocNone);
509 } 504 }
510 505
511 if (oldstyle_fullscreen 506 if (oldstyle_fullscreen
512 || window->x == SDL_WINDOWPOS_CENTERED) { 507 || window->x == SDL_WINDOWPOS_CENTERED) {
525 y = 0; 520 y = 0;
526 } else { 521 } else {
527 y = window->y; 522 y = window->y;
528 } 523 }
529 524
530 w = XCreateWindow(data->display, 525 w = XCreateWindow(display, RootWindow(display, screen), x, y,
531 RootWindow(data->display, displaydata->screen), x, y,
532 window->w, window->h, 0, depth, InputOutput, visual, 526 window->w, window->h, 0, depth, InputOutput, visual,
533 (CWOverrideRedirect | CWBackPixel | CWBorderPixel | 527 (CWOverrideRedirect | CWBackPixel | CWBorderPixel |
534 CWColormap), &xattr); 528 CWColormap), &xattr);
535 if (!w) { 529 if (!w) {
536 SDL_SetError("Couldn't create window"); 530 SDL_SetError("Couldn't create window");
563 && window->y != SDL_WINDOWPOS_UNDEFINED) { 557 && window->y != SDL_WINDOWPOS_UNDEFINED) {
564 sizehints->x = x; 558 sizehints->x = x;
565 sizehints->y = y; 559 sizehints->y = y;
566 sizehints->flags |= USPosition; 560 sizehints->flags |= USPosition;
567 } 561 }
568 XSetWMNormalHints(data->display, w, sizehints); 562 XSetWMNormalHints(display, w, sizehints);
569 XFree(sizehints); 563 XFree(sizehints);
570 } 564 }
571 565
572 if ((window->flags & SDL_WINDOW_BORDERLESS) || oldstyle_fullscreen) { 566 if ((window->flags & SDL_WINDOW_BORDERLESS) || oldstyle_fullscreen) {
573 SDL_bool set; 567 SDL_bool set;
575 569
576 /* We haven't modified the window manager hints yet */ 570 /* We haven't modified the window manager hints yet */
577 set = SDL_FALSE; 571 set = SDL_FALSE;
578 572
579 /* First try to set MWM hints */ 573 /* First try to set MWM hints */
580 WM_HINTS = XInternAtom(data->display, "_MOTIF_WM_HINTS", True); 574 WM_HINTS = XInternAtom(display, "_MOTIF_WM_HINTS", True);
581 if (WM_HINTS != None) { 575 if (WM_HINTS != None) {
582 /* Hints used by Motif compliant window managers */ 576 /* Hints used by Motif compliant window managers */
583 struct 577 struct
584 { 578 {
585 unsigned long flags; 579 unsigned long flags;
588 long input_mode; 582 long input_mode;
589 unsigned long status; 583 unsigned long status;
590 } MWMHints = { 584 } MWMHints = {
591 (1L << 1), 0, 0, 0, 0}; 585 (1L << 1), 0, 0, 0, 0};
592 586
593 XChangeProperty(data->display, w, WM_HINTS, WM_HINTS, 32, 587 XChangeProperty(display, w, WM_HINTS, WM_HINTS, 32,
594 PropModeReplace, (unsigned char *) &MWMHints, 588 PropModeReplace, (unsigned char *) &MWMHints,
595 sizeof(MWMHints) / sizeof(long)); 589 sizeof(MWMHints) / 4);
596 set = SDL_TRUE; 590 set = SDL_TRUE;
597 } 591 }
598 /* Now try to set KWM hints */ 592 /* Now try to set KWM hints */
599 WM_HINTS = XInternAtom(data->display, "KWM_WIN_DECORATION", True); 593 WM_HINTS = XInternAtom(display, "KWM_WIN_DECORATION", True);
600 if (WM_HINTS != None) { 594 if (WM_HINTS != None) {
601 long KWMHints = 0; 595 long KWMHints = 0;
602 596
603 XChangeProperty(data->display, w, 597 XChangeProperty(display, w, WM_HINTS, WM_HINTS, 32,
604 WM_HINTS, WM_HINTS, 32,
605 PropModeReplace, 598 PropModeReplace,
606 (unsigned char *) &KWMHints, 599 (unsigned char *) &KWMHints,
607 sizeof(KWMHints) / sizeof(long)); 600 sizeof(KWMHints) / 4);
608 set = SDL_TRUE; 601 set = SDL_TRUE;
609 } 602 }
610 /* Now try to set GNOME hints */ 603 /* Now try to set GNOME hints */
611 WM_HINTS = XInternAtom(data->display, "_WIN_HINTS", True); 604 WM_HINTS = XInternAtom(display, "_WIN_HINTS", True);
612 if (WM_HINTS != None) { 605 if (WM_HINTS != None) {
613 long GNOMEHints = 0; 606 long GNOMEHints = 0;
614 607
615 XChangeProperty(data->display, w, 608 XChangeProperty(display, w, WM_HINTS, WM_HINTS, 32,
616 WM_HINTS, WM_HINTS, 32,
617 PropModeReplace, 609 PropModeReplace,
618 (unsigned char *) &GNOMEHints, 610 (unsigned char *) &GNOMEHints,
619 sizeof(GNOMEHints) / sizeof(long)); 611 sizeof(GNOMEHints) / 4);
620 set = SDL_TRUE; 612 set = SDL_TRUE;
621 } 613 }
622 /* Finally set the transient hints if necessary */ 614 /* Finally set the transient hints if necessary */
623 if (!set) { 615 if (!set) {
624 XSetTransientForHint(data->display, w, 616 XSetTransientForHint(display, w, RootWindow(display, screen));
625 RootWindow(data->display,
626 displaydata->screen));
627 } 617 }
628 } else { 618 } else {
629 SDL_bool set; 619 SDL_bool set;
630 Atom WM_HINTS; 620 Atom WM_HINTS;
631 621
632 /* We haven't modified the window manager hints yet */ 622 /* We haven't modified the window manager hints yet */
633 set = SDL_FALSE; 623 set = SDL_FALSE;
634 624
635 /* First try to unset MWM hints */ 625 /* First try to unset MWM hints */
636 WM_HINTS = XInternAtom(data->display, "_MOTIF_WM_HINTS", True); 626 WM_HINTS = XInternAtom(display, "_MOTIF_WM_HINTS", True);
637 if (WM_HINTS != None) { 627 if (WM_HINTS != None) {
638 XDeleteProperty(data->display, w, WM_HINTS); 628 XDeleteProperty(display, w, WM_HINTS);
639 set = SDL_TRUE; 629 set = SDL_TRUE;
640 } 630 }
641 /* Now try to unset KWM hints */ 631 /* Now try to unset KWM hints */
642 WM_HINTS = XInternAtom(data->display, "KWM_WIN_DECORATION", True); 632 WM_HINTS = XInternAtom(display, "KWM_WIN_DECORATION", True);
643 if (WM_HINTS != None) { 633 if (WM_HINTS != None) {
644 XDeleteProperty(data->display, w, WM_HINTS); 634 XDeleteProperty(display, w, WM_HINTS);
645 set = SDL_TRUE; 635 set = SDL_TRUE;
646 } 636 }
647 /* Now try to unset GNOME hints */ 637 /* Now try to unset GNOME hints */
648 WM_HINTS = XInternAtom(data->display, "_WIN_HINTS", True); 638 WM_HINTS = XInternAtom(display, "_WIN_HINTS", True);
649 if (WM_HINTS != None) { 639 if (WM_HINTS != None) {
650 XDeleteProperty(data->display, w, WM_HINTS); 640 XDeleteProperty(display, w, WM_HINTS);
651 set = SDL_TRUE; 641 set = SDL_TRUE;
652 } 642 }
653 /* Finally unset the transient hints if necessary */ 643 /* Finally unset the transient hints if necessary */
654 if (!set) { 644 if (!set) {
655 /* NOTE: Does this work? */ 645 /* NOTE: Does this work? */
656 XSetTransientForHint(data->display, w, None); 646 XSetTransientForHint(display, w, None);
657 } 647 }
658 } 648 }
659 649
660 /* Set the input hints so we get keyboard input */ 650 /* Set the input hints so we get keyboard input */
661 wmhints = XAllocWMHints(); 651 wmhints = XAllocWMHints();
662 if (wmhints) { 652 if (wmhints) {
663 wmhints->input = True; 653 wmhints->input = True;
664 wmhints->flags = InputHint; 654 wmhints->flags = InputHint;
665 XSetWMHints(data->display, w, wmhints); 655 XSetWMHints(display, w, wmhints);
666 XFree(wmhints); 656 XFree(wmhints);
667 } 657 }
668 658
669 /* Set the class hints so we can get an icon (AfterStep) */ 659 /* Set the class hints so we can get an icon (AfterStep) */
670 classhints = XAllocClassHint(); 660 classhints = XAllocClassHint();
671 if (classhints != NULL) { 661 if (classhints != NULL) {
672 classhints->res_name = data->classname; 662 classhints->res_name = data->classname;
673 classhints->res_class = data->classname; 663 classhints->res_class = data->classname;
674 XSetClassHint(data->display, w, classhints); 664 XSetClassHint(display, w, classhints);
675 XFree(classhints); 665 XFree(classhints);
676 } 666 }
677 667
678 /* FIXME: Why doesn't this work? */ 668 /* FIXME: Why doesn't this work? */
679 if (window->flags & SDL_WINDOW_FULLSCREEN) { 669 if (window->flags & SDL_WINDOW_FULLSCREEN) {
686 e.xclient.format = 32; 676 e.xclient.format = 32;
687 e.xclient.data.l[0] = _NET_WM_STATE_ADD; 677 e.xclient.data.l[0] = _NET_WM_STATE_ADD;
688 e.xclient.data.l[1] = _NET_WM_STATE_FULLSCREEN; 678 e.xclient.data.l[1] = _NET_WM_STATE_FULLSCREEN;
689 e.xclient.data.l[2] = 0l; 679 e.xclient.data.l[2] = 0l;
690 680
691 XSendEvent(data->display, 681 XSendEvent(display, RootWindow(display, screen), 0,
692 RootWindow(data->display, displaydata->screen), 0,
693 SubstructureNotifyMask | SubstructureRedirectMask, &e); 682 SubstructureNotifyMask | SubstructureRedirectMask, &e);
694 } 683 }
695 684
685 /* Let the window manager know we're a "normal" window */
686 _NET_WM_WINDOW_TYPE = XInternAtom(display, "_NET_WM_WINDOW_TYPE", False);
687 _NET_WM_WINDOW_TYPE_NORMAL = XInternAtom(display, "_NET_WM_WINDOW_TYPE_NORMAL", False);
688 XChangeProperty(display, w, _NET_WM_WINDOW_TYPE, XA_ATOM, 32,
689 PropModeReplace,
690 (unsigned char *)&_NET_WM_WINDOW_TYPE_NORMAL, 1);
691
696 /* Allow the window to be deleted by the window manager */ 692 /* Allow the window to be deleted by the window manager */
697 XSetWMProtocols(data->display, w, &data->WM_DELETE_WINDOW, 1); 693 XSetWMProtocols(display, w, &data->WM_DELETE_WINDOW, 1);
698 694
699 if (SetupWindowData(_this, window, w, SDL_TRUE) < 0) { 695 if (SetupWindowData(_this, window, w, SDL_TRUE) < 0) {
700 XDestroyWindow(data->display, w); 696 XDestroyWindow(display, w);
701 return -1; 697 return -1;
702 } 698 }
703 #ifdef X_HAVE_UTF8_STRING 699 #ifdef X_HAVE_UTF8_STRING
704 { 700 {
705 Uint32 fevent = 0; 701 Uint32 fevent = 0;
706 pXGetICValues(((SDL_WindowData *) window->driverdata)->ic, 702 pXGetICValues(((SDL_WindowData *) window->driverdata)->ic,
707 XNFilterEvents, &fevent, NULL); 703 XNFilterEvents, &fevent, NULL);
708 XSelectInput(data->display, w, 704 XSelectInput(display, w,
709 (FocusChangeMask | EnterWindowMask | LeaveWindowMask | 705 (FocusChangeMask | EnterWindowMask | LeaveWindowMask |
710 ExposureMask | ButtonPressMask | ButtonReleaseMask | 706 ExposureMask | ButtonPressMask | ButtonReleaseMask |
711 PointerMotionMask | KeyPressMask | KeyReleaseMask | 707 PointerMotionMask | KeyPressMask | KeyReleaseMask |
712 PropertyChangeMask | StructureNotifyMask | 708 PropertyChangeMask | StructureNotifyMask |
713 KeymapStateMask | fevent)); 709 KeymapStateMask | fevent));
714 } 710 }
715 #else 711 #else
716 { 712 {
717 XSelectInput(data->display, w, 713 XSelectInput(display, w,
718 (FocusChangeMask | EnterWindowMask | LeaveWindowMask | 714 (FocusChangeMask | EnterWindowMask | LeaveWindowMask |
719 ExposureMask | ButtonPressMask | ButtonReleaseMask | 715 ExposureMask | ButtonPressMask | ButtonReleaseMask |
720 PointerMotionMask | KeyPressMask | KeyReleaseMask | 716 PointerMotionMask | KeyPressMask | KeyReleaseMask |
721 PropertyChangeMask | StructureNotifyMask | 717 PropertyChangeMask | StructureNotifyMask |
722 KeymapStateMask)); 718 KeymapStateMask));