2002-01-03 19:58:39 -05:00
|
|
|
/* Metacity X property convenience routines */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright (C) 2001 Havoc Pennington
|
2002-10-26 03:37:11 -04:00
|
|
|
* Copyright (C) 2002 Red Hat Inc.
|
2002-01-03 19:58:39 -05:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License as
|
|
|
|
* published by the Free Software Foundation; either version 2 of the
|
|
|
|
* License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
|
|
* 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
#include "xprops.h"
|
|
|
|
#include "errors.h"
|
|
|
|
#include "util.h"
|
2002-10-26 03:37:11 -04:00
|
|
|
#include "async-getprop.h"
|
2002-10-26 12:40:50 -04:00
|
|
|
#include "ui.h"
|
|
|
|
#include "metacity-Xatomtype.h"
|
2002-01-03 19:58:39 -05:00
|
|
|
#include <X11/Xatom.h>
|
2002-06-22 00:52:35 -04:00
|
|
|
#include <string.h>
|
2002-01-03 19:58:39 -05:00
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
MetaDisplay *display;
|
|
|
|
Window xwindow;
|
|
|
|
Atom xatom;
|
|
|
|
Atom type;
|
|
|
|
int format;
|
|
|
|
unsigned long n_items;
|
|
|
|
unsigned long bytes_after;
|
|
|
|
unsigned char *prop;
|
|
|
|
} GetPropertyResults;
|
|
|
|
|
2002-01-03 19:58:39 -05:00
|
|
|
static gboolean
|
2002-10-26 03:37:11 -04:00
|
|
|
validate_or_free_results (GetPropertyResults *results,
|
|
|
|
int expected_format,
|
|
|
|
Atom expected_type,
|
|
|
|
gboolean must_have_items)
|
2002-01-03 19:58:39 -05:00
|
|
|
{
|
|
|
|
char *type_name;
|
|
|
|
char *expected_name;
|
|
|
|
char *prop_name;
|
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
if (expected_format == results->format &&
|
|
|
|
expected_type == results->type &&
|
|
|
|
(!must_have_items || results->n_items > 0))
|
2002-01-03 22:25:53 -05:00
|
|
|
return TRUE;
|
2002-01-03 19:58:39 -05:00
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
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);
|
2002-01-03 19:58:39 -05:00
|
|
|
|
2002-01-03 22:25:53 -05:00
|
|
|
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"),
|
2002-10-26 03:37:11 -04:00
|
|
|
results->xwindow,
|
2002-01-03 19:58:39 -05:00
|
|
|
prop_name ? prop_name : "(bad atom)",
|
|
|
|
expected_name ? expected_name : "(bad atom)",
|
|
|
|
expected_format,
|
|
|
|
type_name ? type_name : "(bad atom)",
|
2002-10-26 03:37:11 -04:00
|
|
|
results->format, (int) results->n_items);
|
2002-01-03 19:58:39 -05:00
|
|
|
|
|
|
|
if (type_name)
|
|
|
|
XFree (type_name);
|
|
|
|
if (expected_name)
|
|
|
|
XFree (expected_name);
|
|
|
|
if (prop_name)
|
|
|
|
XFree (prop_name);
|
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
if (results->prop)
|
|
|
|
{
|
|
|
|
XFree (results->prop);
|
|
|
|
results->prop = NULL;
|
|
|
|
}
|
|
|
|
|
2002-01-03 19:58:39 -05:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
static gboolean
|
|
|
|
get_property (MetaDisplay *display,
|
|
|
|
Window xwindow,
|
|
|
|
Atom xatom,
|
|
|
|
Atom req_type,
|
|
|
|
GetPropertyResults *results)
|
2002-01-03 19:58:39 -05:00
|
|
|
{
|
2002-10-26 03:37:11 -04:00
|
|
|
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;
|
2002-01-03 19:58:39 -05:00
|
|
|
|
2002-10-21 17:44:35 -04:00
|
|
|
meta_error_trap_push_with_return (display);
|
2002-01-03 19:58:39 -05:00
|
|
|
if (XGetWindowProperty (display->xdisplay, xwindow, xatom,
|
|
|
|
0, G_MAXLONG,
|
2002-10-26 03:37:11 -04:00
|
|
|
False, req_type, &results->type, &results->format,
|
|
|
|
&results->n_items,
|
|
|
|
&results->bytes_after,
|
|
|
|
(guchar **)&results->prop) != Success ||
|
|
|
|
results->type == None)
|
2002-01-03 19:58:39 -05:00
|
|
|
{
|
2002-10-26 03:37:11 -04:00
|
|
|
if (results->prop)
|
|
|
|
XFree (results->prop);
|
2002-10-21 17:44:35 -04:00
|
|
|
meta_error_trap_pop_with_return (display, TRUE);
|
2002-01-03 19:58:39 -05:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2002-10-21 17:44:35 -04:00
|
|
|
if (meta_error_trap_pop_with_return (display, TRUE) != Success)
|
2002-01-03 19:58:39 -05:00
|
|
|
{
|
2002-10-26 03:37:11 -04:00
|
|
|
if (results->prop)
|
|
|
|
XFree (results->prop);
|
2002-01-03 19:58:39 -05:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
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;
|
2002-01-03 19:58:39 -05:00
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
*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;
|
|
|
|
|
2002-01-03 19:58:39 -05:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
meta_prop_get_cardinal_list (MetaDisplay *display,
|
|
|
|
Window xwindow,
|
|
|
|
Atom xatom,
|
|
|
|
gulong **cardinals_p,
|
|
|
|
int *n_cardinals_p)
|
|
|
|
{
|
2002-10-26 03:37:11 -04:00
|
|
|
GetPropertyResults results;
|
2002-01-03 19:58:39 -05:00
|
|
|
|
|
|
|
*cardinals_p = NULL;
|
|
|
|
*n_cardinals_p = 0;
|
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
if (!get_property (display, xwindow, xatom, XA_CARDINAL,
|
|
|
|
&results))
|
2002-01-03 19:58:39 -05:00
|
|
|
return FALSE;
|
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
return cardinal_list_from_results (&results, cardinals_p, n_cardinals_p);
|
2002-01-03 19:58:39 -05:00
|
|
|
}
|
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
static gboolean
|
|
|
|
motif_hints_from_results (GetPropertyResults *results,
|
|
|
|
MotifWmHints **hints_p)
|
2002-01-03 19:58:39 -05:00
|
|
|
{
|
2002-08-10 14:12:36 -04:00
|
|
|
int real_size, max_size;
|
|
|
|
#define MAX_ITEMS sizeof (MotifWmHints)/sizeof (gulong)
|
2002-01-03 19:58:39 -05:00
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
*hints_p = NULL;
|
2002-01-03 19:58:39 -05:00
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
if (results->type == None || results->n_items <= 0)
|
2002-01-03 19:58:39 -05:00
|
|
|
{
|
|
|
|
meta_verbose ("Motif hints had unexpected type or n_items\n");
|
2002-10-26 03:37:11 -04:00
|
|
|
if (results->prop)
|
|
|
|
{
|
|
|
|
XFree (results->prop);
|
|
|
|
results->prop = NULL;
|
|
|
|
}
|
2002-01-03 19:58:39 -05:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2002-08-10 14:12:36 -04:00
|
|
|
/* 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.
|
|
|
|
*/
|
2002-10-26 03:37:11 -04:00
|
|
|
*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);
|
2002-08-10 14:12:36 -04:00
|
|
|
max_size = MAX_ITEMS * sizeof (gulong);
|
2002-10-26 03:37:11 -04:00
|
|
|
memcpy (*hints_p, results->prop, MIN (real_size, max_size));
|
2002-08-10 14:12:36 -04:00
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
if (results->prop)
|
|
|
|
{
|
|
|
|
XFree (results->prop);
|
|
|
|
results->prop = NULL;
|
|
|
|
}
|
2002-01-03 19:58:39 -05:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
2002-01-03 22:25:53 -05:00
|
|
|
|
|
|
|
gboolean
|
2002-10-26 03:37:11 -04:00
|
|
|
meta_prop_get_motif_hints (MetaDisplay *display,
|
|
|
|
Window xwindow,
|
|
|
|
Atom xatom,
|
|
|
|
MotifWmHints **hints_p)
|
2002-01-03 22:25:53 -05:00
|
|
|
{
|
2002-10-26 03:37:11 -04:00
|
|
|
GetPropertyResults results;
|
2002-01-03 22:25:53 -05:00
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
*hints_p = NULL;
|
2002-01-03 22:25:53 -05:00
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
if (!get_property (display, xwindow, xatom, AnyPropertyType,
|
|
|
|
&results))
|
2002-01-03 22:25:53 -05:00
|
|
|
return FALSE;
|
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
return motif_hints_from_results (&results, hints_p);
|
|
|
|
}
|
2002-01-03 22:25:53 -05:00
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
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;
|
2002-01-03 22:25:53 -05:00
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
*str_p = (char*) results->prop;
|
|
|
|
results->prop = NULL;
|
|
|
|
|
2002-01-03 22:25:53 -05:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
2002-10-26 03:37:11 -04:00
|
|
|
meta_prop_get_latin1_string (MetaDisplay *display,
|
|
|
|
Window xwindow,
|
|
|
|
Atom xatom,
|
|
|
|
char **str_p)
|
2002-01-03 22:25:53 -05:00
|
|
|
{
|
2002-10-26 03:37:11 -04:00
|
|
|
GetPropertyResults results;
|
|
|
|
|
2002-01-03 22:25:53 -05:00
|
|
|
*str_p = NULL;
|
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
if (!get_property (display, xwindow, xatom, XA_STRING,
|
|
|
|
&results))
|
2002-01-03 22:25:53 -05:00
|
|
|
return FALSE;
|
2002-10-26 03:37:11 -04:00
|
|
|
|
|
|
|
return latin1_string_from_results (&results, str_p);
|
|
|
|
}
|
2002-01-03 22:25:53 -05:00
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
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;
|
2002-01-03 22:25:53 -05:00
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
if (results->n_items > 0 &&
|
|
|
|
!g_utf8_validate (results->prop, results->n_items, NULL))
|
2002-01-03 22:25:53 -05:00
|
|
|
{
|
|
|
|
char *name;
|
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
name = XGetAtomName (results->display->xdisplay, results->xatom);
|
2002-01-03 22:25:53 -05:00
|
|
|
meta_warning (_("Property %s on window 0x%lx contained invalid UTF-8\n"),
|
2002-10-26 03:37:11 -04:00
|
|
|
name, results->xwindow);
|
2002-06-08 19:55:27 -04:00
|
|
|
meta_XFree (name);
|
2002-10-26 03:37:11 -04:00
|
|
|
XFree (results->prop);
|
|
|
|
results->prop = NULL;
|
|
|
|
|
2002-01-03 22:25:53 -05:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
*str_p = (char*) results->prop;
|
|
|
|
results->prop = NULL;
|
|
|
|
|
2002-01-03 22:25:53 -05:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2002-06-22 00:52:35 -04:00
|
|
|
gboolean
|
2002-10-26 03:37:11 -04:00
|
|
|
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)
|
2002-06-22 00:52:35 -04:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int n_strings;
|
|
|
|
char **retval;
|
|
|
|
const char *p;
|
|
|
|
|
|
|
|
*str_p = NULL;
|
|
|
|
*n_str_p = 0;
|
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
if (!validate_or_free_results (results, 8,
|
|
|
|
results->display->atom_utf8_string, FALSE))
|
2002-06-22 00:52:35 -04:00
|
|
|
return FALSE;
|
2002-10-26 03:37:11 -04:00
|
|
|
|
2002-06-22 00:52:35 -04:00
|
|
|
/* I'm not sure this is right, but I'm guessing the
|
|
|
|
* property is nul-separated
|
|
|
|
*/
|
|
|
|
i = 0;
|
|
|
|
n_strings = 1;
|
2002-10-26 03:37:11 -04:00
|
|
|
while (i < (int) results->n_items)
|
2002-06-22 00:52:35 -04:00
|
|
|
{
|
2002-10-26 03:37:11 -04:00
|
|
|
if (results->prop[i] == '\0')
|
2002-06-22 00:52:35 -04:00
|
|
|
++n_strings;
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
/* we're guaranteed that results->prop has a nul on the end
|
2002-06-22 00:52:35 -04:00
|
|
|
* by XGetWindowProperty
|
|
|
|
*/
|
|
|
|
|
|
|
|
retval = g_new0 (char*, n_strings + 1);
|
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
p = results->prop;
|
2002-06-22 00:52:35 -04:00
|
|
|
i = 0;
|
|
|
|
while (i < n_strings)
|
|
|
|
{
|
|
|
|
if (!g_utf8_validate (p, -1, NULL))
|
|
|
|
{
|
|
|
|
char *name;
|
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
meta_error_trap_push (results->display);
|
|
|
|
name = XGetAtomName (results->display->xdisplay, results->xatom);
|
|
|
|
meta_error_trap_pop (results->display, TRUE);
|
2002-06-22 00:52:35 -04:00
|
|
|
meta_warning (_("Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n"),
|
2002-10-26 03:37:11 -04:00
|
|
|
name, results->xwindow, i);
|
2002-06-22 00:52:35 -04:00
|
|
|
meta_XFree (name);
|
2002-10-26 03:37:11 -04:00
|
|
|
meta_XFree (results->prop);
|
|
|
|
results->prop = NULL;
|
2002-06-22 00:52:35 -04:00
|
|
|
|
|
|
|
g_strfreev (retval);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
retval[i] = g_strdup (p);
|
|
|
|
|
|
|
|
p = p + strlen (p) + 1;
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
|
|
|
|
*str_p = retval;
|
|
|
|
*n_str_p = i;
|
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
meta_XFree (results->prop);
|
|
|
|
results->prop = NULL;
|
|
|
|
|
2002-06-22 00:52:35 -04:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
/* returns g_malloc not Xmalloc memory */
|
2002-01-03 22:25:53 -05:00
|
|
|
gboolean
|
2002-10-26 03:37:11 -04:00
|
|
|
meta_prop_get_utf8_list (MetaDisplay *display,
|
|
|
|
Window xwindow,
|
|
|
|
Atom xatom,
|
|
|
|
char ***str_p,
|
|
|
|
int *n_str_p)
|
2002-01-03 22:25:53 -05:00
|
|
|
{
|
2002-10-26 03:37:11 -04:00
|
|
|
GetPropertyResults results;
|
2002-01-03 22:25:53 -05:00
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
*str_p = NULL;
|
2002-01-03 22:25:53 -05:00
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
if (!get_property (display, xwindow, xatom,
|
|
|
|
display->atom_utf8_string,
|
|
|
|
&results))
|
2002-01-03 22:25:53 -05:00
|
|
|
return FALSE;
|
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
return utf8_list_from_results (&results, str_p, n_str_p);
|
|
|
|
}
|
2002-01-03 22:25:53 -05:00
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
static gboolean
|
|
|
|
window_from_results (GetPropertyResults *results,
|
|
|
|
Window *window_p)
|
|
|
|
{
|
|
|
|
if (!validate_or_free_results (results, 32, XA_WINDOW, TRUE))
|
|
|
|
return FALSE;
|
2002-01-03 22:25:53 -05:00
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
*window_p = *(Window*) results->prop;
|
|
|
|
XFree (results->prop);
|
|
|
|
results->prop = NULL;
|
2002-01-03 22:25:53 -05:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2002-01-03 22:25:53 -05:00
|
|
|
gboolean
|
|
|
|
meta_prop_get_cardinal (MetaDisplay *display,
|
|
|
|
Window xwindow,
|
|
|
|
Atom xatom,
|
|
|
|
gulong *cardinal_p)
|
|
|
|
|
|
|
|
{
|
|
|
|
return meta_prop_get_cardinal_with_atom_type (display, xwindow, xatom,
|
|
|
|
XA_CARDINAL, cardinal_p);
|
|
|
|
}
|
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2002-01-03 22:25:53 -05:00
|
|
|
gboolean
|
|
|
|
meta_prop_get_cardinal_with_atom_type (MetaDisplay *display,
|
|
|
|
Window xwindow,
|
|
|
|
Atom xatom,
|
|
|
|
Atom prop_type,
|
|
|
|
gulong *cardinal_p)
|
|
|
|
{
|
2002-10-26 03:37:11 -04:00
|
|
|
GetPropertyResults results;
|
2002-01-03 22:25:53 -05:00
|
|
|
|
|
|
|
*cardinal_p = 0;
|
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
if (!get_property (display, xwindow, xatom, prop_type,
|
|
|
|
&results))
|
2002-01-03 22:25:53 -05:00
|
|
|
return FALSE;
|
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
return cardinal_with_atom_type_from_results (&results, prop_type, cardinal_p);
|
|
|
|
}
|
|
|
|
|
2002-10-26 12:40:50 -04:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
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);
|
|
|
|
}
|
2002-01-03 22:25:53 -05:00
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
void
|
|
|
|
meta_prop_get_values (MetaDisplay *display,
|
|
|
|
Window xwindow,
|
|
|
|
MetaPropValue *values,
|
|
|
|
int n_values)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
AgGetPropertyTask **tasks;
|
2002-01-03 22:25:53 -05:00
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
meta_verbose ("Requesting %d properties of 0x%lx at once\n",
|
|
|
|
n_values, xwindow);
|
2002-01-03 22:25:53 -05:00
|
|
|
|
2002-10-26 03:37:11 -04:00
|
|
|
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;
|
2002-10-26 12:40:50 -04:00
|
|
|
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;
|
2002-10-26 03:37:11 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2002-10-26 12:40:50 -04:00
|
|
|
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;
|
2002-10-26 03:37:11 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
next:
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free (tasks);
|
2002-01-03 22:25:53 -05:00
|
|
|
}
|
|
|
|
|