icccm.c revision ecce36be
1ecce36beSmrg/* 2ecce36beSmrg * Copyright © 2008 Arnaud Fontaine <arnau@debian.org> 3ecce36beSmrg * Copyright © 2007-2008 Vincent Torri <vtorri@univ-evry.fr> 4ecce36beSmrg * 5ecce36beSmrg * Permission is hereby granted, free of charge, to any person 6ecce36beSmrg * obtaining a copy of this software and associated documentation 7ecce36beSmrg * files (the "Software"), to deal in the Software without 8ecce36beSmrg * restriction, including without limitation the rights to use, copy, 9ecce36beSmrg * modify, merge, publish, distribute, sublicense, and/or sell copies 10ecce36beSmrg * of the Software, and to permit persons to whom the Software is 11ecce36beSmrg * furnished to do so, subject to the following conditions: 12ecce36beSmrg * 13ecce36beSmrg * The above copyright notice and this permission notice shall be 14ecce36beSmrg * included in all copies or substantial portions of the Software. 15ecce36beSmrg * 16ecce36beSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17ecce36beSmrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18ecce36beSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19ecce36beSmrg * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY 20ecce36beSmrg * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 21ecce36beSmrg * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22ecce36beSmrg * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23ecce36beSmrg * 24ecce36beSmrg * Except as contained in this notice, the names of the authors or 25ecce36beSmrg * their institutions shall not be used in advertising or otherwise to 26ecce36beSmrg * promote the sale, use or other dealings in this Software without 27ecce36beSmrg * prior written authorization from the authors. 28ecce36beSmrg */ 29ecce36beSmrg 30ecce36beSmrg#include <stdlib.h> 31ecce36beSmrg#include <limits.h> 32ecce36beSmrg#include <string.h> 33ecce36beSmrg 34ecce36beSmrg#include "xcb_icccm.h" 35ecce36beSmrg#include "xcb_atom.h" 36ecce36beSmrg 37ecce36beSmrgxcb_get_property_cookie_t 38ecce36beSmrgxcb_get_text_property(xcb_connection_t *c, 39ecce36beSmrg xcb_window_t window, 40ecce36beSmrg xcb_atom_t property) 41ecce36beSmrg{ 42ecce36beSmrg return xcb_get_any_property(c, 0, window, property, UINT_MAX); 43ecce36beSmrg} 44ecce36beSmrg 45ecce36beSmrgxcb_get_property_cookie_t 46ecce36beSmrgxcb_get_text_property_unchecked(xcb_connection_t *c, 47ecce36beSmrg xcb_window_t window, 48ecce36beSmrg xcb_atom_t property) 49ecce36beSmrg{ 50ecce36beSmrg return xcb_get_any_property_unchecked(c, 0, window, property, UINT_MAX); 51ecce36beSmrg} 52ecce36beSmrg 53ecce36beSmrguint8_t 54ecce36beSmrgxcb_get_text_property_reply(xcb_connection_t *c, 55ecce36beSmrg xcb_get_property_cookie_t cookie, 56ecce36beSmrg xcb_get_text_property_reply_t *prop, 57ecce36beSmrg xcb_generic_error_t **e) 58ecce36beSmrg{ 59ecce36beSmrg xcb_get_property_reply_t *reply = xcb_get_property_reply(c, cookie, e); 60ecce36beSmrg 61ecce36beSmrg if(!reply) 62ecce36beSmrg return 0; 63ecce36beSmrg 64ecce36beSmrg prop->_reply = reply; 65ecce36beSmrg prop->encoding = prop->_reply->type; 66ecce36beSmrg prop->format = prop->_reply->format; 67ecce36beSmrg prop->name_len = xcb_get_property_value_length(prop->_reply); 68ecce36beSmrg prop->name = xcb_get_property_value(prop->_reply); 69ecce36beSmrg 70ecce36beSmrg return 1; 71ecce36beSmrg} 72ecce36beSmrg 73ecce36beSmrgvoid 74ecce36beSmrgxcb_get_text_property_reply_wipe(xcb_get_text_property_reply_t *prop) 75ecce36beSmrg{ 76ecce36beSmrg free(prop->_reply); 77ecce36beSmrg} 78ecce36beSmrg 79ecce36beSmrg/* WM_NAME */ 80ecce36beSmrg 81ecce36beSmrgvoid 82ecce36beSmrgxcb_set_wm_name_checked(xcb_connection_t *c, xcb_window_t window, 83ecce36beSmrg xcb_atom_t encoding, uint32_t name_len, 84ecce36beSmrg const char *name) 85ecce36beSmrg{ 86ecce36beSmrg xcb_change_property_checked(c, XCB_PROP_MODE_REPLACE, window, WM_NAME, 87ecce36beSmrg encoding, 8, name_len, name); 88ecce36beSmrg} 89ecce36beSmrg 90ecce36beSmrgvoid 91ecce36beSmrgxcb_set_wm_name(xcb_connection_t *c, xcb_window_t window, xcb_atom_t encoding, 92ecce36beSmrg uint32_t name_len, const char *name) 93ecce36beSmrg{ 94ecce36beSmrg xcb_change_property(c, XCB_PROP_MODE_REPLACE, window, WM_NAME, encoding, 8, 95ecce36beSmrg name_len, name); 96ecce36beSmrg} 97ecce36beSmrg 98ecce36beSmrgxcb_get_property_cookie_t 99ecce36beSmrgxcb_get_wm_name(xcb_connection_t *c, 100ecce36beSmrg xcb_window_t window) 101ecce36beSmrg{ 102ecce36beSmrg return xcb_get_text_property(c, window, WM_NAME); 103ecce36beSmrg} 104ecce36beSmrg 105ecce36beSmrgxcb_get_property_cookie_t 106ecce36beSmrgxcb_get_wm_name_unchecked(xcb_connection_t *c, 107ecce36beSmrg xcb_window_t window) 108ecce36beSmrg{ 109ecce36beSmrg return xcb_get_text_property_unchecked(c, window, WM_NAME); 110ecce36beSmrg} 111ecce36beSmrg 112ecce36beSmrguint8_t 113ecce36beSmrgxcb_get_wm_name_reply(xcb_connection_t *c, 114ecce36beSmrg xcb_get_property_cookie_t cookie, 115ecce36beSmrg xcb_get_text_property_reply_t *prop, 116ecce36beSmrg xcb_generic_error_t **e) 117ecce36beSmrg{ 118ecce36beSmrg return xcb_get_text_property_reply(c, cookie, prop, e); 119ecce36beSmrg} 120ecce36beSmrg 121ecce36beSmrgvoid 122ecce36beSmrgxcb_watch_wm_name(xcb_property_handlers_t *prophs, uint32_t long_len, 123ecce36beSmrg xcb_generic_property_handler_t handler, void *data) 124ecce36beSmrg{ 125ecce36beSmrg xcb_property_set_handler(prophs, WM_NAME, long_len, handler, data); 126ecce36beSmrg} 127ecce36beSmrg 128ecce36beSmrg/* WM_ICON_NAME */ 129ecce36beSmrg 130ecce36beSmrgvoid 131ecce36beSmrgxcb_set_wm_icon_name_checked(xcb_connection_t *c, xcb_window_t window, 132ecce36beSmrg xcb_atom_t encoding, uint32_t name_len, 133ecce36beSmrg const char *name) 134ecce36beSmrg{ 135ecce36beSmrg xcb_change_property_checked(c, XCB_PROP_MODE_REPLACE, window, WM_ICON_NAME, 136ecce36beSmrg encoding, 8, name_len, name); 137ecce36beSmrg} 138ecce36beSmrg 139ecce36beSmrgvoid 140ecce36beSmrgxcb_set_wm_icon_name(xcb_connection_t *c, xcb_window_t window, 141ecce36beSmrg xcb_atom_t encoding, uint32_t name_len, const char *name) 142ecce36beSmrg{ 143ecce36beSmrg xcb_change_property(c, XCB_PROP_MODE_REPLACE, window, WM_ICON_NAME, encoding, 144ecce36beSmrg 8, name_len, name); 145ecce36beSmrg} 146ecce36beSmrg 147ecce36beSmrgxcb_get_property_cookie_t 148ecce36beSmrgxcb_get_wm_icon_name(xcb_connection_t *c, 149ecce36beSmrg xcb_window_t window) 150ecce36beSmrg{ 151ecce36beSmrg return xcb_get_text_property(c, window, WM_ICON_NAME); 152ecce36beSmrg} 153ecce36beSmrg 154ecce36beSmrgxcb_get_property_cookie_t 155ecce36beSmrgxcb_get_wm_icon_name_unchecked(xcb_connection_t *c, 156ecce36beSmrg xcb_window_t window) 157ecce36beSmrg{ 158ecce36beSmrg return xcb_get_text_property_unchecked(c, window, WM_ICON_NAME); 159ecce36beSmrg} 160ecce36beSmrg 161ecce36beSmrguint8_t 162ecce36beSmrgxcb_get_wm_icon_name_reply(xcb_connection_t *c, 163ecce36beSmrg xcb_get_property_cookie_t cookie, 164ecce36beSmrg xcb_get_text_property_reply_t *prop, 165ecce36beSmrg xcb_generic_error_t **e) 166ecce36beSmrg{ 167ecce36beSmrg return xcb_get_text_property_reply(c, cookie, prop, e); 168ecce36beSmrg} 169ecce36beSmrg 170ecce36beSmrgvoid 171ecce36beSmrgxcb_watch_wm_icon_name(xcb_property_handlers_t *prophs, uint32_t long_len, 172ecce36beSmrg xcb_generic_property_handler_t handler, void *data) 173ecce36beSmrg{ 174ecce36beSmrg xcb_property_set_handler(prophs, WM_ICON_NAME, long_len, handler, data); 175ecce36beSmrg} 176ecce36beSmrg 177ecce36beSmrg/* WM_CLIENT_MACHINE */ 178ecce36beSmrg 179ecce36beSmrgvoid 180ecce36beSmrgxcb_set_wm_client_machine_checked(xcb_connection_t *c, xcb_window_t window, 181ecce36beSmrg xcb_atom_t encoding, uint32_t name_len, 182ecce36beSmrg const char *name) 183ecce36beSmrg{ 184ecce36beSmrg xcb_change_property_checked(c, XCB_PROP_MODE_REPLACE, window, 185ecce36beSmrg WM_CLIENT_MACHINE, encoding, 8, name_len, name); 186ecce36beSmrg} 187ecce36beSmrg 188ecce36beSmrgvoid 189ecce36beSmrgxcb_set_wm_client_machine(xcb_connection_t *c, xcb_window_t window, 190ecce36beSmrg xcb_atom_t encoding, uint32_t name_len, 191ecce36beSmrg const char *name) 192ecce36beSmrg{ 193ecce36beSmrg xcb_change_property(c, XCB_PROP_MODE_REPLACE, window, WM_CLIENT_MACHINE, 194ecce36beSmrg encoding, 8, name_len, name); 195ecce36beSmrg} 196ecce36beSmrg 197ecce36beSmrgxcb_get_property_cookie_t 198ecce36beSmrgxcb_get_wm_client_machine(xcb_connection_t *c, 199ecce36beSmrg xcb_window_t window) 200ecce36beSmrg{ 201ecce36beSmrg return xcb_get_text_property(c, window, WM_CLIENT_MACHINE); 202ecce36beSmrg} 203ecce36beSmrg 204ecce36beSmrgxcb_get_property_cookie_t 205ecce36beSmrgxcb_get_wm_client_machine_unchecked(xcb_connection_t *c, 206ecce36beSmrg xcb_window_t window) 207ecce36beSmrg{ 208ecce36beSmrg return xcb_get_text_property_unchecked(c, window, WM_CLIENT_MACHINE); 209ecce36beSmrg} 210ecce36beSmrg 211ecce36beSmrguint8_t 212ecce36beSmrgxcb_get_wm_client_machine_reply(xcb_connection_t *c, 213ecce36beSmrg xcb_get_property_cookie_t cookie, 214ecce36beSmrg xcb_get_text_property_reply_t *prop, 215ecce36beSmrg xcb_generic_error_t **e) 216ecce36beSmrg{ 217ecce36beSmrg return xcb_get_text_property_reply(c, cookie, prop, e); 218ecce36beSmrg} 219ecce36beSmrg 220ecce36beSmrgvoid 221ecce36beSmrgxcb_watch_wm_client_machine(xcb_property_handlers_t *prophs, uint32_t long_len, 222ecce36beSmrg xcb_generic_property_handler_t handler, void *data) 223ecce36beSmrg{ 224ecce36beSmrg xcb_property_set_handler(prophs, WM_CLIENT_MACHINE, long_len, handler, data); 225ecce36beSmrg} 226ecce36beSmrg 227ecce36beSmrg/* WM_CLASS */ 228ecce36beSmrg 229ecce36beSmrgxcb_get_property_cookie_t 230ecce36beSmrgxcb_get_wm_class(xcb_connection_t *c, xcb_window_t window) 231ecce36beSmrg{ 232ecce36beSmrg return xcb_get_property(c, 0, window, WM_CLASS, STRING, 0L, 2048L); 233ecce36beSmrg} 234ecce36beSmrg 235ecce36beSmrgxcb_get_property_cookie_t 236ecce36beSmrgxcb_get_wm_class_unchecked(xcb_connection_t *c, xcb_window_t window) 237ecce36beSmrg{ 238ecce36beSmrg return xcb_get_property_unchecked(c, 0, window, WM_CLASS, STRING, 0L, 2048L); 239ecce36beSmrg} 240ecce36beSmrg 241ecce36beSmrguint8_t 242ecce36beSmrgxcb_get_wm_class_from_reply(xcb_get_wm_class_reply_t *prop, 243ecce36beSmrg xcb_get_property_reply_t *reply) 244ecce36beSmrg{ 245ecce36beSmrg if(!reply || reply->type != STRING || reply->format != 8) 246ecce36beSmrg return 0; 247ecce36beSmrg 248ecce36beSmrg prop->_reply = reply; 249ecce36beSmrg prop->instance_name = (char *) xcb_get_property_value(prop->_reply); 250ecce36beSmrg 251ecce36beSmrg int name_len = strlen(prop->instance_name); 252ecce36beSmrg if(name_len == xcb_get_property_value_length(prop->_reply)) 253ecce36beSmrg name_len--; 254ecce36beSmrg 255ecce36beSmrg prop->class_name = prop->instance_name + name_len + 1; 256ecce36beSmrg 257ecce36beSmrg return 1; 258ecce36beSmrg} 259ecce36beSmrg 260ecce36beSmrguint8_t 261ecce36beSmrgxcb_get_wm_class_reply(xcb_connection_t *c, xcb_get_property_cookie_t cookie, 262ecce36beSmrg xcb_get_wm_class_reply_t *prop, xcb_generic_error_t **e) 263ecce36beSmrg{ 264ecce36beSmrg xcb_get_property_reply_t *reply = xcb_get_property_reply(c, cookie, e); 265ecce36beSmrg uint8_t ret = xcb_get_wm_class_from_reply(prop, reply); 266ecce36beSmrg /* if reply parsing failed, free the reply to avoid mem leak */ 267ecce36beSmrg if(!ret) 268ecce36beSmrg free(reply); 269ecce36beSmrg return ret; 270ecce36beSmrg} 271ecce36beSmrg 272ecce36beSmrgvoid 273ecce36beSmrgxcb_get_wm_class_reply_wipe(xcb_get_wm_class_reply_t *prop) 274ecce36beSmrg{ 275ecce36beSmrg free(prop->_reply); 276ecce36beSmrg} 277ecce36beSmrg 278ecce36beSmrg/* WM_TRANSIENT_FOR */ 279ecce36beSmrg 280ecce36beSmrgxcb_get_property_cookie_t 281ecce36beSmrgxcb_get_wm_transient_for(xcb_connection_t *c, xcb_window_t window) 282ecce36beSmrg{ 283ecce36beSmrg return xcb_get_property(c, 0, window, WM_TRANSIENT_FOR, WINDOW, 0, 1); 284ecce36beSmrg} 285ecce36beSmrg 286ecce36beSmrgxcb_get_property_cookie_t 287ecce36beSmrgxcb_get_wm_transient_for_unchecked(xcb_connection_t *c, xcb_window_t window) 288ecce36beSmrg{ 289ecce36beSmrg return xcb_get_property_unchecked(c, 0, window, WM_TRANSIENT_FOR, WINDOW, 0, 1); 290ecce36beSmrg} 291ecce36beSmrg 292ecce36beSmrguint8_t 293ecce36beSmrgxcb_get_wm_transient_for_from_reply(xcb_window_t *prop, 294ecce36beSmrg xcb_get_property_reply_t *reply) 295ecce36beSmrg{ 296ecce36beSmrg if(!reply || reply->type != WINDOW || reply->format != 32 || !reply->length) 297ecce36beSmrg return 0; 298ecce36beSmrg 299ecce36beSmrg *prop = *((xcb_window_t *) xcb_get_property_value(reply)); 300ecce36beSmrg 301ecce36beSmrg return 1; 302ecce36beSmrg} 303ecce36beSmrg 304ecce36beSmrguint8_t 305ecce36beSmrgxcb_get_wm_transient_for_reply(xcb_connection_t *c, 306ecce36beSmrg xcb_get_property_cookie_t cookie, 307ecce36beSmrg xcb_window_t *prop, 308ecce36beSmrg xcb_generic_error_t **e) 309ecce36beSmrg{ 310ecce36beSmrg xcb_get_property_reply_t *reply = xcb_get_property_reply(c, cookie, e); 311ecce36beSmrg uint8_t ret = xcb_get_wm_transient_for_from_reply(prop, reply); 312ecce36beSmrg free(reply); 313ecce36beSmrg return ret; 314ecce36beSmrg} 315ecce36beSmrg 316ecce36beSmrg/* WM_SIZE_HINTS */ 317ecce36beSmrg 318ecce36beSmrgvoid 319ecce36beSmrgxcb_size_hints_set_position(xcb_size_hints_t *hints, int user_specified, 320ecce36beSmrg int32_t x, int32_t y) 321ecce36beSmrg{ 322ecce36beSmrg hints->flags &= ~(XCB_SIZE_HINT_US_POSITION | XCB_SIZE_HINT_P_POSITION); 323ecce36beSmrg if (user_specified) 324ecce36beSmrg hints->flags |= XCB_SIZE_HINT_US_POSITION; 325ecce36beSmrg else 326ecce36beSmrg hints->flags |= XCB_SIZE_HINT_P_POSITION; 327ecce36beSmrg hints->x = x; 328ecce36beSmrg hints->y = y; 329ecce36beSmrg} 330ecce36beSmrg 331ecce36beSmrgvoid 332ecce36beSmrgxcb_size_hints_set_size(xcb_size_hints_t *hints, int user_specified, 333ecce36beSmrg int32_t width, int32_t height) 334ecce36beSmrg{ 335ecce36beSmrg hints->flags &= ~(XCB_SIZE_HINT_US_SIZE | XCB_SIZE_HINT_P_SIZE); 336ecce36beSmrg if (user_specified) 337ecce36beSmrg hints->flags |= XCB_SIZE_HINT_US_SIZE; 338ecce36beSmrg else 339ecce36beSmrg hints->flags |= XCB_SIZE_HINT_P_SIZE; 340ecce36beSmrg hints->width = width; 341ecce36beSmrg hints->height = height; 342ecce36beSmrg} 343ecce36beSmrg 344ecce36beSmrgvoid 345ecce36beSmrgxcb_size_hints_set_min_size(xcb_size_hints_t *hints, int32_t min_width, 346ecce36beSmrg int32_t min_height) 347ecce36beSmrg{ 348ecce36beSmrg hints->flags |= XCB_SIZE_HINT_P_MIN_SIZE; 349ecce36beSmrg hints->min_width = min_width; 350ecce36beSmrg hints->min_height = min_height; 351ecce36beSmrg} 352ecce36beSmrg 353ecce36beSmrgvoid 354ecce36beSmrgxcb_size_hints_set_max_size(xcb_size_hints_t *hints, int32_t max_width, 355ecce36beSmrg int32_t max_height) 356ecce36beSmrg{ 357ecce36beSmrg hints->flags |= XCB_SIZE_HINT_P_MAX_SIZE; 358ecce36beSmrg hints->max_width = max_width; 359ecce36beSmrg hints->max_height = max_height; 360ecce36beSmrg} 361ecce36beSmrg 362ecce36beSmrgvoid 363ecce36beSmrgxcb_size_hints_set_resize_inc(xcb_size_hints_t *hints, int32_t width_inc, 364ecce36beSmrg int32_t height_inc) 365ecce36beSmrg{ 366ecce36beSmrg hints->flags |= XCB_SIZE_HINT_P_RESIZE_INC; 367ecce36beSmrg hints->width_inc = width_inc; 368ecce36beSmrg hints->height_inc = height_inc; 369ecce36beSmrg} 370ecce36beSmrg 371ecce36beSmrgvoid 372ecce36beSmrgxcb_size_hints_set_aspect(xcb_size_hints_t *hints, int32_t min_aspect_num, 373ecce36beSmrg int32_t min_aspect_den, int32_t max_aspect_num, 374ecce36beSmrg int32_t max_aspect_den) 375ecce36beSmrg{ 376ecce36beSmrg hints->flags |= XCB_SIZE_HINT_P_ASPECT; 377ecce36beSmrg hints->min_aspect_num = min_aspect_num; 378ecce36beSmrg hints->min_aspect_den = min_aspect_den; 379ecce36beSmrg hints->max_aspect_num = max_aspect_num; 380ecce36beSmrg hints->max_aspect_den = max_aspect_den; 381ecce36beSmrg} 382ecce36beSmrg 383ecce36beSmrgvoid 384ecce36beSmrgxcb_size_hints_set_base_size(xcb_size_hints_t *hints, int32_t base_width, 385ecce36beSmrg int32_t base_height) 386ecce36beSmrg{ 387ecce36beSmrg hints->flags |= XCB_SIZE_HINT_BASE_SIZE; 388ecce36beSmrg hints->base_width = base_width; 389ecce36beSmrg hints->base_height = base_height; 390ecce36beSmrg} 391ecce36beSmrg 392ecce36beSmrgvoid 393ecce36beSmrgxcb_size_hints_set_win_gravity(xcb_size_hints_t *hints, xcb_gravity_t win_gravity) 394ecce36beSmrg{ 395ecce36beSmrg hints->flags |= XCB_SIZE_HINT_P_WIN_GRAVITY; 396ecce36beSmrg hints->win_gravity = win_gravity; 397ecce36beSmrg} 398ecce36beSmrg 399ecce36beSmrgvoid 400ecce36beSmrgxcb_set_wm_size_hints_checked(xcb_connection_t *c, xcb_window_t window, 401ecce36beSmrg xcb_atom_t property, xcb_size_hints_t *hints) 402ecce36beSmrg{ 403ecce36beSmrg xcb_change_property_checked(c, XCB_PROP_MODE_REPLACE, window, property, 404ecce36beSmrg WM_SIZE_HINTS, 32, sizeof(*hints) >> 2, hints); 405ecce36beSmrg} 406ecce36beSmrg 407ecce36beSmrgvoid 408ecce36beSmrgxcb_set_wm_size_hints(xcb_connection_t *c, xcb_window_t window, 409ecce36beSmrg xcb_atom_t property, xcb_size_hints_t *hints) 410ecce36beSmrg{ 411ecce36beSmrg xcb_change_property(c, XCB_PROP_MODE_REPLACE, window, property, 412ecce36beSmrg WM_SIZE_HINTS, 32, sizeof(*hints) >> 2, hints); 413ecce36beSmrg} 414ecce36beSmrg 415ecce36beSmrgxcb_get_property_cookie_t 416ecce36beSmrgxcb_get_wm_size_hints(xcb_connection_t *c, xcb_window_t window, 417ecce36beSmrg xcb_atom_t property) 418ecce36beSmrg{ 419ecce36beSmrg /* NumPropSizeElements = 18 (ICCCM version 1). */ 420ecce36beSmrg return xcb_get_property(c, 0, window, property, WM_SIZE_HINTS, 0L, 18); 421ecce36beSmrg} 422ecce36beSmrg 423ecce36beSmrgxcb_get_property_cookie_t 424ecce36beSmrgxcb_get_wm_size_hints_unchecked(xcb_connection_t *c, xcb_window_t window, 425ecce36beSmrg xcb_atom_t property) 426ecce36beSmrg{ 427ecce36beSmrg return xcb_get_property_unchecked(c, 0, window, property, WM_SIZE_HINTS, 428ecce36beSmrg 0L, 18); 429ecce36beSmrg} 430ecce36beSmrg 431ecce36beSmrguint8_t 432ecce36beSmrgxcb_get_wm_size_hints_from_reply(xcb_size_hints_t *hints, xcb_get_property_reply_t *reply) 433ecce36beSmrg{ 434ecce36beSmrg uint32_t flags; 435ecce36beSmrg 436ecce36beSmrg if(!reply) 437ecce36beSmrg return 0; 438ecce36beSmrg 439ecce36beSmrg int length = xcb_get_property_value_length(reply) / (reply->format / 8); 440ecce36beSmrg 441ecce36beSmrg if (!(reply->type == WM_SIZE_HINTS && 442ecce36beSmrg (reply->format == 8 || reply->format == 16 || 443ecce36beSmrg reply->format == 32) && 444ecce36beSmrg /* OldNumPropSizeElements = 15 (pre-ICCCM) */ 445ecce36beSmrg length >= 15)) 446ecce36beSmrg return 0; 447ecce36beSmrg 448ecce36beSmrg memcpy(hints, (xcb_size_hints_t *) xcb_get_property_value (reply), 449ecce36beSmrg length * reply->format >> 3); 450ecce36beSmrg 451ecce36beSmrg flags = (XCB_SIZE_HINT_US_POSITION | XCB_SIZE_HINT_US_SIZE | 452ecce36beSmrg XCB_SIZE_HINT_P_POSITION | XCB_SIZE_HINT_P_SIZE | 453ecce36beSmrg XCB_SIZE_HINT_P_MIN_SIZE | XCB_SIZE_HINT_P_MAX_SIZE | 454ecce36beSmrg XCB_SIZE_HINT_P_RESIZE_INC | XCB_SIZE_HINT_P_ASPECT); 455ecce36beSmrg 456ecce36beSmrg /* NumPropSizeElements = 18 (ICCCM version 1) */ 457ecce36beSmrg if(length >= 18) 458ecce36beSmrg flags |= (XCB_SIZE_HINT_BASE_SIZE | XCB_SIZE_HINT_P_WIN_GRAVITY); 459ecce36beSmrg else 460ecce36beSmrg { 461ecce36beSmrg hints->base_width = 0; 462ecce36beSmrg hints->base_height = 0; 463ecce36beSmrg hints->win_gravity = 0; 464ecce36beSmrg } 465ecce36beSmrg /* get rid of unwanted bits */ 466ecce36beSmrg hints->flags &= flags; 467ecce36beSmrg 468ecce36beSmrg return 1; 469ecce36beSmrg} 470ecce36beSmrg 471ecce36beSmrguint8_t 472ecce36beSmrgxcb_get_wm_size_hints_reply(xcb_connection_t *c, xcb_get_property_cookie_t cookie, 473ecce36beSmrg xcb_size_hints_t *hints, xcb_generic_error_t **e) 474ecce36beSmrg{ 475ecce36beSmrg xcb_get_property_reply_t *reply = xcb_get_property_reply(c, cookie, e); 476ecce36beSmrg uint8_t ret = xcb_get_wm_size_hints_from_reply(hints, reply); 477ecce36beSmrg free(reply); 478ecce36beSmrg return ret; 479ecce36beSmrg} 480ecce36beSmrg 481ecce36beSmrg/* WM_NORMAL_HINTS */ 482ecce36beSmrg 483ecce36beSmrgvoid 484ecce36beSmrgxcb_set_wm_normal_hints_checked(xcb_connection_t *c, xcb_window_t window, 485ecce36beSmrg xcb_size_hints_t *hints) 486ecce36beSmrg{ 487ecce36beSmrg xcb_set_wm_size_hints_checked(c, window, WM_NORMAL_HINTS, hints); 488ecce36beSmrg} 489ecce36beSmrg 490ecce36beSmrgvoid 491ecce36beSmrgxcb_set_wm_normal_hints(xcb_connection_t *c, xcb_window_t window, 492ecce36beSmrg xcb_size_hints_t *hints) 493ecce36beSmrg{ 494ecce36beSmrg xcb_set_wm_size_hints(c, window, WM_NORMAL_HINTS, hints); 495ecce36beSmrg} 496ecce36beSmrg 497ecce36beSmrgxcb_get_property_cookie_t 498ecce36beSmrgxcb_get_wm_normal_hints(xcb_connection_t *c, xcb_window_t window) 499ecce36beSmrg{ 500ecce36beSmrg return xcb_get_wm_size_hints(c, window, WM_NORMAL_HINTS); 501ecce36beSmrg} 502ecce36beSmrg 503ecce36beSmrgxcb_get_property_cookie_t 504ecce36beSmrgxcb_get_wm_normal_hints_unchecked(xcb_connection_t *c, xcb_window_t window) 505ecce36beSmrg{ 506ecce36beSmrg return xcb_get_wm_size_hints_unchecked(c, window, WM_NORMAL_HINTS); 507ecce36beSmrg} 508ecce36beSmrg 509ecce36beSmrguint8_t 510ecce36beSmrgxcb_get_wm_normal_hints_reply(xcb_connection_t *c, 511ecce36beSmrg xcb_get_property_cookie_t cookie, 512ecce36beSmrg xcb_size_hints_t *hints, 513ecce36beSmrg xcb_generic_error_t **e) 514ecce36beSmrg{ 515ecce36beSmrg return xcb_get_wm_size_hints_reply(c, cookie, hints, e); 516ecce36beSmrg} 517ecce36beSmrg 518ecce36beSmrg/* WM_HINTS */ 519ecce36beSmrg 520ecce36beSmrguint32_t 521ecce36beSmrgxcb_wm_hints_get_urgency(xcb_wm_hints_t *hints) 522ecce36beSmrg{ 523ecce36beSmrg return (hints->flags & XCB_WM_HINT_X_URGENCY); 524ecce36beSmrg} 525ecce36beSmrg 526ecce36beSmrgvoid 527ecce36beSmrgxcb_wm_hints_set_input(xcb_wm_hints_t *hints, uint8_t input) 528ecce36beSmrg{ 529ecce36beSmrg hints->input = input; 530ecce36beSmrg hints->flags |= XCB_WM_HINT_INPUT; 531ecce36beSmrg} 532ecce36beSmrg 533ecce36beSmrgvoid 534ecce36beSmrgxcb_wm_hints_set_iconic(xcb_wm_hints_t *hints) 535ecce36beSmrg{ 536ecce36beSmrg hints->initial_state = XCB_WM_STATE_ICONIC; 537ecce36beSmrg hints->flags |= XCB_WM_HINT_STATE; 538ecce36beSmrg} 539ecce36beSmrg 540ecce36beSmrgvoid 541ecce36beSmrgxcb_wm_hints_set_normal(xcb_wm_hints_t *hints) 542ecce36beSmrg{ 543ecce36beSmrg hints->initial_state = XCB_WM_STATE_NORMAL; 544ecce36beSmrg hints->flags |= XCB_WM_HINT_STATE; 545ecce36beSmrg} 546ecce36beSmrg 547ecce36beSmrgvoid 548ecce36beSmrgxcb_wm_hints_set_withdrawn(xcb_wm_hints_t *hints) 549ecce36beSmrg{ 550ecce36beSmrg hints->initial_state = XCB_WM_STATE_WITHDRAWN; 551ecce36beSmrg hints->flags |= XCB_WM_HINT_STATE; 552ecce36beSmrg} 553ecce36beSmrg 554ecce36beSmrgvoid 555ecce36beSmrgxcb_wm_hints_set_none(xcb_wm_hints_t *hints) 556ecce36beSmrg{ 557ecce36beSmrg hints->flags &= ~XCB_WM_HINT_STATE; 558ecce36beSmrg} 559ecce36beSmrg 560ecce36beSmrgvoid 561ecce36beSmrgxcb_wm_hints_set_icon_pixmap(xcb_wm_hints_t *hints, xcb_pixmap_t icon_pixmap) 562ecce36beSmrg{ 563ecce36beSmrg hints->icon_pixmap = icon_pixmap; 564ecce36beSmrg hints->flags |= XCB_WM_HINT_ICON_PIXMAP; 565ecce36beSmrg} 566ecce36beSmrg 567ecce36beSmrgvoid 568ecce36beSmrgxcb_wm_hints_set_icon_mask(xcb_wm_hints_t *hints, xcb_pixmap_t icon_mask) 569ecce36beSmrg{ 570ecce36beSmrg hints->icon_mask = icon_mask; 571ecce36beSmrg hints->flags |= XCB_WM_HINT_ICON_MASK; 572ecce36beSmrg} 573ecce36beSmrg 574ecce36beSmrgvoid 575ecce36beSmrgxcb_wm_hints_set_icon_window(xcb_wm_hints_t *hints, xcb_window_t icon_window) 576ecce36beSmrg{ 577ecce36beSmrg hints->icon_window = icon_window; 578ecce36beSmrg hints->flags |= XCB_WM_HINT_ICON_WINDOW; 579ecce36beSmrg} 580ecce36beSmrg 581ecce36beSmrgvoid 582ecce36beSmrgxcb_wm_hints_set_window_group(xcb_wm_hints_t *hints, xcb_window_t window_group) 583ecce36beSmrg{ 584ecce36beSmrg hints->window_group = window_group; 585ecce36beSmrg hints->flags |= XCB_WM_HINT_WINDOW_GROUP; 586ecce36beSmrg} 587ecce36beSmrg 588ecce36beSmrgvoid 589ecce36beSmrgxcb_wm_hints_set_urgency(xcb_wm_hints_t *hints) 590ecce36beSmrg{ 591ecce36beSmrg hints->flags |= XCB_WM_HINT_X_URGENCY; 592ecce36beSmrg} 593ecce36beSmrg 594ecce36beSmrgvoid 595ecce36beSmrgxcb_set_wm_hints_checked(xcb_connection_t *c, xcb_window_t window, 596ecce36beSmrg xcb_wm_hints_t *hints) 597ecce36beSmrg{ 598ecce36beSmrg xcb_change_property_checked(c, XCB_PROP_MODE_REPLACE, window, WM_HINTS, 599ecce36beSmrg WM_HINTS, 32, sizeof(*hints) >> 2, hints); 600ecce36beSmrg} 601ecce36beSmrg 602ecce36beSmrgvoid 603ecce36beSmrgxcb_set_wm_hints(xcb_connection_t *c, xcb_window_t window, 604ecce36beSmrg xcb_wm_hints_t *hints) 605ecce36beSmrg{ 606ecce36beSmrg xcb_change_property(c, XCB_PROP_MODE_REPLACE, window, WM_HINTS, WM_HINTS, 32, 607ecce36beSmrg sizeof(*hints) >> 2, hints); 608ecce36beSmrg} 609ecce36beSmrg 610ecce36beSmrgxcb_get_property_cookie_t 611ecce36beSmrgxcb_get_wm_hints(xcb_connection_t *c, 612ecce36beSmrg xcb_window_t window) 613ecce36beSmrg{ 614ecce36beSmrg return xcb_get_property(c, 0, window, WM_HINTS, WM_HINTS, 0L, 615ecce36beSmrg XCB_NUM_WM_HINTS_ELEMENTS); 616ecce36beSmrg} 617ecce36beSmrg 618ecce36beSmrgxcb_get_property_cookie_t 619ecce36beSmrgxcb_get_wm_hints_unchecked(xcb_connection_t *c, 620ecce36beSmrg xcb_window_t window) 621ecce36beSmrg{ 622ecce36beSmrg return xcb_get_property_unchecked(c, 0, window, WM_HINTS, WM_HINTS, 0L, 623ecce36beSmrg XCB_NUM_WM_HINTS_ELEMENTS); 624ecce36beSmrg} 625ecce36beSmrg 626ecce36beSmrguint8_t 627ecce36beSmrgxcb_get_wm_hints_from_reply(xcb_wm_hints_t *hints, 628ecce36beSmrg xcb_get_property_reply_t *reply) 629ecce36beSmrg{ 630ecce36beSmrg if(!reply) 631ecce36beSmrg return 0; 632ecce36beSmrg 633ecce36beSmrg int length = xcb_get_property_value_length(reply); 634ecce36beSmrg int num_elem = length / (reply->format / 8); 635ecce36beSmrg 636ecce36beSmrg if (reply->type != WM_HINTS 637ecce36beSmrg || reply->format != 32 638ecce36beSmrg || num_elem < XCB_NUM_WM_HINTS_ELEMENTS - 1) 639ecce36beSmrg return 0; 640ecce36beSmrg 641ecce36beSmrg memcpy(hints, (xcb_size_hints_t *) xcb_get_property_value(reply), length); 642ecce36beSmrg 643ecce36beSmrg if(num_elem < XCB_NUM_WM_HINTS_ELEMENTS) 644ecce36beSmrg hints->window_group = XCB_NONE; 645ecce36beSmrg 646ecce36beSmrg return 1; 647ecce36beSmrg} 648ecce36beSmrg 649ecce36beSmrguint8_t 650ecce36beSmrgxcb_get_wm_hints_reply(xcb_connection_t *c, 651ecce36beSmrg xcb_get_property_cookie_t cookie, 652ecce36beSmrg xcb_wm_hints_t *hints, 653ecce36beSmrg xcb_generic_error_t **e) 654ecce36beSmrg{ 655ecce36beSmrg xcb_get_property_reply_t *reply = xcb_get_property_reply(c, cookie, e); 656ecce36beSmrg int ret = xcb_get_wm_hints_from_reply(hints, reply); 657ecce36beSmrg free(reply); 658ecce36beSmrg return ret; 659ecce36beSmrg} 660ecce36beSmrg 661ecce36beSmrg/* WM_PROTOCOLS */ 662ecce36beSmrg 663ecce36beSmrgvoid 664ecce36beSmrgxcb_set_wm_protocols_checked(xcb_connection_t *c, xcb_atom_t wm_protocols, 665ecce36beSmrg xcb_window_t window, uint32_t list_len, 666ecce36beSmrg xcb_atom_t *list) 667ecce36beSmrg{ 668ecce36beSmrg xcb_change_property_checked(c, XCB_PROP_MODE_REPLACE, window, wm_protocols, 669ecce36beSmrg ATOM, 32, list_len, list); 670ecce36beSmrg} 671ecce36beSmrg 672ecce36beSmrgvoid 673ecce36beSmrgxcb_set_wm_protocols(xcb_connection_t *c, xcb_atom_t wm_protocols, 674ecce36beSmrg xcb_window_t window, uint32_t list_len, xcb_atom_t *list) 675ecce36beSmrg{ 676ecce36beSmrg xcb_change_property(c, XCB_PROP_MODE_REPLACE, window, wm_protocols, ATOM, 32, 677ecce36beSmrg list_len, list); 678ecce36beSmrg} 679ecce36beSmrg 680ecce36beSmrgxcb_get_property_cookie_t 681ecce36beSmrgxcb_get_wm_protocols(xcb_connection_t *c, xcb_window_t window, 682ecce36beSmrg xcb_atom_t wm_protocol_atom) 683ecce36beSmrg{ 684ecce36beSmrg return xcb_get_property(c, 0, window, wm_protocol_atom, ATOM, 0, UINT_MAX); 685ecce36beSmrg} 686ecce36beSmrg 687ecce36beSmrgxcb_get_property_cookie_t 688ecce36beSmrgxcb_get_wm_protocols_unchecked(xcb_connection_t *c, 689ecce36beSmrg xcb_window_t window, 690ecce36beSmrg xcb_atom_t wm_protocol_atom) 691ecce36beSmrg{ 692ecce36beSmrg return xcb_get_property_unchecked(c, 0, window, wm_protocol_atom, ATOM, 0, 693ecce36beSmrg UINT_MAX); 694ecce36beSmrg} 695ecce36beSmrg 696ecce36beSmrguint8_t 697ecce36beSmrgxcb_get_wm_protocols_from_reply(xcb_get_property_reply_t *reply, xcb_get_wm_protocols_reply_t *protocols) 698ecce36beSmrg{ 699ecce36beSmrg if(!reply || reply->type != ATOM || reply->format != 32) 700ecce36beSmrg return 0; 701ecce36beSmrg 702ecce36beSmrg protocols->_reply = reply; 703ecce36beSmrg protocols->atoms_len = xcb_get_property_value_length(protocols->_reply) / (reply->format / 8); 704ecce36beSmrg protocols->atoms = (xcb_atom_t *) xcb_get_property_value(protocols->_reply); 705ecce36beSmrg 706ecce36beSmrg return 1; 707ecce36beSmrg} 708ecce36beSmrg 709ecce36beSmrguint8_t 710ecce36beSmrgxcb_get_wm_protocols_reply(xcb_connection_t *c, 711ecce36beSmrg xcb_get_property_cookie_t cookie, 712ecce36beSmrg xcb_get_wm_protocols_reply_t *protocols, 713ecce36beSmrg xcb_generic_error_t **e) 714ecce36beSmrg{ 715ecce36beSmrg xcb_get_property_reply_t *reply = xcb_get_property_reply(c, cookie, e); 716ecce36beSmrg uint8_t ret = xcb_get_wm_protocols_from_reply(reply, protocols); 717ecce36beSmrg if(!ret) 718ecce36beSmrg free(reply); 719ecce36beSmrg return ret; 720ecce36beSmrg} 721ecce36beSmrg 722ecce36beSmrgvoid 723ecce36beSmrgxcb_get_wm_protocols_reply_wipe(xcb_get_wm_protocols_reply_t *protocols) 724ecce36beSmrg{ 725ecce36beSmrg free(protocols->_reply); 726ecce36beSmrg} 727