]> Pileus Git - ~andy/gtk/blob - gdk/directfb/gdkproperty-directfb.c
Include "config.h" instead of <config.h> Command used: find -name
[~andy/gtk] / gdk / directfb / gdkproperty-directfb.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 Lesser 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  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser 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
20 /*
21  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GTK+ Team.
23  */
24
25 /*
26  * GTK+ DirectFB backend
27  * Copyright (C) 2001-2002  convergence integrated media GmbH
28  * Copyright (C) 2002-2004  convergence GmbH
29  * Written by Denis Oliver Kropp <dok@convergence.de> and
30  *            Sven Neumann <sven@convergence.de>
31  */
32
33 #include "config.h"
34 #include "gdk.h"
35
36 #include <string.h>
37
38 #include "gdkproperty.h"
39
40 #include "gdkdirectfb.h"
41 #include "gdkprivate-directfb.h"
42
43 #include "gdkinternals.h"
44
45 #include "gdkalias.h"
46
47 static GHashTable *names_to_atoms;
48 static GPtrArray *atoms_to_names;
49
50 static const gchar xatoms_string[] = 
51   /* These are all the standard predefined X atoms */
52   "NONE\0"
53   "PRIMARY\0"
54   "SECONDARY\0"
55   "ARC\0"
56   "ATOM\0"
57   "BITMAP\0"
58   "CARDINAL\0"
59   "COLORMAP\0"
60   "CURSOR\0"
61   "CUT_BUFFER0\0"
62   "CUT_BUFFER1\0"
63   "CUT_BUFFER2\0"
64   "CUT_BUFFER3\0"
65   "CUT_BUFFER4\0"
66   "CUT_BUFFER5\0"
67   "CUT_BUFFER6\0"
68   "CUT_BUFFER7\0"
69   "DRAWABLE\0"
70   "FONT\0"
71   "INTEGER\0"
72   "PIXMAP\0"
73   "POINT\0"
74   "RECTANGLE\0"
75   "RESOURCE_MANAGER\0"
76   "RGB_COLOR_MAP\0"
77   "RGB_BEST_MAP\0"
78   "RGB_BLUE_MAP\0"
79   "RGB_DEFAULT_MAP\0"
80   "RGB_GRAY_MAP\0"
81   "RGB_GREEN_MAP\0"
82   "RGB_RED_MAP\0"
83   "STRING\0"
84   "VISUALID\0"
85   "WINDOW\0"
86   "WM_COMMAND\0"
87   "WM_HINTS\0"
88   "WM_CLIENT_MACHINE\0"
89   "WM_ICON_NAME\0"
90   "WM_ICON_SIZE\0"
91   "WM_NAME\0"
92   "WM_NORMAL_HINTS\0"
93   "WM_SIZE_HINTS\0"
94   "WM_ZOOM_HINTS\0"
95   "MIN_SPACE\0"
96   "NORM_SPACE\0"
97   "MAX_SPACE\0"
98   "END_SPACE\0"
99   "SUPERSCRIPT_X\0"
100   "SUPERSCRIPT_Y\0"
101   "SUBSCRIPT_X\0"
102   "SUBSCRIPT_Y\0"
103   "UNDERLINE_POSITION\0"
104   "UNDERLINE_THICKNESS\0"
105   "STRIKEOUT_ASCENT\0"
106   "STRIKEOUT_DESCENT\0"
107   "ITALIC_ANGLE\0"
108   "X_HEIGHT\0"
109   "QUAD_WIDTH\0"
110   "WEIGHT\0"
111   "POINT_SIZE\0"
112   "RESOLUTION\0"
113   "COPYRIGHT\0"
114   "NOTICE\0"
115   "FONT_NAME\0"
116   "FAMILY_NAME\0"
117   "FULL_NAME\0"
118   "CAP_HEIGHT\0"
119   "WM_CLASS\0"
120   "WM_TRANSIENT_FOR\0"
121 ;
122
123 static const gint xatoms_offset[] = {
124     0,   5,  13,  23,  27,  32,  39,  48,  57,  64,  76,  88, 
125   100, 112, 124, 136, 148, 160, 169, 174, 182, 189, 195, 205, 
126   222, 236, 249, 262, 278, 291, 305, 317, 324, 333, 340, 351, 
127   360, 378, 391, 404, 412, 428, 442, 456, 466, 477, 487, 497, 
128   511, 525, 537, 549, 568, 588, 605, 623, 636, 645, 656, 663, 
129   674, 685, 695, 702, 712, 724, 734, 745, 754
130 };
131
132 #define N_CUSTOM_PREDEFINED 1
133
134 static void
135 ensure_atom_tables (void)
136 {
137   int i;
138   
139   if (names_to_atoms)
140     return;
141
142   names_to_atoms = g_hash_table_new (g_str_hash, g_str_equal);
143   atoms_to_names = g_ptr_array_sized_new (G_N_ELEMENTS (xatoms_offset));
144
145   for (i = 0; i < G_N_ELEMENTS (xatoms_offset); i++)
146     {
147       g_hash_table_insert(names_to_atoms, (gchar *)xatoms_string + xatoms_offset[i], GINT_TO_POINTER (i));
148       g_ptr_array_add(atoms_to_names, (gchar *)xatoms_string + xatoms_offset[i]);
149     }
150 }
151
152 static GdkAtom
153 intern_atom_internal (const gchar *atom_name, gboolean allocate)
154 {
155   gpointer result;
156   gchar *name;
157   g_return_val_if_fail (atom_name != NULL, GDK_NONE);
158
159   ensure_atom_tables ();
160   
161   if (g_hash_table_lookup_extended (names_to_atoms, atom_name, NULL, &result))
162     return result;
163   
164   result = GINT_TO_POINTER (atoms_to_names->len);
165   name = allocate ? g_strdup (atom_name) : (gchar *)atom_name;
166   g_hash_table_insert(names_to_atoms, name, result);
167   g_ptr_array_add(atoms_to_names, name);
168   
169   return result;  
170 }
171
172 GdkAtom
173 gdk_atom_intern (const gchar *atom_name,
174                  gboolean     only_if_exists)
175 {
176   return intern_atom_internal (atom_name, TRUE);
177 }
178
179 GdkAtom
180 gdk_atom_intern_static_string (const gchar *atom_name)
181 {
182   return intern_atom_internal (atom_name, FALSE);
183 }
184
185
186 gchar *
187 gdk_atom_name (GdkAtom atom)
188 {
189   if (!atoms_to_names)
190     return NULL;
191     
192   if (GPOINTER_TO_INT (atom) >= atoms_to_names->len)
193     return NULL;
194   return g_strdup(g_ptr_array_index (atoms_to_names, GPOINTER_TO_INT (atom)));
195 }
196
197
198 static void
199 gdk_property_delete_2 (GdkWindow         *window,
200                        GdkAtom            property,
201                        GdkWindowProperty *prop)
202 {
203   GdkWindowImplDirectFB *impl;
204   GdkEvent              *event;
205   GdkWindow             *event_window;
206
207   impl = GDK_WINDOW_IMPL_DIRECTFB (GDK_WINDOW_OBJECT (window)->impl);
208
209   g_hash_table_remove (impl->properties, GUINT_TO_POINTER (property));
210   g_free (prop);
211
212   event_window = gdk_directfb_other_event_window (window, GDK_PROPERTY_NOTIFY);
213
214   if (event_window)
215     {
216       event = gdk_directfb_event_make (event_window, GDK_PROPERTY_NOTIFY);
217       event->property.atom  = property;
218       event->property.state = GDK_PROPERTY_DELETE;
219     }
220 }
221
222 void
223 gdk_property_delete (GdkWindow *window,
224                      GdkAtom    property)
225 {
226   GdkWindowImplDirectFB *impl;
227   GdkWindowProperty     *prop;
228
229   g_return_if_fail (GDK_IS_WINDOW (window));
230
231   impl = GDK_WINDOW_IMPL_DIRECTFB (GDK_WINDOW_OBJECT (window)->impl);
232
233   if (!impl->properties)
234     return;
235
236   prop = g_hash_table_lookup (impl->properties, GUINT_TO_POINTER (property));
237   if (!prop)
238     return;
239
240   gdk_property_delete_2 (window, property, prop);
241 }
242
243 gboolean
244 gdk_property_get (GdkWindow   *window,
245                   GdkAtom      property,
246                   GdkAtom      type,
247                   gulong       offset,
248                   gulong       length,
249                   gint         pdelete,
250                   GdkAtom     *actual_property_type,
251                   gint        *actual_format_type,
252                   gint        *actual_length,
253                   guchar     **data)
254 {
255   GdkWindowImplDirectFB *impl;
256   GdkWindowProperty     *prop;
257   gint                   nbytes = 0;
258
259   g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), FALSE);
260   g_return_val_if_fail (data != NULL, FALSE);
261
262   if (!window)
263     window = _gdk_parent_root;
264
265   if (GDK_WINDOW_DESTROYED (window))
266     return FALSE;
267
268   impl = GDK_WINDOW_IMPL_DIRECTFB (GDK_WINDOW_OBJECT (window)->impl);
269
270   if (!impl->properties)
271     return FALSE;
272
273   prop = g_hash_table_lookup (impl->properties, GUINT_TO_POINTER (property));
274   if (!prop)
275     {
276       if (actual_property_type)
277         *actual_property_type = GDK_NONE;
278       return FALSE;
279     }
280
281   nbytes = CLAMP (length, 0, prop->length - offset * 4);
282
283   if (nbytes > 0 &&
284       (prop->type == 0 /* AnyPropertyType */ || prop->type == type))
285     {
286       *data = g_malloc (nbytes + 1);
287       memcpy (*data, prop->data + offset, nbytes);
288       (*data)[nbytes] = 0;
289     }
290   else
291     {
292       *data = NULL;
293     }
294
295   if (actual_length)
296     *actual_length = nbytes;
297   if (actual_property_type)
298     *actual_property_type = prop->type;
299   if (actual_format_type)
300     *actual_format_type = prop->format;
301
302   /* only delete the property if it was completely retrieved */
303   if (pdelete && length >= *actual_length && *data != NULL)
304     {
305       gdk_property_delete_2 (window, property, prop);
306     }
307
308   return TRUE;
309 }
310
311 void
312 gdk_property_change (GdkWindow    *window,
313                      GdkAtom       property,
314                      GdkAtom       type,
315                      gint          format,
316                      GdkPropMode   mode,
317                      const guchar *data,
318                      gint          nelements)
319 {
320   GdkWindowImplDirectFB *impl;
321   GdkWindowProperty     *prop;
322   GdkWindowProperty     *new_prop;
323   gint                   new_size = 0;
324   GdkEvent              *event;
325   GdkWindow             *event_window;
326
327   g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
328
329   if (!window)
330     window = _gdk_parent_root;
331
332   if (GDK_WINDOW_DESTROYED (window))
333     return;
334
335   impl = GDK_WINDOW_IMPL_DIRECTFB (GDK_WINDOW_OBJECT (window)->impl);
336
337   if (!impl->properties)
338     impl->properties = g_hash_table_new (NULL, NULL);
339
340   prop = g_hash_table_lookup (impl->properties, GUINT_TO_POINTER (property));
341
342   switch (mode)
343     {
344     case GDK_PROP_MODE_REPLACE:
345       new_size = nelements * (format >> 3);
346       break;
347
348     case GDK_PROP_MODE_PREPEND:
349     case GDK_PROP_MODE_APPEND:
350       new_size = nelements * (format >> 3);
351       if (prop)
352         {
353           if (type != prop->type || format != prop->format)
354             return;
355           new_size += prop->length;
356         }
357       break;
358     }
359
360   new_prop = g_malloc (G_STRUCT_OFFSET (GdkWindowProperty, data) + new_size);
361   new_prop->length = new_size;
362   new_prop->type   = type;
363   new_prop->format = format;
364
365   switch (mode)
366     {
367     case GDK_PROP_MODE_REPLACE:
368       memcpy (new_prop->data, data, new_size);
369       break;
370
371     case GDK_PROP_MODE_APPEND:
372       if (prop)
373         memcpy (new_prop->data, prop->data, prop->length);
374       memcpy (new_prop->data + new_prop->length,
375               data, (nelements * (format >> 3)));
376       break;
377
378     case GDK_PROP_MODE_PREPEND:
379       memcpy (new_prop->data, data, (nelements * (format >> 3)));
380       if (prop)
381         memcpy (new_prop->data + (nelements * (format >> 3)),
382                 prop->data, prop->length);
383       break;
384     }
385
386   g_hash_table_insert (impl->properties,
387                        GUINT_TO_POINTER (property), new_prop);
388   g_free (prop);
389
390   event_window = gdk_directfb_other_event_window (window, GDK_PROPERTY_NOTIFY);
391
392   if (event_window)
393     {
394       event = gdk_directfb_event_make (event_window, GDK_PROPERTY_NOTIFY);
395       event->property.atom  = property;
396       event->property.state = GDK_PROPERTY_NEW_VALUE;
397     }
398 }
399 #define __GDK_PROPERTY_X11_C__
400 #include "gdkaliasdef.c"