1 /* |
|
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. Oracle designates this |
|
8 * particular file as subject to the "Classpath" exception as provided |
|
9 * by Oracle in the LICENSE file that accompanied this code. |
|
10 * |
|
11 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 * version 2 for more details (a copy is included in the LICENSE file that |
|
15 * accompanied this code). |
|
16 * |
|
17 * You should have received a copy of the GNU General Public License version |
|
18 * 2 along with this work; if not, write to the Free Software Foundation, |
|
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 * |
|
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
22 * or visit www.oracle.com if you need additional information or have any |
|
23 * questions. |
|
24 */ |
|
25 |
|
26 #ifndef HEADLESS |
|
27 |
|
28 #include <X11/IntrinsicP.h> |
|
29 #include "VDrawingAreaP.h" |
|
30 |
|
31 #endif /* !HEADLESS */ |
|
32 |
|
33 #include <stdio.h> |
|
34 #include <stdlib.h> |
|
35 |
|
36 #ifdef __linux__ |
|
37 /* XXX: Shouldn't be necessary. */ |
|
38 #include "awt_p.h" |
|
39 #endif /* __linux__ */ |
|
40 |
|
41 |
|
42 /****************************************************************** |
|
43 * |
|
44 * Provides Canvas widget which allows the X11 visual to be |
|
45 * changed (the Motif DrawingArea restricts the visual to that |
|
46 * of the parent widget). |
|
47 * |
|
48 ******************************************************************/ |
|
49 |
|
50 |
|
51 /****************************************************************** |
|
52 * |
|
53 * VDrawingArea Widget Resources |
|
54 * |
|
55 ******************************************************************/ |
|
56 |
|
57 #ifndef HEADLESS |
|
58 #define Offset(x) (XtOffsetOf(VDrawingAreaRec, x)) |
|
59 static XtResource resources[]= |
|
60 { |
|
61 { XtNvisual, XtCVisual, XtRVisual, sizeof(Visual*), |
|
62 Offset(vdrawing_area.visual), XtRImmediate, CopyFromParent} |
|
63 }; |
|
64 |
|
65 |
|
66 static void Realize(); |
|
67 static Boolean SetValues(); |
|
68 static void Destroy (); |
|
69 |
|
70 static XmBaseClassExtRec baseClassExtRec = { |
|
71 NULL, |
|
72 NULLQUARK, |
|
73 XmBaseClassExtVersion, |
|
74 sizeof(XmBaseClassExtRec), |
|
75 NULL, /* InitializePrehook */ |
|
76 NULL, /* SetValuesPrehook */ |
|
77 NULL, /* InitializePosthook */ |
|
78 NULL, /* SetValuesPosthook */ |
|
79 NULL, /* secondaryObjectClass */ |
|
80 NULL, /* secondaryCreate */ |
|
81 NULL, /* getSecRes data */ |
|
82 { 0 }, /* fastSubclass flags */ |
|
83 NULL, /* getValuesPrehook */ |
|
84 NULL, /* getValuesPosthook */ |
|
85 NULL, /* classPartInitPrehook */ |
|
86 NULL, /* classPartInitPosthook*/ |
|
87 NULL, /* ext_resources */ |
|
88 NULL, /* compiled_ext_resources*/ |
|
89 0, /* num_ext_resources */ |
|
90 FALSE, /* use_sub_resources */ |
|
91 NULL, /* widgetNavigable */ |
|
92 NULL, /* focusChange */ |
|
93 NULL /* wrapper_data */ |
|
94 }; |
|
95 |
|
96 VDrawingAreaClassRec vDrawingAreaClassRec = { |
|
97 { |
|
98 /* Core class part */ |
|
99 |
|
100 /* superclass */ (WidgetClass)&xmDrawingAreaClassRec, |
|
101 /* class_name */ "VDrawingArea", |
|
102 /* widget_size */ sizeof(VDrawingAreaRec), |
|
103 /* class_initialize */ NULL, |
|
104 /* class_part_initialize*/ NULL, |
|
105 /* class_inited */ FALSE, |
|
106 /* initialize */ NULL, |
|
107 /* initialize_hook */ NULL, |
|
108 /* realize */ Realize, |
|
109 /* actions */ NULL, |
|
110 /* num_actions */ 0, |
|
111 /* resources */ resources, |
|
112 /* num_resources */ XtNumber(resources), |
|
113 /* xrm_class */ NULLQUARK, |
|
114 /* compress_motion */ FALSE, |
|
115 /* compress_exposure */ FALSE, |
|
116 /* compress_enterleave*/ FALSE, |
|
117 /* visible_interest */ FALSE, |
|
118 /* destroy */ Destroy, |
|
119 /* resize */ XtInheritResize, |
|
120 /* expose */ XtInheritExpose, |
|
121 /* set_values */ SetValues, |
|
122 /* set_values_hook */ NULL, |
|
123 /* set_values_almost */ XtInheritSetValuesAlmost, |
|
124 /* get_values_hook */ NULL, |
|
125 /* accept_focus */ NULL, |
|
126 /* version */ XtVersion, |
|
127 /* callback_offsets */ NULL, |
|
128 /* tm_table */ NULL, |
|
129 /* query_geometry */ NULL, |
|
130 /* display_accelerator */ NULL, |
|
131 /* extension */ NULL |
|
132 }, |
|
133 |
|
134 { /* composite_class fields */ |
|
135 XtInheritGeometryManager, /* geometry_manager */ |
|
136 XtInheritChangeManaged, /* change_managed */ |
|
137 XtInheritInsertChild, /* insert_child */ |
|
138 XtInheritDeleteChild, /* delete_child */ |
|
139 NULL, /* extension */ |
|
140 }, |
|
141 |
|
142 { /* constraint_class fields */ |
|
143 NULL, /* resource list */ |
|
144 0, /* num resources */ |
|
145 0, /* constraint size */ |
|
146 NULL, /* init proc */ |
|
147 NULL, /* destroy proc */ |
|
148 NULL, /* set values proc */ |
|
149 NULL, /* extension */ |
|
150 }, |
|
151 |
|
152 { /* manager_class fields */ |
|
153 XtInheritTranslations, /* translations */ |
|
154 NULL, /* syn_resources */ |
|
155 0, /* num_get_resources */ |
|
156 NULL, /* syn_cont_resources */ |
|
157 0, /* num_get_cont_resources */ |
|
158 XmInheritParentProcess, /* parent_process */ |
|
159 NULL, /* extension */ |
|
160 }, |
|
161 |
|
162 { /* drawingArea class */ |
|
163 /* extension */ NULL |
|
164 }, |
|
165 |
|
166 /* VDrawingArea class part */ |
|
167 { |
|
168 /* extension */ NULL |
|
169 } |
|
170 }; |
|
171 |
|
172 WidgetClass vDrawingAreaClass = (WidgetClass)&vDrawingAreaClassRec; |
|
173 |
|
174 static Boolean |
|
175 SetValues(cw, rw, nw, args, num_args) |
|
176 Widget cw; |
|
177 Widget rw; |
|
178 Widget nw; |
|
179 ArgList args; |
|
180 Cardinal *num_args; |
|
181 { |
|
182 VDrawingAreaWidget current = (VDrawingAreaWidget)cw; |
|
183 VDrawingAreaWidget new_w = (VDrawingAreaWidget)nw; |
|
184 |
|
185 if (new_w->vdrawing_area.visual != current->vdrawing_area.visual) { |
|
186 new_w->vdrawing_area.visual = current->vdrawing_area.visual; |
|
187 #ifdef DEBUG |
|
188 fprintf(stdout, "VDrawingArea.SetValues: can't change visual from: visualID=%ld to visualID=%ld\n", |
|
189 current->vdrawing_area.visual->visualid, |
|
190 new_w->vdrawing_area.visual->visualid); |
|
191 #endif |
|
192 |
|
193 } |
|
194 |
|
195 return (False); |
|
196 } |
|
197 |
|
198 int |
|
199 FindWindowInList (Window parentWindow, Window *colormap_windows, int count) |
|
200 { |
|
201 int i; |
|
202 |
|
203 for (i = 0; i < count; i++) |
|
204 if (colormap_windows [i] == parentWindow) |
|
205 return i; |
|
206 return -1; |
|
207 } |
|
208 |
|
209 static void |
|
210 Realize(w, value_mask, attributes) |
|
211 Widget w; |
|
212 XtValueMask *value_mask; |
|
213 XSetWindowAttributes *attributes; |
|
214 { |
|
215 Widget parent; |
|
216 Status status; |
|
217 Window *colormap_windows; |
|
218 Window *new_colormap_windows; |
|
219 int count; |
|
220 int i; |
|
221 VDrawingAreaWidget vd = (VDrawingAreaWidget)w; |
|
222 |
|
223 #ifdef DEBUG |
|
224 fprintf(stdout, "VDrawingArea.Realize: visualID=%ld, depth=%d\n", |
|
225 vd->vdrawing_area.visual->visualid, w->core.depth); |
|
226 #endif |
|
227 |
|
228 /* 4328588: |
|
229 * Since we have our own Realize() function, we don't execute the one for |
|
230 * our super-super class, XmManager, and miss the code which checks that |
|
231 * height and width != 0. I've added that here. -bchristi |
|
232 */ |
|
233 if (!XtWidth(w)) XtWidth(w) = 1 ; |
|
234 if (!XtHeight(w)) XtHeight(w) = 1 ; |
|
235 |
|
236 w->core.window = XCreateWindow (XtDisplay (w), XtWindow (w->core.parent), |
|
237 w->core.x, w->core.y, w->core.width, w->core.height, |
|
238 0, w->core.depth, InputOutput, |
|
239 vd->vdrawing_area.visual, |
|
240 *value_mask, attributes ); |
|
241 |
|
242 /* Need to add this window to the list of Colormap windows */ |
|
243 parent = XtParent (w); |
|
244 while ((parent != NULL) && (!(XtIsShell (parent)))) |
|
245 parent = XtParent (parent); |
|
246 if (parent == NULL) { |
|
247 fprintf (stderr, "NO TopLevel widget?!\n"); |
|
248 return; |
|
249 } |
|
250 |
|
251 status = XGetWMColormapWindows (XtDisplay (w), XtWindow (parent), |
|
252 &colormap_windows, &count); |
|
253 |
|
254 /* If status is zero, add this window and shell to the list |
|
255 of colormap Windows */ |
|
256 if (status == 0) { |
|
257 new_colormap_windows = (Window *) calloc (2, sizeof (Window)); |
|
258 new_colormap_windows [0] = XtWindow (w); |
|
259 new_colormap_windows [1] = XtWindow (parent); |
|
260 XSetWMColormapWindows (XtDisplay (w), XtWindow (parent), |
|
261 new_colormap_windows, 2); |
|
262 free (new_colormap_windows); |
|
263 } else { |
|
264 /* Check if parent is already in the list */ |
|
265 int parent_entry = -1; |
|
266 |
|
267 if (count > 0) |
|
268 parent_entry = FindWindowInList (XtWindow (parent), |
|
269 colormap_windows, count); |
|
270 if (parent_entry == -1) { /* Parent not in list */ |
|
271 new_colormap_windows = (Window *) calloc (count + 2, |
|
272 sizeof (Window)); |
|
273 new_colormap_windows [0] = XtWindow (w); |
|
274 new_colormap_windows [1] = XtWindow (parent); |
|
275 for (i = 0; i < count; i++) |
|
276 new_colormap_windows [i + 2] = colormap_windows [i]; |
|
277 XSetWMColormapWindows (XtDisplay (w), XtWindow (parent), |
|
278 new_colormap_windows, count + 2); |
|
279 |
|
280 } else { /* parent already in list, just add new window */ |
|
281 new_colormap_windows = (Window *) calloc (count + 1, |
|
282 sizeof (Window)); |
|
283 new_colormap_windows [0] = XtWindow (w); |
|
284 for (i = 0; i < count; i++) |
|
285 new_colormap_windows [i + 1] = colormap_windows [i]; |
|
286 XSetWMColormapWindows (XtDisplay (w), XtWindow (parent), |
|
287 new_colormap_windows, count + 1); |
|
288 } |
|
289 free (new_colormap_windows); |
|
290 XFree (colormap_windows); |
|
291 } |
|
292 |
|
293 |
|
294 } |
|
295 |
|
296 static void |
|
297 Destroy(Widget widget) |
|
298 { |
|
299 Status status; |
|
300 Widget parent; |
|
301 Window *colormap_windows; |
|
302 Window *new_colormap_windows; |
|
303 int count; |
|
304 int listEntry; |
|
305 int i; |
|
306 int j; |
|
307 |
|
308 /* Need to get this window's parent shell first */ |
|
309 parent = XtParent (widget); |
|
310 while ((parent != NULL) && (!(XtIsShell (parent)))) |
|
311 parent = XtParent (parent); |
|
312 if (parent == NULL) { |
|
313 fprintf (stderr, "NO TopLevel widget?!\n"); |
|
314 return; |
|
315 } |
|
316 |
|
317 status = XGetWMColormapWindows (XtDisplay (widget), XtWindow (parent), |
|
318 &colormap_windows, &count); |
|
319 |
|
320 /* If status is zero, then there were no colormap windows for |
|
321 the parent ?? */ |
|
322 |
|
323 if (status == 0) |
|
324 return; |
|
325 |
|
326 /* Remove this window from the list of colormap windows */ |
|
327 listEntry = FindWindowInList (XtWindow (widget), colormap_windows, |
|
328 count); |
|
329 |
|
330 new_colormap_windows = (Window *) calloc (count - 1, sizeof (Window)); |
|
331 j = 0; |
|
332 for (i = 0; i < count; i++) { |
|
333 if (i == listEntry) |
|
334 continue; |
|
335 new_colormap_windows [j] = colormap_windows [i]; |
|
336 j++; |
|
337 } |
|
338 XSetWMColormapWindows (XtDisplay (widget), XtWindow (parent), |
|
339 new_colormap_windows, count - 1); |
|
340 free (new_colormap_windows); |
|
341 XFree (colormap_windows); |
|
342 |
|
343 } |
|
344 #endif /* !HEADLESS */ |
|