xcb_aux.c revision ecce36be
1/* 2 * Copyright © 2008 Bart Massey <bart@cs.pdx.edu> 3 * Copyright © 2008 Ian Osgood <iano@quirkster.com> 4 * Copyright © 2008 Jamey Sharp <jamey@minilop.net> 5 * Copyright © 2008 Josh Triplett <josh@freedesktop.org> 6 * 7 * Permission is hereby granted, free of charge, to any person 8 * obtaining a copy of this software and associated documentation 9 * files (the "Software"), to deal in the Software without 10 * restriction, including without limitation the rights to use, copy, 11 * modify, merge, publish, distribute, sublicense, and/or sell copies 12 * of the Software, and to permit persons to whom the Software is 13 * furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be 16 * included in all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY 22 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 23 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 24 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 * Except as contained in this notice, the names of the authors or 27 * their institutions shall not be used in advertising or otherwise to 28 * promote the sale, use or other dealings in this Software without 29 * prior written authorization from the authors. 30 */ 31 32#include <stdio.h> 33#include <stdlib.h> 34#include <string.h> 35 36#include <xcb/xcb.h> 37#include "xcb_aux.h" 38 39/* Connection related functions */ 40 41uint8_t 42xcb_aux_get_depth (xcb_connection_t *c, 43 xcb_screen_t *screen) 44{ 45 xcb_drawable_t drawable; 46 xcb_get_geometry_reply_t *geom; 47 int depth = 0; 48 49 drawable = screen->root; 50 geom = xcb_get_geometry_reply (c, xcb_get_geometry(c, drawable), 0); 51 52 if (geom) { 53 depth = geom->depth; 54 free (geom); 55 } 56 57 return depth; 58} 59 60uint8_t 61xcb_aux_get_depth_of_visual (xcb_screen_t *screen, 62 xcb_visualid_t id) 63{ 64 xcb_depth_iterator_t i; 65 xcb_visualtype_iterator_t j; 66 for (i = xcb_screen_allowed_depths_iterator(screen); 67 i.rem; xcb_depth_next(&i)) 68 for (j = xcb_depth_visuals_iterator(i.data); 69 j.rem; xcb_visualtype_next(&j)) 70 if (j.data->visual_id == id) 71 return i.data->depth; 72 return 0; 73} 74 75xcb_screen_t * 76xcb_aux_get_screen (xcb_connection_t *c, 77 int screen) 78{ 79 xcb_screen_iterator_t i = xcb_setup_roots_iterator(xcb_get_setup(c)); 80 for (; i.rem; --screen, xcb_screen_next(&i)) 81 if (screen == 0) 82 return i.data; 83 return 0; 84} 85 86xcb_visualtype_t * 87xcb_aux_get_visualtype (xcb_connection_t *c, 88 int scr, 89 xcb_visualid_t vid) 90{ 91 xcb_screen_t *screen; 92 xcb_depth_t *depth; 93 xcb_visualtype_iterator_t iter; 94 int cur; 95 96 screen = xcb_aux_get_screen (c, scr); 97 if (!screen) return NULL; 98 99 depth = xcb_screen_allowed_depths_iterator(screen).data; 100 if (!depth) return NULL; 101 102 iter = xcb_depth_visuals_iterator(depth); 103 for (cur = 0 ; cur < iter.rem ; xcb_visualtype_next(&iter), ++cur) 104 if (vid == iter.data->visual_id) 105 return iter.data; 106 107 return NULL; 108} 109 110xcb_visualtype_t * 111xcb_aux_find_visual_by_id (xcb_screen_t *screen, 112 xcb_visualid_t id) 113{ 114 xcb_depth_iterator_t i; 115 xcb_visualtype_iterator_t j; 116 for (i = xcb_screen_allowed_depths_iterator(screen); 117 i.rem; xcb_depth_next(&i)) 118 for (j = xcb_depth_visuals_iterator(i.data); 119 j.rem; xcb_visualtype_next(&j)) 120 if (j.data->visual_id == id) 121 return j.data; 122 return 0; 123} 124 125xcb_visualtype_t * 126xcb_aux_find_visual_by_attrs (xcb_screen_t *screen, 127 int8_t class, 128 int8_t depth) 129{ 130 xcb_depth_iterator_t i; 131 xcb_visualtype_iterator_t j; 132 for (i = xcb_screen_allowed_depths_iterator(screen); 133 i.rem; xcb_depth_next(&i)) { 134 if (depth != -1 && i.data->depth != depth) 135 continue; 136 for (j = xcb_depth_visuals_iterator(i.data); 137 j.rem; xcb_visualtype_next(&j)) 138 if (class == -1 || j.data->_class == class) 139 return j.data; 140 } 141 return 0; 142} 143 144void 145xcb_aux_sync (xcb_connection_t *c) 146{ 147 free(xcb_get_input_focus_reply(c, xcb_get_input_focus(c), NULL)); 148} 149 150/* structs instead of value lists */ 151/* TODO: generate the struct types and functions from protocol masks and descriptions */ 152 153/* This generic implementation of pack_list depends on: 154 a) structs packed to uint32_t size 155 b) structs consist of just uint32_t/int32_t fields in the same order as bitmask 156*/ 157 158static void 159pack_list( uint32_t mask, const uint32_t *src, uint32_t *dest ) 160{ 161 for ( ; mask; mask >>= 1, src++) 162 if (mask & 1) 163 *dest++ = *src; 164} 165 166xcb_void_cookie_t 167xcb_aux_create_window (xcb_connection_t *c, 168 uint8_t depth, 169 xcb_window_t wid, 170 xcb_window_t parent, 171 int16_t x, 172 int16_t y, 173 uint16_t width, 174 uint16_t height, 175 uint16_t border_width, 176 uint16_t _class, 177 xcb_visualid_t visual, 178 uint32_t mask, 179 const xcb_params_cw_t *params) 180{ 181 uint32_t value_list[16]; 182 pack_list(mask, (const uint32_t *)params, value_list); 183 return xcb_create_window(c, depth, wid, parent, 184 x, y, width, height, border_width, 185 _class, visual, mask, value_list); 186} 187 188xcb_void_cookie_t 189xcb_aux_create_window_checked (xcb_connection_t *c, 190 uint8_t depth, 191 xcb_window_t wid, 192 xcb_window_t parent, 193 int16_t x, 194 int16_t y, 195 uint16_t width, 196 uint16_t height, 197 uint16_t border_width, 198 uint16_t _class, 199 xcb_visualid_t visual, 200 uint32_t mask, 201 const xcb_params_cw_t *params) 202{ 203 uint32_t value_list[16]; 204 pack_list(mask, (const uint32_t *)params, value_list); 205 return xcb_create_window_checked(c, depth, wid, parent, 206 x, y, width, height, border_width, 207 _class, visual, mask, value_list); 208} 209 210xcb_void_cookie_t 211xcb_aux_change_window_attributes_checked (xcb_connection_t *c, 212 xcb_window_t window, 213 uint32_t mask, 214 const xcb_params_cw_t *params) 215{ 216 uint32_t value_list[16]; 217 pack_list(mask, (const uint32_t *)params, value_list); 218 return xcb_change_window_attributes_checked( c, window, mask, value_list ); 219} 220 221xcb_void_cookie_t 222xcb_aux_change_window_attributes (xcb_connection_t *c, 223 xcb_window_t window, 224 uint32_t mask, 225 const xcb_params_cw_t *params) 226{ 227 uint32_t value_list[16]; 228 pack_list(mask, (const uint32_t *)params, value_list); 229 return xcb_change_window_attributes( c, window, mask, value_list ); 230} 231 232xcb_void_cookie_t 233xcb_aux_configure_window (xcb_connection_t *c, 234 xcb_window_t window, 235 uint16_t mask, 236 const xcb_params_configure_window_t *params) 237{ 238 uint32_t value_list[8]; 239 pack_list(mask, (const uint32_t *)params, value_list); 240 return xcb_configure_window( c, window, mask, value_list ); 241} 242 243xcb_void_cookie_t 244xcb_aux_create_gc (xcb_connection_t *c, 245 xcb_gcontext_t gid, 246 xcb_drawable_t drawable, 247 uint32_t mask, 248 const xcb_params_gc_t *params) 249{ 250 uint32_t value_list[32]; 251 pack_list(mask, (const uint32_t *)params, value_list); 252 return xcb_create_gc( c, gid, drawable, mask, value_list ); 253} 254 255xcb_void_cookie_t 256xcb_aux_create_gc_checked (xcb_connection_t *c, 257 xcb_gcontext_t gid, 258 xcb_drawable_t drawable, 259 uint32_t mask, 260 const xcb_params_gc_t *params) 261{ 262 uint32_t value_list[32]; 263 pack_list(mask, (const uint32_t *)params, value_list); 264 return xcb_create_gc_checked( c, gid, drawable, mask, value_list); 265} 266 267xcb_void_cookie_t 268xcb_aux_change_gc (xcb_connection_t *c, 269 xcb_gcontext_t gc, 270 uint32_t mask, 271 const xcb_params_gc_t *params) 272{ 273 uint32_t value_list[32]; 274 pack_list(mask, (const uint32_t *)params, value_list); 275 return xcb_change_gc( c, gc, mask, value_list ); 276} 277 278xcb_void_cookie_t 279xcb_aux_change_gc_checked (xcb_connection_t *c, 280 xcb_gcontext_t gc, 281 uint32_t mask, 282 const xcb_params_gc_t *params) 283{ 284 uint32_t value_list[32]; 285 pack_list(mask, (const uint32_t *)params, value_list); 286 return xcb_change_gc_checked( c, gc, mask, value_list ); 287} 288 289xcb_void_cookie_t 290xcb_aux_change_keyboard_control (xcb_connection_t *c, 291 uint32_t mask, 292 const xcb_params_keyboard_t *params) 293{ 294 uint32_t value_list[16]; 295 pack_list(mask, (const uint32_t *)params, value_list); 296 return xcb_change_keyboard_control( c, mask, value_list ); 297} 298 299/* Color related functions */ 300 301/* Return true if the given color name can be translated locally, 302 in which case load the components. Otherwise, a lookup_color request 303 will be needed, so return false. */ 304int 305xcb_aux_parse_color(char *color_name, 306 uint16_t *red, uint16_t *green, uint16_t *blue) 307{ 308 int n, r, g, b, i; 309 if (!color_name || *color_name != '#') 310 return 0; 311 /* 312 * Excitingly weird RGB parsing code from Xlib. 313 */ 314 n = strlen (color_name); 315 color_name++; 316 n--; 317 if (n != 3 && n != 6 && n != 9 && n != 12) 318 return 0; 319 n /= 3; 320 g = b = 0; 321 do { 322 r = g; 323 g = b; 324 b = 0; 325 for (i = n; --i >= 0; ) { 326 char c = *color_name++; 327 b <<= 4; 328 if (c >= '0' && c <= '9') 329 b |= c - '0'; 330 else if (c >= 'A' && c <= 'F') 331 b |= c - ('A' - 10); 332 else if (c >= 'a' && c <= 'f') 333 b |= c - ('a' - 10); 334 else return 0; 335 } 336 } while (*color_name != '\0'); 337 n <<= 2; 338 n = 16 - n; 339 *red = r << n; 340 *green = g << n; 341 *blue = b << n; 342 return 1; 343} 344 345/* Drawing related functions */ 346 347/* Adapted from Xlib */ 348xcb_void_cookie_t 349xcb_aux_set_line_attributes_checked (xcb_connection_t *dpy, 350 xcb_gcontext_t gc, 351 uint16_t linewidth, 352 int32_t linestyle, 353 int32_t capstyle, 354 int32_t joinstyle) 355{ 356 uint32_t mask = 0; 357 xcb_params_gc_t gv; 358 359 XCB_AUX_ADD_PARAM(&mask, &gv, line_width, linewidth); 360 XCB_AUX_ADD_PARAM(&mask, &gv, line_style, linestyle); 361 XCB_AUX_ADD_PARAM(&mask, &gv, cap_style, capstyle); 362 XCB_AUX_ADD_PARAM(&mask, &gv, join_style, joinstyle); 363 return xcb_aux_change_gc_checked(dpy, gc, mask, &gv); 364} 365 366/* Adapted from Xlib */ 367/* XXX It would be wiser for apps just to call 368 clear_area() directly. */ 369xcb_void_cookie_t 370xcb_aux_clear_window(xcb_connection_t * dpy, 371 xcb_window_t w) 372{ 373 return xcb_clear_area(dpy, 0, w, 0, 0, 0, 0); 374} 375