FreeWRL/FreeX3D  3.0.0
GLwDrawA.c
1 /*
2 
3 
4 ???
5 
6 */
7 
8 /****************************************************************************
9  This file is part of the FreeWRL/FreeX3D Distribution.
10 
11  Copyright 2009 CRC Canada. (http://www.crc.gc.ca)
12 
13  FreeWRL/FreeX3D is free software: you can redistribute it and/or modify
14  it under the terms of the GNU Lesser Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  FreeWRL/FreeX3D is distributed in the hope that it will be useful,
19  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  GNU General Public License for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with FreeWRL/FreeX3D. If not, see <http://www.gnu.org/licenses/>.
25 ****************************************************************************/
26 
27 
28 
29 #include <config.h>
30 #include <system.h>
31 #include <display.h>
32 #include <internal.h>
33 
34 #include <libFreeWRL.h>
35 
36 #include "../vrml_parser/Structs.h"
37 #include "../main/headers.h"
38 #include "../vrml_parser/CParseGeneral.h"
39 #include "../scenegraph/Vector.h"
40 #include "../vrml_parser/CFieldDecls.h"
41 #include "../vrml_parser/CParseParser.h"
42 #include "../vrml_parser/CParseLexer.h"
43 #include "../vrml_parser/CParse.h"
44 
45 #include <float.h>
46 
47 #include "../x3d_parser/Bindable.h"
48 #include "../scenegraph/Collision.h"
49 #include "../scenegraph/quaternion.h"
50 #include "../scenegraph/Viewer.h"
51 
52 /*
53  * (c) Copyright 1993, Silicon Graphics, Inc.
54  * ALL RIGHTS RESERVED
55  * Permission to use, copy, modify, and distribute this software for
56  * any purpose and without fee is hereby granted, provided that the above
57  * copyright notice appear in all copies and that both the copyright notice
58  * and this permission notice appear in supporting documentation, and that
59  * the name of Silicon Graphics, Inc. not be used in advertising
60  * or publicity pertaining to distribution of the software without specific,
61  * written prior permission.
62  *
63  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
64  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
65  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
66  * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
67  * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
68  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
69  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
70  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
71  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN
72  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
73  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
74  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
75  *
76  *
77  * US Government Users Restricted Rights
78  * Use, duplication, or disclosure by the Government is subject to
79  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
80  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
81  * clause at DFARS 252.227-7013 and/or in similar or successor
82  * clauses in the FAR or the DOD or NASA FAR Supplement.
83  * Unpublished-- rights reserved under the copyright laws of the
84  * United States. Contractor/manufacturer is Silicon Graphics,
85  * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
86  *
87  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
88  */
89 
90 /*
91  *
92  * This file has been slightly modified from the original for use with Mesa
93  *
94  * Jeroen van der Zijp
95  *
96  * jvz@cyberia.cfdrc.com
97  *
98  */
99 
100 #ifdef HAVE_MOTIF
101 
102 #include <X11/IntrinsicP.h>
103 #include <X11/StringDefs.h>
104 
105 #include "GLwDrawAP.h"
106 
107 #define ATTRIBLIST_SIZE 32
108 
109 #define offset(field) XtOffset(GLwDrawingAreaWidget,glwDrawingArea.field)
110 
111 
112 /* forward definitions */
113 static void createColormap(GLwDrawingAreaWidget w,int offset,XrmValue *value);
114 static void Initialize(GLwDrawingAreaWidget req,GLwDrawingAreaWidget neww,ArgList args,Cardinal *num_args);
115 static void Realize(Widget w,Mask *valueMask,XSetWindowAttributes *attributes);
116 static void Redraw(GLwDrawingAreaWidget w,XEvent *event,Region region);
117 static void Resize(GLwDrawingAreaWidget glw);
118 static void Destroy(GLwDrawingAreaWidget glw);
119 static void glwInput(GLwDrawingAreaWidget glw,XEvent *event,String *params,Cardinal *numParams);
120 
121 
122 
123 static char defaultTranslations[] =
124  "<KeyDown>: glwInput() \n\
125  <KeyUp>: glwInput() \n\
126  <BtnDown>: glwInput() \n\
127  <BtnUp>: glwInput() \n\
128  <BtnMotion>: glwInput() ";
129 
130 
131 static XtActionsRec actions[] = {
132  {"glwInput",(XtActionProc)glwInput}, /* key or mouse input */
133  };
134 
135 
136 /*
137  * There is a bit of unusual handling of the resources here.
138  * Because Xt insists on allocating the colormap resource when it is
139  * processing the core resources (even if we redeclare the colormap
140  * resource here, we need to do a little trick. When Xt first allocates
141  * the colormap, we allow it to allocate the default one, since we have
142  * not yet determined the appropriate visual (which is determined from
143  * resources parsed after the colormap). We also let it allocate colors
144  * in that default colormap.
145  *
146  * In the initialize proc we calculate the actual visual. Then, we
147  * reobtain the colormap resource using XtGetApplicationResources in
148  * the initialize proc. If requested, we also reallocate colors in
149  * that colormap using the same method.
150  */
151 
152 static XtResource resources[] = {
153  /* The GLX attributes. Add any new attributes here */
154 
155  {GLwNbufferSize, GLwCBufferSize, XtRInt, sizeof (int),
156  offset(bufferSize), XtRImmediate, (XtPointer) 0},
157 
158  {GLwNlevel, GLwCLevel, XtRInt, sizeof (int),
159  offset(level), XtRImmediate, (XtPointer) 0},
160 
161  {GLwNrgba, GLwCRgba, XtRBoolean, sizeof (Boolean),
162  offset(rgba), XtRImmediate, (XtPointer) FALSE},
163 
164  {GLwNdoublebuffer, GLwCDoublebuffer, XtRBoolean, sizeof (Boolean),
165  offset(doublebuffer), XtRImmediate, (XtPointer) FALSE},
166 
167  {GLwNstereo, GLwCStereo, XtRBoolean, sizeof (Boolean),
168  offset(stereo), XtRImmediate, (XtPointer) FALSE},
169 
170  {GLwNauxBuffers, GLwCAuxBuffers, XtRInt, sizeof (int),
171  offset(auxBuffers), XtRImmediate, (XtPointer) 0},
172 
173  {GLwNredSize, GLwCColorSize, XtRInt, sizeof (int),
174  offset(redSize), XtRImmediate, (XtPointer) 1},
175 
176  {GLwNgreenSize, GLwCColorSize, XtRInt, sizeof (int),
177  offset(greenSize), XtRImmediate, (XtPointer) 1},
178 
179  {GLwNblueSize, GLwCColorSize, XtRInt, sizeof (int),
180  offset(blueSize), XtRImmediate, (XtPointer) 1},
181 
182  {GLwNalphaSize, GLwCAlphaSize, XtRInt, sizeof (int),
183  offset(alphaSize), XtRImmediate, (XtPointer) 0},
184 
185  {GLwNdepthSize, GLwCDepthSize, XtRInt, sizeof (int),
186  offset(depthSize), XtRImmediate, (XtPointer) 0},
187 
188  {GLwNstencilSize, GLwCStencilSize, XtRInt, sizeof (int),
189  offset(stencilSize), XtRImmediate, (XtPointer) 0},
190 
191  {GLwNaccumRedSize, GLwCAccumColorSize, XtRInt, sizeof (int),
192  offset(accumRedSize), XtRImmediate, (XtPointer) 0},
193 
194  {GLwNaccumGreenSize, GLwCAccumColorSize, XtRInt, sizeof (int),
195  offset(accumGreenSize), XtRImmediate, (XtPointer) 0},
196 
197  {GLwNaccumBlueSize, GLwCAccumColorSize, XtRInt, sizeof (int),
198  offset(accumBlueSize), XtRImmediate, (XtPointer) 0},
199 
200  {GLwNaccumAlphaSize, GLwCAccumAlphaSize, XtRInt, sizeof (int),
201  offset(accumAlphaSize), XtRImmediate, (XtPointer) 0},
202 
203  /* the attribute list */
204  {GLwNattribList, GLwCAttribList, XtRPointer, sizeof(int *),
205  offset(attribList), XtRImmediate, (XtPointer) NULL},
206 
207  /* the visual info */
208  {GLwNvisualInfo, GLwCVisualInfo, GLwRVisualInfo, sizeof (XVisualInfo *),
209  offset(visualInfo), XtRImmediate, (XtPointer) NULL},
210 
211  /* miscellaneous resources */
212  {GLwNinstallColormap, GLwCInstallColormap, XtRBoolean, sizeof (Boolean),
213  offset(installColormap), XtRImmediate, (XtPointer) TRUE},
214 
215  {GLwNallocateBackground, GLwCAllocateColors, XtRBoolean, sizeof (Boolean),
216  offset(allocateBackground), XtRImmediate, (XtPointer) FALSE},
217 
218  {GLwNallocateOtherColors, GLwCAllocateColors, XtRBoolean, sizeof (Boolean),
219  offset(allocateOtherColors), XtRImmediate, (XtPointer) FALSE},
220 
221  {GLwNinstallBackground, GLwCInstallBackground, XtRBoolean, sizeof (Boolean),
222  offset(installBackground), XtRImmediate, (XtPointer) TRUE},
223 
224  {GLwNginitCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList),
225  offset(ginitCallback), XtRImmediate, (XtPointer) NULL},
226 
227  {GLwNinputCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList),
228  offset(inputCallback), XtRImmediate, (XtPointer) NULL},
229 
230  {GLwNresizeCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList),
231  offset(resizeCallback), XtRImmediate, (XtPointer) NULL},
232 
233  {GLwNexposeCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList),
234  offset(exposeCallback), XtRImmediate, (XtPointer) NULL},
235  };
236 
237 
238 /*
239 ** The following resources are reobtained using XtGetApplicationResources
240 ** in the initialize proc.
241 */
242 
243 /* The colormap */
244 static XtResource initializeResources[] = {
245  /* reobtain the colormap with the new visual */
246  {XtNcolormap, XtCColormap, XtRColormap, sizeof(Colormap),
247  XtOffset(GLwDrawingAreaWidget, core.colormap),
248  XtRCallProc,(XtPointer) createColormap},
249  };
250 
251 
252 /* reallocate any colors we need in the new colormap */
253 
254 /* The background is obtained only if the allocateBackground resource is TRUE*/
255 static XtResource backgroundResources[] = {
256  {XtNbackground,XtCBackground,XtRPixel,sizeof(Pixel),
257  XtOffset(GLwDrawingAreaWidget,core.background_pixel),
258  XtRString,(XtPointer)"lightgrey"},
259  /*XtRString,(XtPointer)"XtDefaultBackground"},*/
260 
261  {XtNbackgroundPixmap, XtCPixmap, XtRPixmap, sizeof(Pixmap),
262  XtOffset(GLwDrawingAreaWidget,core.background_pixmap),
263  XtRImmediate,(XtPointer)XtUnspecifiedPixmap},
264  };
265 
266 #undef offset
267 
268 
269 GLwDrawingAreaClassRec glwDrawingAreaClassRec = {
270  { /* core fields */
271  /* superclass */ (WidgetClass) &widgetClassRec,
272  /* class_name */ "GLwDrawingArea",
273  /* widget_size */ sizeof(GLwDrawingAreaRec),
274  /* class_initialize */ NULL,
275  /* class_part_initialize */ NULL,
276  /* class_inited */ FALSE,
277  /* initialize */ (XtInitProc) Initialize,
278  /* initialize_hook */ NULL,
279  /* realize */ Realize,
280  /* actions */ actions,
281  /* num_actions */ XtNumber(actions),
282  /* resources */ resources,
283  /* num_resources */ XtNumber(resources),
284  /* xrm_class */ NULLQUARK,
285  /* compress_motion */ TRUE,
286  /* compress_exposure */ TRUE,
287  /* compress_enterleave */ TRUE,
288  /* visible_interest */ TRUE,
289  /* destroy */ (XtWidgetProc) Destroy,
290  /* resize */ (XtWidgetProc) Resize,
291  /* expose */ (XtExposeProc) Redraw,
292  /* set_values */ NULL,
293  /* set_values_hook */ NULL,
294  /* set_values_almost */ XtInheritSetValuesAlmost,
295  /* get_values_hook */ NULL,
296  /* accept_focus */ NULL,
297  /* version */ XtVersion,
298  /* callback_private */ NULL,
299  /* tm_table */ defaultTranslations,
300  /* query_geometry */ XtInheritQueryGeometry,
301  /* display_accelerator */ XtInheritDisplayAccelerator,
302  /* extension */ NULL
303  },
304  };
305 
306 WidgetClass glwDrawingAreaWidgetClass=(WidgetClass)&glwDrawingAreaClassRec;
307 
308 
309 
310 static void error(Widget w,char* string){
311  char buf[100];
312  sprintf(buf,"GLwDrawingArea: %s\n",string);
313  XtAppError(XtWidgetToApplicationContext(w),buf);
314  }
315 
316 
317 static void warning(Widget w,char* string){
318  char buf[100];
319  sprintf (buf, "GLwDraw: %s\n", string);
320  XtAppWarning(XtWidgetToApplicationContext(w), buf);
321  }
322 
323 
324 
325 /* Initialize the attribList based on the attributes */
326 static void createAttribList(GLwDrawingAreaWidget w){
327  int *ptr;
328  w->glwDrawingArea.attribList = (int*)XtMalloc(ATTRIBLIST_SIZE*sizeof(int));
329  if(!w->glwDrawingArea.attribList){
330  error((Widget)w,"Unable to allocate attribute list");
331  }
332  ptr = w->glwDrawingArea.attribList;
333  *ptr++ = GLX_BUFFER_SIZE;
334  *ptr++ = w->glwDrawingArea.bufferSize;
335  *ptr++ = GLX_LEVEL;
336  *ptr++ = w->glwDrawingArea.level;
337  if(w->glwDrawingArea.rgba) *ptr++ = GLX_RGBA;
338  if(w->glwDrawingArea.doublebuffer) *ptr++ = GLX_DOUBLEBUFFER;
339  if(w->glwDrawingArea.stereo) *ptr++ = GLX_STEREO;
340  *ptr++ = GLX_AUX_BUFFERS;
341  *ptr++ = w->glwDrawingArea.auxBuffers;
342  *ptr++ = GLX_RED_SIZE;
343  *ptr++ = w->glwDrawingArea.redSize;
344  *ptr++ = GLX_GREEN_SIZE;
345  *ptr++ = w->glwDrawingArea.greenSize;
346  *ptr++ = GLX_BLUE_SIZE;
347  *ptr++ = w->glwDrawingArea.blueSize;
348  *ptr++ = GLX_ALPHA_SIZE;
349  *ptr++ = w->glwDrawingArea.alphaSize;
350  *ptr++ = GLX_DEPTH_SIZE;
351  *ptr++ = w->glwDrawingArea.depthSize;
352  *ptr++ = GLX_STENCIL_SIZE;
353  *ptr++ = w->glwDrawingArea.stencilSize;
354  *ptr++ = GLX_ACCUM_RED_SIZE;
355  *ptr++ = w->glwDrawingArea.accumRedSize;
356  *ptr++ = GLX_ACCUM_GREEN_SIZE;
357  *ptr++ = w->glwDrawingArea.accumGreenSize;
358  *ptr++ = GLX_ACCUM_BLUE_SIZE;
359  *ptr++ = w->glwDrawingArea.accumBlueSize;
360  *ptr++ = GLX_ACCUM_ALPHA_SIZE;
361  *ptr++ = w->glwDrawingArea.accumAlphaSize;
362  *ptr++ = None;
363  assert((ptr-w->glwDrawingArea.attribList)<ATTRIBLIST_SIZE);
364  }
365 
366 
367 
368 /* Initialize the visualInfo based on the attribute list */
369 static void createVisualInfo(GLwDrawingAreaWidget w){
370  assert(w->glwDrawingArea.attribList);
371  w->glwDrawingArea.visualInfo=glXChooseVisual(XtDisplay(w),XScreenNumberOfScreen(XtScreen(w)),w->glwDrawingArea.attribList);
372  if(!w->glwDrawingArea.visualInfo) error((Widget)w,"requested visual not supported");
373  }
374 
375 
376 
377 /* Initialize the colormap based on the visual info.
378  * This routine maintains a cache of visual-infos to colormaps. If two
379  * widgets share the same visual info, they share the same colormap.
380  * This function is called by the callProc of the colormap resource entry.
381  */
382 static void createColormap(GLwDrawingAreaWidget w,int offset,XrmValue *value){
383  static struct cmapCache { Visual *visual; Colormap cmap; } *cmapCache;
384  static int cacheEntries=0;
385  static int cacheMalloced=0;
386  register int i;
387 
388  assert(w->glwDrawingArea.visualInfo);
389 
390  /* see if we can find it in the cache */
391  for(i=0; i<cacheEntries; i++){
392  if(cmapCache[i].visual==w->glwDrawingArea.visualInfo->visual){
393  value->addr=(XtPointer)(&cmapCache[i].cmap);
394  return;
395  }
396  }
397 
398  /* not in the cache, create a new entry */
399  if(cacheEntries >= cacheMalloced){
400  /* need to malloc a new one. Since we are likely to have only a
401  * few colormaps, we allocate one the first time, and double
402  * each subsequent time.
403  */
404  if(cacheMalloced==0){
405  cacheMalloced=1;
406  cmapCache=(struct cmapCache*)XtMalloc(sizeof(struct cmapCache));
407  }
408  else{
409  cacheMalloced<<=1;
410  cmapCache=(struct cmapCache*)XtRealloc((char*)cmapCache,sizeof(struct cmapCache)*cacheMalloced);
411  }
412  }
413 
414  cmapCache[cacheEntries].cmap=XCreateColormap(XtDisplay(w),
415  RootWindow(XtDisplay(w),
416  w->glwDrawingArea.visualInfo->screen),
417  w->glwDrawingArea.visualInfo->visual,
418  AllocNone);
419  cmapCache[cacheEntries].visual=w->glwDrawingArea.visualInfo->visual;
420  value->addr=(XtPointer)(&cmapCache[cacheEntries++].cmap);
421  }
422 
423 
424 
425 static void Initialize(GLwDrawingAreaWidget req,GLwDrawingAreaWidget neww,ArgList args,Cardinal *num_args){
426 
427  /* fix size */
428  if(req->core.width==0) neww->core.width=100;
429  if(req->core.height==0) neww->core.width=100;
430 
431  /* create the attribute list if needed */
432  neww->glwDrawingArea.myList=FALSE;
433  if(neww->glwDrawingArea.attribList==NULL){
434  neww->glwDrawingArea.myList=TRUE;
435  createAttribList(neww);
436  }
437 
438  /* Gotta have it */
439  assert(neww->glwDrawingArea.attribList);
440 
441  /* determine the visual info if needed */
442  neww->glwDrawingArea.myVisual=FALSE;
443  if(neww->glwDrawingArea.visualInfo==NULL){
444  neww->glwDrawingArea.myVisual=TRUE;
445  createVisualInfo(neww);
446  }
447 
448  /* Gotta have that too */
449  assert(neww->glwDrawingArea.visualInfo);
450 
451  neww->core.depth=neww->glwDrawingArea.visualInfo->depth;
452 
453  /* Reobtain the colormap and colors in it using XtGetApplicationResources*/
454  XtGetApplicationResources((Widget)neww,neww,initializeResources,XtNumber(initializeResources),args,*num_args);
455 
456  /* obtain the color resources if appropriate */
457  if(req->glwDrawingArea.allocateBackground){
458  XtGetApplicationResources((Widget)neww,neww,backgroundResources,XtNumber(backgroundResources),args,*num_args);
459  }
460  }
461 
462 
463 
464 static void Realize(Widget w,Mask *valueMask,XSetWindowAttributes *attributes){
467  Widget parentShell;
468  Status status;
469  Window windows[2],*windowsReturn,*windowList;
470  int countReturn,i;
471 
472  /* if we haven't requested that the background be both installed and
473  * allocated, don't install it.
474  */
475  if(!(glw->glwDrawingArea.installBackground && glw->glwDrawingArea.allocateBackground)){
476  *valueMask&=~CWBackPixel;
477  }
478 
479  XtCreateWindow(w,(unsigned int)InputOutput,glw->glwDrawingArea.visualInfo->visual,*valueMask,attributes);
480 
481  /* if appropriate, call XSetWMColormapWindows to install the colormap */
482  if(glw->glwDrawingArea.installColormap){
483 
484  /* Get parent shell */
485  for(parentShell=XtParent(w); parentShell&&!XtIsShell(parentShell); parentShell=XtParent(parentShell));
486 
487  if(parentShell && XtWindow(parentShell)){
488 
489  /* check to see if there is already a property */
490  status=XGetWMColormapWindows(XtDisplay(parentShell),XtWindow(parentShell),&windowsReturn,&countReturn);
491 
492  /* if no property, just create one */
493  if(!status){
494  windows[0]=XtWindow(w);
495  windows[1]=XtWindow(parentShell);
496  XSetWMColormapWindows(XtDisplay(parentShell),XtWindow(parentShell),windows,2);
497  }
498 
499  /* there was a property, add myself to the beginning */
500  else{
501  windowList=(Window *)XtMalloc((sizeof(Window))*(countReturn+1));
502  windowList[0]=XtWindow(w);
503  for(i=0; i<countReturn; i++) windowList[i+1]=windowsReturn[i];
504  XSetWMColormapWindows(XtDisplay(parentShell),XtWindow(parentShell),windowList,countReturn+1);
505  XtFree((char*)windowList);
506  XtFree((char*)windowsReturn);
507  }
508  }
509  else{
510  warning(w,"Could not set colormap property on parent shell");
511  }
512  }
513 
514  /* Invoke callbacks */
515  cb.reason=GLwCR_GINIT;
516  cb.event=NULL;
517  cb.width=glw->core.width;
518  cb.height=glw->core.height;
519  XtCallCallbackList((Widget)glw,glw->glwDrawingArea.ginitCallback,&cb);
520  }
521 
522 
523 
524 static void Redraw(GLwDrawingAreaWidget w,XEvent *event,Region region){
526  if(!XtIsRealized((Widget)w)) return;
527  cb.reason=GLwCR_EXPOSE;
528  cb.event=event;
529  cb.width=w->core.width;
530  cb.height=w->core.height;
531  XtCallCallbackList((Widget)w,w->glwDrawingArea.exposeCallback,&cb);
532  }
533 
534 
535 
536 static void Resize(GLwDrawingAreaWidget glw){
538  if(!XtIsRealized((Widget)glw)) return;
539  cb.reason=GLwCR_RESIZE;
540  cb.event=NULL;
541  cb.width=glw->core.width;
542  cb.height=glw->core.height;
543  XtCallCallbackList((Widget)glw,glw->glwDrawingArea.resizeCallback,&cb);
544  }
545 
546 
547 
548 static void Destroy(GLwDrawingAreaWidget glw){
549  Window *windowsReturn;
550  Widget parentShell;
551  Status status;
552  int countReturn;
553  register int i;
554 
555  if(glw->glwDrawingArea.myList && glw->glwDrawingArea.attribList){
556  XtFree((XtPointer)glw->glwDrawingArea.attribList);
557  }
558 
559  if(glw->glwDrawingArea.myVisual && glw->glwDrawingArea.visualInfo){
560  XtFree((XtPointer)glw->glwDrawingArea.visualInfo);
561  }
562 
563  /* if my colormap was installed, remove it */
564  if(glw->glwDrawingArea.installColormap){
565 
566  /* Get parent shell */
567  for(parentShell=XtParent(glw); parentShell&&!XtIsShell(parentShell); parentShell=XtParent(parentShell));
568 
569  if(parentShell && XtWindow(parentShell)){
570 
571  /* make sure there is a property */
572  status=XGetWMColormapWindows(XtDisplay(parentShell),XtWindow(parentShell),&windowsReturn,&countReturn);
573 
574  /* if no property, just return. If there was a property, continue */
575  if(status){
576 
577  /* search for a match */
578  for(i=0; i<countReturn; i++){
579  if(windowsReturn[i]==XtWindow(glw)){
580 
581  /* we found a match, now copy the rest down */
582  for(i++; i<countReturn; i++){ windowsReturn[i-1]=windowsReturn[i]; }
583 
584  XSetWMColormapWindows(XtDisplay(parentShell),XtWindow(parentShell),windowsReturn,countReturn-1);
585  break;
586  }
587  }
588  XtFree((char *)windowsReturn);
589  }
590  }
591  }
592  }
593 
594 
595 
596 /* Action routine for keyboard and mouse events */
597 static void glwInput(GLwDrawingAreaWidget glw,XEvent *event,String *params,Cardinal *numParams){
599  cb.reason=GLwCR_INPUT;
600  cb.event=event;
601  cb.width=glw->core.width;
602  cb.height=glw->core.height;
603  XtCallCallbackList((Widget)glw,glw->glwDrawingArea.inputCallback,&cb);
604  }
605 
606 #endif