diff options
Diffstat (limited to 'stream-servers/NativeSubWindow_x11.cpp')
-rw-r--r-- | stream-servers/NativeSubWindow_x11.cpp | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/stream-servers/NativeSubWindow_x11.cpp b/stream-servers/NativeSubWindow_x11.cpp new file mode 100644 index 00000000..19011f88 --- /dev/null +++ b/stream-servers/NativeSubWindow_x11.cpp @@ -0,0 +1,120 @@ +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#include "NativeSubWindow.h" + +#include <stdio.h> + +static Bool WaitForMapNotify(Display *d, XEvent *e, char *arg) { + if (e->type == MapNotify && e->xmap.window == (Window)arg) { + return 1; + } + return 0; +} + +static Bool WaitForConfigureNotify(Display *d, XEvent *e, char *arg) { + if (e->type == ConfigureNotify && e->xmap.window == (Window)arg) { + return 1; + } + return 0; +} + +static Display *s_display = NULL; + +EGLNativeWindowType createSubWindow(FBNativeWindowType p_window, + int x, + int y, + int width, + int height, + SubWindowRepaintCallback repaint_callback, + void* repaint_callback_param, + int hideWindow) { + // The call to this function is protected by a lock + // in FrameBuffer so it is safe to check and initialize s_display here + if (!s_display) { + s_display = XOpenDisplay(NULL); + } + + XSetWindowAttributes wa; + wa.event_mask = StructureNotifyMask; + wa.override_redirect = True; + Window win = XCreateWindow(s_display, + p_window, + x, + y, + width, + height, + 0, + CopyFromParent, + CopyFromParent, + CopyFromParent, + CWEventMask, + &wa); + if (!hideWindow) { + XMapWindow(s_display,win); + XSetWindowBackground(s_display, win, BlackPixel(s_display, 0)); + XEvent e; + XIfEvent(s_display, &e, WaitForMapNotify, (char *)win); + } + return win; +} + +void destroySubWindow(EGLNativeWindowType win) { + if (!s_display) { + return; + } + XDestroyWindow(s_display, win); +} + +int moveSubWindow(FBNativeWindowType p_parent_window, + EGLNativeWindowType p_sub_window, + int x, + int y, + int width, + int height) { + // This value is set during create, so if it is still null, simply + // return because the global state is corrupted + if (!s_display) { + return false; + } + + // Make sure something has changed, otherwise XIfEvent will block and + // freeze the emulator. + XWindowAttributes attrs; + if (!XGetWindowAttributes(s_display, p_sub_window, &attrs)) { + return false; + } + if (x == attrs.x && y == attrs.y && + width == attrs.width && height == attrs.height) { + // Technically, resizing was a success because it was unneeded. + return true; + } + + // This prevents flicker on resize. + XSetWindowBackgroundPixmap(s_display, p_sub_window, None); + + int ret = XMoveResizeWindow( + s_display, + p_sub_window, + x, + y, + width, + height); + + XEvent e; + XIfEvent(s_display, &e, WaitForConfigureNotify, (char *)p_sub_window); + + return ret; +} |