1 /* GdkGLExt - OpenGL Extension to GDK
2  * Copyright (C) 2002-2004  Naofumi Yasufuku
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.1 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 Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA.
17  */
18 
19 #include "gdkglx.h"
20 #include "gdkglprivate-x11.h"
21 #include "gdkgloverlay-x11.h"
22 
23 #ifdef GDKGLEXT_MULTIHEAD_SUPPORT
24 #include <gdk/gdkscreen.h>
25 #endif /* GDKGLEXT_MULTIHEAD_SUPPORT */
26 
27 #include <X11/Xmd.h>
28 
29 /*
30  * SERVER_OVERLAY_VISUALS property entry format
31  *
32  * format: 32
33  *
34  * <Name>              <Type>      <Description>
35  * overlay_visual      VisualID    Visual ID of visual.
36  * transparent_type    CARD32      None (0).
37  *                                 TransparentPixel (1).
38  *                                 TransparentMask (2).
39  * value               CARD32      Pixel value or transparency mask.
40  * layer               INT32       The layer the visual resides in.
41  */
42 
43 /*
44  * SOV property.
45  * (format is 32: the returned data is represented as a long array)
46  */
47 
48 typedef struct
49 {
50   long overlay_visual;
51   long transparent_type;
52   long value;
53   long layer;
54 } __SOVProp;
55 
56 /* SOV properties data. */
57 
58 typedef struct
59 {
60   __SOVProp *prop;
61   unsigned long num;
62 } __SOVPropArray;
63 
64 static const gchar quark_sov_props_string[] = "gdk-gl-overlay-sov-props";
65 static GQuark quark_sov_props = 0;
66 
67 static void
sov_prop_array_destroy(__SOVPropArray * sov_props)68 sov_prop_array_destroy (__SOVPropArray *sov_props)
69 {
70   if (sov_props->prop != NULL)
71     XFree (sov_props->prop);
72 
73   g_free (sov_props);
74 }
75 
76 static __SOVPropArray *
gdk_gl_overlay_get_sov_props(GdkScreen * screen)77 gdk_gl_overlay_get_sov_props (GdkScreen *screen)
78 {
79   __SOVPropArray *sov_props;
80   GdkWindow *root_window;
81 #ifdef GDKGLEXT_MULTIHEAD_SUPPORT
82   GdkDisplay *display;
83 #endif /* GDKGLEXT_MULTIHEAD_SUPPORT */
84   Display *xdisplay;
85   Atom xa_sov;
86   Status status;
87   Atom actual_type;
88   int actual_format;
89   unsigned long nitems, bytes_after;
90   unsigned char *prop = NULL;
91 
92   GDK_GL_NOTE_FUNC_PRIVATE ();
93 
94 #ifdef GDKGLEXT_MULTIHEAD_SUPPORT
95   root_window = gdk_screen_get_root_window (screen);
96 #else  /* GDKGLEXT_MULTIHEAD_SUPPORT */
97   root_window = gdk_get_default_root_window ();
98 #endif /* GDKGLEXT_MULTIHEAD_SUPPORT */
99 
100   if (quark_sov_props == 0)
101     quark_sov_props = g_quark_from_static_string (quark_sov_props_string);
102 
103   sov_props = g_object_get_qdata (G_OBJECT (root_window), quark_sov_props);
104   if (sov_props != NULL)
105     return sov_props;
106 
107   sov_props = g_malloc (sizeof (__SOVPropArray));
108 
109 #ifdef GDKGLEXT_MULTIHEAD_SUPPORT
110   display = gdk_screen_get_display (screen);
111   xdisplay = GDK_DISPLAY_XDISPLAY (display);
112   xa_sov = gdk_x11_get_xatom_by_name_for_display (display, "SERVER_OVERLAY_VISUALS");
113 #else  /* GDKGLEXT_MULTIHEAD_SUPPORT */
114   xdisplay = gdk_x11_get_default_xdisplay ();
115   xa_sov = gdk_x11_get_xatom_by_name ("SERVER_OVERLAY_VISUALS");
116 #endif /* GDKGLEXT_MULTIHEAD_SUPPORT */
117 
118   status = XGetWindowProperty (xdisplay, GDK_WINDOW_XWINDOW (root_window),
119                                xa_sov, 0L, 1000000L, False, AnyPropertyType,
120                                &actual_type, &actual_format,
121                                &nitems, &bytes_after, &prop);
122   if (status != Success ||
123       actual_type == None ||
124       actual_format != 32 ||
125       nitems < 4)
126     {
127       GDK_GL_NOTE (MISC, g_message (" -- SERVER_OVERLAY_VISUALS: not supported"));
128 
129       if (prop != NULL)
130         XFree (prop);
131 
132       sov_props->prop = NULL;
133       sov_props->num = 0;
134     }
135   else
136     {
137       GDK_GL_NOTE (MISC, g_message (" -- SERVER_OVERLAY_VISUALS: supported"));
138 
139       sov_props->prop = (__SOVProp *) prop;
140       sov_props->num = nitems / (sizeof (__SOVProp) / 4);
141     }
142 
143   g_object_set_qdata_full (G_OBJECT (root_window), quark_sov_props, sov_props,
144                            (GDestroyNotify) sov_prop_array_destroy);
145 
146 #ifdef G_ENABLE_DEBUG
147   if (gdk_gl_debug_flags & GDK_GL_DEBUG_MISC)
148     {
149 #ifdef GDKGLEXT_MULTIHEAD_SUPPORT
150       int screen_num = GDK_SCREEN_XNUMBER (screen);
151 #else  /* GDKGLEXT_MULTIHEAD_SUPPORT */
152       int screen_num = gdk_x11_get_default_screen ();
153 #endif /* GDKGLEXT_MULTIHEAD_SUPPORT */
154       int i;
155 
156       g_message (" -- SERVER_OVERLAY_VISUALS: properties");
157       g_print ("screen\tvisual\ttype\tvalue\tlayer\n");
158       for (i = 0; i < sov_props->num; i++)
159         {
160           g_print ("%d\t0x%lx\t%lu\t%lu\t%ld\n",
161                    screen_num,
162                    (VisualID) (sov_props->prop[i].overlay_visual),
163                    (CARD32)   (sov_props->prop[i].transparent_type),
164                    (CARD32)   (sov_props->prop[i].value),
165                    (INT32)    (sov_props->prop[i].layer));
166         }
167     }
168 #endif /* G_ENABLE_DEBUG */
169 
170   return sov_props;
171 }
172 
173 /* private at present... */
174 gboolean
_gdk_x11_gl_overlay_get_info(GdkVisual * visual,GdkGLOverlayInfo * overlay_info)175 _gdk_x11_gl_overlay_get_info (GdkVisual        *visual,
176                               GdkGLOverlayInfo *overlay_info)
177 {
178   __SOVPropArray *sov_props;
179   VisualID xvisualid;
180   int i;
181 
182   GDK_GL_NOTE_FUNC_PRIVATE ();
183 
184   g_return_val_if_fail (GDK_IS_VISUAL (visual), FALSE);
185   g_return_val_if_fail (overlay_info != NULL, FALSE);
186 
187   /* Get SOV properties. */
188 
189 #ifdef GDKGLEXT_MULTIHEAD_SUPPORT
190   sov_props = gdk_gl_overlay_get_sov_props (gdk_visual_get_screen (visual));
191 #else  /* GDKGLEXT_MULTIHEAD_SUPPORT */
192   sov_props = gdk_gl_overlay_get_sov_props (NULL);
193 #endif /* GDKGLEXT_MULTIHEAD_SUPPORT */
194 
195   /* Look up SOV property for the visual. */
196 
197   xvisualid = GDK_VISUAL_XVISUAL (visual)->visualid;
198 
199   for (i = 0; i < sov_props->num; i++)
200     {
201       if ((VisualID) (sov_props->prop[i].overlay_visual) == xvisualid)
202         {
203           overlay_info->visual           = visual;
204           overlay_info->transparent_type = sov_props->prop[i].transparent_type;
205           overlay_info->value            = sov_props->prop[i].value;
206           overlay_info->layer            = sov_props->prop[i].layer;
207 
208           GDK_GL_NOTE (MISC, g_message (" -- overlay visual"));
209           GDK_GL_NOTE (MISC, g_print ("transparent_type = %d\n",
210                                       overlay_info->transparent_type));
211           GDK_GL_NOTE (MISC, g_print ("value = %u\n",
212                                       overlay_info->value));
213           GDK_GL_NOTE (MISC, g_print ("layer = %d\n",
214                                       overlay_info->layer));
215 
216           return TRUE;
217         }
218     }
219 
220   /* meaningless */
221   overlay_info->visual           = visual;
222   overlay_info->transparent_type = GDK_GL_OVERLAY_TRANSPARENT_NONE;
223   overlay_info->value            = 0;
224   overlay_info->layer            = 0;
225 
226   GDK_GL_NOTE (MISC, g_message (" -- not overlay visual"));
227 
228   return FALSE;
229 }
230