| File: | core/xprops.c |
| Warning: | line 474, column 7 Out of bound memory access (access exceeds upper limit of memory block) |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ | |||
| 2 | ||||
| 3 | /* Croma X property convenience routines */ | |||
| 4 | ||||
| 5 | /* | |||
| 6 | * Copyright (C) 2001 Havoc Pennington | |||
| 7 | * Copyright (C) 2002 Red Hat Inc. | |||
| 8 | * | |||
| 9 | * Some trivial property-unpacking code from Xlib: | |||
| 10 | * Copyright 1987, 1988, 1998 The Open Group | |||
| 11 | * Copyright 1988 by Wyse Technology, Inc., San Jose, Ca, | |||
| 12 | * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, | |||
| 13 | * | |||
| 14 | * This program is free software; you can redistribute it and/or | |||
| 15 | * modify it under the terms of the GNU General Public License as | |||
| 16 | * published by the Free Software Foundation; either version 2 of the | |||
| 17 | * License, or (at your option) any later version. | |||
| 18 | * | |||
| 19 | * This program is distributed in the hope that it will be useful, but | |||
| 20 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| 22 | * General Public License for more details. | |||
| 23 | * | |||
| 24 | * You should have received a copy of the GNU General Public License | |||
| 25 | * along with this program; if not, write to the Free Software | |||
| 26 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | |||
| 27 | * 02110-1301, USA. | |||
| 28 | */ | |||
| 29 | ||||
| 30 | /*********************************************************** | |||
| 31 | Copyright 1988 by Wyse Technology, Inc., San Jose, Ca, | |||
| 32 | Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, | |||
| 33 | ||||
| 34 | All Rights Reserved | |||
| 35 | ||||
| 36 | Permission to use, copy, modify, and distribute this software and its | |||
| 37 | documentation for any purpose and without fee is hereby granted, | |||
| 38 | provided that the above copyright notice appear in all copies and that | |||
| 39 | both that copyright notice and this permission notice appear in | |||
| 40 | supporting documentation, and that the name Digital not be | |||
| 41 | used in advertising or publicity pertaining to distribution of the | |||
| 42 | software without specific, written prior permission. | |||
| 43 | ||||
| 44 | DIGITAL AND WYSE DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | |||
| 45 | INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO | |||
| 46 | EVENT SHALL DIGITAL OR WYSE BE LIABLE FOR ANY SPECIAL, INDIRECT OR | |||
| 47 | CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF | |||
| 48 | USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR | |||
| 49 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | |||
| 50 | PERFORMANCE OF THIS SOFTWARE. | |||
| 51 | ||||
| 52 | ******************************************************************/ | |||
| 53 | ||||
| 54 | /* | |||
| 55 | ||||
| 56 | Copyright 1987, 1988, 1998 The Open Group | |||
| 57 | ||||
| 58 | Permission to use, copy, modify, distribute, and sell this software and its | |||
| 59 | documentation for any purpose is hereby granted without fee, provided that | |||
| 60 | the above copyright notice appear in all copies and that both that | |||
| 61 | copyright notice and this permission notice appear in supporting | |||
| 62 | documentation. | |||
| 63 | ||||
| 64 | The above copyright notice and this permission notice shall be included | |||
| 65 | in all copies or substantial portions of the Software. | |||
| 66 | ||||
| 67 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |||
| 68 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||
| 69 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |||
| 70 | IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR | |||
| 71 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |||
| 72 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |||
| 73 | OTHER DEALINGS IN THE SOFTWARE. | |||
| 74 | ||||
| 75 | Except as contained in this notice, the name of The Open Group shall | |||
| 76 | not be used in advertising or otherwise to promote the sale, use or | |||
| 77 | other dealings in this Software without prior written authorization | |||
| 78 | from The Open Group. | |||
| 79 | ||||
| 80 | */ | |||
| 81 | ||||
| 82 | ||||
| 83 | #include <config.h> | |||
| 84 | #include "xprops.h" | |||
| 85 | #include "errors.h" | |||
| 86 | #include "util.h" | |||
| 87 | #include "async-getprop.h" | |||
| 88 | #include "ui.h" | |||
| 89 | #include "croma-Xatomtype.h" | |||
| 90 | #include <X11/Xatom.h> | |||
| 91 | #include <string.h> | |||
| 92 | #include "window-private.h" | |||
| 93 | ||||
| 94 | typedef struct | |||
| 95 | { | |||
| 96 | MetaDisplay *display; | |||
| 97 | Window xwindow; | |||
| 98 | Atom xatom; | |||
| 99 | Atom type; | |||
| 100 | int format; | |||
| 101 | unsigned long n_items; | |||
| 102 | unsigned long bytes_after; | |||
| 103 | unsigned char *prop; | |||
| 104 | } GetPropertyResults; | |||
| 105 | ||||
| 106 | static gboolean | |||
| 107 | validate_or_free_results (GetPropertyResults *results, | |||
| 108 | int expected_format, | |||
| 109 | Atom expected_type, | |||
| 110 | gboolean must_have_items) | |||
| 111 | { | |||
| 112 | char *type_name; | |||
| 113 | char *expected_name; | |||
| 114 | char *prop_name; | |||
| 115 | const char *title; | |||
| 116 | const char *res_class; | |||
| 117 | const char *res_name; | |||
| 118 | MetaWindow *w; | |||
| 119 | ||||
| 120 | if (expected_format == results->format && | |||
| 121 | expected_type == results->type && | |||
| 122 | (!must_have_items || results->n_items > 0)) | |||
| 123 | return TRUE(!(0)); | |||
| 124 | ||||
| 125 | meta_error_trap_push (results->display); | |||
| 126 | type_name = XGetAtomName (results->display->xdisplay, results->type); | |||
| 127 | expected_name = XGetAtomName (results->display->xdisplay, expected_type); | |||
| 128 | prop_name = XGetAtomName (results->display->xdisplay, results->xatom); | |||
| 129 | meta_error_trap_pop (results->display, TRUE(!(0))); | |||
| 130 | ||||
| 131 | w = meta_display_lookup_x_window (results->display, results->xwindow); | |||
| 132 | ||||
| 133 | if (w != NULL((void*)0)) | |||
| 134 | { | |||
| 135 | title = w->title; | |||
| 136 | res_class = w->res_class; | |||
| 137 | res_name = w->res_name; | |||
| 138 | } | |||
| 139 | else | |||
| 140 | { | |||
| 141 | title = NULL((void*)0); | |||
| 142 | res_class = NULL((void*)0); | |||
| 143 | res_name = NULL((void*)0); | |||
| 144 | } | |||
| 145 | ||||
| 146 | if (title == NULL((void*)0)) | |||
| 147 | title = "unknown"; | |||
| 148 | ||||
| 149 | if (res_class == NULL((void*)0)) | |||
| 150 | res_class = "unknown"; | |||
| 151 | ||||
| 152 | if (res_name == NULL((void*)0)) | |||
| 153 | res_name = "unknown"; | |||
| 154 | ||||
| 155 | meta_warning (_("Window 0x%lx has property %s\nthat was expected to have type %s format %d\nand actually has type %s format %d n_items %d.\nThis is most likely an application bug, not a window manager bug.\nThe window has title=\"%s\" class=\"%s\" name=\"%s\"\n")dgettext ("croma", "Window 0x%lx has property %s\nthat was expected to have type %s format %d\nand actually has type %s format %d n_items %d.\nThis is most likely an application bug, not a window manager bug.\nThe window has title=\"%s\" class=\"%s\" name=\"%s\"\n" ), | |||
| 156 | results->xwindow, | |||
| 157 | prop_name ? prop_name : "(bad atom)", | |||
| 158 | expected_name ? expected_name : "(bad atom)", | |||
| 159 | expected_format, | |||
| 160 | type_name ? type_name : "(bad atom)", | |||
| 161 | results->format, (int) results->n_items, | |||
| 162 | title, res_class, res_name); | |||
| 163 | ||||
| 164 | if (type_name) | |||
| 165 | XFree (type_name); | |||
| 166 | if (expected_name) | |||
| 167 | XFree (expected_name); | |||
| 168 | if (prop_name) | |||
| 169 | XFree (prop_name); | |||
| 170 | ||||
| 171 | if (results->prop) | |||
| 172 | { | |||
| 173 | XFree (results->prop); | |||
| 174 | results->prop = NULL((void*)0); | |||
| 175 | } | |||
| 176 | ||||
| 177 | return FALSE(0); | |||
| 178 | } | |||
| 179 | ||||
| 180 | static gboolean | |||
| 181 | get_property (MetaDisplay *display, | |||
| 182 | Window xwindow, | |||
| 183 | Atom xatom, | |||
| 184 | Atom req_type, | |||
| 185 | GetPropertyResults *results) | |||
| 186 | { | |||
| 187 | results->display = display; | |||
| 188 | results->xwindow = xwindow; | |||
| 189 | results->xatom = xatom; | |||
| 190 | results->prop = NULL((void*)0); | |||
| 191 | results->n_items = 0; | |||
| 192 | results->type = None0L; | |||
| 193 | results->bytes_after = 0; | |||
| 194 | results->format = 0; | |||
| 195 | ||||
| 196 | meta_error_trap_push (display); | |||
| 197 | if (XGetWindowProperty (display->xdisplay, xwindow, xatom, | |||
| 198 | 0, G_MAXLONG9223372036854775807L, | |||
| 199 | False0, req_type, &results->type, &results->format, | |||
| 200 | &results->n_items, | |||
| 201 | &results->bytes_after, | |||
| 202 | &results->prop) != Success0 || | |||
| 203 | results->type == None0L) | |||
| 204 | { | |||
| 205 | if (results->prop) | |||
| 206 | XFree (results->prop); | |||
| 207 | meta_error_trap_pop_with_return (display, TRUE(!(0))); | |||
| 208 | return FALSE(0); | |||
| 209 | } | |||
| 210 | ||||
| 211 | if (meta_error_trap_pop_with_return (display, TRUE(!(0))) != Success0) | |||
| 212 | { | |||
| 213 | if (results->prop) | |||
| 214 | XFree (results->prop); | |||
| 215 | return FALSE(0); | |||
| 216 | } | |||
| 217 | ||||
| 218 | return TRUE(!(0)); | |||
| 219 | } | |||
| 220 | ||||
| 221 | static gboolean | |||
| 222 | atom_list_from_results (GetPropertyResults *results, | |||
| 223 | Atom **atoms_p, | |||
| 224 | int *n_atoms_p) | |||
| 225 | { | |||
| 226 | if (!validate_or_free_results (results, 32, XA_ATOM((Atom) 4), FALSE(0))) | |||
| 227 | return FALSE(0); | |||
| 228 | ||||
| 229 | *atoms_p = (Atom*) results->prop; | |||
| 230 | *n_atoms_p = results->n_items; | |||
| 231 | results->prop = NULL((void*)0); | |||
| 232 | ||||
| 233 | return TRUE(!(0)); | |||
| 234 | } | |||
| 235 | ||||
| 236 | gboolean | |||
| 237 | meta_prop_get_atom_list (MetaDisplay *display, | |||
| 238 | Window xwindow, | |||
| 239 | Atom xatom, | |||
| 240 | Atom **atoms_p, | |||
| 241 | int *n_atoms_p) | |||
| 242 | { | |||
| 243 | GetPropertyResults results; | |||
| 244 | ||||
| 245 | *atoms_p = NULL((void*)0); | |||
| 246 | *n_atoms_p = 0; | |||
| 247 | ||||
| 248 | if (!get_property (display, xwindow, xatom, XA_ATOM((Atom) 4), | |||
| 249 | &results)) | |||
| 250 | return FALSE(0); | |||
| 251 | ||||
| 252 | return atom_list_from_results (&results, atoms_p, n_atoms_p); | |||
| 253 | } | |||
| 254 | ||||
| 255 | static gboolean | |||
| 256 | cardinal_list_from_results (GetPropertyResults *results, | |||
| 257 | gulong **cardinals_p, | |||
| 258 | int *n_cardinals_p) | |||
| 259 | { | |||
| 260 | if (!validate_or_free_results (results, 32, XA_CARDINAL((Atom) 6), FALSE(0))) | |||
| 261 | return FALSE(0); | |||
| 262 | ||||
| 263 | *cardinals_p = (gulong*) results->prop; | |||
| 264 | *n_cardinals_p = results->n_items; | |||
| 265 | results->prop = NULL((void*)0); | |||
| 266 | ||||
| 267 | #if GLIB_SIZEOF_LONG8 == 8 | |||
| 268 | /* Xlib sign-extends format=32 items, but we want them unsigned */ | |||
| 269 | { | |||
| 270 | int i; | |||
| 271 | ||||
| 272 | for (i = 0; i < *n_cardinals_p; i++) | |||
| 273 | (*cardinals_p)[i] = (*cardinals_p)[i] & 0xffffffff; | |||
| 274 | } | |||
| 275 | #endif | |||
| 276 | ||||
| 277 | return TRUE(!(0)); | |||
| 278 | } | |||
| 279 | ||||
| 280 | gboolean | |||
| 281 | meta_prop_get_cardinal_list (MetaDisplay *display, | |||
| 282 | Window xwindow, | |||
| 283 | Atom xatom, | |||
| 284 | gulong **cardinals_p, | |||
| 285 | int *n_cardinals_p) | |||
| 286 | { | |||
| 287 | GetPropertyResults results; | |||
| 288 | ||||
| 289 | *cardinals_p = NULL((void*)0); | |||
| 290 | *n_cardinals_p = 0; | |||
| 291 | ||||
| 292 | if (!get_property (display, xwindow, xatom, XA_CARDINAL((Atom) 6), | |||
| 293 | &results)) | |||
| 294 | return FALSE(0); | |||
| 295 | ||||
| 296 | return cardinal_list_from_results (&results, cardinals_p, n_cardinals_p); | |||
| 297 | } | |||
| 298 | ||||
| 299 | static gboolean | |||
| 300 | motif_hints_from_results (GetPropertyResults *results, | |||
| 301 | Motif_ctkWmHints **hints_p) | |||
| 302 | { | |||
| 303 | int real_size, max_size; | |||
| 304 | #define MAX_ITEMSsizeof (Motif_ctkWmHints)/sizeof (gulong) sizeof (Motif_ctkWmHints)/sizeof (gulong) | |||
| 305 | ||||
| 306 | *hints_p = NULL((void*)0); | |||
| 307 | ||||
| 308 | if (results->type == None0L || results->n_items <= 0) | |||
| 309 | { | |||
| 310 | meta_verbosemeta_verbose_real ("Motif_ctk hints had unexpected type or n_items\n"); | |||
| 311 | if (results->prop) | |||
| 312 | { | |||
| 313 | XFree (results->prop); | |||
| 314 | results->prop = NULL((void*)0); | |||
| 315 | } | |||
| 316 | return FALSE(0); | |||
| 317 | } | |||
| 318 | ||||
| 319 | /* The issue here is that some old crufty code will set a smaller | |||
| 320 | * Motif_ctkWmHints than the one we expect, apparently. I'm not sure of | |||
| 321 | * the history behind it. See bug #89841 for example. | |||
| 322 | */ | |||
| 323 | *hints_p = ag_Xmalloc (sizeof (Motif_ctkWmHints)); | |||
| 324 | if (*hints_p == NULL((void*)0)) | |||
| 325 | { | |||
| 326 | if (results->prop) | |||
| 327 | { | |||
| 328 | XFree (results->prop); | |||
| 329 | results->prop = NULL((void*)0); | |||
| 330 | } | |||
| 331 | return FALSE(0); | |||
| 332 | } | |||
| 333 | real_size = results->n_items * sizeof (gulong); | |||
| 334 | max_size = MAX_ITEMSsizeof (Motif_ctkWmHints)/sizeof (gulong) * sizeof (gulong); | |||
| 335 | memcpy (*hints_p, results->prop, MIN (real_size, max_size)(((real_size) < (max_size)) ? (real_size) : (max_size))); | |||
| 336 | ||||
| 337 | if (results->prop) | |||
| 338 | { | |||
| 339 | XFree (results->prop); | |||
| 340 | results->prop = NULL((void*)0); | |||
| 341 | } | |||
| 342 | ||||
| 343 | return TRUE(!(0)); | |||
| 344 | } | |||
| 345 | ||||
| 346 | gboolean | |||
| 347 | meta_prop_get_motif_hints (MetaDisplay *display, | |||
| 348 | Window xwindow, | |||
| 349 | Atom xatom, | |||
| 350 | Motif_ctkWmHints **hints_p) | |||
| 351 | { | |||
| 352 | GetPropertyResults results; | |||
| 353 | ||||
| 354 | *hints_p = NULL((void*)0); | |||
| 355 | ||||
| 356 | if (!get_property (display, xwindow, xatom, AnyPropertyType0L, | |||
| 357 | &results)) | |||
| 358 | return FALSE(0); | |||
| 359 | ||||
| 360 | return motif_hints_from_results (&results, hints_p); | |||
| 361 | } | |||
| 362 | ||||
| 363 | static gboolean | |||
| 364 | latin1_string_from_results (GetPropertyResults *results, | |||
| 365 | char **str_p) | |||
| 366 | { | |||
| 367 | *str_p = NULL((void*)0); | |||
| 368 | ||||
| 369 | if (!validate_or_free_results (results, 8, XA_STRING((Atom) 31), FALSE(0))) | |||
| 370 | return FALSE(0); | |||
| 371 | ||||
| 372 | *str_p = (char*) results->prop; | |||
| 373 | results->prop = NULL((void*)0); | |||
| 374 | ||||
| 375 | return TRUE(!(0)); | |||
| 376 | } | |||
| 377 | ||||
| 378 | gboolean | |||
| 379 | meta_prop_get_latin1_string (MetaDisplay *display, | |||
| 380 | Window xwindow, | |||
| 381 | Atom xatom, | |||
| 382 | char **str_p) | |||
| 383 | { | |||
| 384 | GetPropertyResults results; | |||
| 385 | ||||
| 386 | *str_p = NULL((void*)0); | |||
| 387 | ||||
| 388 | if (!get_property (display, xwindow, xatom, XA_STRING((Atom) 31), | |||
| 389 | &results)) | |||
| 390 | return FALSE(0); | |||
| 391 | ||||
| 392 | return latin1_string_from_results (&results, str_p); | |||
| 393 | } | |||
| 394 | ||||
| 395 | static gboolean | |||
| 396 | utf8_string_from_results (GetPropertyResults *results, | |||
| 397 | char **str_p) | |||
| 398 | { | |||
| 399 | *str_p = NULL((void*)0); | |||
| 400 | ||||
| 401 | if (!validate_or_free_results (results, 8, | |||
| 402 | results->display->atom_UTF8_STRING, FALSE(0))) | |||
| 403 | return FALSE(0); | |||
| 404 | ||||
| 405 | if (results->n_items > 0 && | |||
| 406 | !g_utf8_validate ((gchar *)results->prop, results->n_items, NULL((void*)0))) | |||
| 407 | { | |||
| 408 | char *name; | |||
| 409 | ||||
| 410 | name = XGetAtomName (results->display->xdisplay, results->xatom); | |||
| 411 | meta_warning (_("Property %s on window 0x%lx contained invalid UTF-8\n")dgettext ("croma", "Property %s on window 0x%lx contained invalid UTF-8\n" ), | |||
| 412 | name, results->xwindow); | |||
| 413 | meta_XFree (name)do { if ((name)) XFree ((name)); } while (0); | |||
| 414 | XFree (results->prop); | |||
| 415 | results->prop = NULL((void*)0); | |||
| 416 | ||||
| 417 | return FALSE(0); | |||
| 418 | } | |||
| 419 | ||||
| 420 | *str_p = (char*) results->prop; | |||
| 421 | results->prop = NULL((void*)0); | |||
| 422 | ||||
| 423 | return TRUE(!(0)); | |||
| 424 | } | |||
| 425 | ||||
| 426 | gboolean | |||
| 427 | meta_prop_get_utf8_string (MetaDisplay *display, | |||
| 428 | Window xwindow, | |||
| 429 | Atom xatom, | |||
| 430 | char **str_p) | |||
| 431 | { | |||
| 432 | GetPropertyResults results; | |||
| 433 | ||||
| 434 | *str_p = NULL((void*)0); | |||
| 435 | ||||
| 436 | if (!get_property (display, xwindow, xatom, | |||
| 437 | display->atom_UTF8_STRING, | |||
| 438 | &results)) | |||
| 439 | return FALSE(0); | |||
| 440 | ||||
| 441 | return utf8_string_from_results (&results, str_p); | |||
| 442 | } | |||
| 443 | ||||
| 444 | /* this one freakishly returns g_malloc memory */ | |||
| 445 | static gboolean | |||
| 446 | utf8_list_from_results (GetPropertyResults *results, | |||
| 447 | char ***str_p, | |||
| 448 | int *n_str_p) | |||
| 449 | { | |||
| 450 | int i; | |||
| 451 | int n_strings; | |||
| 452 | char **retval; | |||
| 453 | const char *p; | |||
| 454 | ||||
| 455 | *str_p = NULL((void*)0); | |||
| 456 | *n_str_p = 0; | |||
| 457 | ||||
| 458 | if (!validate_or_free_results (results, 8, | |||
| 459 | results->display->atom_UTF8_STRING, FALSE(0))) | |||
| 460 | return FALSE(0); | |||
| 461 | ||||
| 462 | /* I'm not sure this is right, but I'm guessing the | |||
| 463 | * property is nul-separated | |||
| 464 | */ | |||
| 465 | i = 0; | |||
| 466 | n_strings = 0; | |||
| 467 | while (i < (int) results->n_items) | |||
| 468 | { | |||
| 469 | if (results->prop[i] == '\0') | |||
| 470 | ++n_strings; | |||
| 471 | ++i; | |||
| 472 | } | |||
| 473 | ||||
| 474 | if (results->prop[results->n_items - 1] != '\0') | |||
| ||||
| 475 | ++n_strings; | |||
| 476 | ||||
| 477 | /* we're guaranteed that results->prop has a nul on the end | |||
| 478 | * by XGetWindowProperty | |||
| 479 | */ | |||
| 480 | ||||
| 481 | retval = g_new0 (char*, n_strings + 1)((char* *) g_malloc0_n ((n_strings + 1), sizeof (char*))); | |||
| 482 | ||||
| 483 | p = (char *)results->prop; | |||
| 484 | i = 0; | |||
| 485 | while (i < n_strings) | |||
| 486 | { | |||
| 487 | if (!g_utf8_validate (p, -1, NULL((void*)0))) | |||
| 488 | { | |||
| 489 | char *name; | |||
| 490 | ||||
| 491 | meta_error_trap_push (results->display); | |||
| 492 | name = XGetAtomName (results->display->xdisplay, results->xatom); | |||
| 493 | meta_error_trap_pop (results->display, TRUE(!(0))); | |||
| 494 | meta_warning (_("Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n")dgettext ("croma", "Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n" ), | |||
| 495 | name, results->xwindow, i); | |||
| 496 | meta_XFree (name)do { if ((name)) XFree ((name)); } while (0); | |||
| 497 | meta_XFree (results->prop)do { if ((results->prop)) XFree ((results->prop)); } while (0); | |||
| 498 | results->prop = NULL((void*)0); | |||
| 499 | ||||
| 500 | g_strfreev (retval); | |||
| 501 | return FALSE(0); | |||
| 502 | } | |||
| 503 | ||||
| 504 | retval[i] = g_strdup (p)g_strdup_inline (p); | |||
| 505 | ||||
| 506 | p = p + strlen (p) + 1; | |||
| 507 | ++i; | |||
| 508 | } | |||
| 509 | ||||
| 510 | *str_p = retval; | |||
| 511 | *n_str_p = i; | |||
| 512 | ||||
| 513 | meta_XFree (results->prop)do { if ((results->prop)) XFree ((results->prop)); } while (0); | |||
| 514 | results->prop = NULL((void*)0); | |||
| 515 | ||||
| 516 | return TRUE(!(0)); | |||
| 517 | } | |||
| 518 | ||||
| 519 | /* returns g_malloc not Xmalloc memory */ | |||
| 520 | gboolean | |||
| 521 | meta_prop_get_utf8_list (MetaDisplay *display, | |||
| 522 | Window xwindow, | |||
| 523 | Atom xatom, | |||
| 524 | char ***str_p, | |||
| 525 | int *n_str_p) | |||
| 526 | { | |||
| 527 | GetPropertyResults results; | |||
| 528 | ||||
| 529 | *str_p = NULL((void*)0); | |||
| 530 | ||||
| 531 | if (!get_property (display, xwindow, xatom, | |||
| 532 | display->atom_UTF8_STRING, | |||
| 533 | &results)) | |||
| 534 | return FALSE(0); | |||
| 535 | ||||
| 536 | return utf8_list_from_results (&results, str_p, n_str_p); | |||
| 537 | } | |||
| 538 | ||||
| 539 | void | |||
| 540 | meta_prop_set_utf8_string_hint (MetaDisplay *display, | |||
| 541 | Window xwindow, | |||
| 542 | Atom atom, | |||
| 543 | const char *val) | |||
| 544 | { | |||
| 545 | meta_error_trap_push (display); | |||
| 546 | XChangeProperty (display->xdisplay, | |||
| 547 | xwindow, atom, | |||
| 548 | display->atom_UTF8_STRING, | |||
| 549 | 8, PropModeReplace0, (guchar*) val, strlen (val)); | |||
| 550 | meta_error_trap_pop (display, FALSE(0)); | |||
| 551 | } | |||
| 552 | ||||
| 553 | static gboolean | |||
| 554 | window_from_results (GetPropertyResults *results, | |||
| 555 | Window *window_p) | |||
| 556 | { | |||
| 557 | if (!validate_or_free_results (results, 32, XA_WINDOW((Atom) 33), TRUE(!(0)))) | |||
| 558 | return FALSE(0); | |||
| 559 | ||||
| 560 | *window_p = *(Window*) results->prop; | |||
| 561 | XFree (results->prop); | |||
| 562 | results->prop = NULL((void*)0); | |||
| 563 | ||||
| 564 | return TRUE(!(0)); | |||
| 565 | } | |||
| 566 | ||||
| 567 | #ifdef HAVE_XSYNC | |||
| 568 | static gboolean | |||
| 569 | counter_from_results (GetPropertyResults *results, | |||
| 570 | XSyncCounter *counter_p) | |||
| 571 | { | |||
| 572 | if (!validate_or_free_results (results, 32, | |||
| 573 | XA_CARDINAL((Atom) 6), | |||
| 574 | TRUE(!(0)))) | |||
| 575 | return FALSE(0); | |||
| 576 | ||||
| 577 | *counter_p = *(XSyncCounter*) results->prop; | |||
| 578 | XFree (results->prop); | |||
| 579 | results->prop = NULL((void*)0); | |||
| 580 | ||||
| 581 | return TRUE(!(0)); | |||
| 582 | } | |||
| 583 | #endif | |||
| 584 | ||||
| 585 | gboolean | |||
| 586 | meta_prop_get_window (MetaDisplay *display, | |||
| 587 | Window xwindow, | |||
| 588 | Atom xatom, | |||
| 589 | Window *window_p) | |||
| 590 | { | |||
| 591 | GetPropertyResults results; | |||
| 592 | ||||
| 593 | *window_p = None0L; | |||
| 594 | ||||
| 595 | if (!get_property (display, xwindow, xatom, XA_WINDOW((Atom) 33), | |||
| 596 | &results)) | |||
| 597 | return FALSE(0); | |||
| 598 | ||||
| 599 | return window_from_results (&results, window_p); | |||
| 600 | } | |||
| 601 | ||||
| 602 | gboolean | |||
| 603 | meta_prop_get_cardinal (MetaDisplay *display, | |||
| 604 | Window xwindow, | |||
| 605 | Atom xatom, | |||
| 606 | gulong *cardinal_p) | |||
| 607 | { | |||
| 608 | return meta_prop_get_cardinal_with_atom_type (display, xwindow, xatom, | |||
| 609 | XA_CARDINAL((Atom) 6), cardinal_p); | |||
| 610 | } | |||
| 611 | ||||
| 612 | static gboolean | |||
| 613 | cardinal_with_atom_type_from_results (GetPropertyResults *results, | |||
| 614 | Atom prop_type, | |||
| 615 | gulong *cardinal_p) | |||
| 616 | { | |||
| 617 | if (!validate_or_free_results (results, 32, prop_type, TRUE(!(0)))) | |||
| 618 | return FALSE(0); | |||
| 619 | ||||
| 620 | *cardinal_p = *(gulong*) results->prop; | |||
| 621 | #if GLIB_SIZEOF_LONG8 == 8 | |||
| 622 | /* Xlib sign-extends format=32 items, but we want them unsigned */ | |||
| 623 | *cardinal_p &= 0xffffffff; | |||
| 624 | #endif | |||
| 625 | XFree (results->prop); | |||
| 626 | results->prop = NULL((void*)0); | |||
| 627 | ||||
| 628 | return TRUE(!(0)); | |||
| 629 | } | |||
| 630 | ||||
| 631 | gboolean | |||
| 632 | meta_prop_get_cardinal_with_atom_type (MetaDisplay *display, | |||
| 633 | Window xwindow, | |||
| 634 | Atom xatom, | |||
| 635 | Atom prop_type, | |||
| 636 | gulong *cardinal_p) | |||
| 637 | { | |||
| 638 | GetPropertyResults results; | |||
| 639 | ||||
| 640 | *cardinal_p = 0; | |||
| 641 | ||||
| 642 | if (!get_property (display, xwindow, xatom, prop_type, | |||
| 643 | &results)) | |||
| 644 | return FALSE(0); | |||
| 645 | ||||
| 646 | return cardinal_with_atom_type_from_results (&results, prop_type, cardinal_p); | |||
| 647 | } | |||
| 648 | ||||
| 649 | static char * | |||
| 650 | text_property_to_utf8 (Display *xdisplay, | |||
| 651 | const XTextProperty *prop) | |||
| 652 | { | |||
| 653 | char *ret = NULL((void*)0); | |||
| 654 | char **local_list = NULL((void*)0); | |||
| 655 | const char *charset = NULL((void*)0); | |||
| 656 | int count = 0; | |||
| 657 | int res; | |||
| 658 | ||||
| 659 | res = XmbTextPropertyToTextList (xdisplay, prop, &local_list, &count); | |||
| 660 | if (res == XNoMemory-1 || res == XLocaleNotSupported-2 || res == XConverterNotFound-3) | |||
| 661 | return NULL((void*)0); | |||
| 662 | ||||
| 663 | if (count == 0) | |||
| 664 | { | |||
| 665 | XFreeStringList (local_list); | |||
| 666 | return NULL((void*)0); | |||
| 667 | } | |||
| 668 | ||||
| 669 | if (g_get_charset (&charset)) | |||
| 670 | ret = g_strdup (local_list[0])g_strdup_inline (local_list[0]); | |||
| 671 | else | |||
| 672 | ret = g_convert (local_list[0], -1, "UTF-8", charset, NULL((void*)0), NULL((void*)0), NULL((void*)0)); | |||
| 673 | ||||
| 674 | XFreeStringList (local_list); | |||
| 675 | return ret; | |||
| 676 | } | |||
| 677 | ||||
| 678 | static gboolean | |||
| 679 | text_property_from_results (GetPropertyResults *results, | |||
| 680 | char **utf8_str_p) | |||
| 681 | { | |||
| 682 | XTextProperty tp; | |||
| 683 | ||||
| 684 | *utf8_str_p = NULL((void*)0); | |||
| 685 | ||||
| 686 | tp.value = results->prop; | |||
| 687 | results->prop = NULL((void*)0); | |||
| 688 | tp.encoding = results->type; | |||
| 689 | tp.format = results->format; | |||
| 690 | tp.nitems = results->n_items; | |||
| 691 | ||||
| 692 | *utf8_str_p = text_property_to_utf8 (results->display->xdisplay, &tp); | |||
| 693 | ||||
| 694 | if (tp.value != NULL((void*)0)) | |||
| 695 | XFree (tp.value); | |||
| 696 | ||||
| 697 | return *utf8_str_p != NULL((void*)0); | |||
| 698 | } | |||
| 699 | ||||
| 700 | gboolean | |||
| 701 | meta_prop_get_text_property (MetaDisplay *display, | |||
| 702 | Window xwindow, | |||
| 703 | Atom xatom, | |||
| 704 | char **utf8_str_p) | |||
| 705 | { | |||
| 706 | GetPropertyResults results; | |||
| 707 | ||||
| 708 | if (!get_property (display, xwindow, xatom, AnyPropertyType0L, | |||
| 709 | &results)) | |||
| 710 | return FALSE(0); | |||
| 711 | ||||
| 712 | return text_property_from_results (&results, utf8_str_p); | |||
| 713 | } | |||
| 714 | ||||
| 715 | /* From Xmd.h */ | |||
| 716 | #ifndef cvtINT32toInt | |||
| 717 | #if SIZEOF_VOID_P8 == 8 | |||
| 718 | #define cvtINT8toInt(val)((((unsigned int)val) & 0x00000080) ? (((unsigned int)val ) | 0xffffffffffffff00) : ((unsigned int)val)) ((((unsigned int)val) & 0x00000080) ? (((unsigned int)val) | 0xffffffffffffff00) : ((unsigned int)val)) | |||
| 719 | #define cvtINT16toInt(val)((((unsigned int)val) & 0x00008000) ? (((unsigned int)val ) | 0xffffffffffff0000) : ((unsigned int)val)) ((((unsigned int)val) & 0x00008000) ? (((unsigned int)val) | 0xffffffffffff0000) : ((unsigned int)val)) | |||
| 720 | #define cvtINT32toInt(val)((((unsigned int)val) & 0x80000000) ? (((unsigned int)val ) | 0xffffffff00000000) : ((unsigned int)val)) ((((unsigned int)val) & 0x80000000) ? (((unsigned int)val) | 0xffffffff00000000) : ((unsigned int)val)) | |||
| 721 | #define cvtINT8toShort(val)((((unsigned int)val) & 0x00000080) ? (((unsigned int)val ) | 0xffffffffffffff00) : ((unsigned int)val)) cvtINT8toInt(val)((((unsigned int)val) & 0x00000080) ? (((unsigned int)val ) | 0xffffffffffffff00) : ((unsigned int)val)) | |||
| 722 | #define cvtINT16toShort(val)((((unsigned int)val) & 0x00008000) ? (((unsigned int)val ) | 0xffffffffffff0000) : ((unsigned int)val)) cvtINT16toInt(val)((((unsigned int)val) & 0x00008000) ? (((unsigned int)val ) | 0xffffffffffff0000) : ((unsigned int)val)) | |||
| 723 | #define cvtINT32toShort(val)((((unsigned int)val) & 0x80000000) ? (((unsigned int)val ) | 0xffffffff00000000) : ((unsigned int)val)) cvtINT32toInt(val)((((unsigned int)val) & 0x80000000) ? (((unsigned int)val ) | 0xffffffff00000000) : ((unsigned int)val)) | |||
| 724 | #define cvtINT8toLong(val)((((unsigned int)val) & 0x00000080) ? (((unsigned int)val ) | 0xffffffffffffff00) : ((unsigned int)val)) cvtINT8toInt(val)((((unsigned int)val) & 0x00000080) ? (((unsigned int)val ) | 0xffffffffffffff00) : ((unsigned int)val)) | |||
| 725 | #define cvtINT16toLong(val)((((unsigned int)val) & 0x00008000) ? (((unsigned int)val ) | 0xffffffffffff0000) : ((unsigned int)val)) cvtINT16toInt(val)((((unsigned int)val) & 0x00008000) ? (((unsigned int)val ) | 0xffffffffffff0000) : ((unsigned int)val)) | |||
| 726 | #define cvtINT32toLong(val)((((unsigned int)val) & 0x80000000) ? (((unsigned int)val ) | 0xffffffff00000000) : ((unsigned int)val)) cvtINT32toInt(val)((((unsigned int)val) & 0x80000000) ? (((unsigned int)val ) | 0xffffffff00000000) : ((unsigned int)val)) | |||
| 727 | #else | |||
| 728 | #define cvtINT8toInt(val)((((unsigned int)val) & 0x00000080) ? (((unsigned int)val ) | 0xffffffffffffff00) : ((unsigned int)val)) (val) | |||
| 729 | #define cvtINT16toInt(val)((((unsigned int)val) & 0x00008000) ? (((unsigned int)val ) | 0xffffffffffff0000) : ((unsigned int)val)) (val) | |||
| 730 | #define cvtINT32toInt(val)((((unsigned int)val) & 0x80000000) ? (((unsigned int)val ) | 0xffffffff00000000) : ((unsigned int)val)) (val) | |||
| 731 | #define cvtINT8toShort(val)((((unsigned int)val) & 0x00000080) ? (((unsigned int)val ) | 0xffffffffffffff00) : ((unsigned int)val)) (val) | |||
| 732 | #define cvtINT16toShort(val)((((unsigned int)val) & 0x00008000) ? (((unsigned int)val ) | 0xffffffffffff0000) : ((unsigned int)val)) (val) | |||
| 733 | #define cvtINT32toShort(val)((((unsigned int)val) & 0x80000000) ? (((unsigned int)val ) | 0xffffffff00000000) : ((unsigned int)val)) (val) | |||
| 734 | #define cvtINT8toLong(val)((((unsigned int)val) & 0x00000080) ? (((unsigned int)val ) | 0xffffffffffffff00) : ((unsigned int)val)) (val) | |||
| 735 | #define cvtINT16toLong(val)((((unsigned int)val) & 0x00008000) ? (((unsigned int)val ) | 0xffffffffffff0000) : ((unsigned int)val)) (val) | |||
| 736 | #define cvtINT32toLong(val)((((unsigned int)val) & 0x80000000) ? (((unsigned int)val ) | 0xffffffff00000000) : ((unsigned int)val)) (val) | |||
| 737 | #endif /* SIZEOF_VOID_P == 8 */ | |||
| 738 | #endif /* cvtINT32toInt() */ | |||
| 739 | ||||
| 740 | static gboolean | |||
| 741 | wm_hints_from_results (GetPropertyResults *results, | |||
| 742 | XWMHints **hints_p) | |||
| 743 | { | |||
| 744 | XWMHints *hints; | |||
| 745 | xPropWMHints *raw; | |||
| 746 | ||||
| 747 | *hints_p = NULL((void*)0); | |||
| 748 | ||||
| 749 | if (!validate_or_free_results (results, 32, XA_WM_HINTS((Atom) 35), TRUE(!(0)))) | |||
| 750 | return FALSE(0); | |||
| 751 | ||||
| 752 | /* pre-R3 bogusly truncated window_group, don't fail on them */ | |||
| 753 | if (results->n_items < (NumPropWMHintsElements9 - 1)) | |||
| 754 | { | |||
| 755 | meta_verbosemeta_verbose_real ("WM_HINTS property too short: %d should be %d\n", | |||
| 756 | (int) results->n_items, NumPropWMHintsElements9 - 1); | |||
| 757 | if (results->prop) | |||
| 758 | { | |||
| 759 | XFree (results->prop); | |||
| 760 | results->prop = NULL((void*)0); | |||
| 761 | } | |||
| 762 | return FALSE(0); | |||
| 763 | } | |||
| 764 | ||||
| 765 | hints = ag_Xmalloc0 (sizeof (XWMHints)); | |||
| 766 | ||||
| 767 | raw = (xPropWMHints*) (gpointer) results->prop; | |||
| 768 | ||||
| 769 | hints->flags = raw->flags; | |||
| 770 | hints->input = (raw->input ? True1 : False0); | |||
| 771 | hints->initial_state = cvtINT32toInt (raw->initialState)((((unsigned int)raw->initialState) & 0x80000000) ? (( (unsigned int)raw->initialState) | 0xffffffff00000000) : ( (unsigned int)raw->initialState)); | |||
| 772 | hints->icon_pixmap = raw->iconPixmap; | |||
| 773 | hints->icon_window = raw->iconWindow; | |||
| 774 | hints->icon_x = cvtINT32toInt (raw->iconX)((((unsigned int)raw->iconX) & 0x80000000) ? (((unsigned int)raw->iconX) | 0xffffffff00000000) : ((unsigned int)raw ->iconX)); | |||
| 775 | hints->icon_y = cvtINT32toInt (raw->iconY)((((unsigned int)raw->iconY) & 0x80000000) ? (((unsigned int)raw->iconY) | 0xffffffff00000000) : ((unsigned int)raw ->iconY)); | |||
| 776 | hints->icon_mask = raw->iconMask; | |||
| 777 | if (results->n_items >= NumPropWMHintsElements9) | |||
| 778 | hints->window_group = raw->windowGroup; | |||
| 779 | else | |||
| 780 | hints->window_group = 0; | |||
| 781 | ||||
| 782 | if (results->prop) | |||
| 783 | { | |||
| 784 | XFree (results->prop); | |||
| 785 | results->prop = NULL((void*)0); | |||
| 786 | } | |||
| 787 | ||||
| 788 | *hints_p = hints; | |||
| 789 | ||||
| 790 | return TRUE(!(0)); | |||
| 791 | } | |||
| 792 | ||||
| 793 | gboolean | |||
| 794 | meta_prop_get_wm_hints (MetaDisplay *display, | |||
| 795 | Window xwindow, | |||
| 796 | Atom xatom, | |||
| 797 | XWMHints **hints_p) | |||
| 798 | { | |||
| 799 | GetPropertyResults results; | |||
| 800 | ||||
| 801 | *hints_p = NULL((void*)0); | |||
| 802 | ||||
| 803 | if (!get_property (display, xwindow, xatom, XA_WM_HINTS((Atom) 35), | |||
| 804 | &results)) | |||
| 805 | return FALSE(0); | |||
| 806 | ||||
| 807 | return wm_hints_from_results (&results, hints_p); | |||
| 808 | } | |||
| 809 | ||||
| 810 | static gboolean | |||
| 811 | class_hint_from_results (GetPropertyResults *results, | |||
| 812 | XClassHint *class_hint) | |||
| 813 | { | |||
| 814 | int len_name, len_class; | |||
| 815 | ||||
| 816 | class_hint->res_class = NULL((void*)0); | |||
| 817 | class_hint->res_name = NULL((void*)0); | |||
| 818 | ||||
| 819 | if (!validate_or_free_results (results, 8, XA_STRING((Atom) 31), FALSE(0))) | |||
| 820 | return FALSE(0); | |||
| 821 | ||||
| 822 | len_name = strlen ((char *) results->prop); | |||
| 823 | if (! (class_hint->res_name = ag_Xmalloc (len_name+1))) | |||
| 824 | { | |||
| 825 | XFree (results->prop); | |||
| 826 | results->prop = NULL((void*)0); | |||
| 827 | return FALSE(0); | |||
| 828 | } | |||
| 829 | ||||
| 830 | g_strlcpy (class_hint->res_name, (char *)results->prop, (len_name + 1)); | |||
| 831 | ||||
| 832 | if (len_name == (int) results->n_items) | |||
| 833 | len_name--; | |||
| 834 | ||||
| 835 | len_class = strlen ((char *)results->prop + len_name + 1); | |||
| 836 | ||||
| 837 | if (! (class_hint->res_class = ag_Xmalloc(len_class+1))) | |||
| 838 | { | |||
| 839 | XFree(class_hint->res_name); | |||
| 840 | class_hint->res_name = NULL((void*)0); | |||
| 841 | XFree (results->prop); | |||
| 842 | results->prop = NULL((void*)0); | |||
| 843 | return FALSE(0); | |||
| 844 | } | |||
| 845 | ||||
| 846 | g_strlcpy (class_hint->res_class, (char *)results->prop + len_name + 1, (len_class + 1)); | |||
| 847 | ||||
| 848 | XFree (results->prop); | |||
| 849 | results->prop = NULL((void*)0); | |||
| 850 | ||||
| 851 | return TRUE(!(0)); | |||
| 852 | } | |||
| 853 | ||||
| 854 | gboolean | |||
| 855 | meta_prop_get_class_hint (MetaDisplay *display, | |||
| 856 | Window xwindow, | |||
| 857 | Atom xatom, | |||
| 858 | XClassHint *class_hint) | |||
| 859 | { | |||
| 860 | GetPropertyResults results; | |||
| 861 | ||||
| 862 | class_hint->res_class = NULL((void*)0); | |||
| 863 | class_hint->res_name = NULL((void*)0); | |||
| 864 | ||||
| 865 | if (!get_property (display, xwindow, xatom, XA_STRING((Atom) 31), | |||
| 866 | &results)) | |||
| 867 | return FALSE(0); | |||
| 868 | ||||
| 869 | return class_hint_from_results (&results, class_hint); | |||
| 870 | } | |||
| 871 | ||||
| 872 | static gboolean | |||
| 873 | size_hints_from_results (GetPropertyResults *results, | |||
| 874 | XSizeHints **hints_p, | |||
| 875 | gulong *flags_p) | |||
| 876 | { | |||
| 877 | xPropSizeHints *raw; | |||
| 878 | XSizeHints *hints; | |||
| 879 | ||||
| 880 | *hints_p = NULL((void*)0); | |||
| 881 | *flags_p = 0; | |||
| 882 | ||||
| 883 | if (!validate_or_free_results (results, 32, XA_WM_SIZE_HINTS((Atom) 41), FALSE(0))) | |||
| 884 | return FALSE(0); | |||
| 885 | ||||
| 886 | if (results->n_items < OldNumPropSizeElements15) | |||
| 887 | return FALSE(0); | |||
| 888 | ||||
| 889 | raw = (xPropSizeHints*) (gpointer) results->prop; | |||
| 890 | ||||
| 891 | hints = ag_Xmalloc (sizeof (XSizeHints)); | |||
| 892 | ||||
| 893 | /* XSizeHints misdeclares these as int instead of long */ | |||
| 894 | hints->flags = raw->flags; | |||
| 895 | hints->x = cvtINT32toInt (raw->x)((((unsigned int)raw->x) & 0x80000000) ? (((unsigned int )raw->x) | 0xffffffff00000000) : ((unsigned int)raw->x) ); | |||
| 896 | hints->y = cvtINT32toInt (raw->y)((((unsigned int)raw->y) & 0x80000000) ? (((unsigned int )raw->y) | 0xffffffff00000000) : ((unsigned int)raw->y) ); | |||
| 897 | hints->width = cvtINT32toInt (raw->width)((((unsigned int)raw->width) & 0x80000000) ? (((unsigned int)raw->width) | 0xffffffff00000000) : ((unsigned int)raw ->width)); | |||
| 898 | hints->height = cvtINT32toInt (raw->height)((((unsigned int)raw->height) & 0x80000000) ? (((unsigned int)raw->height) | 0xffffffff00000000) : ((unsigned int)raw ->height)); | |||
| 899 | hints->min_width = cvtINT32toInt (raw->minWidth)((((unsigned int)raw->minWidth) & 0x80000000) ? (((unsigned int)raw->minWidth) | 0xffffffff00000000) : ((unsigned int )raw->minWidth)); | |||
| 900 | hints->min_height = cvtINT32toInt (raw->minHeight)((((unsigned int)raw->minHeight) & 0x80000000) ? (((unsigned int)raw->minHeight) | 0xffffffff00000000) : ((unsigned int )raw->minHeight)); | |||
| 901 | hints->max_width = cvtINT32toInt (raw->maxWidth)((((unsigned int)raw->maxWidth) & 0x80000000) ? (((unsigned int)raw->maxWidth) | 0xffffffff00000000) : ((unsigned int )raw->maxWidth)); | |||
| 902 | hints->max_height = cvtINT32toInt (raw->maxHeight)((((unsigned int)raw->maxHeight) & 0x80000000) ? (((unsigned int)raw->maxHeight) | 0xffffffff00000000) : ((unsigned int )raw->maxHeight)); | |||
| 903 | hints->width_inc = cvtINT32toInt (raw->widthInc)((((unsigned int)raw->widthInc) & 0x80000000) ? (((unsigned int)raw->widthInc) | 0xffffffff00000000) : ((unsigned int )raw->widthInc)); | |||
| 904 | hints->height_inc = cvtINT32toInt (raw->heightInc)((((unsigned int)raw->heightInc) & 0x80000000) ? (((unsigned int)raw->heightInc) | 0xffffffff00000000) : ((unsigned int )raw->heightInc)); | |||
| 905 | hints->min_aspect.x = cvtINT32toInt (raw->minAspectX)((((unsigned int)raw->minAspectX) & 0x80000000) ? (((unsigned int)raw->minAspectX) | 0xffffffff00000000) : ((unsigned int )raw->minAspectX)); | |||
| 906 | hints->min_aspect.y = cvtINT32toInt (raw->minAspectY)((((unsigned int)raw->minAspectY) & 0x80000000) ? (((unsigned int)raw->minAspectY) | 0xffffffff00000000) : ((unsigned int )raw->minAspectY)); | |||
| 907 | hints->max_aspect.x = cvtINT32toInt (raw->maxAspectX)((((unsigned int)raw->maxAspectX) & 0x80000000) ? (((unsigned int)raw->maxAspectX) | 0xffffffff00000000) : ((unsigned int )raw->maxAspectX)); | |||
| 908 | hints->max_aspect.y = cvtINT32toInt (raw->maxAspectY)((((unsigned int)raw->maxAspectY) & 0x80000000) ? (((unsigned int)raw->maxAspectY) | 0xffffffff00000000) : ((unsigned int )raw->maxAspectY)); | |||
| 909 | ||||
| 910 | *flags_p = (USPosition(1L << 0) | USSize(1L << 1) | PAllHints((1L << 2)|(1L << 3)|(1L << 4)|(1L << 5)|(1L << 6)|(1L << 7))); | |||
| 911 | if (results->n_items >= NumPropSizeElements18) | |||
| 912 | { | |||
| 913 | hints->base_width= cvtINT32toInt (raw->baseWidth)((((unsigned int)raw->baseWidth) & 0x80000000) ? (((unsigned int)raw->baseWidth) | 0xffffffff00000000) : ((unsigned int )raw->baseWidth)); | |||
| 914 | hints->base_height= cvtINT32toInt (raw->baseHeight)((((unsigned int)raw->baseHeight) & 0x80000000) ? (((unsigned int)raw->baseHeight) | 0xffffffff00000000) : ((unsigned int )raw->baseHeight)); | |||
| 915 | hints->win_gravity= cvtINT32toInt (raw->winGravity)((((unsigned int)raw->winGravity) & 0x80000000) ? (((unsigned int)raw->winGravity) | 0xffffffff00000000) : ((unsigned int )raw->winGravity)); | |||
| 916 | *flags_p |= (PBaseSize(1L << 8) | PWinGravity(1L << 9)); | |||
| 917 | } | |||
| 918 | ||||
| 919 | hints->flags &= (*flags_p); /* get rid of unwanted bits */ | |||
| 920 | ||||
| 921 | XFree (results->prop); | |||
| 922 | results->prop = NULL((void*)0); | |||
| 923 | ||||
| 924 | *hints_p = hints; | |||
| 925 | ||||
| 926 | return TRUE(!(0)); | |||
| 927 | } | |||
| 928 | ||||
| 929 | gboolean | |||
| 930 | meta_prop_get_size_hints (MetaDisplay *display, | |||
| 931 | Window xwindow, | |||
| 932 | Atom xatom, | |||
| 933 | XSizeHints **hints_p, | |||
| 934 | gulong *flags_p) | |||
| 935 | { | |||
| 936 | GetPropertyResults results; | |||
| 937 | ||||
| 938 | *hints_p = NULL((void*)0); | |||
| 939 | *flags_p = 0; | |||
| 940 | ||||
| 941 | if (!get_property (display, xwindow, xatom, XA_WM_SIZE_HINTS((Atom) 41), | |||
| 942 | &results)) | |||
| 943 | return FALSE(0); | |||
| 944 | ||||
| 945 | return size_hints_from_results (&results, hints_p, flags_p); | |||
| 946 | } | |||
| 947 | ||||
| 948 | static AgGetPropertyTask* | |||
| 949 | get_task (MetaDisplay *display, | |||
| 950 | Window xwindow, | |||
| 951 | Atom xatom, | |||
| 952 | Atom req_type) | |||
| 953 | { | |||
| 954 | return ag_task_create (display->xdisplay, | |||
| 955 | xwindow, | |||
| 956 | xatom, 0, G_MAXLONG9223372036854775807L, | |||
| 957 | False0, req_type); | |||
| 958 | } | |||
| 959 | ||||
| 960 | static char* | |||
| 961 | latin1_to_utf8 (const char *text) | |||
| 962 | { | |||
| 963 | GString *str; | |||
| 964 | const char *p; | |||
| 965 | ||||
| 966 | str = g_string_new (""); | |||
| 967 | ||||
| 968 | p = text; | |||
| 969 | while (*p) | |||
| 970 | { | |||
| 971 | g_string_append_unichar (str, *p); | |||
| 972 | ++p; | |||
| 973 | } | |||
| 974 | ||||
| 975 | return g_string_free (str, FALSE)(__builtin_constant_p ((0)) ? (((0)) ? (g_string_free) ((str) , ((0))) : g_string_free_and_steal (str)) : (g_string_free) ( (str), ((0)))); | |||
| 976 | } | |||
| 977 | ||||
| 978 | void | |||
| 979 | meta_prop_get_values (MetaDisplay *display, | |||
| 980 | Window xwindow, | |||
| 981 | MetaPropValue *values, | |||
| 982 | int n_values) | |||
| 983 | { | |||
| 984 | int i; | |||
| 985 | AgGetPropertyTask **tasks; | |||
| 986 | ||||
| 987 | meta_verbosemeta_verbose_real ("Requesting %d properties of 0x%lx at once\n", | |||
| 988 | n_values, xwindow); | |||
| 989 | ||||
| 990 | if (n_values == 0) | |||
| ||||
| 991 | return; | |||
| 992 | ||||
| 993 | tasks = g_new0 (AgGetPropertyTask*, n_values)((AgGetPropertyTask* *) g_malloc0_n ((n_values), sizeof (AgGetPropertyTask *))); | |||
| 994 | ||||
| 995 | /* Start up tasks. The "values" array can have values | |||
| 996 | * with atom == None, which means to ignore that element. | |||
| 997 | */ | |||
| 998 | i = 0; | |||
| 999 | while (i < n_values) | |||
| 1000 | { | |||
| 1001 | if (values[i].required_type == None0L) | |||
| 1002 | { | |||
| 1003 | switch (values[i].type) | |||
| 1004 | { | |||
| 1005 | case META_PROP_VALUE_INVALID: | |||
| 1006 | /* This means we don't really want a value, e.g. got | |||
| 1007 | * property notify on an atom we don't care about. | |||
| 1008 | */ | |||
| 1009 | if (values[i].atom != None0L) | |||
| 1010 | meta_bug ("META_PROP_VALUE_INVALID requested in %s\n", G_STRFUNC((const char*) (__func__))); | |||
| 1011 | break; | |||
| 1012 | case META_PROP_VALUE_UTF8_LIST: | |||
| 1013 | case META_PROP_VALUE_UTF8: | |||
| 1014 | values[i].required_type = display->atom_UTF8_STRING; | |||
| 1015 | break; | |||
| 1016 | case META_PROP_VALUE_STRING: | |||
| 1017 | case META_PROP_VALUE_STRING_AS_UTF8: | |||
| 1018 | values[i].required_type = XA_STRING((Atom) 31); | |||
| 1019 | break; | |||
| 1020 | case META_PROP_VALUE_MOTIF_HINTS: | |||
| 1021 | values[i].required_type = AnyPropertyType0L; | |||
| 1022 | break; | |||
| 1023 | case META_PROP_VALUE_CARDINAL_LIST: | |||
| 1024 | case META_PROP_VALUE_CARDINAL: | |||
| 1025 | values[i].required_type = XA_CARDINAL((Atom) 6); | |||
| 1026 | break; | |||
| 1027 | case META_PROP_VALUE_WINDOW: | |||
| 1028 | values[i].required_type = XA_WINDOW((Atom) 33); | |||
| 1029 | break; | |||
| 1030 | case META_PROP_VALUE_ATOM_LIST: | |||
| 1031 | values[i].required_type = XA_ATOM((Atom) 4); | |||
| 1032 | break; | |||
| 1033 | case META_PROP_VALUE_TEXT_PROPERTY: | |||
| 1034 | values[i].required_type = AnyPropertyType0L; | |||
| 1035 | break; | |||
| 1036 | case META_PROP_VALUE_WM_HINTS: | |||
| 1037 | values[i].required_type = XA_WM_HINTS((Atom) 35); | |||
| 1038 | break; | |||
| 1039 | case META_PROP_VALUE_CLASS_HINT: | |||
| 1040 | values[i].required_type = XA_STRING((Atom) 31); | |||
| 1041 | break; | |||
| 1042 | case META_PROP_VALUE_SIZE_HINTS: | |||
| 1043 | values[i].required_type = XA_WM_SIZE_HINTS((Atom) 41); | |||
| 1044 | break; | |||
| 1045 | case META_PROP_VALUE_SYNC_COUNTER: | |||
| 1046 | values[i].required_type = XA_CARDINAL((Atom) 6); | |||
| 1047 | break; | |||
| 1048 | } | |||
| 1049 | } | |||
| 1050 | ||||
| 1051 | if (values[i].atom != None0L) | |||
| 1052 | tasks[i] = get_task (display, xwindow, | |||
| 1053 | values[i].atom, values[i].required_type); | |||
| 1054 | ||||
| 1055 | ++i; | |||
| 1056 | } | |||
| 1057 | ||||
| 1058 | /* Get replies for all our tasks */ | |||
| 1059 | meta_topicmeta_topic_real (META_DEBUG_SYNC, "Syncing to get %d GetProperty replies in %s\n", | |||
| 1060 | n_values, G_STRFUNC((const char*) (__func__))); | |||
| 1061 | XSync (display->xdisplay, False0); | |||
| 1062 | ||||
| 1063 | /* Collect results, should arrive in order requested */ | |||
| 1064 | i = 0; | |||
| 1065 | while (i < n_values) | |||
| 1066 | { | |||
| 1067 | AgGetPropertyTask *task; | |||
| 1068 | GetPropertyResults results; | |||
| 1069 | ||||
| 1070 | if (tasks[i] == NULL((void*)0)) | |||
| 1071 | { | |||
| 1072 | /* Probably values[i].type was None, or ag_task_create() | |||
| 1073 | * returned NULL. | |||
| 1074 | */ | |||
| 1075 | values[i].type = META_PROP_VALUE_INVALID; | |||
| 1076 | goto next; | |||
| 1077 | } | |||
| 1078 | ||||
| 1079 | task = ag_get_next_completed_task (display->xdisplay); | |||
| 1080 | g_assert (task != NULL)do { if (task != ((void*)0)) ; else g_assertion_message_expr ( "croma", "core/xprops.c", 1080, ((const char*) (__func__)), "task != NULL" ); } while (0); | |||
| 1081 | g_assert (ag_task_have_reply (task))do { if (ag_task_have_reply (task)) ; else g_assertion_message_expr ("croma", "core/xprops.c", 1081, ((const char*) (__func__)), "ag_task_have_reply (task)"); } while (0); | |||
| 1082 | ||||
| 1083 | results.display = display; | |||
| 1084 | results.xwindow = xwindow; | |||
| 1085 | results.xatom = values[i].atom; | |||
| 1086 | results.prop = NULL((void*)0); | |||
| 1087 | results.n_items = 0; | |||
| 1088 | results.type = None0L; | |||
| 1089 | results.bytes_after = 0; | |||
| 1090 | results.format = 0; | |||
| 1091 | ||||
| 1092 | if (ag_task_get_reply_and_free (task, | |||
| 1093 | &results.type, &results.format, | |||
| 1094 | &results.n_items, | |||
| 1095 | &results.bytes_after, | |||
| 1096 | &results.prop) != Success0 || | |||
| 1097 | results.type == None0L) | |||
| 1098 | { | |||
| 1099 | values[i].type = META_PROP_VALUE_INVALID; | |||
| 1100 | if (results.prop) | |||
| 1101 | { | |||
| 1102 | XFree (results.prop); | |||
| 1103 | results.prop = NULL((void*)0); | |||
| 1104 | } | |||
| 1105 | goto next; | |||
| 1106 | } | |||
| 1107 | ||||
| 1108 | switch (values[i].type) | |||
| 1109 | { | |||
| 1110 | case META_PROP_VALUE_INVALID: | |||
| 1111 | g_assert_not_reached ()do { g_assertion_message_expr ("croma", "core/xprops.c", 1111 , ((const char*) (__func__)), ((void*)0)); } while (0); | |||
| 1112 | break; | |||
| 1113 | case META_PROP_VALUE_UTF8_LIST: | |||
| 1114 | if (!utf8_list_from_results (&results, | |||
| 1115 | &values[i].v.string_list.strings, | |||
| 1116 | &values[i].v.string_list.n_strings)) | |||
| 1117 | values[i].type = META_PROP_VALUE_INVALID; | |||
| 1118 | break; | |||
| 1119 | case META_PROP_VALUE_UTF8: | |||
| 1120 | if (!utf8_string_from_results (&results, | |||
| 1121 | &values[i].v.str)) | |||
| 1122 | values[i].type = META_PROP_VALUE_INVALID; | |||
| 1123 | break; | |||
| 1124 | case META_PROP_VALUE_STRING: | |||
| 1125 | if (!latin1_string_from_results (&results, | |||
| 1126 | &values[i].v.str)) | |||
| 1127 | values[i].type = META_PROP_VALUE_INVALID; | |||
| 1128 | break; | |||
| 1129 | case META_PROP_VALUE_STRING_AS_UTF8: | |||
| 1130 | if (!latin1_string_from_results (&results, | |||
| 1131 | &values[i].v.str)) | |||
| 1132 | values[i].type = META_PROP_VALUE_INVALID; | |||
| 1133 | else | |||
| 1134 | { | |||
| 1135 | char *new_str; | |||
| 1136 | char *xmalloc_new_str; | |||
| 1137 | ||||
| 1138 | new_str = latin1_to_utf8 (values[i].v.str); | |||
| 1139 | xmalloc_new_str = ag_Xmalloc (strlen (new_str) + 1); | |||
| 1140 | if (xmalloc_new_str != NULL((void*)0)) | |||
| 1141 | { | |||
| 1142 | g_strlcpy (xmalloc_new_str, new_str, (strlen (new_str) + 1)); | |||
| 1143 | meta_XFree (values[i].v.str)do { if ((values[i].v.str)) XFree ((values[i].v.str)); } while (0); | |||
| 1144 | values[i].v.str = xmalloc_new_str; | |||
| 1145 | } | |||
| 1146 | ||||
| 1147 | g_free (new_str); | |||
| 1148 | } | |||
| 1149 | break; | |||
| 1150 | case META_PROP_VALUE_MOTIF_HINTS: | |||
| 1151 | if (!motif_hints_from_results (&results, | |||
| 1152 | &values[i].v.motif_hints)) | |||
| 1153 | values[i].type = META_PROP_VALUE_INVALID; | |||
| 1154 | break; | |||
| 1155 | case META_PROP_VALUE_CARDINAL_LIST: | |||
| 1156 | if (!cardinal_list_from_results (&results, | |||
| 1157 | &values[i].v.cardinal_list.cardinals, | |||
| 1158 | &values[i].v.cardinal_list.n_cardinals)) | |||
| 1159 | values[i].type = META_PROP_VALUE_INVALID; | |||
| 1160 | break; | |||
| 1161 | case META_PROP_VALUE_CARDINAL: | |||
| 1162 | if (!cardinal_with_atom_type_from_results (&results, | |||
| 1163 | values[i].required_type, | |||
| 1164 | &values[i].v.cardinal)) | |||
| 1165 | values[i].type = META_PROP_VALUE_INVALID; | |||
| 1166 | break; | |||
| 1167 | case META_PROP_VALUE_WINDOW: | |||
| 1168 | if (!window_from_results (&results, | |||
| 1169 | &values[i].v.xwindow)) | |||
| 1170 | values[i].type = META_PROP_VALUE_INVALID; | |||
| 1171 | break; | |||
| 1172 | case META_PROP_VALUE_ATOM_LIST: | |||
| 1173 | if (!atom_list_from_results (&results, | |||
| 1174 | &values[i].v.atom_list.atoms, | |||
| 1175 | &values[i].v.atom_list.n_atoms)) | |||
| 1176 | values[i].type = META_PROP_VALUE_INVALID; | |||
| 1177 | break; | |||
| 1178 | case META_PROP_VALUE_TEXT_PROPERTY: | |||
| 1179 | if (!text_property_from_results (&results, &values[i].v.str)) | |||
| 1180 | values[i].type = META_PROP_VALUE_INVALID; | |||
| 1181 | break; | |||
| 1182 | case META_PROP_VALUE_WM_HINTS: | |||
| 1183 | if (!wm_hints_from_results (&results, &values[i].v.wm_hints)) | |||
| 1184 | values[i].type = META_PROP_VALUE_INVALID; | |||
| 1185 | break; | |||
| 1186 | case META_PROP_VALUE_CLASS_HINT: | |||
| 1187 | if (!class_hint_from_results (&results, &values[i].v.class_hint)) | |||
| 1188 | values[i].type = META_PROP_VALUE_INVALID; | |||
| 1189 | break; | |||
| 1190 | case META_PROP_VALUE_SIZE_HINTS: | |||
| 1191 | if (!size_hints_from_results (&results, | |||
| 1192 | &values[i].v.size_hints.hints, | |||
| 1193 | &values[i].v.size_hints.flags)) | |||
| 1194 | values[i].type = META_PROP_VALUE_INVALID; | |||
| 1195 | break; | |||
| 1196 | case META_PROP_VALUE_SYNC_COUNTER: | |||
| 1197 | #ifdef HAVE_XSYNC | |||
| 1198 | if (!counter_from_results (&results, | |||
| 1199 | &values[i].v.xcounter)) | |||
| 1200 | values[i].type = META_PROP_VALUE_INVALID; | |||
| 1201 | #else | |||
| 1202 | values[i].type = META_PROP_VALUE_INVALID; | |||
| 1203 | if (results.prop) | |||
| 1204 | { | |||
| 1205 | XFree (results.prop); | |||
| 1206 | results.prop = NULL((void*)0); | |||
| 1207 | } | |||
| 1208 | #endif | |||
| 1209 | break; | |||
| 1210 | } | |||
| 1211 | ||||
| 1212 | next: | |||
| 1213 | ++i; | |||
| 1214 | } | |||
| 1215 | ||||
| 1216 | g_free (tasks); | |||
| 1217 | } | |||
| 1218 | ||||
| 1219 | static void | |||
| 1220 | free_value (MetaPropValue *value) | |||
| 1221 | { | |||
| 1222 | switch (value->type) | |||
| 1223 | { | |||
| 1224 | case META_PROP_VALUE_INVALID: | |||
| 1225 | break; | |||
| 1226 | case META_PROP_VALUE_UTF8: | |||
| 1227 | case META_PROP_VALUE_STRING: | |||
| 1228 | case META_PROP_VALUE_STRING_AS_UTF8: | |||
| 1229 | meta_XFree (value->v.str)do { if ((value->v.str)) XFree ((value->v.str)); } while (0); | |||
| 1230 | break; | |||
| 1231 | case META_PROP_VALUE_MOTIF_HINTS: | |||
| 1232 | meta_XFree (value->v.motif_hints)do { if ((value->v.motif_hints)) XFree ((value->v.motif_hints )); } while (0); | |||
| 1233 | break; | |||
| 1234 | case META_PROP_VALUE_CARDINAL: | |||
| 1235 | break; | |||
| 1236 | case META_PROP_VALUE_WINDOW: | |||
| 1237 | break; | |||
| 1238 | case META_PROP_VALUE_ATOM_LIST: | |||
| 1239 | meta_XFree (value->v.atom_list.atoms)do { if ((value->v.atom_list.atoms)) XFree ((value->v.atom_list .atoms)); } while (0); | |||
| 1240 | break; | |||
| 1241 | case META_PROP_VALUE_TEXT_PROPERTY: | |||
| 1242 | meta_XFree (value->v.str)do { if ((value->v.str)) XFree ((value->v.str)); } while (0); | |||
| 1243 | break; | |||
| 1244 | case META_PROP_VALUE_WM_HINTS: | |||
| 1245 | meta_XFree (value->v.wm_hints)do { if ((value->v.wm_hints)) XFree ((value->v.wm_hints )); } while (0); | |||
| 1246 | break; | |||
| 1247 | case META_PROP_VALUE_CLASS_HINT: | |||
| 1248 | meta_XFree (value->v.class_hint.res_class)do { if ((value->v.class_hint.res_class)) XFree ((value-> v.class_hint.res_class)); } while (0); | |||
| 1249 | meta_XFree (value->v.class_hint.res_name)do { if ((value->v.class_hint.res_name)) XFree ((value-> v.class_hint.res_name)); } while (0); | |||
| 1250 | break; | |||
| 1251 | case META_PROP_VALUE_SIZE_HINTS: | |||
| 1252 | meta_XFree (value->v.size_hints.hints)do { if ((value->v.size_hints.hints)) XFree ((value->v. size_hints.hints)); } while (0); | |||
| 1253 | break; | |||
| 1254 | case META_PROP_VALUE_UTF8_LIST: | |||
| 1255 | g_strfreev (value->v.string_list.strings); | |||
| 1256 | break; | |||
| 1257 | case META_PROP_VALUE_CARDINAL_LIST: | |||
| 1258 | meta_XFree (value->v.cardinal_list.cardinals)do { if ((value->v.cardinal_list.cardinals)) XFree ((value ->v.cardinal_list.cardinals)); } while (0); | |||
| 1259 | break; | |||
| 1260 | case META_PROP_VALUE_SYNC_COUNTER: | |||
| 1261 | break; | |||
| 1262 | } | |||
| 1263 | } | |||
| 1264 | ||||
| 1265 | void | |||
| 1266 | meta_prop_free_values (MetaPropValue *values, | |||
| 1267 | int n_values) | |||
| 1268 | { | |||
| 1269 | int i; | |||
| 1270 | ||||
| 1271 | i = 0; | |||
| 1272 | while (i < n_values) | |||
| 1273 | { | |||
| 1274 | free_value (&values[i]); | |||
| 1275 | ++i; | |||
| 1276 | } | |||
| 1277 | ||||
| 1278 | /* Zero the whole thing to quickly detect breakage */ | |||
| 1279 | memset (values, '\0', sizeof (MetaPropValue) * n_values); | |||
| 1280 | } |