blob: f5ea1a1b512c8c7468ab7f8adacb64caa2637138 [file] [log] [blame]
/*
* 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) {
// 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);
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;
}