d4bcfacad73c60893ba6d90fdae02617bcb3bef0
[mesa.git] / src / glw / GLwDrawA.c
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 *
41 * This file has been slightly modified from the original for use with Mesa
42 *
43 * Jeroen van der Zijp
44 *
45 * jvz@cyberia.cfdrc.com
46 *
47 */
48 #include <X11/IntrinsicP.h>
49 #include <X11/StringDefs.h>
50 #include <GL/glx.h>
51 #include <GL/gl.h>
52 #ifdef __GLX_MOTIF
53 #include <Xm/PrimitiveP.h>
54 #include "GLwMDrawAP.h"
55 #else
56 #include "GLwDrawAP.h"
57 #endif
58 #include <assert.h>
59 #include <stdio.h>
60
61 #ifdef __GLX_MOTIF
62 #define GLwDrawingAreaWidget GLwMDrawingAreaWidget
63 #define GLwDrawingAreaClassRec GLwMDrawingAreaClassRec
64 #define glwDrawingAreaClassRec glwMDrawingAreaClassRec
65 #define glwDrawingAreaWidgetClass glwMDrawingAreaWidgetClass
66 #define GLwDrawingAreaRec GLwMDrawingAreaRec
67 #endif
68
69 #define ATTRIBLIST_SIZE 32
70
71 #define offset(field) XtOffset(GLwDrawingAreaWidget,glwDrawingArea.field)
72
73
74 /* forward definitions */
75 static void createColormap(GLwDrawingAreaWidget w,int offset,XrmValue *value);
76 static void Initialize(GLwDrawingAreaWidget req,GLwDrawingAreaWidget neww,ArgList args,Cardinal *num_args);
77 static void Realize(Widget w,Mask *valueMask,XSetWindowAttributes *attributes);
78 static void Redraw(GLwDrawingAreaWidget w,XEvent *event,Region region);
79 static void Resize(GLwDrawingAreaWidget glw);
80 static void Destroy(GLwDrawingAreaWidget glw);
81 static void glwInput(GLwDrawingAreaWidget glw,XEvent *event,String *params,Cardinal *numParams);
82
83
84
85 static char defaultTranslations[] =
86 #ifdef __GLX_MOTIF
87 "<Key>osfHelp:PrimitiveHelp() \n"
88 #endif
89 "<KeyDown>: glwInput() \n\
90 <KeyUp>: glwInput() \n\
91 <BtnDown>: glwInput() \n\
92 <BtnUp>: glwInput() \n\
93 <BtnMotion>: glwInput() ";
94
95
96 static XtActionsRec actions[] = {
97 {"glwInput",(XtActionProc)glwInput}, /* key or mouse input */
98 };
99
100
101 /*
102 * There is a bit of unusual handling of the resources here.
103 * Because Xt insists on allocating the colormap resource when it is
104 * processing the core resources (even if we redeclare the colormap
105 * resource here, we need to do a little trick. When Xt first allocates
106 * the colormap, we allow it to allocate the default one, since we have
107 * not yet determined the appropriate visual (which is determined from
108 * resources parsed after the colormap). We also let it allocate colors
109 * in that default colormap.
110 *
111 * In the initialize proc we calculate the actual visual. Then, we
112 * reobtain the colormap resource using XtGetApplicationResources in
113 * the initialize proc. If requested, we also reallocate colors in
114 * that colormap using the same method.
115 */
116
117 static XtResource resources[] = {
118 /* The GLX attributes. Add any new attributes here */
119
120 {GLwNbufferSize, GLwCBufferSize, XtRInt, sizeof (int),
121 offset(bufferSize), XtRImmediate, (XtPointer) 0},
122
123 {GLwNlevel, GLwCLevel, XtRInt, sizeof (int),
124 offset(level), XtRImmediate, (XtPointer) 0},
125
126 {GLwNrgba, GLwCRgba, XtRBoolean, sizeof (Boolean),
127 offset(rgba), XtRImmediate, (XtPointer) FALSE},
128
129 {GLwNdoublebuffer, GLwCDoublebuffer, XtRBoolean, sizeof (Boolean),
130 offset(doublebuffer), XtRImmediate, (XtPointer) FALSE},
131
132 {GLwNstereo, GLwCStereo, XtRBoolean, sizeof (Boolean),
133 offset(stereo), XtRImmediate, (XtPointer) FALSE},
134
135 {GLwNauxBuffers, GLwCAuxBuffers, XtRInt, sizeof (int),
136 offset(auxBuffers), XtRImmediate, (XtPointer) 0},
137
138 {GLwNredSize, GLwCColorSize, XtRInt, sizeof (int),
139 offset(redSize), XtRImmediate, (XtPointer) 1},
140
141 {GLwNgreenSize, GLwCColorSize, XtRInt, sizeof (int),
142 offset(greenSize), XtRImmediate, (XtPointer) 1},
143
144 {GLwNblueSize, GLwCColorSize, XtRInt, sizeof (int),
145 offset(blueSize), XtRImmediate, (XtPointer) 1},
146
147 {GLwNalphaSize, GLwCAlphaSize, XtRInt, sizeof (int),
148 offset(alphaSize), XtRImmediate, (XtPointer) 0},
149
150 {GLwNdepthSize, GLwCDepthSize, XtRInt, sizeof (int),
151 offset(depthSize), XtRImmediate, (XtPointer) 0},
152
153 {GLwNstencilSize, GLwCStencilSize, XtRInt, sizeof (int),
154 offset(stencilSize), XtRImmediate, (XtPointer) 0},
155
156 {GLwNaccumRedSize, GLwCAccumColorSize, XtRInt, sizeof (int),
157 offset(accumRedSize), XtRImmediate, (XtPointer) 0},
158
159 {GLwNaccumGreenSize, GLwCAccumColorSize, XtRInt, sizeof (int),
160 offset(accumGreenSize), XtRImmediate, (XtPointer) 0},
161
162 {GLwNaccumBlueSize, GLwCAccumColorSize, XtRInt, sizeof (int),
163 offset(accumBlueSize), XtRImmediate, (XtPointer) 0},
164
165 {GLwNaccumAlphaSize, GLwCAccumAlphaSize, XtRInt, sizeof (int),
166 offset(accumAlphaSize), XtRImmediate, (XtPointer) 0},
167
168 /* the attribute list */
169 {GLwNattribList, GLwCAttribList, XtRPointer, sizeof(int *),
170 offset(attribList), XtRImmediate, (XtPointer) NULL},
171
172 /* the visual info */
173 {GLwNvisualInfo, GLwCVisualInfo, GLwRVisualInfo, sizeof (XVisualInfo *),
174 offset(visualInfo), XtRImmediate, (XtPointer) NULL},
175
176 /* miscellaneous resources */
177 {GLwNinstallColormap, GLwCInstallColormap, XtRBoolean, sizeof (Boolean),
178 offset(installColormap), XtRImmediate, (XtPointer) TRUE},
179
180 {GLwNallocateBackground, GLwCAllocateColors, XtRBoolean, sizeof (Boolean),
181 offset(allocateBackground), XtRImmediate, (XtPointer) FALSE},
182
183 {GLwNallocateOtherColors, GLwCAllocateColors, XtRBoolean, sizeof (Boolean),
184 offset(allocateOtherColors), XtRImmediate, (XtPointer) FALSE},
185
186 {GLwNinstallBackground, GLwCInstallBackground, XtRBoolean, sizeof (Boolean),
187 offset(installBackground), XtRImmediate, (XtPointer) TRUE},
188
189 {GLwNginitCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList),
190 offset(ginitCallback), XtRImmediate, (XtPointer) NULL},
191
192 {GLwNinputCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList),
193 offset(inputCallback), XtRImmediate, (XtPointer) NULL},
194
195 {GLwNresizeCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList),
196 offset(resizeCallback), XtRImmediate, (XtPointer) NULL},
197
198 {GLwNexposeCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList),
199 offset(exposeCallback), XtRImmediate, (XtPointer) NULL},
200
201 /* Changes to Motif primitive resources */
202 #ifdef __GLX_MOTIF
203 {XmNtraversalOn, XmCTraversalOn, XmRBoolean, sizeof (Boolean),
204 XtOffset (GLwDrawingAreaWidget, primitive.traversal_on), XmRImmediate,
205 (XtPointer)FALSE},
206
207 /* highlighting is normally disabled, as when Motif tries to disable
208 * highlighting, it tries to reset the color back to the parent's
209 * background (usually Motif blue). Unfortunately, that is in a
210 * different colormap, and doesn't work too well.
211 */
212 {XmNhighlightOnEnter, XmCHighlightOnEnter, XmRBoolean, sizeof (Boolean),
213 XtOffset (GLwDrawingAreaWidget, primitive.highlight_on_enter),
214 XmRImmediate, (XtPointer) FALSE},
215
216 {XmNhighlightThickness, XmCHighlightThickness, XmRHorizontalDimension,
217 sizeof (Dimension),
218 XtOffset (GLwDrawingAreaWidget, primitive.highlight_thickness),
219 XmRImmediate, (XtPointer) 0},
220 #endif
221 };
222
223
224 /*
225 ** The following resources are reobtained using XtGetApplicationResources
226 ** in the initialize proc.
227 */
228
229 /* The colormap */
230 static XtResource initializeResources[] = {
231 /* reobtain the colormap with the new visual */
232 {XtNcolormap, XtCColormap, XtRColormap, sizeof(Colormap),
233 XtOffset(GLwDrawingAreaWidget, core.colormap),
234 XtRCallProc,(XtPointer) createColormap},
235 };
236
237
238 /* reallocate any colors we need in the new colormap */
239
240 /* The background is obtained only if the allocateBackground resource is TRUE*/
241 static XtResource backgroundResources[] = {
242 #ifdef __GLX_MOTIF
243 {XmNbackground, XmCBackground,XmRPixel,
244 sizeof(Pixel),XtOffset(GLwDrawingAreaWidget,core.background_pixel),
245 XmRString,(XtPointer)"lightgrey"},
246 /*XmRCallProc,(XtPointer)_XmBackgroundColorDefault},*/
247
248 {XmNbackgroundPixmap,XmCPixmap,XmRXmBackgroundPixmap,
249 sizeof(Pixmap),XtOffset(GLwDrawingAreaWidget,core.background_pixmap),
250 XmRImmediate,(XtPointer)XmUNSPECIFIED_PIXMAP},
251
252 #else
253 {XtNbackground,XtCBackground,XtRPixel,sizeof(Pixel),
254 XtOffset(GLwDrawingAreaWidget,core.background_pixel),
255 XtRString,(XtPointer)"lightgrey"},
256 /*XtRString,(XtPointer)"XtDefaultBackground"},*/
257
258 {XtNbackgroundPixmap, XtCPixmap, XtRPixmap, sizeof(Pixmap),
259 XtOffset(GLwDrawingAreaWidget,core.background_pixmap),
260 XtRImmediate,(XtPointer)XtUnspecifiedPixmap},
261 #endif
262 };
263
264
265
266 /* The other colors such as the foreground are allocated only if
267 * allocateOtherColors are set. These resources only exist in Motif.
268 */
269 #ifdef __GLX_MOTIF
270 static XtResource otherColorResources[] = {
271 {XmNforeground,XmCForeground,XmRPixel,
272 sizeof(Pixel),XtOffset(GLwDrawingAreaWidget,primitive.foreground),
273 XmRString,(XtPointer)"lighgrey"},
274 /*XmRCallProc, (XtPointer) _XmForegroundColorDefault},*/
275
276 {XmNhighlightColor,XmCHighlightColor,XmRPixel,sizeof(Pixel),
277 XtOffset(GLwDrawingAreaWidget,primitive.highlight_color),
278 XmRString,(XtPointer)"lightgrey"},
279 /*XmRCallProc,(XtPointer)_XmHighlightColorDefault},*/
280
281 {XmNhighlightPixmap,XmCHighlightPixmap,XmRPrimHighlightPixmap,
282 sizeof(Pixmap),
283 XtOffset(GLwDrawingAreaWidget,primitive.highlight_pixmap),
284 XmRImmediate,(XtPointer)XmUNSPECIFIED_PIXMAP},
285 /*XmRCallProc,(XtPointer)_XmPrimitiveHighlightPixmapDefault},*/
286 };
287 #endif
288
289
290 #undef offset
291
292
293 GLwDrawingAreaClassRec glwDrawingAreaClassRec = {
294 { /* core fields */
295 #ifdef __GLX_MOTIF
296 /* superclass */ (WidgetClass) &xmPrimitiveClassRec,
297 /* class_name */ "GLwMDrawingArea",
298 #else /* not __GLX_MOTIF */
299 /* superclass */ (WidgetClass) &widgetClassRec,
300 /* class_name */ "GLwDrawingArea",
301 #endif /* __GLX_MOTIF */
302 /* widget_size */ sizeof(GLwDrawingAreaRec),
303 /* class_initialize */ NULL,
304 /* class_part_initialize */ NULL,
305 /* class_inited */ FALSE,
306 /* initialize */ (XtInitProc) Initialize,
307 /* initialize_hook */ NULL,
308 /* realize */ Realize,
309 /* actions */ actions,
310 /* num_actions */ XtNumber(actions),
311 /* resources */ resources,
312 /* num_resources */ XtNumber(resources),
313 /* xrm_class */ NULLQUARK,
314 /* compress_motion */ TRUE,
315 /* compress_exposure */ TRUE,
316 /* compress_enterleave */ TRUE,
317 /* visible_interest */ TRUE,
318 /* destroy */ (XtWidgetProc) Destroy,
319 /* resize */ (XtWidgetProc) Resize,
320 /* expose */ (XtExposeProc) Redraw,
321 /* set_values */ NULL,
322 /* set_values_hook */ NULL,
323 /* set_values_almost */ XtInheritSetValuesAlmost,
324 /* get_values_hook */ NULL,
325 /* accept_focus */ NULL,
326 /* version */ XtVersion,
327 /* callback_private */ NULL,
328 /* tm_table */ defaultTranslations,
329 /* query_geometry */ XtInheritQueryGeometry,
330 /* display_accelerator */ XtInheritDisplayAccelerator,
331 /* extension */ NULL
332 },
333 #ifdef __GLX_MOTIF /* primitive resources */
334 {
335 /* border_highlight */ XmInheritBorderHighlight,
336 /* border_unhighlight */ XmInheritBorderUnhighlight,
337 /* translations */ XtInheritTranslations,
338 /* arm_and_activate */ NULL,
339 /* get_resources */ NULL,
340 /* num get_resources */ 0,
341 /* extension */ NULL,
342 }
343 #endif
344 };
345
346 WidgetClass glwDrawingAreaWidgetClass=(WidgetClass)&glwDrawingAreaClassRec;
347
348
349
350 static void error(Widget w,char* string){
351 char buf[100];
352 #ifdef __GLX_MOTIF
353 sprintf(buf,"GLwMDrawingArea: %s\n",string);
354 #else
355 sprintf(buf,"GLwDrawingArea: %s\n",string);
356 #endif
357 XtAppError(XtWidgetToApplicationContext(w),buf);
358 }
359
360
361 static void warning(Widget w,char* string){
362 char buf[100];
363 #ifdef __GLX_MOTIF
364 sprintf (buf, "GLwMDraw: %s\n", string);
365 #else
366 sprintf (buf, "GLwDraw: %s\n", string);
367 #endif
368 XtAppWarning(XtWidgetToApplicationContext(w), buf);
369 }
370
371
372
373 /* Initialize the attribList based on the attributes */
374 static void createAttribList(GLwDrawingAreaWidget w){
375 int *ptr;
376 w->glwDrawingArea.attribList = (int*)XtMalloc(ATTRIBLIST_SIZE*sizeof(int));
377 if(!w->glwDrawingArea.attribList){
378 error((Widget)w,"Unable to allocate attribute list");
379 }
380 ptr = w->glwDrawingArea.attribList;
381 *ptr++ = GLX_BUFFER_SIZE;
382 *ptr++ = w->glwDrawingArea.bufferSize;
383 *ptr++ = GLX_LEVEL;
384 *ptr++ = w->glwDrawingArea.level;
385 if(w->glwDrawingArea.rgba) *ptr++ = GLX_RGBA;
386 if(w->glwDrawingArea.doublebuffer) *ptr++ = GLX_DOUBLEBUFFER;
387 if(w->glwDrawingArea.stereo) *ptr++ = GLX_STEREO;
388 *ptr++ = GLX_AUX_BUFFERS;
389 *ptr++ = w->glwDrawingArea.auxBuffers;
390 *ptr++ = GLX_RED_SIZE;
391 *ptr++ = w->glwDrawingArea.redSize;
392 *ptr++ = GLX_GREEN_SIZE;
393 *ptr++ = w->glwDrawingArea.greenSize;
394 *ptr++ = GLX_BLUE_SIZE;
395 *ptr++ = w->glwDrawingArea.blueSize;
396 *ptr++ = GLX_ALPHA_SIZE;
397 *ptr++ = w->glwDrawingArea.alphaSize;
398 *ptr++ = GLX_DEPTH_SIZE;
399 *ptr++ = w->glwDrawingArea.depthSize;
400 *ptr++ = GLX_STENCIL_SIZE;
401 *ptr++ = w->glwDrawingArea.stencilSize;
402 *ptr++ = GLX_ACCUM_RED_SIZE;
403 *ptr++ = w->glwDrawingArea.accumRedSize;
404 *ptr++ = GLX_ACCUM_GREEN_SIZE;
405 *ptr++ = w->glwDrawingArea.accumGreenSize;
406 *ptr++ = GLX_ACCUM_BLUE_SIZE;
407 *ptr++ = w->glwDrawingArea.accumBlueSize;
408 *ptr++ = GLX_ACCUM_ALPHA_SIZE;
409 *ptr++ = w->glwDrawingArea.accumAlphaSize;
410 *ptr++ = None;
411 assert((ptr-w->glwDrawingArea.attribList)<ATTRIBLIST_SIZE);
412 }
413
414
415
416 /* Initialize the visualInfo based on the attribute list */
417 static void createVisualInfo(GLwDrawingAreaWidget w){
418 static XVisualInfo *visualInfo;
419 assert(w->glwDrawingArea.attribList);
420 w->glwDrawingArea.visualInfo=glXChooseVisual(XtDisplay(w),XScreenNumberOfScreen(XtScreen(w)),w->glwDrawingArea.attribList);
421 if(!w->glwDrawingArea.visualInfo) error((Widget)w,"requested visual not supported");
422 }
423
424
425
426 /* Initialize the colormap based on the visual info.
427 * This routine maintains a cache of visual-infos to colormaps. If two
428 * widgets share the same visual info, they share the same colormap.
429 * This function is called by the callProc of the colormap resource entry.
430 */
431 static void createColormap(GLwDrawingAreaWidget w,int offset,XrmValue *value){
432 static struct cmapCache { Visual *visual; Colormap cmap; } *cmapCache;
433 static int cacheEntries=0;
434 static int cacheMalloced=0;
435 register int i;
436
437 assert(w->glwDrawingArea.visualInfo);
438
439 /* see if we can find it in the cache */
440 for(i=0; i<cacheEntries; i++){
441 if(cmapCache[i].visual==w->glwDrawingArea.visualInfo->visual){
442 value->addr=(XtPointer)(&cmapCache[i].cmap);
443 return;
444 }
445 }
446
447 /* not in the cache, create a new entry */
448 if(cacheEntries >= cacheMalloced){
449 /* need to malloc a new one. Since we are likely to have only a
450 * few colormaps, we allocate one the first time, and double
451 * each subsequent time.
452 */
453 if(cacheMalloced==0){
454 cacheMalloced=1;
455 cmapCache=(struct cmapCache*)XtMalloc(sizeof(struct cmapCache));
456 }
457 else{
458 cacheMalloced<<=1;
459 cmapCache=(struct cmapCache*)XtRealloc((char*)cmapCache,sizeof(struct cmapCache)*cacheMalloced);
460 }
461 }
462
463 cmapCache[cacheEntries].cmap=XCreateColormap(XtDisplay(w),
464 RootWindow(XtDisplay(w),
465 w->glwDrawingArea.visualInfo->screen),
466 w->glwDrawingArea.visualInfo->visual,
467 AllocNone);
468 cmapCache[cacheEntries].visual=w->glwDrawingArea.visualInfo->visual;
469 value->addr=(XtPointer)(&cmapCache[cacheEntries++].cmap);
470 }
471
472
473
474 static void Initialize(GLwDrawingAreaWidget req,GLwDrawingAreaWidget neww,ArgList args,Cardinal *num_args){
475
476 /* fix size */
477 if(req->core.width==0) neww->core.width=100;
478 if(req->core.height==0) neww->core.width=100;
479
480 /* create the attribute list if needed */
481 neww->glwDrawingArea.myList=FALSE;
482 if(neww->glwDrawingArea.attribList==NULL){
483 neww->glwDrawingArea.myList=TRUE;
484 createAttribList(neww);
485 }
486
487 /* Gotta have it */
488 assert(neww->glwDrawingArea.attribList);
489
490 /* determine the visual info if needed */
491 neww->glwDrawingArea.myVisual=FALSE;
492 if(neww->glwDrawingArea.visualInfo==NULL){
493 neww->glwDrawingArea.myVisual=TRUE;
494 createVisualInfo(neww);
495 }
496
497 /* Gotta have that too */
498 assert(neww->glwDrawingArea.visualInfo);
499
500 neww->core.depth=neww->glwDrawingArea.visualInfo->depth;
501
502 /* Reobtain the colormap and colors in it using XtGetApplicationResources*/
503 XtGetApplicationResources((Widget)neww,neww,initializeResources,XtNumber(initializeResources),args,*num_args);
504
505 /* obtain the color resources if appropriate */
506 if(req->glwDrawingArea.allocateBackground){
507 XtGetApplicationResources((Widget)neww,neww,backgroundResources,XtNumber(backgroundResources),args,*num_args);
508 }
509
510 #ifdef __GLX_MOTIF
511 if(req->glwDrawingArea.allocateOtherColors){
512 XtGetApplicationResources((Widget)neww,neww,otherColorResources,XtNumber(otherColorResources),args,*num_args);
513 }
514 #endif
515 }
516
517
518
519 static void Realize(Widget w,Mask *valueMask,XSetWindowAttributes *attributes){
520 register GLwDrawingAreaWidget glw=(GLwDrawingAreaWidget)w;
521 GLwDrawingAreaCallbackStruct cb;
522 Widget parentShell;
523 Status status;
524 Window windows[2],*windowsReturn,*windowList;
525 int countReturn,i;
526
527 /* if we haven't requested that the background be both installed and
528 * allocated, don't install it.
529 */
530 if(!(glw->glwDrawingArea.installBackground && glw->glwDrawingArea.allocateBackground)){
531 *valueMask&=~CWBackPixel;
532 }
533
534 XtCreateWindow(w,(unsigned int)InputOutput,glw->glwDrawingArea.visualInfo->visual,*valueMask,attributes);
535
536 /* if appropriate, call XSetWMColormapWindows to install the colormap */
537 if(glw->glwDrawingArea.installColormap){
538
539 /* Get parent shell */
540 for(parentShell=XtParent(w); parentShell&&!XtIsShell(parentShell); parentShell=XtParent(parentShell));
541
542 if(parentShell && XtWindow(parentShell)){
543
544 /* check to see if there is already a property */
545 status=XGetWMColormapWindows(XtDisplay(parentShell),XtWindow(parentShell),&windowsReturn,&countReturn);
546
547 /* if no property, just create one */
548 if(!status){
549 windows[0]=XtWindow(w);
550 windows[1]=XtWindow(parentShell);
551 XSetWMColormapWindows(XtDisplay(parentShell),XtWindow(parentShell),windows,2);
552 }
553
554 /* there was a property, add myself to the beginning */
555 else{
556 windowList=(Window *)XtMalloc((sizeof(Window))*(countReturn+1));
557 windowList[0]=XtWindow(w);
558 for(i=0; i<countReturn; i++) windowList[i+1]=windowsReturn[i];
559 XSetWMColormapWindows(XtDisplay(parentShell),XtWindow(parentShell),windowList,countReturn+1);
560 XtFree((char*)windowList);
561 XtFree((char*)windowsReturn);
562 }
563 }
564 else{
565 warning(w,"Could not set colormap property on parent shell");
566 }
567 }
568
569 /* Invoke callbacks */
570 cb.reason=GLwCR_GINIT;
571 cb.event=NULL;
572 cb.width=glw->core.width;
573 cb.height=glw->core.height;
574 XtCallCallbackList((Widget)glw,glw->glwDrawingArea.ginitCallback,&cb);
575 }
576
577
578
579 static void Redraw(GLwDrawingAreaWidget w,XEvent *event,Region region){
580 GLwDrawingAreaCallbackStruct cb;
581 XtCallbackList cblist;
582 if(!XtIsRealized((Widget)w)) return;
583 cb.reason=GLwCR_EXPOSE;
584 cb.event=event;
585 cb.width=w->core.width;
586 cb.height=w->core.height;
587 XtCallCallbackList((Widget)w,w->glwDrawingArea.exposeCallback,&cb);
588 }
589
590
591
592 static void Resize(GLwDrawingAreaWidget glw){
593 GLwDrawingAreaCallbackStruct cb;
594 if(!XtIsRealized((Widget)glw)) return;
595 cb.reason=GLwCR_RESIZE;
596 cb.event=NULL;
597 cb.width=glw->core.width;
598 cb.height=glw->core.height;
599 XtCallCallbackList((Widget)glw,glw->glwDrawingArea.resizeCallback,&cb);
600 }
601
602
603
604 static void Destroy(GLwDrawingAreaWidget glw){
605 Window *windowsReturn;
606 Widget parentShell;
607 Status status;
608 int countReturn;
609 register int i;
610
611 if(glw->glwDrawingArea.myList && glw->glwDrawingArea.attribList){
612 XtFree((XtPointer)glw->glwDrawingArea.attribList);
613 }
614
615 if(glw->glwDrawingArea.myVisual && glw->glwDrawingArea.visualInfo){
616 XtFree((XtPointer)glw->glwDrawingArea.visualInfo);
617 }
618
619 /* if my colormap was installed, remove it */
620 if(glw->glwDrawingArea.installColormap){
621
622 /* Get parent shell */
623 for(parentShell=XtParent(glw); parentShell&&!XtIsShell(parentShell); parentShell=XtParent(parentShell));
624
625 if(parentShell && XtWindow(parentShell)){
626
627 /* make sure there is a property */
628 status=XGetWMColormapWindows(XtDisplay(parentShell),XtWindow(parentShell),&windowsReturn,&countReturn);
629
630 /* if no property, just return. If there was a property, continue */
631 if(status){
632
633 /* search for a match */
634 for(i=0; i<countReturn; i++){
635 if(windowsReturn[i]==XtWindow(glw)){
636
637 /* we found a match, now copy the rest down */
638 for(i++; i<countReturn; i++){ windowsReturn[i-1]=windowsReturn[i]; }
639
640 XSetWMColormapWindows(XtDisplay(parentShell),XtWindow(parentShell),windowsReturn,countReturn-1);
641 break;
642 }
643 }
644 XtFree((char *)windowsReturn);
645 }
646 }
647 }
648 }
649
650
651
652 /* Action routine for keyboard and mouse events */
653 static void glwInput(GLwDrawingAreaWidget glw,XEvent *event,String *params,Cardinal *numParams){
654 GLwDrawingAreaCallbackStruct cb;
655 cb.reason=GLwCR_INPUT;
656 cb.event=event;
657 cb.width=glw->core.width;
658 cb.height=glw->core.height;
659 XtCallCallbackList((Widget)glw,glw->glwDrawingArea.inputCallback,&cb);
660 }
661
662
663 #ifdef __GLX_MOTIF
664
665 /* Create routine */
666 Widget GLwCreateMDrawingArea(Widget parent, char *name,ArgList arglist,Cardinal argcount){
667 return XtCreateWidget(name,glwMDrawingAreaWidgetClass, parent, arglist,argcount);
668 }
669
670 #endif
671
672
673 #ifndef __GLX_MOTIF
674
675 /* Make context current */
676 void GLwDrawingAreaMakeCurrent(Widget w,GLXContext ctx){
677 glXMakeCurrent(XtDisplay(w),XtWindow(w),ctx);
678 }
679
680
681 /* Swap buffers convenience function */
682 void GLwDrawingAreaSwapBuffers(Widget w){
683 glXSwapBuffers(XtDisplay(w),XtWindow(w));
684 }
685
686 #endif