/**
* rofi
*
* MIT/X11 License
* Copyright (c) 2012 Sean Pringle <sean.pringle@gmail.com>
* Modified 2013-2016 Qball Cow <qball@gmpclient.org>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <glib.h>
#include <cairo.h>
#include <cairo-xcb.h>
#include <xcb/xcb.h>
#include <xcb/randr.h>
#include <xcb/xinerama.h>
#include <xcb/xcb_ewmh.h>
#include <xcb/xproto.h>
#include "xcb-internal.h"
#include "xcb.h"
#include "settings.h"
#include "helper.h"
#include <rofi.h>
#define OVERLAP( a, b, c, \
d ) ( ( ( a ) == ( c ) && \
( b ) == ( d ) ) || \
MIN ( ( a ) + ( b ), ( c ) + ( d ) ) - MAX ( ( a ), ( c ) ) > 0 )
#define INTERSECT( x, y, w, h, x1, y1, w1, \
h1 ) ( OVERLAP ( ( x ), ( w ), ( x1 ), \
( w1 ) ) && OVERLAP ( ( y ), ( h ), ( y1 ), ( h1 ) ) )
#include "x11-helper.h"
#include "xkb-internal.h"
#define LOG_DOMAIN "X11Helper"
struct _xcb_stuff xcb_int = {
.connection = NULL,
.screen = NULL,
.screen_nbr = -1,
.sndisplay = NULL,
.sncontext = NULL,
.monitors = NULL
};
xcb_stuff *xcb = &xcb_int;
enum
{
X11MOD_SHIFT,
X11MOD_CONTROL,
X11MOD_ALT,
X11MOD_META,
X11MOD_SUPER,
X11MOD_HYPER,
X11MOD_ANY,
NUM_X11MOD
};
xcb_depth_t *depth = NULL;
xcb_visualtype_t *visual = NULL;
xcb_colormap_t map = XCB_COLORMAP_NONE;
xcb_depth_t *root_depth = NULL;
xcb_visualtype_t *root_visual = NULL;
xcb_atom_t netatoms[NUM_NETATOMS];
const char *netatom_names[] = { EWMH_ATOMS ( ATOM_CHAR ) };
static unsigned int x11_mod_masks[NUM_X11MOD];
static xcb_pixmap_t get_root_pixmap ( xcb_connection_t *c,
xcb_screen_t *screen,
xcb_atom_t atom )
{
xcb_get_property_cookie_t cookie;
xcb_get_property_reply_t *reply;
xcb_pixmap_t rootpixmap = XCB_NONE;
cookie = xcb_get_property ( c,
0,
screen->root,
atom,
XCB_ATOM_PIXMAP,
0,
1 );
reply = xcb_get_property_reply ( c, cookie, NULL );
if ( reply ) {
if ( xcb_get_property_value_length ( reply ) == sizeof ( xcb_pixmap_t ) ) {
memcpy ( &rootpixmap, xcb_get_property_value ( reply ), sizeof ( xcb_pixmap_t ) );
}
free ( reply );
}
return rootpixmap;
}
cairo_surface_t * x11_helper_get_bg_surface ( void )
{
xcb_pixmap_t pm = get_root_pixmap ( xcb->connection, xcb->screen, netatoms[ESETROOT_PMAP_ID] );
if ( pm == XCB_NONE ) {
return NULL;
}
return cairo_xcb_surface_create ( xcb->connection, pm, root_visual,
xcb->screen->width_in_pixels, xcb->screen->height_in_pixels );
}
// retrieve a text property from a window
// technically we could use window_get_prop(), but this is better for character set support
char* window_get_text_prop ( xcb_window_t w, xcb_atom_t atom )
{
xcb_get_property_cookie_t c = xcb_get_property ( xcb->connection, 0, w, atom, XCB_GET_PROPERTY_TYPE_ANY, 0, UINT_MAX );
xcb_get_property_reply_t *r = xcb_get_property_reply ( xcb->connection, c, NULL );
if ( r ) {
if ( xcb_get_property_value_length ( r ) > 0 ) {
char *str = NULL;
if ( r->type == netatoms[UTF8_STRING] ) {
str = g_strndup ( xcb_get_property_value ( r ), xcb_get_property_value_length ( r ) );
}
else if ( r->type == netatoms[STRI