]> Pileus Git - ~andy/gtk/blob - gdk/x11/gdkproperty-x11.c
38665ca0c4a00442a4b998ee83d68847fb09af2c
[~andy/gtk] / gdk / x11 / gdkproperty-x11.c
1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19 #include <X11/Xlib.h>
20 #include <X11/Xatom.h>
21 #include <string.h>
22 #include "gdk.h"
23 #include "gdkprivate.h"
24
25
26 GdkAtom
27 gdk_atom_intern (const gchar *atom_name,
28                  gint         only_if_exists)
29 {
30   return XInternAtom (gdk_display, atom_name, only_if_exists);
31 }
32
33 gchar *
34 gdk_atom_name (GdkAtom atom)
35 {
36   gchar *t;
37   gchar *name;
38
39   /* If this atom doesn't exist, we'll die with an X error unless
40      we take precautions */
41
42   gdk_error_warnings = 0;
43   gdk_error_code = 0;
44   t = XGetAtomName (gdk_display, atom);
45   gdk_error_warnings = 1;
46
47   if (gdk_error_code == -1)
48     {
49       if (t)
50         XFree (t);
51
52       return NULL;
53     }
54   else
55     {
56       name = g_strdup (t);
57       if (t)
58         XFree (t);
59       
60       return name;
61     }
62 }
63
64 gint
65 gdk_property_get (GdkWindow   *window,
66                   GdkAtom      property,
67                   GdkAtom      type,
68                   gulong       offset,
69                   gulong       length,
70                   gint         pdelete,
71                   GdkAtom     *actual_property_type,
72                   gint        *actual_format_type,
73                   gint        *actual_length,
74                   guchar     **data)
75 {
76   Display *xdisplay;
77   Window xwindow;
78   Atom ret_prop_type;
79   gint ret_format;
80   gulong ret_nitems;
81   gulong ret_bytes_after;
82   gulong ret_length;
83   guchar *ret_data;
84
85   if (window)
86     {
87       GdkWindowPrivate *private;
88
89       private = (GdkWindowPrivate*) window;
90       if (private->destroyed)
91         return FALSE;
92
93       xdisplay = private->xdisplay;
94       xwindow = private->xwindow;
95     }
96   else
97     {
98       xdisplay = gdk_display;
99       xwindow = gdk_root_window;
100     }
101
102   ret_data = NULL;
103   XGetWindowProperty (xdisplay, xwindow, property,
104                       offset, (length + 3) / 4, pdelete,
105                       type, &ret_prop_type, &ret_format,
106                       &ret_nitems, &ret_bytes_after,
107                       &ret_data);
108
109   if ((ret_prop_type == None) && (ret_format == 0)) {
110     return FALSE;
111   }
112
113   if (actual_property_type)
114     *actual_property_type = ret_prop_type;
115   if (actual_format_type)
116     *actual_format_type = ret_format;
117
118   if (ret_prop_type != type)
119     {
120       gchar *rn, *pn;
121
122       XFree (ret_data);
123       rn = gdk_atom_name(ret_prop_type);
124       pn = gdk_atom_name(type);
125       g_warning("Couldn't match property type %s to %s\n", rn, pn);
126       g_free(rn); g_free(pn);
127       return FALSE;
128     }
129
130   /* FIXME: ignoring bytes_after could have very bad effects */
131
132   if (data)
133     {
134       switch (ret_format)
135         {
136         case 8:
137           ret_length = ret_nitems;
138           break;
139         case 16:
140           ret_length = 2 * ret_nitems;
141           break;
142         case 32:
143           ret_length = 4 * ret_nitems;
144           break;
145         default:
146           g_warning ("unknown property return format: %d", ret_format);
147           XFree (ret_data);
148           return FALSE;
149         }
150
151       *data = g_new (guchar, ret_length);
152       memcpy (*data, ret_data, ret_length);
153       if (actual_length)
154         *actual_length = ret_length;
155     }
156
157   XFree (ret_data);
158
159   return TRUE;
160 }
161
162 void
163 gdk_property_change (GdkWindow   *window,
164                      GdkAtom      property,
165                      GdkAtom      type,
166                      gint         format,
167                      GdkPropMode  mode,
168                      guchar      *data,
169                      gint         nelements)
170 {
171   Display *xdisplay;
172   Window xwindow;
173
174   if (window)
175     {
176       GdkWindowPrivate *private;
177
178       private = (GdkWindowPrivate*) window;
179       if (private->destroyed)
180         return;
181
182       xdisplay = private->xdisplay;
183       xwindow = private->xwindow;
184     }
185   else
186     {
187       xdisplay = gdk_display;
188       xwindow = gdk_root_window;
189     }
190
191   XChangeProperty (xdisplay, xwindow, property, type,
192                    format, mode, data, nelements);
193 }
194
195 void
196 gdk_property_delete (GdkWindow *window,
197                      GdkAtom    property)
198 {
199   Display *xdisplay;
200   Window xwindow;
201
202   if (window)
203     {
204       GdkWindowPrivate *private;
205
206       private = (GdkWindowPrivate*) window;
207       if (private->destroyed)
208         return;
209
210       xdisplay = private->xdisplay;
211       xwindow = private->xwindow;
212     }
213   else
214     {
215       xdisplay = gdk_display;
216       xwindow = gdk_root_window;
217     }
218
219   XDeleteProperty (xdisplay, xwindow, property);
220 }