From 0d88e937876bf2527c967863d6dc8e8d451cf2f6 Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Sat, 26 Oct 2002 16:40:50 +0000 Subject: [PATCH] new function (meta_prop_get_wm_hints): new function 2002-10-26 Havoc Pennington * src/xprops.c (meta_prop_get_text_property): new function (meta_prop_get_wm_hints): new function (meta_prop_get_class_hint): new function --- ChangeLog | 6 ++ src/Makefile.am | 1 + src/async-getprop.c | 6 ++ src/async-getprop.h | 3 +- src/metacity-Xatomtype.h | 134 ++++++++++++++++++++++++ src/window.c | 69 +++---------- src/xprops.c | 218 +++++++++++++++++++++++++++++++++++++++ src/xprops.h | 21 +++- 8 files changed, 404 insertions(+), 54 deletions(-) create mode 100644 src/metacity-Xatomtype.h diff --git a/ChangeLog b/ChangeLog index 2fd916c43..a4decf6fd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2002-10-26 Havoc Pennington + + * src/xprops.c (meta_prop_get_text_property): new function + (meta_prop_get_wm_hints): new function + (meta_prop_get_class_hint): new function + 2002-10-26 Havoc Pennington * src/window.c (meta_window_new): use multi-value-get on a couple diff --git a/src/Makefile.am b/src/Makefile.am index 3888c42b0..4340e0a02 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -45,6 +45,7 @@ metacity_SOURCES= \ menu.h \ metaaccellabel.c \ metaaccellabel.h \ + metacity-Xatomtype.h \ place.c \ place.h \ prefs.c \ diff --git a/src/async-getprop.c b/src/async-getprop.c index 1c160239e..4b9f55944 100644 --- a/src/async-getprop.c +++ b/src/async-getprop.c @@ -641,3 +641,9 @@ ag_Xmalloc (unsigned long bytes) { return (void*) Xmalloc (bytes); } + +void* +ag_Xmalloc0 (unsigned long bytes) +{ + return (void*) Xcalloc (bytes, 1); +} diff --git a/src/async-getprop.h b/src/async-getprop.h index 35d4befdf..f190900fc 100644 --- a/src/async-getprop.h +++ b/src/async-getprop.h @@ -55,7 +55,8 @@ 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); +void* ag_Xmalloc (unsigned long bytes); +void* ag_Xmalloc0 (unsigned long bytes); #endif diff --git a/src/metacity-Xatomtype.h b/src/metacity-Xatomtype.h new file mode 100644 index 000000000..7ab7e5a04 --- /dev/null +++ b/src/metacity-Xatomtype.h @@ -0,0 +1,134 @@ +/* $Xorg: Xatomtype.h,v 1.4 2001/02/09 02:03:38 xorgcvs Exp $ */ + +/*********************************************************** + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef _XATOMTYPE_H_ +#define _XATOMTYPE_H_ + +/* + * This files defines crock C structures for calling XGetWindowProperty and + * XChangeProperty. All fields must be longs as the semantics of property + * routines will handle conversion to and from actual 32 bit objects. If your + * compiler doesn't treat &structoflongs the same as &arrayoflongs[0], you + * will have some work to do. + */ + +#define BOOL long +#define SIGNEDINT long +#define UNSIGNEDINT unsigned long +#define RESOURCEID unsigned long + + +/* this structure may be extended, but do not change the order */ +typedef struct { + UNSIGNEDINT flags; + SIGNEDINT x, y, width, height; /* need to cvt; only for pre-ICCCM */ + SIGNEDINT minWidth, minHeight; /* need to cvt */ + SIGNEDINT maxWidth, maxHeight; /* need to cvt */ + SIGNEDINT widthInc, heightInc; /* need to cvt */ + SIGNEDINT minAspectX, minAspectY; /* need to cvt */ + SIGNEDINT maxAspectX, maxAspectY; /* need to cvt */ + SIGNEDINT baseWidth,baseHeight; /* need to cvt; ICCCM version 1 */ + SIGNEDINT winGravity; /* need to cvt; ICCCM version 1 */ +} xPropSizeHints; +#define OldNumPropSizeElements 15 /* pre-ICCCM */ +#define NumPropSizeElements 18 /* ICCCM version 1 */ + +/* this structure may be extended, but do not change the order */ +/* RGB properties */ +typedef struct { + RESOURCEID colormap; + UNSIGNEDINT red_max; + UNSIGNEDINT red_mult; + UNSIGNEDINT green_max; + UNSIGNEDINT green_mult; + UNSIGNEDINT blue_max; + UNSIGNEDINT blue_mult; + UNSIGNEDINT base_pixel; + RESOURCEID visualid; /* ICCCM version 1 */ + RESOURCEID killid; /* ICCCM version 1 */ +} xPropStandardColormap; +#define OldNumPropStandardColormapElements 8 /* pre-ICCCM */ +#define NumPropStandardColormapElements 10 /* ICCCM version 1 */ + + +/* this structure may be extended, but do not change the order */ +typedef struct { + UNSIGNEDINT flags; + BOOL input; /* need to convert */ + SIGNEDINT initialState; /* need to cvt */ + RESOURCEID iconPixmap; + RESOURCEID iconWindow; + SIGNEDINT iconX; /* need to cvt */ + SIGNEDINT iconY; /* need to cvt */ + RESOURCEID iconMask; + UNSIGNEDINT windowGroup; + } xPropWMHints; +#define NumPropWMHintsElements 9 /* number of elements in this structure */ + +/* this structure defines the icon size hints information */ +typedef struct { + SIGNEDINT minWidth, minHeight; /* need to cvt */ + SIGNEDINT maxWidth, maxHeight; /* need to cvt */ + SIGNEDINT widthInc, heightInc; /* need to cvt */ + } xPropIconSize; +#define NumPropIconSizeElements 6 /* number of elements in this structure */ + +/* this structure defines the window manager state information */ +typedef struct { + SIGNEDINT state; /* need to cvt */ + RESOURCEID iconWindow; +} xPropWMState; +#define NumPropWMStateElements 2 /* number of elements in struct */ + +#undef BOOL +#undef SIGNEDINT +#undef UNSIGNEDINT +#undef RESOURCEID + +#endif /* _XATOMTYPE_H_ */ diff --git a/src/window.c b/src/window.c index dab1bc857..c6c171509 100644 --- a/src/window.c +++ b/src/window.c @@ -38,6 +38,7 @@ #include "group.h" #include +#include typedef enum { @@ -123,10 +124,6 @@ static void meta_window_move_resize_internal (MetaWindow *window, void meta_window_move_resize_now (MetaWindow *window); -static char* get_text_property (MetaDisplay *display, - Window xwindow, - Atom atom); - void meta_window_unqueue_calc_showing (MetaWindow *window); void meta_window_flush_calc_showing (MetaWindow *window); @@ -4219,9 +4216,10 @@ update_title (MetaWindow *window) if (window->title == NULL) { - window->title = get_text_property (window->display, - window->xwindow, - XA_WM_NAME); + meta_prop_get_text_property (window->display, + window->xwindow, + XA_WM_NAME, + &window->title); if (window->title) { @@ -4299,13 +4297,12 @@ update_wm_hints (MetaWindow *window) window->xgroup_leader = None; window->wm_hints_pixmap = None; window->wm_hints_mask = None; - - meta_error_trap_push (window->display); - - hints = XGetWMHints (window->display->xdisplay, - window->xwindow); - meta_error_trap_pop (window->display, TRUE); + hints = NULL; + meta_prop_get_wm_hints (window->display, + window->xwindow, + XA_WM_HINTS, + &hints); if (hints) { @@ -4566,11 +4563,10 @@ update_wm_class (MetaWindow *window) ch.res_name = NULL; ch.res_class = NULL; - meta_error_trap_push (window->display); - XGetClassHint (window->display->xdisplay, - window->xwindow, - &ch); - meta_error_trap_pop (window->display, TRUE); + meta_prop_get_class_hint (window->display, + window->xwindow, + XA_WM_CLASS, + &ch); if (ch.res_name) { @@ -4730,38 +4726,6 @@ update_transient_for (MetaWindow *window) meta_stack_update_transient (window->screen->stack, window); } -static char* -get_text_property (MetaDisplay *display, - Window xwindow, - Atom atom) -{ - XTextProperty text; - char *retval; - - meta_error_trap_push (display); - - text.nitems = 0; - if (XGetTextProperty (display->xdisplay, - xwindow, - &text, - atom)) - { - retval = meta_text_property_to_utf8 (display->xdisplay, &text); - - if (text.nitems > 0) - XFree (text.value); - } - else - { - retval = NULL; - meta_verbose ("XGetTextProperty() failed\n"); - } - - meta_error_trap_pop (display, TRUE); - - return retval; -} - /* some legacy cruft */ typedef enum { @@ -4930,8 +4894,9 @@ update_icon_name (MetaWindow *window) if (window->icon_name == NULL) { - window->icon_name = get_text_property (window->display, window->xwindow, - XA_WM_ICON_NAME); + meta_prop_get_text_property (window->display, window->xwindow, + XA_WM_ICON_NAME, + &window->icon_name); if (window->icon_name) { diff --git a/src/xprops.c b/src/xprops.c index 70966f87c..bc66db2ce 100644 --- a/src/xprops.c +++ b/src/xprops.c @@ -25,6 +25,8 @@ #include "errors.h" #include "util.h" #include "async-getprop.h" +#include "ui.h" +#include "metacity-Xatomtype.h" #include #include @@ -506,6 +508,201 @@ meta_prop_get_cardinal_with_atom_type (MetaDisplay *display, return cardinal_with_atom_type_from_results (&results, prop_type, cardinal_p); } +static gboolean +text_property_from_results (GetPropertyResults *results, + char **utf8_str_p) +{ + XTextProperty tp; + + *utf8_str_p = NULL; + + tp.value = results->prop; + results->prop = NULL; + tp.encoding = results->type; + tp.format = results->format; + tp.nitems = results->n_items; + + *utf8_str_p = meta_text_property_to_utf8 (results->display->xdisplay, + &tp); + + if (tp.value != NULL) + XFree (tp.value); + + return *utf8_str_p != NULL; +} + +gboolean +meta_prop_get_text_property (MetaDisplay *display, + Window xwindow, + Atom xatom, + char **utf8_str_p) +{ + GetPropertyResults results; + + if (!get_property (display, xwindow, xatom, AnyPropertyType, + &results)) + return FALSE; + + return text_property_from_results (&results, utf8_str_p); +} + +/* From Xmd.h */ +#ifndef cvtINT32toInt +#if defined(WORD64) && defined(UNSIGNEDBITFIELDS) +#define cvtINT8toInt(val) (((val) & 0x00000080) ? ((val) | 0xffffffffffffff00) : (val)) +#define cvtINT16toInt(val) (((val) & 0x00008000) ? ((val) | 0xffffffffffff0000) : (val)) +#define cvtINT32toInt(val) (((val) & 0x80000000) ? ((val) | 0xffffffff00000000) : (val)) +#define cvtINT8toShort(val) cvtINT8toInt(val) +#define cvtINT16toShort(val) cvtINT16toInt(val) +#define cvtINT32toShort(val) cvtINT32toInt(val) +#define cvtINT8toLong(val) cvtINT8toInt(val) +#define cvtINT16toLong(val) cvtINT16toInt(val) +#define cvtINT32toLong(val) cvtINT32toInt(val) +#else +#define cvtINT8toInt(val) (val) +#define cvtINT16toInt(val) (val) +#define cvtINT32toInt(val) (val) +#define cvtINT8toShort(val) (val) +#define cvtINT16toShort(val) (val) +#define cvtINT32toShort(val) (val) +#define cvtINT8toLong(val) (val) +#define cvtINT16toLong(val) (val) +#define cvtINT32toLong(val) (val) +#endif /* WORD64 and UNSIGNEDBITFIELDS */ +#endif /* cvtINT32toInt() */ + +static gboolean +wm_hints_from_results (GetPropertyResults *results, + XWMHints **hints_p) +{ + XWMHints *hints; + xPropWMHints *raw; + + *hints_p = NULL; + + if (!validate_or_free_results (results, 32, XA_WM_HINTS, TRUE)) + return FALSE; + + /* pre-R3 bogusly truncated window_group, don't fail on them */ + if (results->n_items < (NumPropWMHintsElements - 1)) + { + meta_verbose ("WM_HINTS property too short: %d should be %d\n", + (int) results->n_items, NumPropWMHintsElements - 1); + if (results->prop) + { + XFree (results->prop); + results->prop = NULL; + } + return FALSE; + } + + hints = ag_Xmalloc0 (sizeof (XWMHints)); + + raw = (xPropWMHints*) results->prop; + + hints->flags = raw->flags; + hints->input = (raw->input ? True : False); + hints->initial_state = cvtINT32toInt (raw->initialState); + hints->icon_pixmap = raw->iconPixmap; + hints->icon_window = raw->iconWindow; + hints->icon_x = cvtINT32toInt (raw->iconX); + hints->icon_y = cvtINT32toInt (raw->iconY); + hints->icon_mask = raw->iconMask; + if (results->n_items >= NumPropWMHintsElements) + hints->window_group = raw->windowGroup; + else + hints->window_group = 0; + + if (results->prop) + { + XFree (results->prop); + results->prop = NULL; + } + + *hints_p = hints; + + return TRUE; +} + +gboolean +meta_prop_get_wm_hints (MetaDisplay *display, + Window xwindow, + Atom xatom, + XWMHints **hints_p) +{ + GetPropertyResults results; + + *hints_p = NULL; + + if (!get_property (display, xwindow, xatom, XA_WM_HINTS, + &results)) + return FALSE; + + return wm_hints_from_results (&results, hints_p); +} + +static gboolean +class_hint_from_results (GetPropertyResults *results, + XClassHint *class_hint) +{ + int len_name, len_class; + + class_hint->res_class = NULL; + class_hint->res_name = NULL; + + if (!validate_or_free_results (results, 8, XA_STRING, FALSE)) + return FALSE; + + len_name = strlen ((char *) results->prop); + if (! (class_hint->res_name = ag_Xmalloc (len_name+1))) + { + XFree (results->prop); + results->prop = NULL; + return FALSE; + } + + strcpy (class_hint->res_name, results->prop); + + if (len_name == (int) results->n_items) + len_name--; + + len_class = strlen (results->prop + len_name + 1); + + if (! (class_hint->res_class = ag_Xmalloc(len_class+1))) + { + XFree(class_hint->res_name); + class_hint->res_name = NULL; + XFree (results->prop); + results->prop = NULL; + return FALSE; + } + + strcpy (class_hint->res_class, results->prop + len_name + 1); + + XFree (results->prop); + results->prop = NULL; + + return TRUE; +} + +gboolean +meta_prop_get_class_hint (MetaDisplay *display, + Window xwindow, + Atom xatom, + XClassHint *class_hint) +{ + GetPropertyResults results; + + class_hint->res_class = NULL; + class_hint->res_name = NULL; + + if (!get_property (display, xwindow, xatom, XA_STRING, + &results)) + return FALSE; + + return class_hint_from_results (&results, class_hint); +} + static AgGetPropertyTask* get_task (MetaDisplay *display, Window xwindow, @@ -566,6 +763,15 @@ meta_prop_get_values (MetaDisplay *display, case META_PROP_VALUE_ATOM_LIST: values[i].required_type = XA_ATOM; break; + case META_PROP_VALUE_TEXT_PROPERTY: + values[i].required_type = AnyPropertyType; + break; + case META_PROP_VALUE_WM_HINTS: + values[i].required_type = XA_WM_HINTS; + break; + case META_PROP_VALUE_CLASS_HINT: + values[i].required_type = XA_STRING; + break; } } @@ -672,6 +878,18 @@ meta_prop_get_values (MetaDisplay *display, &values[i].v.atom_list.n_atoms)) values[i].type = META_PROP_VALUE_INVALID; break; + case META_PROP_VALUE_TEXT_PROPERTY: + if (!text_property_from_results (&results, &values[i].v.str)) + values[i].type = META_PROP_VALUE_INVALID; + break; + case META_PROP_VALUE_WM_HINTS: + if (!wm_hints_from_results (&results, &values[i].v.wm_hints)) + values[i].type = META_PROP_VALUE_INVALID; + break; + case META_PROP_VALUE_CLASS_HINT: + if (!class_hint_from_results (&results, &values[i].v.class_hint)) + values[i].type = META_PROP_VALUE_INVALID; + break; } next: diff --git a/src/xprops.h b/src/xprops.h index bd0f998c7..d1da7d99a 100644 --- a/src/xprops.h +++ b/src/xprops.h @@ -107,6 +107,20 @@ gboolean meta_prop_get_cardinal_with_atom_type (MetaDisplay *display, Atom xatom, Atom prop_type, gulong *cardinal_p); +gboolean meta_prop_get_text_property (MetaDisplay *display, + Window xwindow, + Atom xatom, + char **utf8_str_p); + +gboolean meta_prop_get_wm_hints (MetaDisplay *display, + Window xwindow, + Atom xatom, + XWMHints **hints_p); + +gboolean meta_prop_get_class_hint (MetaDisplay *display, + Window xwindow, + Atom xatom, + XClassHint *class_hint); typedef enum { @@ -118,7 +132,10 @@ typedef enum META_PROP_VALUE_WINDOW, META_PROP_VALUE_CARDINAL_LIST, META_PROP_VALUE_UTF8_LIST, - META_PROP_VALUE_ATOM_LIST + META_PROP_VALUE_ATOM_LIST, + META_PROP_VALUE_TEXT_PROPERTY, /* comes back as UTF-8 string */ + META_PROP_VALUE_WM_HINTS, + META_PROP_VALUE_CLASS_HINT } MetaPropValueType; /* used to request/return/store property values */ @@ -134,6 +151,8 @@ typedef struct MotifWmHints *motif_hints; Window xwindow; gulong cardinal; + XWMHints *wm_hints; + XClassHint class_hint; struct {