From eb8b643bf29646f8323c3bb49e7e70392dc6574b Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Thu, 26 Dec 2013 19:01:23 +0900 Subject: [PATCH] ecore-x - add call to create a permanent window that is not deleted on exit --- src/lib/ecore_x/Ecore_X.h | 1 + src/lib/ecore_x/xcb/ecore_xcb_window.c | 82 ++++++++++++++++++++++++++ src/lib/ecore_x/xlib/ecore_x_window.c | 68 +++++++++++++++++++++ 3 files changed, 151 insertions(+) diff --git a/src/lib/ecore_x/Ecore_X.h b/src/lib/ecore_x/Ecore_X.h index 1241b24408..c5ed5f3864 100644 --- a/src/lib/ecore_x/Ecore_X.h +++ b/src/lib/ecore_x/Ecore_X.h @@ -1409,6 +1409,7 @@ EAPI int ecore_x_window_argb_get(Ecore_X_Window win); EAPI Ecore_X_Window ecore_x_window_manager_argb_new(Ecore_X_Window parent, int x, int y, int w, int h); EAPI Ecore_X_Window ecore_x_window_argb_new(Ecore_X_Window parent, int x, int y, int w, int h); EAPI Ecore_X_Window ecore_x_window_override_argb_new(Ecore_X_Window parent, int x, int y, int w, int h); +EAPI Ecore_X_Window ecore_x_window_permanent_create(Ecore_X_Window parent, Ecore_X_Atom unique_atom); /* @since 1.9 */ EAPI Ecore_X_Window ecore_x_window_input_new(Ecore_X_Window parent, int x, int y, int w, int h); EAPI void ecore_x_window_configure(Ecore_X_Window win, Ecore_X_Window_Configure_Mask mask, int x, int y, int w, int h, int border_width, Ecore_X_Window sibling, int stack_mode); EAPI void ecore_x_window_cursor_set(Ecore_X_Window win, Ecore_X_Cursor c); diff --git a/src/lib/ecore_x/xcb/ecore_xcb_window.c b/src/lib/ecore_x/xcb/ecore_xcb_window.c index 087c39182b..094f145836 100644 --- a/src/lib/ecore_x/xcb/ecore_xcb_window.c +++ b/src/lib/ecore_x/xcb/ecore_xcb_window.c @@ -310,6 +310,88 @@ ecore_x_window_override_argb_new(Ecore_X_Window parent, return win; } +EAPI Ecore_X_Window +ecore_x_window_permanent_create(Ecore_X_Window parent, + Ecore_X_Atom unique_atom) +{ + xcb_connection_t *conn; + Ecore_X_Window win, win2, realwin; + uint32_t mask, mask_list[9]; + xcb_get_property_reply_t *reply; + xcb_get_property_cookie_t cookie; + unsigned long ldata, *datap; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + conn = xcb_connect(name, NULL); + if (!conn) return 0; + + xcb_grab_server(conn); + cookie = xcb_get_property_unchecked(conn, 0, parent, unique_atom, + ECORE_X_ATOM_WINDOW, 0, 0x7fffffff); + reply = xcb_get_property_reply(conn, cookie, NULL); + if (reply) + { + if ((reply->type == ECORE_X_ATOM_WINDOW) && (reply->format == 32) && + (reply->value_len == 1) && + ((datap = (unsigned long *)xcb_get_property_value(reply)))) + { + win = (Ecore_X_Window)(*datap); + free(reply); + cookie = xcb_get_property_unchecked(conn, 0, win, unique_atom, + ECORE_X_ATOM_WINDOW, 0, 0x7fffffff); + reply = xcb_get_property_reply(conn, cookie, NULL); + if (reply) + { + if ((reply->type == ECORE_X_ATOM_WINDOW) && (reply->format == 32) && + (reply->value_len == 1) && + ((datap = (unsigned long *)xcb_get_property_value(reply)))) + { + win2 = (Ecore_X_Window)(*datap); + free(reply); + if (win2 == win) realwin = win; + } + else free(reply); + } + } + else free(reply); + } + if (realwin != 0) + { + xcb_ungrab_server(conn); + xcb_flush(conn); + xcb_disconnect(conn); + return realwin; + } + mask = (XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY | + XCB_CW_WIN_GRAVITY | XCB_CW_BACKING_STORE | + XCB_CW_OVERRIDE_REDIRECT | XCB_CW_SAVE_UNDER | XCB_CW_EVENT_MASK | + XCB_CW_DONT_PROPAGATE); + mask_list[0] = XCB_BACK_PIXMAP_NONE; + mask_list[1] = 0; + mask_list[2] = XCB_GRAVITY_NORTH_WEST; + mask_list[3] = XCB_GRAVITY_NORTH_WEST; + mask_list[4] = XCB_BACKING_STORE_NOT_USEFUL; + mask_list[5] = 1; + mask_list[6] = 0; + mask_list[7] = XCB_EVENT_MASK_NO_EVENT; + mask_list[8] = XCB_EVENT_MASK_NO_EVENT; + win = xcb_generate_id(conn); + xcb_create_window(conn, XCB_COPY_FROM_PARENT, + win, parent, -77, -77, 7, 7, 0, + XCB_WINDOW_CLASS_INPUT_OUTPUT, + XCB_COPY_FROM_PARENT, mask, mask_list); + ldata = (unsigned long)win; + xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win, unique_atom, + ECORE_X_ATOM_WINDOW, 32, 1, (unsigned char *)ldata); + xcb_change_property(conn, XCB_PROP_MODE_REPLACE, parent, unique_atom, + ECORE_X_ATOM_WINDOW, 32, 1, (unsigned char *)ldata); + xcb_set_close_down_mode(conn, XCB_CLOSE_DOWN_RETAIN_PERMANENT); + xcb_ungrab_server(conn); + xcb_flush(conn); + xcb_disconnect(conn); + return win; +} + /** * @defgroup Ecore_X_Window_Destroy_Group X Window Destroy Functions * @ingroup Ecore_X_Group diff --git a/src/lib/ecore_x/xlib/ecore_x_window.c b/src/lib/ecore_x/xlib/ecore_x_window.c index ac0f34a06c..e4c9e747f3 100644 --- a/src/lib/ecore_x/xlib/ecore_x_window.c +++ b/src/lib/ecore_x/xlib/ecore_x_window.c @@ -1786,3 +1786,71 @@ ecore_x_window_override_argb_new(Ecore_X_Window parent, #endif /* ifdef ECORE_XRENDER */ } +EAPI Ecore_X_Window +ecore_x_window_permanent_create(Ecore_X_Window parent, + Ecore_X_Atom unique_atom) +{ + Display *disp; + Window win, win2, realwin = 0; + Atom type_ret; + int format_ret; + unsigned long ldata, bytes_after, num_ret, *datap; + unsigned char *prop_ret; + + LOGFN(__FILE__, __LINE__, __FUNCTION__); + disp = XOpenDisplay(DisplayString(_ecore_x_disp)); + if (!disp) return 0; + + XGrabServer(disp); + if (XGetWindowProperty(disp, parent, unique_atom, 0, 0x7fffffff, + False, XA_WINDOW, &type_ret, &format_ret, + &num_ret, &bytes_after, &prop_ret)) + { + if (prop_ret) + { + if ((format_ret == 32) && (type_ret == XA_WINDOW) && + (num_ret == 1)) + { + datap = (unsigned long *)prop_ret; + win = (Window)(*datap); + XFree(prop_ret); + if (XGetWindowProperty(disp, win, unique_atom, 0, 0x7fffffff, + False, XA_WINDOW, &type_ret, &format_ret, + &num_ret, &bytes_after, &prop_ret)) + { + if (prop_ret) + { + if ((format_ret == 32) && (type_ret == XA_WINDOW) && + (num_ret == 1)) + { + datap = (unsigned long *)prop_ret; + win2 = (Window)(*datap); + XFree(prop_ret); + if (win2 == win) realwin = win; + } + else XFree(prop_ret); + } + } + } + else XFree(prop_ret); + } + } + if (realwin != 0) + { + XUngrabServer(disp); + XFlush(disp); + XCloseDisplay(disp); + return realwin; + } + win = XCreateSimpleWindow(disp, parent, -77, -77, 7, 7, 0, 0, 0); + ldata = (unsigned long)win; + XChangeProperty(disp, win, unique_atom, XA_WINDOW, 32, + PropModeReplace, (unsigned char *)(&ldata), 1); + XChangeProperty(disp, parent, unique_atom, XA_WINDOW, 32, + PropModeReplace, (unsigned char *)(&ldata), 1); + XSetCloseDownMode(disp, RetainPermanent); + XUngrabServer(disp); + XFlush(disp); + XCloseDisplay(disp); + return win; +}