Home | History | Annotate | Download | only in ut_renderer
      1 /*
      2 * Copyright (C) 2011 The Android Open Source Project
      3 *
      4 * Licensed under the Apache License, Version 2.0 (the "License");
      5 * you may not use this file except in compliance with the License.
      6 * You may obtain a copy of the License at
      7 *
      8 * http://www.apache.org/licenses/LICENSE-2.0
      9 *
     10 * Unless required by applicable law or agreed to in writing, software
     11 * distributed under the License is distributed on an "AS IS" BASIS,
     12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 * See the License for the specific language governing permissions and
     14 * limitations under the License.
     15 */
     16 #include "X11Windowing.h"
     17 
     18 #include <stdio.h>
     19 #include <stdlib.h>
     20 #include <X11/Xlib.h>
     21 #include <X11/Xutil.h>
     22 
     23 #define DEBUG 0
     24 #if DEBUG
     25 #  define D(...) printf(__VA_ARGS__), printf("\n")
     26 #else
     27 #  define D(...) ((void)0)
     28 #endif
     29 
     30 /* Try to remember the window position between creates/destroys */
     31 static int X11_wmXPos = 100;
     32 static int X11_wmYPos = 100;
     33 
     34 static int X11_wmXAdjust = 0;
     35 static int X11_wmYAdjust = 0;
     36 
     37 static void
     38 get_window_pos( Display *disp, Window win, int *px, int *py )
     39 {
     40     Window  child;
     41 
     42     XTranslateCoordinates( disp, win, DefaultRootWindow(disp),  0, 0, px, py, &child );
     43 }
     44 
     45 
     46 static void
     47 set_window_pos(Display *disp, Window win, int x, int y)
     48 {
     49     int   xNew, yNew;
     50     int   xAdjust = X11_wmXAdjust;
     51     int   yAdjust = X11_wmYAdjust;
     52 
     53     /* this code is tricky because some window managers, but not all,
     54      * will translate the final window position by a given offset
     55      * corresponding to the frame decoration.
     56      *
     57      * so we first try to move the window, get the position that the
     58      * window manager has set, and if they are different, re-position the
     59      * window again with an adjustment.
     60      *
     61      * this causes a slight flicker since the window 'jumps' very
     62      * quickly from one position to the other.
     63      */
     64 
     65     D("%s: move to [%d,%d] adjusted to [%d,%d]", __FUNCTION__,
     66       x, y, x+xAdjust, y+yAdjust);
     67     XMoveWindow(disp, win, x + xAdjust, y + yAdjust);
     68     XSync(disp, True);
     69     get_window_pos(disp, win, &xNew, &yNew);
     70     if (xNew != x || yNew != y) {
     71         X11_wmXAdjust = xAdjust = x - xNew;
     72         X11_wmYAdjust = yAdjust = y - yNew;
     73         D("%s: read pos [%d,%d], recomputing adjust=[%d,%d] moving to [%d,%d]\n",
     74           __FUNCTION__, xNew, yNew, xAdjust, yAdjust, x+xAdjust, y+yAdjust);
     75         XMoveWindow(disp, win, x + xAdjust, y + yAdjust );
     76     }
     77     XSync(disp, False);
     78 }
     79 
     80 
     81 NativeDisplayType X11Windowing::getNativeDisplay()
     82 {
     83     Display *dpy = XOpenDisplay(NULL);
     84     return (NativeDisplayType)dpy;
     85 }
     86 
     87 NativeWindowType X11Windowing::createNativeWindow(NativeDisplayType _dpy, int width, int height)
     88 {
     89     Display *dpy = (Display *) _dpy;
     90 
     91     long defaultScreen = DefaultScreen( dpy );
     92     Window rootWindow = RootWindow(dpy, defaultScreen);
     93     int depth = DefaultDepth(dpy, defaultScreen);
     94     XVisualInfo *visualInfo = new XVisualInfo;
     95 
     96     XMatchVisualInfo(dpy, defaultScreen, depth, TrueColor, visualInfo);
     97     if (visualInfo == NULL) {
     98         fprintf(stderr, "couldn't find matching visual\n");
     99         return NULL;
    100     }
    101 
    102     Colormap x11Colormap = XCreateColormap(dpy, rootWindow, visualInfo->visual, AllocNone);
    103     XSetWindowAttributes sWA;
    104     sWA.colormap = x11Colormap;
    105     sWA.event_mask = StructureNotifyMask | ExposureMask;
    106     sWA.background_pixel = 0;
    107     sWA.border_pixel = 0;
    108     unsigned int attributes_mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap;
    109 
    110     Window win = XCreateWindow( dpy,
    111                                 rootWindow,
    112                                 X11_wmXPos, X11_wmYPos, width, height,
    113                                 0, CopyFromParent, InputOutput,
    114                                 CopyFromParent, attributes_mask, &sWA);
    115 
    116     XMapWindow(dpy, win);
    117     XFlush(dpy);
    118     set_window_pos(dpy, win, X11_wmXPos, X11_wmYPos);
    119     return NativeWindowType(win);
    120 }
    121 
    122 int X11Windowing::destroyNativeWindow(NativeDisplayType _dpy, NativeWindowType _win)
    123 {
    124     Display *dpy = (Display *)_dpy;
    125     Window win = (Window)_win;
    126     get_window_pos(dpy, win, &X11_wmXPos, &X11_wmYPos);
    127     D("%s: Saved window position [%d, %d]\n", __FUNCTION__, X11_wmXPos, X11_wmYPos);
    128     XDestroyWindow(dpy, win);
    129     XFlush(dpy);
    130     return 0;
    131 }
    132