1 /*
2 * (c) Copyright 1993, Silicon Graphics, Inc.
3 * ALL RIGHTS RESERVED
4 * Permission to use, copy, modify, and distribute this software for
5 * any purpose and without fee is hereby granted, provided that the above
6 * copyright notice appear in all copies and that both the copyright notice
7 * and this permission notice appear in supporting documentation, and that
8 * the name of Silicon Graphics, Inc. not be used in advertising
9 * or publicity pertaining to distribution of the software without specific,
10 * written prior permission.
11 *
12 * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
13 * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
14 * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
15 * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
16 * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
17 * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
18 * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
19 * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
20 * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN
21 * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
22 * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
23 * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
24 *
25 *
26 * US Government Users Restricted Rights
27 * Use, duplication, or disclosure by the Government is subject to
28 * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
29 * (c)(1)(ii) of the Rights in Technical Data and Computer Software
30 * clause at DFARS 252.227-7013 and/or in similar or successor
31 * clauses in the FAR or the DOD or NASA FAR Supplement.
32 * Unpublished-- rights reserved under the copyright laws of the
33 * United States. Contractor/manufacturer is Silicon Graphics,
34 * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
35 *
36 * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
37 */
38
39 /*
40 * This file has been slightly modified from the original for use with Mesa.
41 *
42 * Jeroen van der Zijp <jvz@cyberia.cfdrc.com>
43 */
44
45 /*
46 * This file has been heavily modified from the original. It has been
47 * stripped down and moved into the SoXt namespace to avoid potential
48 * name-collisions with externally installed GL widgets, and all pure
49 * Xt vs. Xt/Motif ifdef wrappers have been removed (only the Motif
50 * parts remain). You are encouraged to rather go back to the source,
51 * which you will find with Mesa, than to base your GL widget derivation
52 * on this code.
53 *
54 * Lars J. Aas <larsa@sim.no>,
55 * 19th may 2000
56 */
57
58 #include <assert.h>
59 #include <stdio.h>
60
61 #include <X11/IntrinsicP.h>
62 #include <X11/StringDefs.h>
63 #include <GL/gl.h>
64 #include <Xm/PrimitiveP.h>
65
66 #include <Inventor/errors/SoDebugError.h>
67
68 #include <soxtdefs.h>
69 #include <Inventor/Xt/widgets/SoXtGLAreaP.h>
70
71 #define ATTRIBLIST_SIZE 30
72
73 // *************************************************************************
74 // forward declarations:
75
76 static void createColormap(SoXtGLAreaWidget, int, XrmValue *);
77 static void Initialize(SoXtGLAreaWidget, SoXtGLAreaWidget,
78 ArgList, Cardinal *);
79 static void Realize(Widget, Mask *, XSetWindowAttributes *);
80 static void Redraw(SoXtGLAreaWidget, XEvent *, Region);
81 static void Resize(SoXtGLAreaWidget);
82 static void Destroy(SoXtGLAreaWidget);
83 static void glwInput(SoXtGLAreaWidget, XEvent *, String *, Cardinal *);
84 static Boolean SoXtGLArea_set_values(Widget, Widget, Widget, ArgList, Cardinal *);
85
86 // *************************************************************************
87
88 static
89 char
90 SoXtGLArea_defaultTranslations[] =
91 "<Key>osfHelp:PrimitiveHelp() \n\
92 <KeyDown>: glwInput() \n\
93 <KeyUp>: glwInput() \n\
94 <BtnDown>: glwInput() \n\
95 <BtnUp>: glwInput() \n\
96 <BtnMotion>: glwInput() ";
97
98 static
99 XtActionsRec
100 SoXtGLArea_actions[] = {
101 { "glwInput", (XtActionProc) glwInput }, // key or mouse input
102 }; // actions
103
104 // There is a bit of unusual handling of the resources here.
105 // Because Xt insists on allocating the colormap resource when it is
106 // processing the core resources (even if we redeclare the colormap
107 // resource here, we need to do a little trick. When Xt first allocates
108 // the colormap, we allow it to allocate the default one, since we have
109 // not yet determined the appropriate visual (which is determined from
110 // resources parsed after the colormap). We also let it allocate colors
111 // in that default colormap.
112 //
113 // In the initialize proc we calculate the actual visual. Then, we
114 // reobtain the colormap resource using XtGetApplicationResources in
115 // the initialize proc. If requested, we also reallocate colors in
116 // that colormap using the same method.
117
118 #define coffset(field) XtOffset(SoXtGLAreaWidget, core.field)
119 #define poffset(field) XtOffset(SoXtGLAreaWidget, primitive.field)
120 #define offset(field) XtOffset(SoXtGLAreaWidget, soxtGLArea.field)
121
122 static
123 XtResource
124 SoXtGLArea_resources[] =
125 {
126 // The GLX attributes. Add any new attributes here
127 {
128 SoXtNbufferSize, SoXtCBufferSize, XtRInt,
129 sizeof(int), offset(bufferSize),
130 XtRImmediate, (XtPointer) 0
131 }, {
132 SoXtNlevel, SoXtCLevel, XtRInt,
133 sizeof(int), offset(level),
134 XtRImmediate, (XtPointer) 0
135 }, {
136 SoXtNrgba, SoXtCRgba, XtRBoolean,
137 sizeof(Boolean), offset(rgba),
138 XtRImmediate, (XtPointer) FALSE
139 }, {
140 SoXtNdoublebuffer, SoXtCDoublebuffer, XtRBoolean,
141 sizeof(Boolean), offset(doublebuffer),
142 XtRImmediate, (XtPointer) FALSE
143 }, {
144 SoXtNstereo, SoXtCStereo, XtRBoolean,
145 sizeof(Boolean), offset(stereo),
146 XtRImmediate, (XtPointer) FALSE
147 }, {
148 SoXtNauxBuffers, SoXtCAuxBuffers, XtRInt,
149 sizeof(int), offset(auxBuffers),
150 XtRImmediate, (XtPointer) 0
151 }, {
152 SoXtNredSize, SoXtCColorSize, XtRInt,
153 sizeof(int), offset(redSize),
154 XtRImmediate, (XtPointer) 1
155 }, {
156 SoXtNgreenSize, SoXtCColorSize, XtRInt,
157 sizeof(int), offset(greenSize),
158 XtRImmediate, (XtPointer) 1
159 }, {
160 SoXtNblueSize, SoXtCColorSize, XtRInt,
161 sizeof(int), offset(blueSize),
162 XtRImmediate, (XtPointer) 1
163 }, {
164 SoXtNalphaSize, SoXtCAlphaSize, XtRInt,
165 sizeof(int), offset(alphaSize),
166 XtRImmediate, (XtPointer) 0
167 }, {
168 SoXtNdepthSize, SoXtCDepthSize, XtRInt,
169 sizeof(int), offset(depthSize),
170 XtRImmediate, (XtPointer) 0
171 }, {
172 SoXtNstencilSize, SoXtCStencilSize, XtRInt,
173 sizeof(int), offset(stencilSize),
174 XtRImmediate, (XtPointer) 0
175 }, {
176 SoXtNaccumRedSize, SoXtCAccumColorSize, XtRInt,
177 sizeof(int), offset(accumRedSize),
178 XtRImmediate, (XtPointer) 0
179 }, {
180 SoXtNaccumGreenSize, SoXtCAccumColorSize, XtRInt,
181 sizeof(int), offset(accumGreenSize),
182 XtRImmediate, (XtPointer) 0
183 }, {
184 SoXtNaccumBlueSize, SoXtCAccumColorSize, XtRInt,
185 sizeof(int), offset(accumBlueSize),
186 XtRImmediate, (XtPointer) 0
187 }, {
188 SoXtNaccumAlphaSize, SoXtCAccumAlphaSize, XtRInt,
189 sizeof(int), offset(accumAlphaSize),
190 XtRImmediate, (XtPointer) 0
191 }, { // the attribute list
192 SoXtNattribList, SoXtCAttribList, XtRPointer,
193 sizeof(int *), offset(attribList),
194 XtRImmediate, (XtPointer) NULL
195 }, { // the visual info
196 SoXtNvisualInfo, SoXtCVisualInfo, SoXtRVisualInfo,
197 sizeof(XVisualInfo *), offset(visualInfo),
198 XtRImmediate, (XtPointer) NULL
199 },
200 // miscellaneous resources
201 {
202 SoXtNinstallColormap, SoXtCInstallColormap, XtRBoolean,
203 sizeof(Boolean), offset(installColormap),
204 XtRImmediate, (XtPointer) TRUE
205 }, {
206 SoXtNallocateBackground, SoXtCAllocateColors, XtRBoolean,
207 sizeof(Boolean), offset(allocateBackground),
208 XtRImmediate, (XtPointer) FALSE
209 }, {
210 SoXtNallocateOtherColors, SoXtCAllocateColors, XtRBoolean,
211 sizeof(Boolean), offset(allocateOtherColors),
212 XtRImmediate, (XtPointer) FALSE
213 }, {
214 SoXtNinstallBackground, SoXtCInstallBackground, XtRBoolean,
215 sizeof(Boolean), offset(installBackground),
216 XtRImmediate, (XtPointer) TRUE
217 }, {
218 SoXtNginitCallback, SoXtCCallback, XtRCallback,
219 sizeof(XtCallbackList), offset(ginitCallback),
220 XtRImmediate, (XtPointer) NULL
221 }, {
222 SoXtNinputCallback, SoXtCCallback, XtRCallback,
223 sizeof(XtCallbackList), offset(inputCallback),
224 XtRImmediate, (XtPointer) NULL
225 }, {
226 SoXtNresizeCallback, SoXtCCallback, XtRCallback,
227 sizeof(XtCallbackList), offset(resizeCallback),
228 XtRImmediate, (XtPointer) NULL
229 }, {
230 SoXtNexposeCallback, SoXtCCallback, XtRCallback,
231 sizeof(XtCallbackList), offset(exposeCallback),
232 XtRImmediate, (XtPointer) NULL
233 }, {
234 SoXtNrefresh, SoXtCRefresh, XtRBoolean,
235 sizeof(Boolean), offset(refresh),
236 XtRImmediate, (XtPointer) NULL
237 },
238
239 // Changes to Motif primitive resources
240 {
241 XmNtraversalOn, XmCTraversalOn, XmRBoolean,
242 sizeof(Boolean), poffset(traversal_on),
243 XmRImmediate, (XtPointer) FALSE
244 },
245 // highlighting is normally disabled, as when Motif tries to disable
246 // highlighting, it tries to reset the color back to the parent's
247 // background (usually Motif blue). Unfortunately, that is in a
248 // different colormap, and doesn't work too well.
249 {
250 XmNhighlightOnEnter, XmCHighlightOnEnter, XmRBoolean,
251 sizeof(Boolean), poffset(highlight_on_enter),
252 XmRImmediate, (XtPointer) FALSE
253 }, {
254 XmNhighlightThickness, XmCHighlightThickness, XmRHorizontalDimension,
255 sizeof(Dimension), poffset(highlight_thickness),
256 XmRImmediate, (XtPointer) 0
257 },
258 }; // resources
259
260 /*
261 ** The following resources are reobtained using XtGetApplicationResources
262 ** in the initialize proc.
263 */
264
265 // The colormap
266 static XtResource initializeResources[] =
267 {
268 // reobtain the colormap with the new visual
269 {
270 XtNcolormap, XtCColormap, XtRColormap,
271 sizeof(Colormap), coffset(colormap),
272 XtRCallProc,(XtPointer) createColormap
273 },
274 }; // initializeResources
275
276 // reallocate any colors we need in the new colormap
277 // The background is obtained only if the allocateBackground resource is TRUE
278
279 static XtResource backgroundResources[] =
280 {
281 {
282 XmNbackground, XmCBackground, XmRPixel,
283 sizeof(Pixel), coffset(background_pixel),
284 XmRString, (XtPointer) "lightgrey"
285 }, {
286 XmNbackgroundPixmap, XmCPixmap, XmRXmBackgroundPixmap,
287 sizeof(Pixmap), coffset(background_pixmap),
288 XmRImmediate, (XtPointer) XmUNSPECIFIED_PIXMAP
289 },
290 }; // backgroundResources
291
292 // The other colors such as the foreground are allocated only if
293 // allocateOtherColors are set. These resources only exist in Motif.
294
295 static XtResource otherColorResources[] =
296 {
297 {
298 XmNforeground, XmCForeground, XmRPixel,
299 sizeof(Pixel), poffset(foreground),
300 XmRString, (XtPointer) "lighgrey"
301 }, {
302 XmNhighlightColor, XmCHighlightColor, XmRPixel,
303 sizeof(Pixel), poffset(highlight_color),
304 XmRString, (XtPointer) "lightgrey"
305 }, {
306 XmNhighlightPixmap, XmCHighlightPixmap, XmRPrimHighlightPixmap,
307 sizeof(Pixmap), poffset(highlight_pixmap),
308 XmRImmediate, (XtPointer) XmUNSPECIFIED_PIXMAP
309 },
310 }; // otherColorResources
311
312 #undef coffset
313 #undef poffset
314 #undef offset
315
316 SoXtGLAreaClassRec soxtGLAreaClassRec = {
317 { // core fields
318 (WidgetClass) &xmPrimitiveClassRec, // superclass
319 "SoXtGLArea", // class_name
320 sizeof(SoXtGLAreaRec), // widget_size
321 NULL, // class_initialize
322 NULL, // class_part_initialize
323 FALSE, // class_inited
324 (XtInitProc) Initialize, // initialize
325 NULL, // initialize_hook
326 Realize, // realize
327 SoXtGLArea_actions, // actions
328 XtNumber(SoXtGLArea_actions), // num_actions
329 SoXtGLArea_resources, // resources
330 XtNumber(SoXtGLArea_resources), // num_resources
331 NULLQUARK, // xrm_class
332 TRUE, // compress_motion
333 TRUE, // compress_exposure
334 TRUE, // compress_enterleave
335 TRUE, // visible_interest
336 (XtWidgetProc) Destroy, // destroy
337 (XtWidgetProc) Resize, // resize
338 (XtExposeProc) Redraw, // expose
339 SoXtGLArea_set_values, // set_values
340 NULL, // set_values_hook
341 XtInheritSetValuesAlmost, // set_values_almost
342 NULL, // get_values_hook
343 NULL, // accept_focus
344 XtVersion, // version
345 NULL, // callback_private
346 SoXtGLArea_defaultTranslations, // tm_table
347 XtInheritQueryGeometry, // query_geometry
348 XtInheritDisplayAccelerator, // display_accelerator
349 NULL // extension
350 }, {
351 XmInheritBorderHighlight, // border_highlight
352 XmInheritBorderUnhighlight, // border_unhighlight
353 XtInheritTranslations, // translations
354 NULL, // arm_and_activate
355 NULL, // get_resources
356 0, // num get_resources
357 NULL // extension
358 }, {
359 (XtPointer) NULL // extension
360 }
361 }; // soxtGLAreaClassRec
362
363 WidgetClass soxtGLAreaWidgetClass = (WidgetClass) &soxtGLAreaClassRec;
364
365 static void
error(Widget w,char * string)366 error(
367 Widget w,
368 char * string)
369 {
370 char buf[100];
371 sprintf(buf, "SoXtGLArea: %s\n", string);
372 XtAppError(XtWidgetToApplicationContext(w), buf);
373 } // error()
374
375 static void
warning(Widget w,char * string)376 warning(
377 Widget w,
378 char * string)
379 {
380 char buf[100];
381 sprintf(buf, "SoXtGLArea: %s\n", string);
382 XtAppWarning(XtWidgetToApplicationContext(w), buf);
383 } // warning()
384
385 // *************************************************************************
386
387 // Initialize the attribList based on the attributes
388
389 static void
createAttribList(SoXtGLAreaWidget widget)390 createAttribList(
391 SoXtGLAreaWidget widget)
392 {
393 int * ptr;
394 widget->soxtGLArea.attribList =
395 (int *) XtMalloc(ATTRIBLIST_SIZE * sizeof(int));
396 if (! widget->soxtGLArea.attribList)
397 error((Widget) widget, "Unable to allocate attribute list");
398 ptr = widget->soxtGLArea.attribList;
399 *ptr++ = GLX_BUFFER_SIZE;
400 *ptr++ = widget->soxtGLArea.bufferSize;
401 *ptr++ = GLX_LEVEL;
402 *ptr++ = widget->soxtGLArea.level;
403 if (widget->soxtGLArea.rgba) *ptr++ = GLX_RGBA;
404 if (widget->soxtGLArea.doublebuffer) *ptr++ = GLX_DOUBLEBUFFER;
405 if (widget->soxtGLArea.stereo) *ptr++ = GLX_STEREO;
406 *ptr++ = GLX_AUX_BUFFERS;
407 *ptr++ = widget->soxtGLArea.auxBuffers;
408 *ptr++ = GLX_RED_SIZE;
409 *ptr++ = widget->soxtGLArea.redSize;
410 *ptr++ = GLX_GREEN_SIZE;
411 *ptr++ = widget->soxtGLArea.greenSize;
412 *ptr++ = GLX_BLUE_SIZE;
413 *ptr++ = widget->soxtGLArea.blueSize;
414 *ptr++ = GLX_ALPHA_SIZE;
415 *ptr++ = widget->soxtGLArea.alphaSize;
416 *ptr++ = GLX_DEPTH_SIZE;
417 *ptr++ = widget->soxtGLArea.depthSize;
418 *ptr++ = GLX_STENCIL_SIZE;
419 *ptr++ = widget->soxtGLArea.stencilSize;
420 *ptr++ = GLX_ACCUM_RED_SIZE;
421 *ptr++ = widget->soxtGLArea.accumRedSize;
422 *ptr++ = GLX_ACCUM_GREEN_SIZE;
423 *ptr++ = widget->soxtGLArea.accumGreenSize;
424 *ptr++ = GLX_ACCUM_BLUE_SIZE;
425 *ptr++ = widget->soxtGLArea.accumBlueSize;
426 *ptr++ = GLX_ACCUM_ALPHA_SIZE;
427 *ptr++ = widget->soxtGLArea.accumAlphaSize;
428 *ptr++ = None;
429 assert((ptr - widget->soxtGLArea.attribList) < ATTRIBLIST_SIZE);
430 } // createAttribList()
431
432 // *************************************************************************
433 // Initialize the visualInfo based on the attribute list
434
435 static void
createVisualInfo(SoXtGLAreaWidget widget)436 createVisualInfo(
437 SoXtGLAreaWidget widget)
438 {
439 static XVisualInfo * visualInfo;
440 assert(widget->soxtGLArea.attribList);
441
442 if (widget->soxtGLArea.visualInfo == NULL)
443 widget->soxtGLArea.visualInfo =
444 glXChooseVisual(XtDisplay(widget),
445 XScreenNumberOfScreen(XtScreen(widget)),
446 widget->soxtGLArea.attribList);
447 if (! widget->soxtGLArea.visualInfo)
448 error((Widget) widget, "requested visual not supported");
449 } // createVisualkInfo()
450
451 // *************************************************************************
452
453 /* Initialize the colormap based on the visual info.
454 * This routine maintains a cache of visual-infos to colormaps. If two
455 * widgets share the same visual info, they share the same colormap.
456 * This function is called by the callProc of the colormap resource entry.
457 */
458
459 static void
createColormap(SoXtGLAreaWidget widget,int offset,XrmValue * value)460 createColormap(
461 SoXtGLAreaWidget widget,
462 int offset,
463 XrmValue * value)
464 {
465 static struct cmapCache {
466 Visual * visual;
467 Colormap cmap;
468 } * cmapCache;
469 static int cacheEntries = 0;
470 static int cacheMalloced = 0;
471 register int i;
472
473 assert(widget->soxtGLArea.visualInfo);
474
475 // see if we can find it in the cache
476 for (i = 0; i < cacheEntries; i++) {
477 if (cmapCache[i].visual == widget->soxtGLArea.visualInfo->visual) {
478 value->addr = (char *) &cmapCache[i].cmap;
479 return;
480 }
481 }
482
483 // not in the cache, create a new entry
484 if (cacheEntries >= cacheMalloced) {
485 // need to malloc a new one. Since we are likely to have only a
486 // few colormaps, we allocate one the first time, and double
487 // each subsequent time.
488 if (cacheMalloced == 0) {
489 cacheMalloced = 1;
490 cmapCache = (struct cmapCache *) XtMalloc(sizeof(struct cmapCache));
491 } else {
492 cacheMalloced <<= 1;
493 cmapCache = (struct cmapCache *) XtRealloc((char *) cmapCache,
494 sizeof(struct cmapCache) * cacheMalloced);
495 }
496 }
497
498 cmapCache[cacheEntries].cmap =
499 XCreateColormap(XtDisplay(widget),
500 RootWindow(XtDisplay(widget),
501 widget->soxtGLArea.visualInfo->screen),
502 widget->soxtGLArea.visualInfo->visual,
503 AllocNone);
504 cmapCache[cacheEntries].visual = widget->soxtGLArea.visualInfo->visual;
505 value->addr = (char *) &cmapCache[cacheEntries++].cmap;
506 } // createColormap()
507
508 // *************************************************************************
509
510 static void
Initialize(SoXtGLAreaWidget req,SoXtGLAreaWidget neww,ArgList args,Cardinal * num_args)511 Initialize(
512 SoXtGLAreaWidget req,
513 SoXtGLAreaWidget neww,
514 ArgList args,
515 Cardinal * num_args)
516 {
517 // fix size
518 if (req->core.width == 0) neww->core.width = 100;
519 if (req->core.height == 0) neww->core.width = 100;
520
521 // create the attribute list if needed
522 neww->soxtGLArea.myList = FALSE;
523 if (neww->soxtGLArea.attribList == NULL) {
524 neww->soxtGLArea.myList = TRUE;
525 createAttribList(neww);
526 }
527
528 // Gotta have it
529 assert(neww->soxtGLArea.attribList);
530
531 // determine the visual info if needed
532 neww->soxtGLArea.myVisual = FALSE;
533 if (neww->soxtGLArea.visualInfo == NULL) {
534 neww->soxtGLArea.myVisual = TRUE;
535 createVisualInfo(neww);
536 }
537
538 // Gotta have that too
539 assert(neww->soxtGLArea.visualInfo);
540
541 neww->core.depth = neww->soxtGLArea.visualInfo->depth;
542
543 // Reobtain the colormap and colors in it using XtGetApplicationResources
544 XtGetApplicationResources((Widget) neww, neww, initializeResources,
545 XtNumber(initializeResources), args, *num_args);
546
547 // obtain the color resources if appropriate
548 if (req->soxtGLArea.allocateBackground) {
549 XtGetApplicationResources((Widget) neww, neww, backgroundResources,
550 XtNumber(backgroundResources), args, *num_args);
551 }
552
553 if (req->soxtGLArea.allocateOtherColors) {
554 XtGetApplicationResources((Widget) neww, neww, otherColorResources,
555 XtNumber(otherColorResources), args, *num_args);
556 }
557 } // Initialize()
558
559 // *************************************************************************
560
561 static void
Realize(Widget widget,Mask * valueMask,XSetWindowAttributes * attributes)562 Realize(
563 Widget widget,
564 Mask * valueMask,
565 XSetWindowAttributes * attributes)
566 {
567 register SoXtGLAreaWidget glw = (SoXtGLAreaWidget) widget;
568 SoXtGLAreaCallbackStruct cb;
569 Widget parentShell;
570 Status status;
571 Window windows[2], * windowsReturn, * windowList;
572 int countReturn, i;
573
574 // if we haven't requested that the background be both installed and
575 // allocated, don't install it.
576
577 if (! (glw->soxtGLArea.installBackground &&
578 glw->soxtGLArea.allocateBackground))
579 *valueMask &= ~CWBackPixel;
580
581 XtCreateWindow(widget, (unsigned int) InputOutput,
582 glw->soxtGLArea.visualInfo->visual, *valueMask, attributes);
583
584 // if appropriate, call XSetWMColormapWindows to install the colormap
585 if (glw->soxtGLArea.installColormap) {
586
587 // get parent shell
588 for (parentShell = XtParent(widget);
589 parentShell && ! XtIsShell(parentShell);
590 parentShell = XtParent(parentShell)) { }
591
592 if (parentShell && XtWindow(parentShell)) {
593
594 // check to see if there is already a property
595 status = XGetWMColormapWindows(XtDisplay(parentShell),
596 XtWindow(parentShell),
597 &windowsReturn, &countReturn);
598
599 // if no property, just create one
600 if (! status) {
601 windows[0] = XtWindow(widget);
602 windows[1] = XtWindow(parentShell);
603 XSetWMColormapWindows(XtDisplay(parentShell), XtWindow(parentShell),
604 windows, 2);
605 } else {
606 // there was a property, add myself to the beginning
607 windowList = (Window *) XtMalloc(sizeof(Window) * (countReturn+1));
608 windowList[0] = XtWindow(widget);
609 for (i = 0; i < countReturn; i++)
610 windowList[i+1] = windowsReturn[i];
611 XSetWMColormapWindows(XtDisplay(parentShell), XtWindow(parentShell),
612 windowList, countReturn + 1);
613 XtFree((char *) windowList);
614 XtFree((char *) windowsReturn);
615 }
616 } else {
617 warning(widget, "Could not set colormap property on parent shell");
618 }
619 }
620 // Invoke init callbacks:
621 cb.reason = SoXtCR_GINIT;
622 cb.event = NULL;
623 cb.width = glw->core.width;
624 cb.height = glw->core.height;
625 XtCallCallbackList((Widget) glw, glw->soxtGLArea.ginitCallback, &cb);
626 } // Realize()
627
628 // *************************************************************************
629
630 static void
Redraw(SoXtGLAreaWidget widget,XEvent * event,Region region)631 Redraw(
632 SoXtGLAreaWidget widget,
633 XEvent * event,
634 Region region)
635 {
636 SoXtGLAreaCallbackStruct cb;
637 XtCallbackList cblist;
638 if (! XtIsRealized((Widget) widget))
639 return;
640 cb.reason = SoXtCR_EXPOSE;
641 cb.event = event;
642 cb.width = widget->core.width;
643 cb.height = widget->core.height;
644 XtCallCallbackList((Widget) widget, widget->soxtGLArea.exposeCallback, &cb);
645 } // Redraw()
646
647 // *************************************************************************
648
649 static void
Resize(SoXtGLAreaWidget glw)650 Resize(
651 SoXtGLAreaWidget glw)
652 {
653 SoXtGLAreaCallbackStruct cb;
654 if (! XtIsRealized((Widget) glw))
655 return;
656 cb.reason = SoXtCR_RESIZE;
657 cb.event = NULL;
658 cb.width = glw->core.width;
659 cb.height = glw->core.height;
660 XtCallCallbackList((Widget) glw, glw->soxtGLArea.resizeCallback, &cb);
661 } // Resize()
662
663 // *************************************************************************
664
665 static void
Destroy(SoXtGLAreaWidget glw)666 Destroy(
667 SoXtGLAreaWidget glw)
668 {
669 Window * windowsReturn;
670 Widget parentShell;
671 Status status;
672 int countReturn;
673 register int i;
674
675 if (glw->soxtGLArea.myList && glw->soxtGLArea.attribList)
676 XtFree((char *) glw->soxtGLArea.attribList);
677
678 if (glw->soxtGLArea.myVisual && glw->soxtGLArea.visualInfo)
679 XtFree((char *) glw->soxtGLArea.visualInfo);
680
681 // if my colormap was installed, remove it
682 if (glw->soxtGLArea.installColormap) {
683 // Get parent shell
684 for (parentShell = XtParent(glw);
685 parentShell && ! XtIsShell(parentShell);
686 parentShell = XtParent(parentShell)) { }
687
688 if (parentShell && XtWindow(parentShell)) {
689 // make sure there is a property
690 status = XGetWMColormapWindows(XtDisplay(parentShell),
691 XtWindow(parentShell),
692 &windowsReturn, &countReturn);
693
694 // if no property, just return. If there was a property, continue
695 if (status) {
696 // search for a match
697 for (i = 0; i < countReturn; i++) {
698 if (windowsReturn[i] == XtWindow(glw)) {
699 // we found a match, now copy the rest down
700 for (i++; i < countReturn; i++)
701 windowsReturn[i-1] = windowsReturn[i];
702
703 XSetWMColormapWindows(XtDisplay(parentShell),
704 XtWindow(parentShell), windowsReturn, countReturn-1);
705 break;
706 }
707 }
708 XtFree((char *) windowsReturn);
709 }
710 }
711 }
712 } // Destroy()
713
714 // *************************************************************************
715
716 // Action routine for keyboard and mouse events
717
718 static void
glwInput(SoXtGLAreaWidget glw,XEvent * event,String * params,Cardinal * numParams)719 glwInput(
720 SoXtGLAreaWidget glw,
721 XEvent * event,
722 String * params,
723 Cardinal * numParams)
724 {
725 SoXtGLAreaCallbackStruct cb;
726 cb.reason = SoXtCR_INPUT;
727 cb.event = event;
728 cb.width = glw->core.width;
729 cb.height = glw->core.height;
730 XtCallCallbackList((Widget) glw, glw->soxtGLArea.inputCallback, &cb);
731 } // glwInput()
732
733 // *************************************************************************
734
735 void
SoXtGLAreaMakeCurrent(Widget w,GLXContext ctx)736 SoXtGLAreaMakeCurrent(
737 Widget w,
738 GLXContext ctx)
739 {
740 glXMakeCurrent(XtDisplay(w), XtWindow(w), ctx);
741 } // SoXtGLAreaMakeCurrent()
742
743 // *************************************************************************
744
745 void
SoXtGLAreaSwapBuffers(Widget w)746 SoXtGLAreaSwapBuffers(
747 Widget w)
748 {
749 glXSwapBuffers(XtDisplay(w), XtWindow(w));
750 } // SoXtGLAreaSwapBuffers()
751
752 // *************************************************************************
753
754 Boolean
SoXtGLArea_set_values(Widget current,Widget request,Widget new_widget,ArgList args,Cardinal * num_args)755 SoXtGLArea_set_values(
756 Widget current,
757 Widget request,
758 Widget new_widget,
759 ArgList args,
760 Cardinal * num_args)
761 {
762 Boolean redisplay = False;
763 SoXtGLAreaWidget curcw = (SoXtGLAreaWidget) current;
764 SoXtGLAreaWidget reqcw = (SoXtGLAreaWidget) request;
765 SoXtGLAreaWidget newcw = (SoXtGLAreaWidget) new_widget;
766
767 if (newcw->soxtGLArea.refresh != curcw->soxtGLArea.refresh) {
768 newcw->soxtGLArea.refresh = False;
769 redisplay = True;
770 }
771
772 return redisplay;
773 } // SoXtGLArea_set_values()
774
775 // *************************************************************************
776
777