Mercurial > sdl-ios-xcode
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)); |