2247 lines
64 KiB
C
2247 lines
64 KiB
C
#include "ecore_xcb_private.h"
|
|
#ifdef ECORE_XCB_RENDER
|
|
# include <xcb/render.h>
|
|
#endif
|
|
#ifdef ECORE_XCB_SHAPE
|
|
# include <xcb/shape.h>
|
|
#endif
|
|
#ifdef ECORE_XCB_XPRINT
|
|
#include <xcb/xprint.h>
|
|
#endif
|
|
|
|
/* local function prototypes */
|
|
static Ecore_X_Window _ecore_xcb_window_argb_internal_new(Ecore_X_Window parent,
|
|
int x,
|
|
int y,
|
|
int w,
|
|
int h,
|
|
uint8_t override_redirect,
|
|
uint8_t save_under);
|
|
static Ecore_X_Window _ecore_xcb_window_at_xy_get(Ecore_X_Window base,
|
|
int bx,
|
|
int by,
|
|
int x,
|
|
int y,
|
|
Ecore_X_Window *skip,
|
|
int skip_num);
|
|
static int _ecore_xcb_window_modifiers_get(unsigned int state);
|
|
static xcb_visualtype_t *_ecore_xcb_window_find_visual_by_id(xcb_visualid_t id);
|
|
#ifdef ECORE_XCB_XPRINT
|
|
static xcb_screen_t *_ecore_xcb_window_screen_of_display(int screen);
|
|
#endif
|
|
|
|
/* local variables */
|
|
static int ignore_num = 0;
|
|
static Ecore_X_Window *ignore_list = NULL;
|
|
|
|
/* external variables */
|
|
int _ecore_xcb_button_grabs_num = 0;
|
|
int _ecore_xcb_key_grabs_num = 0;
|
|
Ecore_X_Window *_ecore_xcb_button_grabs = NULL;
|
|
Ecore_X_Window *_ecore_xcb_key_grabs = NULL;
|
|
Eina_Bool (*_ecore_xcb_window_grab_replay_func)(void *data,
|
|
int type,
|
|
void *event);
|
|
void *_ecore_xcb_window_grab_replay_data;
|
|
|
|
/**
|
|
* @defgroup Ecore_X_Window_Create_Group X Window Creation Functions
|
|
* @ingroup Ecore
|
|
*
|
|
* Functions that can be used to create an X window.
|
|
*/
|
|
|
|
/**
|
|
* Creates a new window.
|
|
* @param parent The parent window to use. If @p parent is @c 0, the root
|
|
* window of the default display is used.
|
|
* @param x X position.
|
|
* @param y Y position.
|
|
* @param w Width.
|
|
* @param h Height.
|
|
* @return The new window handle.
|
|
* @ingroup Ecore_X_Window_Create_Group
|
|
*/
|
|
EAPI Ecore_X_Window
|
|
ecore_x_window_new(Ecore_X_Window parent,
|
|
int x,
|
|
int y,
|
|
int w,
|
|
int h)
|
|
{
|
|
Ecore_X_Window win;
|
|
uint32_t mask, mask_list[9];
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
if (parent == 0)
|
|
parent = ((xcb_screen_t *)_ecore_xcb_screen)->root;
|
|
|
|
/* NB: Order here is very important due to xcb_cw_t enum */
|
|
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] = 0;
|
|
mask_list[6] = 0;
|
|
mask_list[7] = (XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
|
|
XCB_EVENT_MASK_BUTTON_PRESS |
|
|
XCB_EVENT_MASK_BUTTON_RELEASE |
|
|
XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
|
|
XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE |
|
|
XCB_EVENT_MASK_VISIBILITY_CHANGE |
|
|
XCB_EVENT_MASK_STRUCTURE_NOTIFY |
|
|
XCB_EVENT_MASK_FOCUS_CHANGE |
|
|
XCB_EVENT_MASK_PROPERTY_CHANGE |
|
|
XCB_EVENT_MASK_COLOR_MAP_CHANGE);
|
|
mask_list[8] = XCB_EVENT_MASK_NO_EVENT;
|
|
|
|
win = xcb_generate_id(_ecore_xcb_conn);
|
|
xcb_create_window(_ecore_xcb_conn, XCB_COPY_FROM_PARENT,
|
|
win, parent, x, y, w, h, 0,
|
|
XCB_WINDOW_CLASS_INPUT_OUTPUT,
|
|
XCB_COPY_FROM_PARENT, mask, mask_list);
|
|
|
|
if (parent == ((xcb_screen_t *)_ecore_xcb_screen)->root)
|
|
ecore_x_window_defaults_set(win);
|
|
|
|
return win;
|
|
}
|
|
|
|
/**
|
|
* Creates a window with the override redirect attribute set to @c True.
|
|
* @param parent The parent window to use. If @p parent is @c 0, the root
|
|
* window of the default display is used.
|
|
* @param x X position.
|
|
* @param y Y position.
|
|
* @param w Width.
|
|
* @param h Height.
|
|
* @return The new window handle.
|
|
* @ingroup Ecore_X_Window_Create_Group
|
|
*/
|
|
EAPI Ecore_X_Window
|
|
ecore_x_window_override_new(Ecore_X_Window parent,
|
|
int x,
|
|
int y,
|
|
int w,
|
|
int h)
|
|
{
|
|
Ecore_X_Window win;
|
|
uint32_t mask, mask_list[9];
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
if (parent == 0)
|
|
parent = ((xcb_screen_t *)_ecore_xcb_screen)->root;
|
|
|
|
/* NB: Order here is very important due to xcb_cw_t enum */
|
|
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_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
|
|
XCB_EVENT_MASK_BUTTON_PRESS |
|
|
XCB_EVENT_MASK_BUTTON_RELEASE |
|
|
XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
|
|
XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE |
|
|
XCB_EVENT_MASK_VISIBILITY_CHANGE |
|
|
XCB_EVENT_MASK_STRUCTURE_NOTIFY |
|
|
XCB_EVENT_MASK_FOCUS_CHANGE |
|
|
XCB_EVENT_MASK_PROPERTY_CHANGE |
|
|
XCB_EVENT_MASK_COLOR_MAP_CHANGE);
|
|
mask_list[8] = XCB_EVENT_MASK_NO_EVENT;
|
|
|
|
win = xcb_generate_id(_ecore_xcb_conn);
|
|
xcb_create_window(_ecore_xcb_conn, XCB_COPY_FROM_PARENT,
|
|
win, parent, x, y, w, h, 0,
|
|
XCB_WINDOW_CLASS_INPUT_OUTPUT,
|
|
XCB_COPY_FROM_PARENT, mask, mask_list);
|
|
|
|
return win;
|
|
}
|
|
|
|
/**
|
|
* Creates a new input window.
|
|
* @param parent The parent window to use. If @p parent is @c 0, the root
|
|
* window of the default display is used.
|
|
* @param x X position.
|
|
* @param y Y position.
|
|
* @param w Width.
|
|
* @param h Height.
|
|
* @return The new window.
|
|
* @ingroup Ecore_X_Window_Create_Group
|
|
*/
|
|
EAPI Ecore_X_Window
|
|
ecore_x_window_input_new(Ecore_X_Window parent,
|
|
int x,
|
|
int y,
|
|
int w,
|
|
int h)
|
|
{
|
|
Ecore_X_Window win;
|
|
uint32_t mask, mask_list[3];
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__)
|
|
CHECK_XCB_CONN;
|
|
|
|
if (parent == 0)
|
|
parent = ((xcb_screen_t *)_ecore_xcb_screen)->root;
|
|
|
|
/* NB: Order here is very important due to xcb_cw_t enum */
|
|
mask = (XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK |
|
|
XCB_CW_DONT_PROPAGATE);
|
|
|
|
mask_list[0] = 1;
|
|
mask_list[1] = (XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
|
|
XCB_EVENT_MASK_BUTTON_PRESS |
|
|
XCB_EVENT_MASK_BUTTON_RELEASE |
|
|
XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
|
|
XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE |
|
|
XCB_EVENT_MASK_VISIBILITY_CHANGE |
|
|
XCB_EVENT_MASK_STRUCTURE_NOTIFY |
|
|
XCB_EVENT_MASK_FOCUS_CHANGE |
|
|
XCB_EVENT_MASK_PROPERTY_CHANGE |
|
|
XCB_EVENT_MASK_COLOR_MAP_CHANGE);
|
|
mask_list[2] = XCB_EVENT_MASK_NO_EVENT;
|
|
|
|
win = xcb_generate_id(_ecore_xcb_conn);
|
|
xcb_create_window(_ecore_xcb_conn, XCB_COPY_FROM_PARENT,
|
|
win, parent, x, y, w, h, 0,
|
|
XCB_WINDOW_CLASS_INPUT_ONLY,
|
|
XCB_COPY_FROM_PARENT, mask, mask_list);
|
|
|
|
return win;
|
|
}
|
|
|
|
/**
|
|
* Creates a new window.
|
|
* @param parent The parent window to use. If @p parent is @c 0, the root
|
|
* window of the default display is used.
|
|
* @param x X position.
|
|
* @param y Y position.
|
|
* @param w Width.
|
|
* @param h Height.
|
|
* @return The new window handle.
|
|
* @ingroup Ecore_X_Window_Create_Group
|
|
*/
|
|
EAPI Ecore_X_Window
|
|
ecore_x_window_manager_argb_new(Ecore_X_Window parent,
|
|
int x,
|
|
int y,
|
|
int w,
|
|
int h)
|
|
{
|
|
Ecore_X_Window win = 0;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
win = _ecore_xcb_window_argb_internal_new(parent, x, y, w, h, 1, 0);
|
|
|
|
return win;
|
|
}
|
|
|
|
/**
|
|
* Creates a new window.
|
|
* @param parent The parent window to use. If @p parent is @c 0, the root
|
|
* window of the default display is used.
|
|
* @param x X position.
|
|
* @param y Y position.
|
|
* @param w Width.
|
|
* @param h Height.
|
|
* @return The new window handle.
|
|
* @ingroup Ecore_X_Window_Create_Group
|
|
*/
|
|
EAPI Ecore_X_Window
|
|
ecore_x_window_argb_new(Ecore_X_Window parent,
|
|
int x,
|
|
int y,
|
|
int w,
|
|
int h)
|
|
{
|
|
Ecore_X_Window win = 0;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
win = _ecore_xcb_window_argb_internal_new(parent, x, y, w, h, 0, 0);
|
|
|
|
return win;
|
|
}
|
|
|
|
/**
|
|
* Creates a window with the override redirect attribute set to @c True.
|
|
* @param parent The parent window to use. If @p parent is @c 0, the root
|
|
* window of the default display is used.
|
|
* @param x X position.
|
|
* @param y Y position.
|
|
* @param w Width.
|
|
* @param h Height.
|
|
* @return The new window handle.
|
|
* @ingroup Ecore_X_Window_Create_Group
|
|
*/
|
|
EAPI Ecore_X_Window
|
|
ecore_x_window_override_argb_new(Ecore_X_Window parent,
|
|
int x,
|
|
int y,
|
|
int w,
|
|
int h)
|
|
{
|
|
Ecore_X_Window win = 0;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
win = _ecore_xcb_window_argb_internal_new(parent, x, y, w, h, 1, 0);
|
|
|
|
return win;
|
|
}
|
|
|
|
/**
|
|
* @defgroup Ecore_X_Window_Destroy_Group X Window Destroy Functions
|
|
* @ingroup Ecore
|
|
*
|
|
* Functions to destroy X windows.
|
|
*/
|
|
|
|
/**
|
|
* Deletes the given window.
|
|
* @param win The given window.
|
|
* @ingroup Ecore_X_Window_Destroy_Group
|
|
*/
|
|
EAPI void
|
|
ecore_x_window_free(Ecore_X_Window win)
|
|
{
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
if (win)
|
|
{
|
|
/* xcb_destroy_notify_event_t ev; */
|
|
/* Ecore_X_Window root; */
|
|
|
|
/* if (xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)).rem == 1) */
|
|
/* root = ((xcb_screen_t *)_ecore_xcb_screen)->root; */
|
|
/* else */
|
|
/* { */
|
|
/* xcb_get_geometry_cookie_t cookie; */
|
|
/* xcb_get_geometry_reply_t *reply; */
|
|
|
|
/* cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, win); */
|
|
/* reply = xcb_get_geometry_reply(_ecore_xcb_conn, cookie, NULL); */
|
|
/* if (!reply) return; */
|
|
/* root = reply->root; */
|
|
/* free(reply); */
|
|
/* } */
|
|
|
|
/* memset(&ev, 0, sizeof(xcb_destroy_notify_event_t)); */
|
|
|
|
/* ev.response_type = XCB_DESTROY_NOTIFY; */
|
|
/* ev.window = win; */
|
|
/* ev.event = root; */
|
|
|
|
/* xcb_send_event(_ecore_xcb_conn, 0, root, */
|
|
/* XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | */
|
|
/* XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, */
|
|
/* (const char *)&ev); */
|
|
|
|
xcb_destroy_window(_ecore_xcb_conn, win);
|
|
// ecore_x_flush();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sends a delete request to the given window.
|
|
* @param win The given window.
|
|
* @ingroup Ecore_X_Window_Destroy_Group
|
|
*/
|
|
EAPI void
|
|
ecore_x_window_delete_request_send(Ecore_X_Window win)
|
|
{
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
if (!win) return;
|
|
ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS,
|
|
XCB_EVENT_MASK_NO_EVENT,
|
|
ECORE_X_ATOM_WM_DELETE_WINDOW,
|
|
XCB_CURRENT_TIME, 0, 0, 0);
|
|
}
|
|
|
|
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)
|
|
{
|
|
uint16_t vmask = 0;
|
|
uint32_t vlist[7];
|
|
unsigned int i = 0;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
if (!win) return;
|
|
|
|
if (mask & XCB_CONFIG_WINDOW_X)
|
|
{
|
|
vmask |= XCB_CONFIG_WINDOW_X;
|
|
vlist[i++] = x;
|
|
}
|
|
if (mask & XCB_CONFIG_WINDOW_Y)
|
|
{
|
|
vmask |= XCB_CONFIG_WINDOW_Y;
|
|
vlist[i++] = y;
|
|
}
|
|
if (mask & XCB_CONFIG_WINDOW_WIDTH)
|
|
{
|
|
vmask |= XCB_CONFIG_WINDOW_WIDTH;
|
|
vlist[i++] = w;
|
|
}
|
|
if (mask & XCB_CONFIG_WINDOW_HEIGHT)
|
|
{
|
|
vmask |= XCB_CONFIG_WINDOW_HEIGHT;
|
|
vlist[i++] = h;
|
|
}
|
|
if (mask & XCB_CONFIG_WINDOW_BORDER_WIDTH)
|
|
{
|
|
vmask |= XCB_CONFIG_WINDOW_BORDER_WIDTH;
|
|
vlist[i++] = border_width;
|
|
}
|
|
if (mask & XCB_CONFIG_WINDOW_SIBLING)
|
|
{
|
|
vmask |= XCB_CONFIG_WINDOW_SIBLING;
|
|
vlist[i++] = sibling;
|
|
}
|
|
if (mask & XCB_CONFIG_WINDOW_STACK_MODE)
|
|
{
|
|
vmask |= XCB_CONFIG_WINDOW_STACK_MODE;
|
|
vlist[i++] = stack_mode;
|
|
}
|
|
|
|
xcb_configure_window(_ecore_xcb_conn, win, vmask,
|
|
(const uint32_t *)&vlist);
|
|
// ecore_x_flush();
|
|
}
|
|
|
|
/**
|
|
* @defgroup Ecore_X_Window_Geometry_Group X Window Geometry Functions
|
|
* @ingroup Ecore
|
|
*
|
|
* Functions that change or retrieve the geometry of X windows.
|
|
*/
|
|
|
|
/**
|
|
* Moves a window to the position @p x, @p y.
|
|
*
|
|
* The position is relative to the upper left hand corner of the
|
|
* parent window.
|
|
*
|
|
* @param win The window to move.
|
|
* @param x X position.
|
|
* @param y Y position.
|
|
* @ingroup Ecore_X_Window_Geometry_Group
|
|
*/
|
|
EAPI void
|
|
ecore_x_window_move(Ecore_X_Window win,
|
|
int x,
|
|
int y)
|
|
{
|
|
uint32_t list[2], mask;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
if (!win) return;
|
|
|
|
mask = (XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y);
|
|
list[0] = x;
|
|
list[1] = y;
|
|
|
|
xcb_configure_window(_ecore_xcb_conn, win, mask,
|
|
(const uint32_t *)&list);
|
|
// ecore_x_flush();
|
|
}
|
|
|
|
/**
|
|
* Resizes a window.
|
|
* @param win The window to resize.
|
|
* @param w New width of the window.
|
|
* @param h New height of the window.
|
|
* @ingroup Ecore_X_Window_Geometry_Group
|
|
*/
|
|
EAPI void
|
|
ecore_x_window_resize(Ecore_X_Window win,
|
|
int w,
|
|
int h)
|
|
{
|
|
uint32_t list[2], mask;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
if (!win) return;
|
|
if (w < 1) w = 1;
|
|
if (h < 1) h = 1;
|
|
|
|
mask = (XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT);
|
|
list[0] = w;
|
|
list[1] = h;
|
|
|
|
xcb_configure_window(_ecore_xcb_conn, win, mask,
|
|
(const uint32_t *)&list);
|
|
// ecore_x_flush();
|
|
}
|
|
|
|
/**
|
|
* Moves and resizes a window.
|
|
* @param win The window to move and resize.
|
|
* @param x New X position of the window.
|
|
* @param y New Y position of the window.
|
|
* @param w New width of the window.
|
|
* @param h New height of the window.
|
|
* @ingroup Ecore_X_Window_Geometry_Group
|
|
*/
|
|
EAPI void
|
|
ecore_x_window_move_resize(Ecore_X_Window win,
|
|
int x,
|
|
int y,
|
|
int w,
|
|
int h)
|
|
{
|
|
uint32_t list[4], mask;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
if (!win) return;
|
|
if (w < 1) w = 1;
|
|
if (h < 1) h = 1;
|
|
|
|
mask = (XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y |
|
|
XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT);
|
|
list[0] = x;
|
|
list[1] = y;
|
|
list[2] = w;
|
|
list[3] = h;
|
|
|
|
xcb_configure_window(_ecore_xcb_conn, win, mask,
|
|
(const uint32_t *)&list);
|
|
// ecore_x_flush();
|
|
}
|
|
|
|
/**
|
|
* Retrieves the width of the border of the given window.
|
|
* @param win The given window.
|
|
* @return Width of the border of @p win.
|
|
* @ingroup Ecore_X_Window_Geometry_Group
|
|
*/
|
|
EAPI int
|
|
ecore_x_window_border_width_get(Ecore_X_Window win)
|
|
{
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
if (!win) return 0;
|
|
return ecore_x_drawable_border_width_get(win);
|
|
}
|
|
|
|
/**
|
|
* Sets the width of the border of the given window.
|
|
* @param win The given window.
|
|
* @param width The new border width.
|
|
* @ingroup Ecore_X_Window_Geometry_Group
|
|
*/
|
|
EAPI void
|
|
ecore_x_window_border_width_set(Ecore_X_Window win,
|
|
int border_width)
|
|
{
|
|
uint32_t list;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
if (!win) return;
|
|
|
|
list = border_width;
|
|
|
|
xcb_configure_window(_ecore_xcb_conn, win,
|
|
XCB_CONFIG_WINDOW_BORDER_WIDTH, &list);
|
|
// ecore_x_flush();
|
|
}
|
|
|
|
/**
|
|
* @defgroup Ecore_X_Window_Z_Order_Group X Window Z Order Functions
|
|
* @ingroup Ecore
|
|
*
|
|
* Functions that change the Z order of X windows.
|
|
*/
|
|
|
|
/**
|
|
* Raises the given window.
|
|
* @param win The window to raise.
|
|
* @ingroup Ecore_X_Window_Z_Order_Group
|
|
*/
|
|
EAPI void
|
|
ecore_x_window_raise(Ecore_X_Window win)
|
|
{
|
|
uint32_t list[] = { XCB_STACK_MODE_ABOVE };
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
xcb_configure_window(_ecore_xcb_conn, win,
|
|
XCB_CONFIG_WINDOW_STACK_MODE, list);
|
|
// ecore_x_flush();
|
|
}
|
|
|
|
/**
|
|
* Lowers the given window.
|
|
* @param win The window to lower.
|
|
* @ingroup Ecore_X_Window_Z_Order_Group
|
|
*/
|
|
EAPI void
|
|
ecore_x_window_lower(Ecore_X_Window win)
|
|
{
|
|
uint32_t list[] = { XCB_STACK_MODE_BELOW };
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
xcb_configure_window(_ecore_xcb_conn, win,
|
|
XCB_CONFIG_WINDOW_STACK_MODE, list);
|
|
// ecore_x_flush();
|
|
}
|
|
|
|
/**
|
|
* Retrieves the depth of the given window.
|
|
* @param win The given window.
|
|
* @return Depth of the window.
|
|
*/
|
|
EAPI int
|
|
ecore_x_window_depth_get(Ecore_X_Window win)
|
|
{
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
return ecore_x_drawable_depth_get(win);
|
|
}
|
|
|
|
/**
|
|
* @defgroup Ecore_X_Window_Properties_Group X Window Property Functions
|
|
* @ingroup Ecore
|
|
*
|
|
* Functions that set window properties.
|
|
*/
|
|
|
|
/**
|
|
* Sets the default properties for the given window.
|
|
*
|
|
* The default properties set for the window are @c WM_CLIENT_MACHINE and
|
|
* @c _NET_WM_PID.
|
|
*
|
|
* @param win The given window.
|
|
* @ingroup Ecore_X_Window_Properties_Group
|
|
*/
|
|
EAPI void
|
|
ecore_x_window_defaults_set(Ecore_X_Window win)
|
|
{
|
|
char buff[MAXHOSTNAMELEN], **argv;
|
|
int argc;
|
|
pid_t pid;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
gethostname(buff, MAXHOSTNAMELEN);
|
|
buff[MAXHOSTNAMELEN - 1] = '\0';
|
|
|
|
xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win,
|
|
ECORE_X_ATOM_WM_CLIENT_MACHINE, ECORE_X_ATOM_STRING,
|
|
8, strlen(buff), buff);
|
|
|
|
pid = getpid();
|
|
ecore_x_netwm_pid_set(win, pid);
|
|
ecore_x_netwm_window_type_set(win, ECORE_X_WINDOW_TYPE_NORMAL);
|
|
ecore_app_args_get(&argc, &argv);
|
|
ecore_x_icccm_command_set(win, argc, argv);
|
|
}
|
|
|
|
/**
|
|
* @defgroup Ecore_X_Window_Visibility_Group X Window Visibility Functions
|
|
* @ingroup Ecore
|
|
*
|
|
* Functions to access and change the visibility of X windows.
|
|
*/
|
|
|
|
/**
|
|
* Shows a window.
|
|
*
|
|
* Synonymous to "mapping" a window in X Window System terminology.
|
|
*
|
|
* @param win The window to show.
|
|
* @ingroup Ecore_X_Window_Visibility
|
|
*/
|
|
EAPI void
|
|
ecore_x_window_show(Ecore_X_Window win)
|
|
{
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
if (win)
|
|
xcb_map_window(_ecore_xcb_conn, win);
|
|
}
|
|
|
|
/**
|
|
* Hides a window.
|
|
*
|
|
* Synonymous to "unmapping" a window in X Window System terminology.
|
|
*
|
|
* @param win The window to hide.
|
|
* @ingroup Ecore_X_Window_Visibility
|
|
*/
|
|
EAPI void
|
|
ecore_x_window_hide(Ecore_X_Window win)
|
|
{
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
if (win)
|
|
{
|
|
xcb_unmap_notify_event_t ev;
|
|
Ecore_X_Window root;
|
|
|
|
if (xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)).rem == 1)
|
|
root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
|
|
else
|
|
{
|
|
xcb_get_geometry_cookie_t cookie;
|
|
xcb_get_geometry_reply_t *reply;
|
|
|
|
cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, win);
|
|
reply = xcb_get_geometry_reply(_ecore_xcb_conn, cookie, NULL);
|
|
if (!reply) return;
|
|
root = reply->root;
|
|
free(reply);
|
|
}
|
|
|
|
xcb_unmap_window(_ecore_xcb_conn, win);
|
|
memset(&ev, 0, sizeof(xcb_unmap_notify_event_t));
|
|
|
|
ev.response_type = XCB_UNMAP_NOTIFY;
|
|
ev.window = win;
|
|
ev.event = root;
|
|
ev.from_configure = 0;
|
|
|
|
xcb_send_event(_ecore_xcb_conn, 0, root,
|
|
(XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
|
|
XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT),
|
|
(const char *)&ev);
|
|
|
|
// ecore_x_flush();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @defgroup Ecore_X_Window_Focus_Functions X Window Focus Functions
|
|
* @ingroup Ecore
|
|
*
|
|
* Functions that give the focus to an X Window.
|
|
*/
|
|
|
|
/**
|
|
* Sets the focus to the window @p win.
|
|
* @param win The window to focus.
|
|
* @ingroup Ecore_X_Window_Focus_Functions
|
|
*/
|
|
EAPI void
|
|
ecore_x_window_focus(Ecore_X_Window win)
|
|
{
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
|
|
|
|
xcb_set_input_focus(_ecore_xcb_conn,
|
|
XCB_INPUT_FOCUS_PARENT, win, XCB_CURRENT_TIME);
|
|
// ecore_x_flush();
|
|
}
|
|
|
|
/**
|
|
* Sets the focus to the given window at a specific time.
|
|
* @param win The window to focus.
|
|
* @param t When to set the focus to the window.
|
|
* @ingroup Ecore_X_Window_Focus_Functions
|
|
*/
|
|
EAPI void
|
|
ecore_x_window_focus_at_time(Ecore_X_Window win,
|
|
Ecore_X_Time time EINA_UNUSED)
|
|
{
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
|
|
xcb_set_input_focus(_ecore_xcb_conn,
|
|
XCB_INPUT_FOCUS_PARENT, win, XCB_CURRENT_TIME);
|
|
// ecore_x_flush();
|
|
}
|
|
|
|
/**
|
|
* @defgroup Ecore_X_Window_Parent_Group X Window Parent Functions
|
|
* @ingroup Ecore
|
|
*
|
|
* Functions that retrieve or changes the parent window of a window.
|
|
*/
|
|
|
|
/**
|
|
* Moves a window to within another window at a given position.
|
|
* @param win The window to reparent.
|
|
* @param new_parent The new parent window.
|
|
* @param x X position within new parent window.
|
|
* @param y Y position within new parent window.
|
|
* @ingroup Ecore_X_Window_Parent_Group
|
|
*/
|
|
EAPI void
|
|
ecore_x_window_reparent(Ecore_X_Window win,
|
|
Ecore_X_Window parent,
|
|
int x,
|
|
int y)
|
|
{
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
if (parent == 0)
|
|
parent = ((xcb_screen_t *)_ecore_xcb_screen)->root;
|
|
|
|
xcb_reparent_window(_ecore_xcb_conn, win, parent, x, y);
|
|
// ecore_x_flush();
|
|
}
|
|
|
|
EAPI void
|
|
ecore_x_window_pixmap_set(Ecore_X_Window win,
|
|
Ecore_X_Pixmap pixmap)
|
|
{
|
|
uint32_t list;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
list = pixmap;
|
|
|
|
xcb_change_window_attributes(_ecore_xcb_conn, win,
|
|
XCB_CW_BACK_PIXMAP, &list);
|
|
// ecore_x_flush();
|
|
}
|
|
|
|
/**
|
|
* Sets the background color of the given window.
|
|
* @param win The given window
|
|
* @param r red value (0...65536, 16 bits)
|
|
* @param g green value (0...65536, 16 bits)
|
|
* @param b blue value (0...65536, 16 bits)
|
|
*/
|
|
EAPI void
|
|
ecore_x_window_background_color_set(Ecore_X_Window win,
|
|
unsigned short red,
|
|
unsigned short green,
|
|
unsigned short blue)
|
|
{
|
|
xcb_alloc_color_cookie_t cookie;
|
|
xcb_alloc_color_reply_t *reply;
|
|
uint32_t list;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
cookie =
|
|
xcb_alloc_color_unchecked(_ecore_xcb_conn,
|
|
((xcb_screen_t *)_ecore_xcb_screen)->default_colormap,
|
|
red, green, blue);
|
|
reply = xcb_alloc_color_reply(_ecore_xcb_conn, cookie, NULL);
|
|
if (!reply) return;
|
|
list = reply->pixel;
|
|
free(reply);
|
|
|
|
xcb_change_window_attributes(_ecore_xcb_conn, win,
|
|
XCB_CW_BACK_PIXEL, &list);
|
|
// ecore_x_flush();
|
|
}
|
|
|
|
EAPI void
|
|
ecore_x_window_pixel_gravity_set(Ecore_X_Window win,
|
|
Ecore_X_Gravity gravity)
|
|
{
|
|
uint32_t list;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
list = gravity;
|
|
|
|
xcb_change_window_attributes(_ecore_xcb_conn, win,
|
|
XCB_CW_BIT_GRAVITY, &list);
|
|
// ecore_x_flush();
|
|
}
|
|
|
|
EAPI void
|
|
ecore_x_window_gravity_set(Ecore_X_Window win,
|
|
Ecore_X_Gravity gravity)
|
|
{
|
|
uint32_t list;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
list = gravity;
|
|
|
|
xcb_change_window_attributes(_ecore_xcb_conn, win,
|
|
XCB_CW_WIN_GRAVITY, &list);
|
|
// ecore_x_flush();
|
|
}
|
|
|
|
EAPI void
|
|
ecore_x_window_override_set(Ecore_X_Window win,
|
|
Eina_Bool override)
|
|
{
|
|
uint32_t list;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
list = override;
|
|
|
|
xcb_change_window_attributes(_ecore_xcb_conn, win,
|
|
XCB_CW_OVERRIDE_REDIRECT, &list);
|
|
// ecore_x_flush();
|
|
}
|
|
|
|
/**
|
|
* @brief Show the cursor on a window of type Ecore_X_Window.
|
|
* @param win The window for which the cursor will be showed.
|
|
* @param show Enables the show of the cursor on the window if equals EINA_TRUE, disables if equals EINA_FALSE.
|
|
*/
|
|
EAPI void
|
|
ecore_x_window_cursor_show(Ecore_X_Window win,
|
|
Eina_Bool show)
|
|
{
|
|
uint32_t list = 0;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
|
|
|
|
if (!show)
|
|
{
|
|
Ecore_X_Cursor cursor;
|
|
Ecore_X_Pixmap p, m;
|
|
Ecore_X_GC gc;
|
|
xcb_point_t point;
|
|
|
|
p = xcb_generate_id(_ecore_xcb_conn);
|
|
xcb_create_pixmap(_ecore_xcb_conn, 1, p, win, 1, 1);
|
|
m = xcb_generate_id(_ecore_xcb_conn);
|
|
xcb_create_pixmap(_ecore_xcb_conn, 1, m, win, 1, 1);
|
|
gc = xcb_generate_id(_ecore_xcb_conn);
|
|
xcb_create_gc(_ecore_xcb_conn, gc, win, 0, NULL);
|
|
xcb_change_gc(_ecore_xcb_conn, gc, XCB_GC_FOREGROUND, &list);
|
|
point.x = 0;
|
|
point.y = 0;
|
|
xcb_poly_point(_ecore_xcb_conn, XCB_COORD_MODE_ORIGIN,
|
|
win, gc, 1, &point);
|
|
xcb_free_gc(_ecore_xcb_conn, gc);
|
|
|
|
cursor = xcb_generate_id(_ecore_xcb_conn);
|
|
xcb_create_cursor(_ecore_xcb_conn, cursor,
|
|
p, m, 0, 0, 0, 0, 0, 0, 0, 0);
|
|
list = cursor;
|
|
|
|
xcb_change_window_attributes(_ecore_xcb_conn, win,
|
|
XCB_CW_CURSOR, &list);
|
|
|
|
xcb_free_cursor(_ecore_xcb_conn, cursor);
|
|
xcb_free_pixmap(_ecore_xcb_conn, m);
|
|
xcb_free_pixmap(_ecore_xcb_conn, p);
|
|
}
|
|
else
|
|
{
|
|
xcb_change_window_attributes(_ecore_xcb_conn, win,
|
|
XCB_CW_CURSOR, &list);
|
|
}
|
|
// ecore_x_flush();
|
|
}
|
|
|
|
EAPI void
|
|
ecore_x_window_cursor_set(Ecore_X_Window win,
|
|
Ecore_X_Cursor cursor)
|
|
{
|
|
uint32_t list;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
list = cursor;
|
|
|
|
xcb_change_window_attributes(_ecore_xcb_conn, win, XCB_CW_CURSOR, &list);
|
|
// ecore_x_flush();
|
|
}
|
|
|
|
EAPI void
|
|
ecore_x_window_container_manage(Ecore_X_Window win)
|
|
{
|
|
uint32_t list;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
list = (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
|
|
XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY);
|
|
|
|
xcb_change_window_attributes(_ecore_xcb_conn, win,
|
|
XCB_CW_EVENT_MASK, &list);
|
|
// ecore_x_flush();
|
|
}
|
|
|
|
EAPI void
|
|
ecore_x_window_client_manage(Ecore_X_Window win)
|
|
{
|
|
uint32_t list;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
list = (XCB_EVENT_MASK_VISIBILITY_CHANGE |
|
|
XCB_EVENT_MASK_FOCUS_CHANGE |
|
|
XCB_EVENT_MASK_PROPERTY_CHANGE |
|
|
XCB_EVENT_MASK_COLOR_MAP_CHANGE |
|
|
XCB_EVENT_MASK_STRUCTURE_NOTIFY |
|
|
XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY);
|
|
|
|
xcb_change_window_attributes(_ecore_xcb_conn, win,
|
|
XCB_CW_EVENT_MASK, &list);
|
|
|
|
#ifdef ECORE_XCB_SHAPE
|
|
xcb_shape_select_input(_ecore_xcb_conn, win, EINA_TRUE);
|
|
#endif
|
|
// ecore_x_flush();
|
|
}
|
|
|
|
EAPI void
|
|
ecore_x_window_sniff(Ecore_X_Window win)
|
|
{
|
|
uint32_t list;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
list = (XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
|
|
XCB_EVENT_MASK_PROPERTY_CHANGE);
|
|
|
|
xcb_change_window_attributes(_ecore_xcb_conn, win,
|
|
XCB_CW_EVENT_MASK, &list);
|
|
// ecore_x_flush();
|
|
}
|
|
|
|
EAPI void
|
|
ecore_x_window_client_sniff(Ecore_X_Window win)
|
|
{
|
|
uint32_t list;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
list = (XCB_EVENT_MASK_VISIBILITY_CHANGE |
|
|
XCB_EVENT_MASK_STRUCTURE_NOTIFY |
|
|
XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
|
|
XCB_EVENT_MASK_FOCUS_CHANGE |
|
|
XCB_EVENT_MASK_PROPERTY_CHANGE |
|
|
XCB_EVENT_MASK_COLOR_MAP_CHANGE);
|
|
|
|
xcb_change_window_attributes(_ecore_xcb_conn, win,
|
|
XCB_CW_EVENT_MASK, &list);
|
|
#ifdef ECORE_XCB_SHAPE
|
|
xcb_shape_select_input(_ecore_xcb_conn, win, EINA_TRUE);
|
|
#endif
|
|
// ecore_x_flush();
|
|
}
|
|
|
|
EAPI void
|
|
ecore_x_window_area_clear(Ecore_X_Window win,
|
|
int x,
|
|
int y,
|
|
int w,
|
|
int h)
|
|
{
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
xcb_clear_area(_ecore_xcb_conn, 0, win, x, y, w, h);
|
|
// ecore_x_flush();
|
|
}
|
|
|
|
EAPI void
|
|
ecore_x_window_area_expose(Ecore_X_Window win,
|
|
int x,
|
|
int y,
|
|
int w,
|
|
int h)
|
|
{
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
xcb_clear_area(_ecore_xcb_conn, 1, win, x, y, w, h);
|
|
// ecore_x_flush();
|
|
}
|
|
|
|
EAPI void
|
|
ecore_x_window_save_set_add(Ecore_X_Window win)
|
|
{
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
xcb_change_save_set(_ecore_xcb_conn, XCB_SET_MODE_INSERT, win);
|
|
}
|
|
|
|
EAPI void
|
|
ecore_x_window_save_set_del(Ecore_X_Window win)
|
|
{
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
xcb_change_save_set(_ecore_xcb_conn, XCB_SET_MODE_DELETE, win);
|
|
}
|
|
|
|
/**
|
|
* gets the window that has focus.
|
|
* @return The window that has focus.
|
|
* @ingroup Ecore_X_Window_Focus_Functions
|
|
*/
|
|
EAPI Ecore_X_Window
|
|
ecore_x_window_focus_get(void)
|
|
{
|
|
xcb_get_input_focus_cookie_t cookie;
|
|
xcb_get_input_focus_reply_t *reply;
|
|
Ecore_X_Window focus = 0;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
cookie = xcb_get_input_focus_unchecked(_ecore_xcb_conn);
|
|
reply = xcb_get_input_focus_reply(_ecore_xcb_conn, cookie, NULL);
|
|
if (!reply) return 0;
|
|
focus = reply->focus;
|
|
free(reply);
|
|
return focus;
|
|
}
|
|
|
|
EAPI int
|
|
ecore_x_window_argb_get(Ecore_X_Window win)
|
|
{
|
|
uint8_t ret = 0;
|
|
#ifdef ECORE_XCB_RENDER
|
|
Ecore_X_Visual visual;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
// if (!win) return ret;
|
|
|
|
#ifdef ECORE_XCB_RENDER
|
|
/* grab the window's visual */
|
|
visual = _ecore_xcb_window_visual_get(win);
|
|
|
|
/* check if this visual supports alpha */
|
|
ret = _ecore_xcb_render_visual_supports_alpha(visual);
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
ecore_x_window_manage(Ecore_X_Window win)
|
|
{
|
|
xcb_get_window_attributes_cookie_t cookie;
|
|
xcb_get_window_attributes_reply_t *reply;
|
|
xcb_void_cookie_t change_cookie;
|
|
xcb_generic_error_t *err;
|
|
uint32_t list;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
cookie = xcb_get_window_attributes(_ecore_xcb_conn, win);
|
|
reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL);
|
|
if (!reply) return EINA_FALSE;
|
|
|
|
ecore_x_sync(); // needed
|
|
|
|
list = (XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
|
|
XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_RESIZE_REDIRECT |
|
|
XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
|
|
XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
|
|
XCB_EVENT_MASK_STRUCTURE_NOTIFY |
|
|
XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
|
|
reply->your_event_mask);
|
|
free(reply);
|
|
|
|
change_cookie = xcb_change_window_attributes(_ecore_xcb_conn, win,
|
|
XCB_CW_EVENT_MASK, &list);
|
|
|
|
ecore_x_sync(); // needed
|
|
|
|
err = xcb_request_check(_ecore_xcb_conn, change_cookie);
|
|
if (err)
|
|
{
|
|
_ecore_xcb_error_handle(err);
|
|
free(err);
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
ecore_x_window_attributes_get(Ecore_X_Window win,
|
|
Ecore_X_Window_Attributes *att_ret)
|
|
{
|
|
xcb_get_window_attributes_cookie_t cookie;
|
|
xcb_get_window_attributes_reply_t *reply;
|
|
xcb_get_geometry_cookie_t gcookie;
|
|
xcb_get_geometry_reply_t *greply;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, win);
|
|
reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL);
|
|
if (!reply) return EINA_FALSE;
|
|
|
|
memset(att_ret, 0, sizeof(Ecore_X_Window_Attributes));
|
|
|
|
if (reply->map_state != XCB_MAP_STATE_UNMAPPED)
|
|
att_ret->visible = EINA_TRUE;
|
|
|
|
if (reply->map_state == XCB_MAP_STATE_VIEWABLE)
|
|
att_ret->viewable = EINA_TRUE;
|
|
|
|
if (reply->override_redirect)
|
|
att_ret->override = EINA_TRUE;
|
|
|
|
if (reply->_class == XCB_WINDOW_CLASS_INPUT_ONLY)
|
|
att_ret->input_only = EINA_TRUE;
|
|
|
|
if (reply->save_under)
|
|
att_ret->save_under = EINA_TRUE;
|
|
|
|
att_ret->event_mask.mine = reply->your_event_mask;
|
|
att_ret->event_mask.all = reply->all_event_masks;
|
|
att_ret->event_mask.no_propagate = reply->do_not_propagate_mask;
|
|
att_ret->window_gravity = reply->win_gravity;
|
|
att_ret->pixel_gravity = reply->bit_gravity;
|
|
att_ret->colormap = reply->colormap;
|
|
att_ret->visual = _ecore_xcb_window_find_visual_by_id(reply->visual);
|
|
|
|
free(reply);
|
|
|
|
gcookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, win);
|
|
greply = xcb_get_geometry_reply(_ecore_xcb_conn, gcookie, NULL);
|
|
if (!greply) return EINA_TRUE;
|
|
|
|
/* xcb_translate_coordinates_reply_t *trans; */
|
|
/* xcb_query_tree_cookie_t tcookie; */
|
|
/* xcb_query_tree_reply_t *treply; */
|
|
|
|
/* tcookie = xcb_query_tree(_ecore_xcb_conn, win); */
|
|
/* treply = xcb_query_tree_reply(_ecore_xcb_conn, tcookie, NULL); */
|
|
|
|
/* trans = */
|
|
/* xcb_translate_coordinates_reply(_ecore_xcb_conn, */
|
|
/* xcb_translate_coordinates(_ecore_xcb_conn, */
|
|
/* win, treply->parent, greply->x, greply->y), NULL); */
|
|
/* free(treply); */
|
|
|
|
att_ret->root = greply->root;
|
|
att_ret->depth = greply->depth;
|
|
// att_ret->x = trans->dst_x;
|
|
// att_ret->y = trans->dst_y;
|
|
att_ret->x = greply->x;
|
|
att_ret->y = greply->y;
|
|
att_ret->w = greply->width;
|
|
att_ret->h = greply->height;
|
|
att_ret->border = greply->border_width;
|
|
|
|
// free(trans);
|
|
|
|
free(greply);
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
/**
|
|
* Retrieves the size of the given window.
|
|
* @param win The given window.
|
|
* @param w Pointer to an integer into which the width is to be stored.
|
|
* @param h Pointer to an integer into which the height is to be stored.
|
|
* @ingroup Ecore_X_Window_Geometry_Group
|
|
*/
|
|
EAPI void
|
|
ecore_x_window_size_get(Ecore_X_Window win,
|
|
int *width,
|
|
int *height)
|
|
{
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
|
|
ecore_x_drawable_geometry_get(win, NULL, NULL, width, height);
|
|
}
|
|
|
|
/**
|
|
* Set if a window should be ignored.
|
|
* @param win The given window.
|
|
* @param ignore if to ignore
|
|
*/
|
|
EAPI void
|
|
ecore_x_window_ignore_set(Ecore_X_Window win,
|
|
int ignore)
|
|
{
|
|
int i = 0, j = 0, count = 0;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
if (ignore)
|
|
{
|
|
if (ignore_list)
|
|
{
|
|
for (i = 0; i < ignore_num; i++)
|
|
if (win == ignore_list[i]) return;
|
|
|
|
ignore_list =
|
|
realloc(ignore_list, (ignore_num + 1) * sizeof(Ecore_X_Window));
|
|
if (!ignore_list) return;
|
|
|
|
ignore_list[ignore_num++] = win;
|
|
}
|
|
else
|
|
{
|
|
ignore_num = 0;
|
|
ignore_list = malloc(sizeof(Ecore_X_Window));
|
|
if (!ignore_list) return;
|
|
ignore_list[ignore_num++] = win;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!ignore_list) return;
|
|
for (count = ignore_num, i = 0, j = 0; i < count; i++)
|
|
{
|
|
if (win != ignore_list[i])
|
|
ignore_list[j++] = ignore_list[i];
|
|
else
|
|
ignore_num--;
|
|
}
|
|
if (ignore_num <= 0)
|
|
{
|
|
free(ignore_list);
|
|
ignore_list = NULL;
|
|
return;
|
|
}
|
|
|
|
ignore_list =
|
|
realloc(ignore_list, ignore_num * sizeof(Ecore_X_Window));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the ignore list
|
|
* @param num number of windows in the list
|
|
* @return list of windows to ignore
|
|
*/
|
|
EAPI Ecore_X_Window *
|
|
ecore_x_window_ignore_list(int *num)
|
|
{
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
if (num) *num = ignore_num;
|
|
return ignore_list;
|
|
}
|
|
|
|
/**
|
|
* Get a list of all the root windows on the server.
|
|
*
|
|
* @note The returned array will need to be freed after use.
|
|
* @param num_ret Pointer to integer to put number of windows returned in.
|
|
* @return An array of all the root windows. @c NULL is returned if memory
|
|
* could not be allocated for the list, or if @p num_ret is @c NULL.
|
|
*/
|
|
EAPI Ecore_X_Window *
|
|
ecore_x_window_root_list(int *num_ret)
|
|
{
|
|
xcb_screen_iterator_t iter;
|
|
uint8_t i, num;
|
|
Ecore_X_Window *roots = NULL;
|
|
#ifdef ECORE_XCB_XPRINT
|
|
const xcb_query_extension_reply_t *ext_reply;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
if (!num_ret) return NULL;
|
|
if (num_ret) *num_ret = 0;
|
|
|
|
/* if (xcb_connection_has_error(_ecore_xcb_conn)) */
|
|
/* { */
|
|
/* DBG("XCB Connection Has Error !!!"); */
|
|
/* return NULL; */
|
|
/* } */
|
|
|
|
num = ecore_x_screen_count_get();
|
|
|
|
#ifdef ECORE_XCB_XPRINT
|
|
ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_x_print_id);
|
|
if ((ext_reply) && (ext_reply->present))
|
|
{
|
|
xcb_x_print_print_query_screens_cookie_t cookie;
|
|
xcb_x_print_print_query_screens_reply_t *reply;
|
|
|
|
cookie = xcb_x_print_print_query_screens_unchecked(_ecore_xcb_conn);
|
|
reply =
|
|
xcb_x_print_print_query_screens_reply(_ecore_xcb_conn, cookie, NULL);
|
|
if (reply)
|
|
{
|
|
xcb_window_t *screens;
|
|
int psnum = 0, overlap = 0, j = 0, k = 0;
|
|
|
|
psnum = xcb_x_print_print_query_screens_roots_length(reply);
|
|
screens = xcb_x_print_print_query_screens_roots(reply);
|
|
for (i = 0; i < num; i++)
|
|
{
|
|
for (j = 0; j < psnum; j++)
|
|
{
|
|
xcb_screen_t *s;
|
|
|
|
if ((s = _ecore_xcb_window_screen_of_display(i)))
|
|
{
|
|
if (s->root == screens[j])
|
|
overlap++;
|
|
}
|
|
}
|
|
}
|
|
if (!(roots = malloc((num - overlap)
|
|
* sizeof(Ecore_X_Window)))) return NULL;
|
|
for (i = 0; i < num; i++)
|
|
{
|
|
Eina_Bool is_print = EINA_FALSE;
|
|
|
|
for (j = 0; j < psnum; j++)
|
|
{
|
|
xcb_screen_t *s;
|
|
|
|
if ((s = _ecore_xcb_window_screen_of_display(i)))
|
|
{
|
|
if (s->root == screens[j])
|
|
{
|
|
is_print = EINA_TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (!is_print)
|
|
{
|
|
xcb_screen_t *s;
|
|
|
|
if ((s = _ecore_xcb_window_screen_of_display(i)))
|
|
{
|
|
roots[k] = s->root;
|
|
k++;
|
|
}
|
|
}
|
|
}
|
|
if (num_ret) *num_ret = k;
|
|
free(reply);
|
|
}
|
|
else
|
|
{
|
|
/* Fallback to default method */
|
|
iter =
|
|
xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn));
|
|
if (!(roots = malloc(num * sizeof(Ecore_X_Window)))) return NULL;
|
|
if (num_ret) *num_ret = num;
|
|
for (i = 0; iter.rem; xcb_screen_next(&iter), i++)
|
|
roots[i] = iter.data->root;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Fallback to default method */
|
|
iter =
|
|
xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn));
|
|
if (!(roots = malloc(num * sizeof(Ecore_X_Window)))) return NULL;
|
|
if (num_ret) *num_ret = num;
|
|
for (i = 0; iter.rem; xcb_screen_next(&iter), i++)
|
|
roots[i] = iter.data->root;
|
|
}
|
|
#else
|
|
iter =
|
|
xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn));
|
|
if (!(roots = malloc(num * sizeof(Ecore_X_Window)))) return NULL;
|
|
if (num_ret) *num_ret = num;
|
|
for (i = 0; iter.rem; xcb_screen_next(&iter), i++)
|
|
roots[i] = iter.data->root;
|
|
#endif
|
|
|
|
return roots;
|
|
}
|
|
|
|
EAPI Ecore_X_Window *
|
|
ecore_x_window_children_get(Ecore_X_Window win,
|
|
int *num)
|
|
{
|
|
xcb_query_tree_cookie_t cookie;
|
|
xcb_query_tree_reply_t *reply;
|
|
Ecore_X_Window *windows = NULL;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
if (num) *num = 0;
|
|
cookie = xcb_query_tree_unchecked(_ecore_xcb_conn, win);
|
|
reply = xcb_query_tree_reply(_ecore_xcb_conn, cookie, NULL);
|
|
if (!reply) return NULL;
|
|
|
|
if (num) *num = reply->children_len;
|
|
if (reply->children_len > 0)
|
|
{
|
|
windows = malloc(sizeof(Ecore_X_Window) * reply->children_len);
|
|
if (windows)
|
|
{
|
|
unsigned int i = 0;
|
|
xcb_window_t *w;
|
|
|
|
w = xcb_query_tree_children(reply);
|
|
for (i = 0; i < reply->children_len; i++)
|
|
windows[i] = w[i];
|
|
}
|
|
}
|
|
|
|
free(reply);
|
|
return windows;
|
|
}
|
|
|
|
/**
|
|
* Retrieves the root window a given window is on.
|
|
* @param win The window to get the root window of
|
|
* @return The root window of @p win
|
|
* @ingroup Ecore_X_Window_Geometry_Group
|
|
*/
|
|
EAPI Ecore_X_Window
|
|
ecore_x_window_root_get(Ecore_X_Window win)
|
|
{
|
|
xcb_get_geometry_cookie_t gcookie;
|
|
xcb_get_geometry_reply_t *greply;
|
|
Ecore_X_Window window = 0;
|
|
|
|
/* LOGFN(__FILE__, __LINE__, __FUNCTION__); */
|
|
CHECK_XCB_CONN;
|
|
|
|
gcookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, win);
|
|
greply = xcb_get_geometry_reply(_ecore_xcb_conn, gcookie, NULL);
|
|
if (!greply) return 0;
|
|
window = greply->root;
|
|
free(greply);
|
|
|
|
return window;
|
|
}
|
|
|
|
EAPI Ecore_X_Window
|
|
ecore_x_window_root_first_get(void)
|
|
{
|
|
return ((xcb_screen_t *)_ecore_xcb_screen)->root;
|
|
}
|
|
|
|
/**
|
|
* Retrieves the geometry of the given window.
|
|
*
|
|
* Note that the x & y coordingates are relative to your parent. In
|
|
* particular for reparenting window managers - relative to you window border.
|
|
* If you want screen coordinates either walk the window tree to the root,
|
|
* else for ecore_evas applications see ecore_evas_geometry_get(). Elementary
|
|
* applications can use elm_win_screen_position_get().
|
|
*
|
|
* @param win The given window.
|
|
* @param x Pointer to an integer in which the X position is to be stored.
|
|
* @param y Pointer to an integer in which the Y position is to be stored.
|
|
* @param w Pointer to an integer in which the width is to be stored.
|
|
* @param h Pointer to an integer in which the height is to be stored.
|
|
* @ingroup Ecore_X_Window_Geometry_Group
|
|
*/
|
|
EAPI void
|
|
ecore_x_window_geometry_get(Ecore_X_Window win,
|
|
int *x,
|
|
int *y,
|
|
int *w,
|
|
int *h)
|
|
{
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
|
|
ecore_x_drawable_geometry_get(win, x, y, w, h);
|
|
}
|
|
|
|
/**
|
|
* Retrieves the top, visible window at the given location.
|
|
* @param x The given X position.
|
|
* @param y The given Y position.
|
|
* @return The window at that position.
|
|
* @ingroup Ecore_X_Window_Geometry_Group
|
|
*/
|
|
EAPI Ecore_X_Window
|
|
ecore_x_window_at_xy_get(int x,
|
|
int y)
|
|
{
|
|
Ecore_X_Window root, win = 0;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
|
|
|
|
ecore_x_grab();
|
|
win = _ecore_xcb_window_at_xy_get(root, 0, 0, x, y, NULL, 0);
|
|
ecore_x_ungrab();
|
|
|
|
return win ? win : root;
|
|
}
|
|
|
|
/**
|
|
* Retrieves the top, visible window at the given location,
|
|
* but skips the windows in the list.
|
|
* @param x The given X position.
|
|
* @param y The given Y position.
|
|
* @param skip The list of windows to be skipped.
|
|
* @param skip_num The number of windows to be skipped.
|
|
* @return The window at that position.
|
|
* @ingroup Ecore_X_Window_Geometry_Group
|
|
*/
|
|
EAPI Ecore_X_Window
|
|
ecore_x_window_at_xy_with_skip_get(int x,
|
|
int y,
|
|
Ecore_X_Window *skip,
|
|
int skip_num)
|
|
{
|
|
Ecore_X_Window root, win = 0;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
|
|
|
|
ecore_x_grab();
|
|
win = _ecore_xcb_window_at_xy_get(root, 0, 0, x, y, skip, skip_num);
|
|
ecore_x_ungrab();
|
|
|
|
return win ? win : root;
|
|
}
|
|
|
|
EAPI Ecore_X_Window
|
|
ecore_x_window_at_xy_begin_get(Ecore_X_Window begin,
|
|
int x,
|
|
int y)
|
|
{
|
|
Ecore_X_Window win = 0;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
ecore_x_grab();
|
|
win = _ecore_xcb_window_at_xy_get(begin, 0, 0, x, y, NULL, 0);
|
|
ecore_x_ungrab();
|
|
|
|
return win ? win : begin;
|
|
}
|
|
|
|
/**
|
|
* Retrieves the parent window of the given window.
|
|
* @param win The given window.
|
|
* @return The parent window of @p win.
|
|
* @ingroup Ecore_X_Window_Parent_Group
|
|
*/
|
|
EAPI Ecore_X_Window
|
|
ecore_x_window_parent_get(Ecore_X_Window win)
|
|
{
|
|
xcb_query_tree_cookie_t cookie;
|
|
xcb_query_tree_reply_t *reply;
|
|
Ecore_X_Window window = 0;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
// if (!win) return 0;
|
|
cookie = xcb_query_tree(_ecore_xcb_conn, win);
|
|
reply = xcb_query_tree_reply(_ecore_xcb_conn, cookie, NULL);
|
|
if (!reply) return 0;
|
|
window = reply->parent;
|
|
free(reply);
|
|
|
|
return window;
|
|
}
|
|
|
|
/**
|
|
* Finds out whether the given window is currently visible.
|
|
* @param win The given window.
|
|
* @return 1 if the window is visible, otherwise 0.
|
|
* @ingroup Ecore_X_Window_Visibility_Group
|
|
*/
|
|
EAPI int
|
|
ecore_x_window_visible_get(Ecore_X_Window win)
|
|
{
|
|
xcb_get_window_attributes_cookie_t cookie;
|
|
xcb_get_window_attributes_reply_t *reply;
|
|
int ret = EINA_FALSE;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, win);
|
|
reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL);
|
|
if (!reply) return EINA_FALSE;
|
|
|
|
if (reply->map_state == XCB_MAP_STATE_VIEWABLE)
|
|
ret = EINA_TRUE;
|
|
|
|
free(reply);
|
|
return ret;
|
|
}
|
|
|
|
EAPI void
|
|
ecore_x_window_button_grab(Ecore_X_Window win,
|
|
int button,
|
|
Ecore_X_Event_Mask mask,
|
|
int mod,
|
|
int any_mod)
|
|
{
|
|
int i = 0;
|
|
uint16_t m, locks[8], ev;
|
|
uint8_t b;
|
|
Ecore_X_Window *t;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
b = button;
|
|
if (b == 0)
|
|
b = XCB_BUTTON_INDEX_ANY;
|
|
|
|
m = _ecore_xcb_window_modifiers_get(mod);
|
|
if (any_mod) m = XCB_MOD_MASK_ANY;
|
|
|
|
locks[0] = 0;
|
|
locks[1] = ECORE_X_LOCK_CAPS;
|
|
locks[2] = ECORE_X_LOCK_NUM;
|
|
locks[3] = ECORE_X_LOCK_SCROLL;
|
|
locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
|
|
locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
|
|
locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
|
|
locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
|
|
|
|
ev = mask;
|
|
for (i = 0; i < 8; i++)
|
|
xcb_grab_button(_ecore_xcb_conn, 0, win, ev,
|
|
XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC,
|
|
XCB_NONE, XCB_NONE, b, m | locks[i]);
|
|
|
|
_ecore_xcb_button_grabs_num++;
|
|
t = realloc(_ecore_xcb_button_grabs,
|
|
_ecore_xcb_button_grabs_num * sizeof(Ecore_X_Window));
|
|
if (!t) return;
|
|
|
|
_ecore_xcb_button_grabs = t;
|
|
_ecore_xcb_button_grabs[_ecore_xcb_button_grabs_num - 1] = win;
|
|
}
|
|
|
|
EAPI void
|
|
ecore_x_window_button_ungrab(Ecore_X_Window win,
|
|
int button,
|
|
int mod,
|
|
int any_mod)
|
|
{
|
|
int i = 0;
|
|
uint16_t m = 0, locks[8];
|
|
uint8_t b;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
b = button;
|
|
if (b == 0) b = XCB_BUTTON_INDEX_ANY;
|
|
|
|
m = _ecore_xcb_window_modifiers_get(mod);
|
|
if (any_mod) m = XCB_MOD_MASK_ANY;
|
|
|
|
locks[0] = 0;
|
|
locks[1] = ECORE_X_LOCK_CAPS;
|
|
locks[2] = ECORE_X_LOCK_NUM;
|
|
locks[3] = ECORE_X_LOCK_SCROLL;
|
|
locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
|
|
locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
|
|
locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
|
|
locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
|
|
|
|
for (i = 0; i < 8; i++)
|
|
xcb_ungrab_button(_ecore_xcb_conn, b, win, m | locks[i]);
|
|
|
|
_ecore_xcb_sync_magic_send(1, win);
|
|
}
|
|
|
|
EAPI void
|
|
ecore_x_window_key_grab(Ecore_X_Window win,
|
|
const char *key,
|
|
int mod,
|
|
int any_mod)
|
|
{
|
|
xcb_keycode_t keycode = XCB_NO_SYMBOL;
|
|
uint16_t m = 0, locks[8];
|
|
int i = 0;
|
|
Ecore_X_Window *t;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
keycode = _ecore_xcb_keymap_string_to_keycode(key);
|
|
if (keycode == XCB_NO_SYMBOL) return;
|
|
|
|
m = _ecore_xcb_window_modifiers_get(mod);
|
|
if (any_mod) m = XCB_MOD_MASK_ANY;
|
|
|
|
locks[0] = 0;
|
|
locks[1] = ECORE_X_LOCK_CAPS;
|
|
locks[2] = ECORE_X_LOCK_NUM;
|
|
locks[3] = ECORE_X_LOCK_SCROLL;
|
|
locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
|
|
locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
|
|
locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
|
|
locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
|
|
|
|
for (i = 0; i < 8; i++)
|
|
xcb_grab_key(_ecore_xcb_conn, 0, win, m | locks[i],
|
|
keycode, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
|
|
_ecore_xcb_key_grabs_num++;
|
|
t = realloc(_ecore_xcb_key_grabs,
|
|
_ecore_xcb_key_grabs_num * sizeof(Ecore_X_Window));
|
|
if (!t) return;
|
|
_ecore_xcb_key_grabs = t;
|
|
_ecore_xcb_key_grabs[_ecore_xcb_key_grabs_num - 1] = win;
|
|
}
|
|
|
|
EAPI void
|
|
ecore_x_window_key_ungrab(Ecore_X_Window win,
|
|
const char *key,
|
|
int mod,
|
|
int any_mod)
|
|
{
|
|
xcb_keycode_t keycode = XCB_NO_SYMBOL;
|
|
uint16_t m = 0, locks[8];
|
|
int i = 0;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
keycode = _ecore_xcb_keymap_string_to_keycode(key);
|
|
if (keycode == XCB_NO_SYMBOL) return;
|
|
|
|
m = _ecore_xcb_window_modifiers_get(mod);
|
|
if (any_mod) m = XCB_MOD_MASK_ANY;
|
|
|
|
locks[0] = 0;
|
|
locks[1] = ECORE_X_LOCK_CAPS;
|
|
locks[2] = ECORE_X_LOCK_NUM;
|
|
locks[3] = ECORE_X_LOCK_SCROLL;
|
|
locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
|
|
locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
|
|
locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
|
|
locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
|
|
|
|
for (i = 0; i < 8; i++)
|
|
xcb_ungrab_key(_ecore_xcb_conn, keycode, win, m | locks[i]);
|
|
|
|
_ecore_xcb_sync_magic_send(2, win);
|
|
}
|
|
|
|
/* local functions */
|
|
Ecore_X_Window
|
|
_ecore_xcb_window_root_of_screen_get(int screen)
|
|
{
|
|
xcb_screen_iterator_t iter;
|
|
|
|
CHECK_XCB_CONN;
|
|
iter = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn));
|
|
for (; iter.rem; --screen, xcb_screen_next(&iter))
|
|
if (screen == 0)
|
|
{
|
|
xcb_screen_t *s;
|
|
|
|
if ((s = iter.data))
|
|
return s->root;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static Ecore_X_Window
|
|
_ecore_xcb_window_argb_internal_new(Ecore_X_Window parent,
|
|
int x,
|
|
int y,
|
|
int w,
|
|
int h,
|
|
uint8_t override_redirect,
|
|
uint8_t save_under)
|
|
{
|
|
Ecore_X_Window win = 0;
|
|
#ifdef ECORE_XCB_RENDER
|
|
uint32_t value_list[10];
|
|
uint32_t value_mask;
|
|
uint32_t vis;
|
|
Ecore_X_Colormap colormap;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RENDER
|
|
if (parent == 0)
|
|
parent = ((xcb_screen_t *)_ecore_xcb_screen)->root;
|
|
|
|
vis =
|
|
_ecore_xcb_render_find_visual_id(XCB_RENDER_PICT_TYPE_DIRECT, EINA_TRUE);
|
|
|
|
colormap = xcb_generate_id(_ecore_xcb_conn);
|
|
xcb_create_colormap(_ecore_xcb_conn, XCB_COLORMAP_ALLOC_NONE,
|
|
colormap, parent, vis);
|
|
|
|
value_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 | XCB_CW_COLORMAP);
|
|
|
|
value_list[0] = XCB_BACK_PIXMAP_NONE;
|
|
value_list[1] = 0;
|
|
value_list[2] = XCB_GRAVITY_NORTH_WEST;
|
|
value_list[3] = XCB_GRAVITY_NORTH_WEST;
|
|
value_list[4] = XCB_BACKING_STORE_NOT_USEFUL;
|
|
value_list[5] = override_redirect;
|
|
value_list[6] = save_under;
|
|
value_list[7] = (XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
|
|
XCB_EVENT_MASK_BUTTON_PRESS |
|
|
XCB_EVENT_MASK_BUTTON_RELEASE |
|
|
XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
|
|
XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE |
|
|
XCB_EVENT_MASK_VISIBILITY_CHANGE |
|
|
XCB_EVENT_MASK_STRUCTURE_NOTIFY |
|
|
XCB_EVENT_MASK_FOCUS_CHANGE |
|
|
XCB_EVENT_MASK_PROPERTY_CHANGE |
|
|
XCB_EVENT_MASK_COLOR_MAP_CHANGE);
|
|
value_list[8] = XCB_EVENT_MASK_NO_EVENT;
|
|
value_list[9] = colormap;
|
|
|
|
win = xcb_generate_id(_ecore_xcb_conn);
|
|
xcb_create_window(_ecore_xcb_conn, 32, win, parent, x, y, w, h, 0,
|
|
XCB_WINDOW_CLASS_INPUT_OUTPUT, vis, value_mask,
|
|
value_list);
|
|
|
|
xcb_free_colormap(_ecore_xcb_conn, colormap);
|
|
|
|
if (parent == ((xcb_screen_t *)_ecore_xcb_screen)->root)
|
|
ecore_x_window_defaults_set(win);
|
|
#endif
|
|
|
|
return win;
|
|
}
|
|
|
|
static Ecore_X_Window
|
|
_ecore_xcb_window_at_xy_get(Ecore_X_Window base,
|
|
int bx,
|
|
int by,
|
|
int x,
|
|
int y,
|
|
Ecore_X_Window *skip,
|
|
int skip_num)
|
|
{
|
|
xcb_query_tree_cookie_t cookie;
|
|
xcb_query_tree_reply_t *reply;
|
|
Ecore_X_Window *windows = NULL;
|
|
int wx, wy, ww, wh, num, i = 0;
|
|
Eina_Bool skipit = EINA_FALSE;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
if (!ecore_x_window_visible_get(base)) return 0;
|
|
|
|
ecore_x_window_geometry_get(base, &wx, &wy, &ww, &wh);
|
|
wx += bx;
|
|
wy += by;
|
|
|
|
if (!((x >= wx) && (y >= wy) && (x < (wx + ww)) && (y < (wy + wh))))
|
|
return 0;
|
|
|
|
cookie = xcb_query_tree_unchecked(_ecore_xcb_conn, base);
|
|
reply = xcb_query_tree_reply(_ecore_xcb_conn, cookie, NULL);
|
|
if (!reply) return 0;
|
|
|
|
num = reply->children_len;
|
|
windows = xcb_query_tree_children(reply);
|
|
|
|
for (i = (num - 1); i >= 0; --i)
|
|
{
|
|
skipit = EINA_FALSE;
|
|
|
|
if (skip)
|
|
{
|
|
int j = 0;
|
|
|
|
for (j = 0; j < skip_num; j++)
|
|
{
|
|
if (windows[i] == skip[j])
|
|
{
|
|
skipit = EINA_TRUE;
|
|
goto onward;
|
|
}
|
|
}
|
|
}
|
|
onward:
|
|
if (!skipit)
|
|
{
|
|
Ecore_X_Window child = 0;
|
|
|
|
child =
|
|
_ecore_xcb_window_at_xy_get(windows[i],
|
|
wx, wy, x, y, skip, skip_num);
|
|
if (child)
|
|
{
|
|
if (reply) free(reply);
|
|
return child;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (reply) free(reply);
|
|
return base;
|
|
}
|
|
|
|
Ecore_X_Visual
|
|
_ecore_xcb_window_visual_get(Ecore_X_Window win)
|
|
{
|
|
xcb_get_window_attributes_cookie_t cookie;
|
|
xcb_get_window_attributes_reply_t *reply;
|
|
Ecore_X_Visual visual = 0;
|
|
|
|
CHECK_XCB_CONN;
|
|
|
|
cookie = xcb_get_window_attributes(_ecore_xcb_conn, win);
|
|
reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL);
|
|
if (!reply) return 0;
|
|
visual = _ecore_xcb_window_find_visual_by_id(reply->visual);
|
|
free(reply);
|
|
|
|
return visual;
|
|
}
|
|
|
|
void
|
|
_ecore_xcb_window_button_grab_remove(Ecore_X_Window win)
|
|
{
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
if (_ecore_xcb_button_grabs_num > 0)
|
|
{
|
|
int i = 0, shuffle = 0;
|
|
|
|
for (i = 0; i < _ecore_xcb_button_grabs_num; i++)
|
|
{
|
|
if (shuffle)
|
|
_ecore_xcb_button_grabs[i - 1] = _ecore_xcb_button_grabs[i];
|
|
|
|
if ((!shuffle) && (_ecore_xcb_button_grabs[i] == win))
|
|
shuffle = 1;
|
|
}
|
|
|
|
if (shuffle)
|
|
{
|
|
Ecore_X_Window *t;
|
|
|
|
_ecore_xcb_button_grabs_num--;
|
|
if (_ecore_xcb_button_grabs_num <= 0)
|
|
{
|
|
free(_ecore_xcb_button_grabs);
|
|
_ecore_xcb_button_grabs = NULL;
|
|
return;
|
|
}
|
|
|
|
t = realloc(_ecore_xcb_button_grabs,
|
|
_ecore_xcb_button_grabs_num * sizeof(Ecore_X_Window));
|
|
if (!t) return;
|
|
_ecore_xcb_button_grabs = t;
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
_ecore_xcb_window_key_grab_remove(Ecore_X_Window win)
|
|
{
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
if (_ecore_xcb_key_grabs_num > 0)
|
|
{
|
|
int i = 0, shuffle = 0;
|
|
|
|
for (i = 0; i < _ecore_xcb_key_grabs_num; i++)
|
|
{
|
|
if (shuffle)
|
|
_ecore_xcb_key_grabs[i - 1] = _ecore_xcb_key_grabs[i];
|
|
|
|
if ((!shuffle) && (_ecore_xcb_key_grabs[i] == win))
|
|
shuffle = 1;
|
|
}
|
|
|
|
if (shuffle)
|
|
{
|
|
Ecore_X_Window *t;
|
|
|
|
_ecore_xcb_key_grabs_num--;
|
|
if (_ecore_xcb_key_grabs_num <= 0)
|
|
{
|
|
free(_ecore_xcb_key_grabs);
|
|
_ecore_xcb_key_grabs = NULL;
|
|
return;
|
|
}
|
|
|
|
t = realloc(_ecore_xcb_key_grabs,
|
|
_ecore_xcb_key_grabs_num * sizeof(Ecore_X_Window));
|
|
if (!t) return;
|
|
_ecore_xcb_key_grabs = t;
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
_ecore_xcb_window_grab_allow_events(Ecore_X_Window event_win,
|
|
Ecore_X_Window child_win,
|
|
int type,
|
|
void *event,
|
|
Ecore_X_Time timestamp)
|
|
{
|
|
int i = 0;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
for (i = 0; i < _ecore_xcb_button_grabs_num; i++)
|
|
{
|
|
if ((_ecore_xcb_button_grabs[i] == event_win) ||
|
|
(_ecore_xcb_button_grabs[i] == child_win))
|
|
{
|
|
Eina_Bool replay = EINA_FALSE;
|
|
|
|
if (_ecore_xcb_window_grab_replay_func)
|
|
{
|
|
replay =
|
|
_ecore_xcb_window_grab_replay_func(_ecore_xcb_window_grab_replay_data,
|
|
type, event);
|
|
}
|
|
if (replay)
|
|
{
|
|
xcb_allow_events(_ecore_xcb_conn,
|
|
XCB_ALLOW_REPLAY_POINTER, timestamp);
|
|
}
|
|
else
|
|
{
|
|
xcb_allow_events(_ecore_xcb_conn,
|
|
XCB_ALLOW_ASYNC_POINTER, timestamp);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
static int
|
|
_ecore_xcb_window_modifiers_get(unsigned int state)
|
|
{
|
|
int xmodifiers = 0;
|
|
|
|
if (state & ECORE_EVENT_MODIFIER_SHIFT)
|
|
xmodifiers |= ECORE_X_MODIFIER_SHIFT;
|
|
if (state & ECORE_EVENT_MODIFIER_CTRL)
|
|
xmodifiers |= ECORE_X_MODIFIER_CTRL;
|
|
if (state & ECORE_EVENT_MODIFIER_ALT)
|
|
xmodifiers |= ECORE_X_MODIFIER_ALT;
|
|
if (state & ECORE_EVENT_MODIFIER_WIN)
|
|
xmodifiers |= ECORE_X_MODIFIER_WIN;
|
|
if (state & ECORE_EVENT_MODIFIER_ALTGR)
|
|
xmodifiers |= ECORE_X_MODIFIER_ALTGR;
|
|
if (state & ECORE_EVENT_LOCK_SCROLL)
|
|
xmodifiers |= ECORE_X_LOCK_SCROLL;
|
|
if (state & ECORE_EVENT_LOCK_NUM)
|
|
xmodifiers |= ECORE_X_LOCK_NUM;
|
|
if (state & ECORE_EVENT_LOCK_CAPS)
|
|
xmodifiers |= ECORE_X_LOCK_CAPS;
|
|
if (state & ECORE_EVENT_LOCK_SHIFT)
|
|
xmodifiers |= ECORE_X_LOCK_SHIFT;
|
|
|
|
return xmodifiers;
|
|
}
|
|
|
|
static xcb_visualtype_t *
|
|
_ecore_xcb_window_find_visual_by_id(xcb_visualid_t id)
|
|
{
|
|
xcb_depth_iterator_t diter;
|
|
xcb_visualtype_iterator_t viter;
|
|
|
|
CHECK_XCB_CONN;
|
|
diter = xcb_screen_allowed_depths_iterator(_ecore_xcb_screen);
|
|
for (; diter.rem; xcb_depth_next(&diter))
|
|
{
|
|
viter = xcb_depth_visuals_iterator(diter.data);
|
|
for (; viter.rem; xcb_visualtype_next(&viter))
|
|
{
|
|
if (viter.data->visual_id == id)
|
|
return viter.data;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
#ifdef ECORE_XCB_XPRINT
|
|
static xcb_screen_t *
|
|
_ecore_xcb_window_screen_of_display(int screen)
|
|
{
|
|
xcb_screen_iterator_t iter;
|
|
|
|
CHECK_XCB_CONN;
|
|
iter = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn));
|
|
for (; iter.rem; --screen, xcb_screen_next(&iter))
|
|
if (screen == 0)
|
|
return iter.data;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
#endif
|