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