summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHavoc Pennington <hp@pobox.com>2002-10-26 07:37:11 +0000
committerHavoc Pennington <hp@src.gnome.org>2002-10-26 07:37:11 +0000
commit5a8af8c2fb897825b7ea196197299f01645b0d17 (patch)
tree71733f380ab9959e4e8362baabb70b59b6e0f10c
parente8097a6f8f4bb2864a5ca99ed245b031a3806454 (diff)
downloadmetacity-5a8af8c2fb897825b7ea196197299f01645b0d17.tar.gz
use multi-value-get on a couple of properties for testing
2002-10-26 Havoc Pennington <hp@pobox.com> * src/window.c (meta_window_new): use multi-value-get on a couple of properties for testing * src/xprops.c (meta_prop_get_values): implement multi-value-get * src/window.c (update_mwm_hints): XFree motif hints as we changed it to use Xmalloc * src/xprops.c: massively rework this to set up a get-multiple-properties-at-once API. * src/async-getprop.c (ag_Xmalloc): new function
-rw-r--r--ChangeLog15
-rw-r--r--src/Makefile.am2
-rw-r--r--src/async-getprop.c6
-rw-r--r--src/async-getprop.h3
-rw-r--r--src/window.c44
-rw-r--r--src/xprops.c726
-rw-r--r--src/xprops.h59
7 files changed, 571 insertions, 284 deletions
diff --git a/ChangeLog b/ChangeLog
index 44bc825e..2fd916c4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2002-10-26 Havoc Pennington <hp@pobox.com>
+
+ * src/window.c (meta_window_new): use multi-value-get on a couple
+ of properties for testing
+
+ * src/xprops.c (meta_prop_get_values): implement multi-value-get
+
+ * src/window.c (update_mwm_hints): XFree motif hints as we changed
+ it to use Xmalloc
+
+ * src/xprops.c: massively rework this to set up a
+ get-multiple-properties-at-once API.
+
+ * src/async-getprop.c (ag_Xmalloc): new function
+
2002-10-25 Havoc Pennington <hp@pobox.com>
Add "busy cursor on app startup" support, conditionally - works
diff --git a/src/Makefile.am b/src/Makefile.am
index 2590a32d..3888c42b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -8,6 +8,8 @@ EGGFILES= \
eggaccelerators.h
metacity_SOURCES= \
+ async-getprop.c \
+ async-getprop.h \
common.h \
core.c \
core.h \
diff --git a/src/async-getprop.c b/src/async-getprop.c
index 62fbe9f2..1c160239 100644
--- a/src/async-getprop.c
+++ b/src/async-getprop.c
@@ -635,3 +635,9 @@ ag_get_next_completed_task (Display *display)
return (AgGetPropertyTask*) dd->completed_tasks;
}
+
+void*
+ag_Xmalloc (unsigned long bytes)
+{
+ return (void*) Xmalloc (bytes);
+}
diff --git a/src/async-getprop.h b/src/async-getprop.h
index 9ff3df1e..35d4befd 100644
--- a/src/async-getprop.h
+++ b/src/async-getprop.h
@@ -54,6 +54,9 @@ Display* ag_task_get_display (AgGetPropertyTask *task);
AgGetPropertyTask* ag_get_next_completed_task (Display *display);
+/* so other headers don't have to include internal Xlib goo */
+void* ag_Xmalloc (unsigned long bytes);
+
#endif
diff --git a/src/window.c b/src/window.c
index 666aa792..dab1bc85 100644
--- a/src/window.c
+++ b/src/window.c
@@ -153,16 +153,29 @@ wm_state_to_string (int state)
}
MetaWindow*
-meta_window_new (MetaDisplay *display, Window xwindow,
- gboolean must_be_viewable)
+meta_window_new (MetaDisplay *display,
+ Window xwindow,
+ gboolean must_be_viewable)
{
MetaWindow *window;
XWindowAttributes attrs;
GSList *tmp;
MetaWorkspace *space;
gulong existing_wm_state;
- char *str;
- unsigned long cardinal;
+#define N_INITIAL_PROPS 2
+ MetaPropValue initial_props[N_INITIAL_PROPS];
+
+ g_assert (N_INITIAL_PROPS == (int) G_N_ELEMENTS (initial_props));
+
+ memset (initial_props, '\0', sizeof (initial_props));
+
+#define INITIAL_PROP_WM_CLIENT_MACHINE 0
+ initial_props[0].type = META_PROP_VALUE_STRING;
+ initial_props[0].atom = display->atom_wm_client_machine;
+
+#define INITIAL_PROP_NET_WM_PID 1
+ initial_props[1].type = META_PROP_VALUE_CARDINAL;
+ initial_props[1].atom = display->atom_net_wm_pid;
meta_verbose ("Attempting to manage 0x%lx\n", xwindow);
@@ -427,21 +440,26 @@ meta_window_new (MetaDisplay *display, Window xwindow,
window->initial_workspace = 0; /* not used */
meta_display_register_x_window (display, &window->xwindow, window);
- if (meta_prop_get_latin1_string (window->display, window->xwindow,
- window->display->atom_wm_client_machine,
- &str))
+ meta_prop_get_values (display, window->xwindow,
+ initial_props, N_INITIAL_PROPS);
+
+ if (initial_props[INITIAL_PROP_WM_CLIENT_MACHINE].type !=
+ META_PROP_VALUE_INVALID)
{
- window->wm_client_machine = g_strdup (str);
- meta_XFree (str);
+ window->wm_client_machine =
+ g_strdup (initial_props[INITIAL_PROP_WM_CLIENT_MACHINE].v.str);
+
+ meta_XFree (initial_props[INITIAL_PROP_WM_CLIENT_MACHINE].v.str);
meta_verbose ("Window has client machine \"%s\"\n",
window->wm_client_machine);
}
- if (meta_prop_get_cardinal (window->display, window->xwindow,
- window->display->atom_net_wm_pid,
- &cardinal))
+ if (initial_props[INITIAL_PROP_NET_WM_PID].type !=
+ META_PROP_VALUE_INVALID)
{
+ gulong cardinal = (int) initial_props[INITIAL_PROP_NET_WM_PID].v.cardinal;
+
if (cardinal <= 0)
meta_warning (_("Application set a bogus _NET_WM_PID %ld\n"),
cardinal);
@@ -4491,7 +4509,7 @@ update_mwm_hints (MetaWindow *window)
else
meta_verbose ("Functions flag unset\n");
- g_free (hints);
+ meta_XFree (hints);
recalc_window_features (window);
}
diff --git a/src/xprops.c b/src/xprops.c
index c57c8be9..70966f87 100644
--- a/src/xprops.c
+++ b/src/xprops.c
@@ -2,6 +2,7 @@
/*
* Copyright (C) 2001 Havoc Pennington
+ * Copyright (C) 2002 Red Hat Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -23,41 +24,50 @@
#include "xprops.h"
#include "errors.h"
#include "util.h"
+#include "async-getprop.h"
#include <X11/Xatom.h>
#include <string.h>
+typedef struct
+{
+ MetaDisplay *display;
+ Window xwindow;
+ Atom xatom;
+ Atom type;
+ int format;
+ unsigned long n_items;
+ unsigned long bytes_after;
+ unsigned char *prop;
+} GetPropertyResults;
+
static gboolean
-check_type_and_format (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- int expected_format,
- Atom expected_type,
- int n_items, /* -1 to not check this */
- int format,
- Atom type)
+validate_or_free_results (GetPropertyResults *results,
+ int expected_format,
+ Atom expected_type,
+ gboolean must_have_items)
{
char *type_name;
char *expected_name;
char *prop_name;
- if (expected_format == format &&
- expected_type == type &&
- (n_items < 0 || n_items > 0))
+ if (expected_format == results->format &&
+ expected_type == results->type &&
+ (!must_have_items || results->n_items > 0))
return TRUE;
- meta_error_trap_push (display);
- type_name = XGetAtomName (display->xdisplay, type);
- expected_name = XGetAtomName (display->xdisplay, expected_type);
- prop_name = XGetAtomName (display->xdisplay, xatom);
- meta_error_trap_pop (display, TRUE);
+ meta_error_trap_push (results->display);
+ type_name = XGetAtomName (results->display->xdisplay, results->type);
+ expected_name = XGetAtomName (results->display->xdisplay, expected_type);
+ prop_name = XGetAtomName (results->display->xdisplay, results->xatom);
+ meta_error_trap_pop (results->display, TRUE);
meta_warning (_("Window 0x%lx has property %s that was expected to have type %s format %d and actually has type %s format %d n_items %d\n"),
- xwindow,
+ results->xwindow,
prop_name ? prop_name : "(bad atom)",
expected_name ? expected_name : "(bad atom)",
expected_format,
type_name ? type_name : "(bad atom)",
- format, n_items);
+ results->format, (int) results->n_items);
if (type_name)
XFree (type_name);
@@ -66,49 +76,102 @@ check_type_and_format (MetaDisplay *display,
if (prop_name)
XFree (prop_name);
+ if (results->prop)
+ {
+ XFree (results->prop);
+ results->prop = NULL;
+ }
+
return FALSE;
}
-gboolean
-meta_prop_get_atom_list (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- Atom **atoms_p,
- int *n_atoms_p)
+static gboolean
+get_property (MetaDisplay *display,
+ Window xwindow,
+ Atom xatom,
+ Atom req_type,
+ GetPropertyResults *results)
{
- Atom type;
- int format;
- gulong n_atoms;
- gulong bytes_after;
- Atom *atoms;
-
- *atoms_p = NULL;
- *n_atoms_p = 0;
+ results->display = display;
+ results->xwindow = xwindow;
+ results->xatom = xatom;
+ results->prop = NULL;
+ results->n_items = 0;
+ results->type = None;
+ results->bytes_after = 0;
+ results->format = 0;
meta_error_trap_push_with_return (display);
if (XGetWindowProperty (display->xdisplay, xwindow, xatom,
0, G_MAXLONG,
- False, XA_ATOM, &type, &format, &n_atoms,
- &bytes_after, (guchar **)&atoms) != Success ||
- type == None)
+ False, req_type, &results->type, &results->format,
+ &results->n_items,
+ &results->bytes_after,
+ (guchar **)&results->prop) != Success ||
+ results->type == None)
{
+ if (results->prop)
+ XFree (results->prop);
meta_error_trap_pop_with_return (display, TRUE);
return FALSE;
}
if (meta_error_trap_pop_with_return (display, TRUE) != Success)
- return FALSE;
-
- if (!check_type_and_format (display, xwindow, xatom, 32, XA_ATOM,
- -1, format, type))
{
- XFree (atoms);
+ if (results->prop)
+ XFree (results->prop);
return FALSE;
}
- *atoms_p = atoms;
- *n_atoms_p = n_atoms;
+ return TRUE;
+}
+
+static gboolean
+atom_list_from_results (GetPropertyResults *results,
+ Atom **atoms_p,
+ int *n_atoms_p)
+{
+ if (!validate_or_free_results (results, 32, XA_ATOM, FALSE))
+ return FALSE;
+ *atoms_p = (Atom*) results->prop;
+ *n_atoms_p = results->n_items;
+ results->prop = NULL;
+
+ return TRUE;
+}
+
+gboolean
+meta_prop_get_atom_list (MetaDisplay *display,
+ Window xwindow,
+ Atom xatom,
+ Atom **atoms_p,
+ int *n_atoms_p)
+{
+ GetPropertyResults results;
+
+ *atoms_p = NULL;
+ *n_atoms_p = 0;
+
+ if (!get_property (display, xwindow, xatom, XA_ATOM,
+ &results))
+ return FALSE;
+
+ return atom_list_from_results (&results, atoms_p, n_atoms_p);
+}
+
+static gboolean
+cardinal_list_from_results (GetPropertyResults *results,
+ gulong **cardinals_p,
+ int *n_cardinals_p)
+{
+ if (!validate_or_free_results (results, 32, XA_CARDINAL, FALSE))
+ return FALSE;
+
+ *cardinals_p = (gulong*) results->prop;
+ *n_cardinals_p = results->n_items;
+ results->prop = NULL;
+
return TRUE;
}
@@ -119,205 +182,169 @@ meta_prop_get_cardinal_list (MetaDisplay *display,
gulong **cardinals_p,
int *n_cardinals_p)
{
- Atom type;
- int format;
- gulong n_cardinals;
- gulong bytes_after;
- gulong *cardinals;
+ GetPropertyResults results;
*cardinals_p = NULL;
*n_cardinals_p = 0;
-
- meta_error_trap_push_with_return (display);
- if (XGetWindowProperty (display->xdisplay, xwindow, xatom,
- 0, G_MAXLONG,
- False, XA_CARDINAL, &type, &format, &n_cardinals,
- &bytes_after, (guchar **)&cardinals) != Success ||
- type == None)
- {
- meta_error_trap_pop_with_return (display, TRUE);
- return FALSE;
- }
- if (meta_error_trap_pop_with_return (display, TRUE) != Success)
+ if (!get_property (display, xwindow, xatom, XA_CARDINAL,
+ &results))
return FALSE;
- if (!check_type_and_format (display, xwindow, xatom, 32, XA_CARDINAL,
- -1, format, type))
- {
- XFree (cardinals);
- return FALSE;
- }
-
- *cardinals_p = cardinals;
- *n_cardinals_p = n_cardinals;
-
- return TRUE;
+ return cardinal_list_from_results (&results, cardinals_p, n_cardinals_p);
}
-gboolean
-meta_prop_get_motif_hints (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- MotifWmHints **hints_p)
+static gboolean
+motif_hints_from_results (GetPropertyResults *results,
+ MotifWmHints **hints_p)
{
- Atom type;
- int format;
- gulong bytes_after;
- MotifWmHints *hints;
- gulong n_items;
int real_size, max_size;
-
#define MAX_ITEMS sizeof (MotifWmHints)/sizeof (gulong)
- *hints_p = NULL;
-
- hints = NULL;
- n_items = 0;
- meta_error_trap_push_with_return (display);
- if (XGetWindowProperty (display->xdisplay, xwindow, xatom,
- 0, MAX_ITEMS,
- False, AnyPropertyType, &type, &format, &n_items,
- &bytes_after, (guchar **)&hints) != Success ||
- type == None)
- {
- meta_error_trap_pop_with_return (display, TRUE);
- return FALSE;
- }
+ *hints_p = NULL;
- if (meta_error_trap_pop_with_return (display, TRUE) != Success)
- return FALSE;
-
- if (type == None || n_items <= 0)
+ if (results->type == None || results->n_items <= 0)
{
meta_verbose ("Motif hints had unexpected type or n_items\n");
- XFree (hints);
+ if (results->prop)
+ {
+ XFree (results->prop);
+ results->prop = NULL;
+ }
return FALSE;
}
- g_assert (hints != NULL);
-
/* The issue here is that some old crufty code will set a smaller
* MotifWmHints than the one we expect, apparently. I'm not sure of
* the history behind it. See bug #89841 for example.
*/
- *hints_p = g_new0 (MotifWmHints, 1);
- real_size = n_items * sizeof (gulong);
+ *hints_p = ag_Xmalloc (sizeof (MotifWmHints));
+ if (*hints_p == NULL)
+ {
+ if (results->prop)
+ {
+ XFree (results->prop);
+ results->prop = NULL;
+ }
+ return FALSE;
+ }
+ real_size = results->n_items * sizeof (gulong);
max_size = MAX_ITEMS * sizeof (gulong);
- memcpy (*hints_p, hints, MIN (real_size, max_size));
+ memcpy (*hints_p, results->prop, MIN (real_size, max_size));
- XFree (hints);
+ if (results->prop)
+ {
+ XFree (results->prop);
+ results->prop = NULL;
+ }
return TRUE;
}
gboolean
-meta_prop_get_latin1_string (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- char **str_p)
+meta_prop_get_motif_hints (MetaDisplay *display,
+ Window xwindow,
+ Atom xatom,
+ MotifWmHints **hints_p)
{
- Atom type;
- int format;
- gulong bytes_after;
- guchar *str;
- gulong n_items;
-
- *str_p = NULL;
+ GetPropertyResults results;
- meta_error_trap_push_with_return (display);
- if (XGetWindowProperty (display->xdisplay, xwindow, xatom,
- 0, G_MAXLONG,
- False, XA_STRING, &type, &format, &n_items,
- &bytes_after, (guchar **)&str) != Success ||
- type == None)
- {
- meta_error_trap_pop_with_return (display, TRUE);
- return FALSE;
- }
+ *hints_p = NULL;
- if (meta_error_trap_pop_with_return (display, TRUE) != Success)
+ if (!get_property (display, xwindow, xatom, AnyPropertyType,
+ &results))
return FALSE;
- if (!check_type_and_format (display, xwindow, xatom, 8, XA_STRING,
- -1, format, type))
- {
- XFree (str);
- return FALSE;
- }
+ return motif_hints_from_results (&results, hints_p);
+}
- *str_p = str;
+static gboolean
+latin1_string_from_results (GetPropertyResults *results,
+ char **str_p)
+{
+ *str_p = NULL;
+
+ if (!validate_or_free_results (results, 8, XA_STRING, FALSE))
+ return FALSE;
+ *str_p = (char*) results->prop;
+ results->prop = NULL;
+
return TRUE;
}
gboolean
-meta_prop_get_utf8_string (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- char **str_p)
+meta_prop_get_latin1_string (MetaDisplay *display,
+ Window xwindow,
+ Atom xatom,
+ char **str_p)
{
- Atom type;
- int format;
- gulong bytes_after;
- guchar *str;
- gulong n_items;
-
+ GetPropertyResults results;
+
*str_p = NULL;
-
- meta_error_trap_push_with_return (display);
- if (XGetWindowProperty (display->xdisplay, xwindow, xatom,
- 0, G_MAXLONG,
- False, display->atom_utf8_string,
- &type, &format, &n_items,
- &bytes_after, (guchar **)&str) != Success ||
- type == None)
- {
- meta_error_trap_pop_with_return (display, TRUE);
- return FALSE;
- }
- if (meta_error_trap_pop_with_return (display, TRUE) != Success)
+ if (!get_property (display, xwindow, xatom, XA_STRING,
+ &results))
return FALSE;
+
+ return latin1_string_from_results (&results, str_p);
+}
- if (!check_type_and_format (display, xwindow, xatom, 8,
- display->atom_utf8_string,
- -1, format, type))
- {
- XFree (str);
- return FALSE;
- }
+static gboolean
+utf8_string_from_results (GetPropertyResults *results,
+ char **str_p)
+{
+ *str_p = NULL;
+
+ if (!validate_or_free_results (results, 8,
+ results->display->atom_utf8_string, FALSE))
+ return FALSE;
- if (!g_utf8_validate (str, n_items, NULL))
+ if (results->n_items > 0 &&
+ !g_utf8_validate (results->prop, results->n_items, NULL))
{
char *name;
- name = XGetAtomName (display->xdisplay, xatom);
+ name = XGetAtomName (results->display->xdisplay, results->xatom);
meta_warning (_("Property %s on window 0x%lx contained invalid UTF-8\n"),
- name, xwindow);
+ name, results->xwindow);
meta_XFree (name);
- XFree (str);
-
+ XFree (results->prop);
+ results->prop = NULL;
+
return FALSE;
}
- *str_p = str;
-
+ *str_p = (char*) results->prop;
+ results->prop = NULL;
+
return TRUE;
}
gboolean
-meta_prop_get_utf8_list (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- char ***str_p,
- int *n_str_p)
+meta_prop_get_utf8_string (MetaDisplay *display,
+ Window xwindow,
+ Atom xatom,
+ char **str_p)
+{
+ GetPropertyResults results;
+
+ *str_p = NULL;
+
+ if (!get_property (display, xwindow, xatom,
+ display->atom_utf8_string,
+ &results))
+ return FALSE;
+
+ return utf8_string_from_results (&results, str_p);
+}
+
+/* this one freakishly returns g_malloc memory */
+static gboolean
+utf8_list_from_results (GetPropertyResults *results,
+ char ***str_p,
+ int *n_str_p)
{
- Atom type;
- int format;
- gulong bytes_after;
- guchar *val;
- gulong n_items;
int i;
int n_strings;
char **retval;
@@ -325,49 +352,30 @@ meta_prop_get_utf8_list (MetaDisplay *display,
*str_p = NULL;
*n_str_p = 0;
-
- meta_error_trap_push_with_return (display);
- if (XGetWindowProperty (display->xdisplay, xwindow, xatom,
- 0, G_MAXLONG,
- False, display->atom_utf8_string,
- &type, &format, &n_items,
- &bytes_after, (guchar **)&val) != Success ||
- type == None)
- {
- meta_error_trap_pop_with_return (display, TRUE);
- return FALSE;
- }
- if (meta_error_trap_pop_with_return (display, TRUE) != Success)
+ if (!validate_or_free_results (results, 8,
+ results->display->atom_utf8_string, FALSE))
return FALSE;
-
- if (!check_type_and_format (display, xwindow, xatom, 8,
- display->atom_utf8_string,
- -1, format, type))
- {
- XFree (val);
- return FALSE;
- }
-
+
/* I'm not sure this is right, but I'm guessing the
* property is nul-separated
*/
i = 0;
n_strings = 1;
- while (i < (int) n_items)
+ while (i < (int) results->n_items)
{
- if (val[i] == '\0')
+ if (results->prop[i] == '\0')
++n_strings;
++i;
}
- /* we're guaranteed that val has a nul on the end
+ /* we're guaranteed that results->prop has a nul on the end
* by XGetWindowProperty
*/
retval = g_new0 (char*, n_strings + 1);
- p = val;
+ p = results->prop;
i = 0;
while (i < n_strings)
{
@@ -375,13 +383,14 @@ meta_prop_get_utf8_list (MetaDisplay *display,
{
char *name;
- meta_error_trap_push (display);
- name = XGetAtomName (display->xdisplay, xatom);
- meta_error_trap_pop (display, TRUE);
+ meta_error_trap_push (results->display);
+ name = XGetAtomName (results->display->xdisplay, results->xatom);
+ meta_error_trap_pop (results->display, TRUE);
meta_warning (_("Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n"),
- name, xwindow, i);
+ name, results->xwindow, i);
meta_XFree (name);
- meta_XFree (val);
+ meta_XFree (results->prop);
+ results->prop = NULL;
g_strfreev (retval);
return FALSE;
@@ -396,54 +405,64 @@ meta_prop_get_utf8_list (MetaDisplay *display,
*str_p = retval;
*n_str_p = i;
- meta_XFree (val);
-
+ meta_XFree (results->prop);
+ results->prop = NULL;
+
return TRUE;
}
+/* returns g_malloc not Xmalloc memory */
gboolean
-meta_prop_get_window (MetaDisplay *display,
- Window xwindow,
- Atom xatom,
- Window *window_p)
+meta_prop_get_utf8_list (MetaDisplay *display,
+ Window xwindow,
+ Atom xatom,
+ char ***str_p,
+ int *n_str_p)
{
- Atom type;
- int format;
- gulong bytes_after;
- Window *window;
- gulong n_items;
+ GetPropertyResults results;
- *window_p = None;
-
- meta_error_trap_push_with_return (display);
- if (XGetWindowProperty (display->xdisplay, xwindow, xatom,
- 0, G_MAXLONG,
- False, XA_WINDOW, &type, &format, &n_items,
- &bytes_after, (guchar **)&window) != Success ||
- type == None)
- {
- meta_error_trap_pop_with_return (display, TRUE);
- return FALSE;
- }
+ *str_p = NULL;
- if (meta_error_trap_pop_with_return (display, TRUE) != Success)
+ if (!get_property (display, xwindow, xatom,
+ display->atom_utf8_string,
+ &results))
return FALSE;
- if (!check_type_and_format (display, xwindow, xatom, 32, XA_WINDOW,
- -1, format, type))
- {
- XFree (window);
- return FALSE;
- }
+ return utf8_list_from_results (&results, str_p, n_str_p);
+}
- *window_p = *window;
+static gboolean
+window_from_results (GetPropertyResults *results,
+ Window *window_p)
+{
+ if (!validate_or_free_results (results, 32, XA_WINDOW, TRUE))
+ return FALSE;
- XFree (window);
+ *window_p = *(Window*) results->prop;
+ XFree (results->prop);
+ results->prop = NULL;
return TRUE;
}
gboolean
+meta_prop_get_window (MetaDisplay *display,
+ Window xwindow,
+ Atom xatom,
+ Window *window_p)
+{
+ GetPropertyResults results;
+
+ *window_p = None;
+
+ if (!get_property (display, xwindow, xatom, XA_WINDOW,
+ &results))
+ return FALSE;
+
+ return window_from_results (&results, window_p);
+}
+
+gboolean
meta_prop_get_cardinal (MetaDisplay *display,
Window xwindow,
Atom xatom,
@@ -454,6 +473,21 @@ meta_prop_get_cardinal (MetaDisplay *display,
XA_CARDINAL, cardinal_p);
}
+static gboolean
+cardinal_with_atom_type_from_results (GetPropertyResults *results,
+ Atom prop_type,
+ gulong *cardinal_p)
+{
+ if (!validate_or_free_results (results, 32, prop_type, TRUE))
+ return FALSE;
+
+ *cardinal_p = *(gulong*) results->prop;
+ XFree (results->prop);
+ results->prop = NULL;
+
+ return TRUE;
+}
+
gboolean
meta_prop_get_cardinal_with_atom_type (MetaDisplay *display,
Window xwindow,
@@ -461,39 +495,189 @@ meta_prop_get_cardinal_with_atom_type (MetaDisplay *display,
Atom prop_type,
gulong *cardinal_p)
{
- Atom type;
- int format;
- gulong bytes_after;
- gulong *cardinal;
- gulong n_items;
+ GetPropertyResults results;
*cardinal_p = 0;
-
- meta_error_trap_push_with_return (display);
- if (XGetWindowProperty (display->xdisplay, xwindow, xatom,
- 0, G_MAXLONG,
- False, prop_type, &type, &format, &n_items,
- &bytes_after, (guchar **)&cardinal) != Success ||
- type == None)
- {
- meta_error_trap_pop_with_return (display, TRUE);
- return FALSE;
- }
- if (meta_error_trap_pop_with_return (display, TRUE) != Success)
+ if (!get_property (display, xwindow, xatom, prop_type,
+ &results))
return FALSE;
- if (!check_type_and_format (display, xwindow, xatom, 32, prop_type,
- -1, format, type))
- {
- XFree (cardinal);
- return FALSE;
- }
+ return cardinal_with_atom_type_from_results (&results, prop_type, cardinal_p);
+}
+
+static AgGetPropertyTask*
+get_task (MetaDisplay *display,
+ Window xwindow,
+ Atom xatom,
+ Atom req_type)
+{
+ return ag_task_create (display->xdisplay,
+ xwindow,
+ xatom, 0, G_MAXLONG,
+ False, req_type);
+}
- *cardinal_p = *cardinal;
+void
+meta_prop_get_values (MetaDisplay *display,
+ Window xwindow,
+ MetaPropValue *values,
+ int n_values)
+{
+ int i;
+ AgGetPropertyTask **tasks;
- XFree (cardinal);
+ meta_verbose ("Requesting %d properties of 0x%lx at once\n",
+ n_values, xwindow);
- return TRUE;
+ if (n_values == 0)
+ return;
+
+ tasks = g_new0 (AgGetPropertyTask*, n_values);
+
+ /* Start up tasks */
+ i = 0;
+ while (i < n_values)
+ {
+ if (values[i].required_type == None)
+ {
+ switch (values[i].type)
+ {
+ case META_PROP_VALUE_INVALID:
+ meta_bug ("META_PROP_VALUE_INVALID requested in %s\n", __FUNCTION__);
+ break;
+ case META_PROP_VALUE_UTF8_LIST:
+ case META_PROP_VALUE_UTF8:
+ values[i].required_type = display->atom_utf8_string;
+ break;
+ case META_PROP_VALUE_STRING:
+ values[i].required_type = XA_STRING;
+ break;
+ case META_PROP_VALUE_MOTIF_HINTS:
+ values[i].required_type = AnyPropertyType;
+ break;
+ case META_PROP_VALUE_CARDINAL_LIST:
+ case META_PROP_VALUE_CARDINAL:
+ values[i].required_type = XA_CARDINAL;
+ break;
+ case META_PROP_VALUE_WINDOW:
+ values[i].required_type = XA_WINDOW;
+ break;
+ case META_PROP_VALUE_ATOM_LIST:
+ values[i].required_type = XA_ATOM;
+ break;
+ }
+ }
+
+ tasks[i] = get_task (display, xwindow,
+ values[i].atom, values[i].required_type);
+
+ ++i;
+ }
+
+ /* Get replies for all our tasks */
+ XSync (display->xdisplay, False);
+
+ /* Collect results, should arrive in order requested */
+ i = 0;
+ while (i < n_values)
+ {
+ AgGetPropertyTask *task;
+ GetPropertyResults results;
+
+ if (tasks[i] == NULL)
+ {
+ /* task creation failed for this property
+ * (doesn't actually happen I guess)
+ */
+ values[i].type = META_PROP_VALUE_INVALID;
+ goto next;
+ }
+
+ task = ag_get_next_completed_task (display->xdisplay);
+ g_assert (task != NULL);
+ g_assert (ag_task_have_reply (task));
+
+ results.display = display;
+ results.xwindow = xwindow;
+ results.xatom = values[i].atom;
+ results.prop = NULL;
+ results.n_items = 0;
+ results.type = None;
+ results.bytes_after = 0;
+ results.format = 0;
+
+ if (ag_task_get_reply_and_free (task,
+ &results.type, &results.format,
+ &results.n_items,
+ &results.bytes_after,
+ (guchar **)&results.prop) != Success ||
+ results.type == None)
+ {
+ values[i].type = META_PROP_VALUE_INVALID;
+ if (results.prop)
+ {
+ XFree (results.prop);
+ results.prop = NULL;
+ }
+ goto next;
+ }
+
+ switch (values[i].type)
+ {
+ case META_PROP_VALUE_INVALID:
+ g_assert_not_reached ();
+ break;
+ case META_PROP_VALUE_UTF8_LIST:
+ if (!utf8_list_from_results (&results,
+ &values[i].v.string_list.strings,
+ &values[i].v.string_list.n_strings))
+ values[i].type = META_PROP_VALUE_INVALID;
+ break;
+ case META_PROP_VALUE_UTF8:
+ if (!utf8_string_from_results (&results,
+ &values[i].v.str))
+ values[i].type = META_PROP_VALUE_INVALID;
+ break;
+ case META_PROP_VALUE_STRING:
+ if (!latin1_string_from_results (&results,
+ &values[i].v.str))
+ values[i].type = META_PROP_VALUE_INVALID;
+ break;
+ case META_PROP_VALUE_MOTIF_HINTS:
+ if (!motif_hints_from_results (&results,
+ &values[i].v.motif_hints))
+ values[i].type = META_PROP_VALUE_INVALID;
+ break;
+ case META_PROP_VALUE_CARDINAL_LIST:
+ if (!cardinal_list_from_results (&results,
+ &values[i].v.cardinal_list.cardinals,
+ &values[i].v.cardinal_list.n_cardinals))
+ values[i].type = META_PROP_VALUE_INVALID;
+ break;
+ case META_PROP_VALUE_CARDINAL:
+ if (!cardinal_with_atom_type_from_results (&results,
+ values[i].required_type,
+ &values[i].v.cardinal))
+ values[i].type = META_PROP_VALUE_INVALID;
+ break;
+ case META_PROP_VALUE_WINDOW:
+ if (!window_from_results (&results,
+ &values[i].v.xwindow))
+ values[i].type = META_PROP_VALUE_INVALID;
+ break;
+ case META_PROP_VALUE_ATOM_LIST:
+ if (!atom_list_from_results (&results,
+ &values[i].v.atom_list.atoms,
+ &values[i].v.atom_list.n_atoms))
+ values[i].type = META_PROP_VALUE_INVALID;
+ break;
+ }
+
+ next:
+ ++i;
+ }
+
+ g_free (tasks);
}
diff --git a/src/xprops.h b/src/xprops.h
index aef8b4fb..bd0f998c 100644
--- a/src/xprops.h
+++ b/src/xprops.h
@@ -108,6 +108,65 @@ gboolean meta_prop_get_cardinal_with_atom_type (MetaDisplay *display,
Atom prop_type,
gulong *cardinal_p);
+typedef enum
+{
+ META_PROP_VALUE_INVALID,
+ META_PROP_VALUE_UTF8,
+ META_PROP_VALUE_STRING,
+ META_PROP_VALUE_MOTIF_HINTS,
+ META_PROP_VALUE_CARDINAL,
+ META_PROP_VALUE_WINDOW,
+ META_PROP_VALUE_CARDINAL_LIST,
+ META_PROP_VALUE_UTF8_LIST,
+ META_PROP_VALUE_ATOM_LIST
+} MetaPropValueType;
+
+/* used to request/return/store property values */
+typedef struct
+{
+ MetaPropValueType type;
+ Atom atom;
+ Atom required_type; /* autofilled if None */
+
+ union
+ {
+ char *str;
+ MotifWmHints *motif_hints;
+ Window xwindow;
+ gulong cardinal;
+
+ struct
+ {
+ gulong *cardinals;
+ int n_cardinals;
+ } cardinal_list;
+
+ struct
+ {
+ char **strings;
+ int n_strings;
+ } string_list;
+
+ struct
+ {
+ Atom *atoms;
+ int n_atoms;
+ } atom_list;
+
+ } v;
+
+} MetaPropValue;
+
+/* Each value has type and atom initialized. If there's an error,
+ * or property is unset, type comes back as INVALID;
+ * else type comes back as it originated, and the data
+ * is filled in.
+ */
+void meta_prop_get_values (MetaDisplay *display,
+ Window xwindow,
+ MetaPropValue *values,
+ int n_values);
+
#endif