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 */ 75static void createColormap(GLwDrawingAreaWidget w,int offset,XrmValue *value); 76static void Initialize(GLwDrawingAreaWidget req,GLwDrawingAreaWidget neww,ArgList args,Cardinal *num_args); 77static void Realize(Widget w,Mask *valueMask,XSetWindowAttributes *attributes); 78static void Redraw(GLwDrawingAreaWidget w,XEvent *event,Region region); 79static void Resize(GLwDrawingAreaWidget glw); 80static void Destroy(GLwDrawingAreaWidget glw); 81static void glwInput(GLwDrawingAreaWidget glw,XEvent *event,String *params,Cardinal *numParams); 82 83 84 85static 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 96static 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 117static 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 */ 230static 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*/ 241static 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 270static XtResource otherColorResources[] = { 271 {XmNforeground,XmCForeground,XmRPixel, 272 sizeof(Pixel),XtOffset(GLwDrawingAreaWidget,primitive.foreground), 273 XmRString,(XtPointer)"lightgrey"}, 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 293GLwDrawingAreaClassRec 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 346WidgetClass glwDrawingAreaWidgetClass=(WidgetClass)&glwDrawingAreaClassRec; 347 348 349 350static 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 361static 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 */ 374static 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 */ 417static void createVisualInfo(GLwDrawingAreaWidget w){ 418 assert(w->glwDrawingArea.attribList); 419 w->glwDrawingArea.visualInfo=glXChooseVisual(XtDisplay(w),XScreenNumberOfScreen(XtScreen(w)),w->glwDrawingArea.attribList); 420 if(!w->glwDrawingArea.visualInfo) error((Widget)w,"requested visual not supported"); 421 } 422 423 424 425/* Initialize the colormap based on the visual info. 426 * This routine maintains a cache of visual-infos to colormaps. If two 427 * widgets share the same visual info, they share the same colormap. 428 * This function is called by the callProc of the colormap resource entry. 429 */ 430static void createColormap(GLwDrawingAreaWidget w,int offset,XrmValue *value){ 431 static struct cmapCache { Visual *visual; Colormap cmap; } *cmapCache; 432 static int cacheEntries=0; 433 static int cacheMalloced=0; 434 register int i; 435 436 assert(w->glwDrawingArea.visualInfo); 437 438 /* see if we can find it in the cache */ 439 for(i=0; i<cacheEntries; i++){ 440 if(cmapCache[i].visual==w->glwDrawingArea.visualInfo->visual){ 441 value->addr=(XtPointer)(&cmapCache[i].cmap); 442 return; 443 } 444 } 445 446 /* not in the cache, create a new entry */ 447 if(cacheEntries >= cacheMalloced){ 448 /* need to malloc a new one. Since we are likely to have only a 449 * few colormaps, we allocate one the first time, and double 450 * each subsequent time. 451 */ 452 if(cacheMalloced==0){ 453 cacheMalloced=1; 454 cmapCache=(struct cmapCache*)XtMalloc(sizeof(struct cmapCache)); 455 } 456 else{ 457 cacheMalloced<<=1; 458 cmapCache=(struct cmapCache*)XtRealloc((char*)cmapCache,sizeof(struct cmapCache)*cacheMalloced); 459 } 460 } 461 462 cmapCache[cacheEntries].cmap=XCreateColormap(XtDisplay(w), 463 RootWindow(XtDisplay(w), 464 w->glwDrawingArea.visualInfo->screen), 465 w->glwDrawingArea.visualInfo->visual, 466 AllocNone); 467 cmapCache[cacheEntries].visual=w->glwDrawingArea.visualInfo->visual; 468 value->addr=(XtPointer)(&cmapCache[cacheEntries++].cmap); 469 } 470 471 472 473static void Initialize(GLwDrawingAreaWidget req,GLwDrawingAreaWidget neww,ArgList args,Cardinal *num_args){ 474 475 /* fix size */ 476 if(req->core.width==0) neww->core.width=100; 477 if(req->core.height==0) neww->core.width=100; 478 479 /* create the attribute list if needed */ 480 neww->glwDrawingArea.myList=FALSE; 481 if(neww->glwDrawingArea.attribList==NULL){ 482 neww->glwDrawingArea.myList=TRUE; 483 createAttribList(neww); 484 } 485 486 /* Gotta have it */ 487 assert(neww->glwDrawingArea.attribList); 488 489 /* determine the visual info if needed */ 490 neww->glwDrawingArea.myVisual=FALSE; 491 if(neww->glwDrawingArea.visualInfo==NULL){ 492 neww->glwDrawingArea.myVisual=TRUE; 493 createVisualInfo(neww); 494 } 495 496 /* Gotta have that too */ 497 assert(neww->glwDrawingArea.visualInfo); 498 499 neww->core.depth=neww->glwDrawingArea.visualInfo->depth; 500 501 /* Reobtain the colormap and colors in it using XtGetApplicationResources*/ 502 XtGetApplicationResources((Widget)neww,neww,initializeResources,XtNumber(initializeResources),args,*num_args); 503 504 /* obtain the color resources if appropriate */ 505 if(req->glwDrawingArea.allocateBackground){ 506 XtGetApplicationResources((Widget)neww,neww,backgroundResources,XtNumber(backgroundResources),args,*num_args); 507 } 508 509#ifdef __GLX_MOTIF 510 if(req->glwDrawingArea.allocateOtherColors){ 511 XtGetApplicationResources((Widget)neww,neww,otherColorResources,XtNumber(otherColorResources),args,*num_args); 512 } 513#endif 514 } 515 516 517 518static void Realize(Widget w,Mask *valueMask,XSetWindowAttributes *attributes){ 519 register GLwDrawingAreaWidget glw=(GLwDrawingAreaWidget)w; 520 GLwDrawingAreaCallbackStruct cb; 521 Widget parentShell; 522 Status status; 523 Window windows[2],*windowsReturn,*windowList; 524 int countReturn,i; 525 526 /* if we haven't requested that the background be both installed and 527 * allocated, don't install it. 528 */ 529 if(!(glw->glwDrawingArea.installBackground && glw->glwDrawingArea.allocateBackground)){ 530 *valueMask&=~CWBackPixel; 531 } 532 533 XtCreateWindow(w,(unsigned int)InputOutput,glw->glwDrawingArea.visualInfo->visual,*valueMask,attributes); 534 535 /* if appropriate, call XSetWMColormapWindows to install the colormap */ 536 if(glw->glwDrawingArea.installColormap){ 537 538 /* Get parent shell */ 539 for(parentShell=XtParent(w); parentShell&&!XtIsShell(parentShell); parentShell=XtParent(parentShell)); 540 541 if(parentShell && XtWindow(parentShell)){ 542 543 /* check to see if there is already a property */ 544 status=XGetWMColormapWindows(XtDisplay(parentShell),XtWindow(parentShell),&windowsReturn,&countReturn); 545 546 /* if no property, just create one */ 547 if(!status){ 548 windows[0]=XtWindow(w); 549 windows[1]=XtWindow(parentShell); 550 XSetWMColormapWindows(XtDisplay(parentShell),XtWindow(parentShell),windows,2); 551 } 552 553 /* there was a property, add myself to the beginning */ 554 else{ 555 windowList=(Window *)XtMalloc((sizeof(Window))*(countReturn+1)); 556 windowList[0]=XtWindow(w); 557 for(i=0; i<countReturn; i++) windowList[i+1]=windowsReturn[i]; 558 XSetWMColormapWindows(XtDisplay(parentShell),XtWindow(parentShell),windowList,countReturn+1); 559 XtFree((char*)windowList); 560 XtFree((char*)windowsReturn); 561 } 562 } 563 else{ 564 warning(w,"Could not set colormap property on parent shell"); 565 } 566 } 567 568 /* Invoke callbacks */ 569 cb.reason=GLwCR_GINIT; 570 cb.event=NULL; 571 cb.width=glw->core.width; 572 cb.height=glw->core.height; 573 XtCallCallbackList((Widget)glw,glw->glwDrawingArea.ginitCallback,&cb); 574 } 575 576 577 578static void Redraw(GLwDrawingAreaWidget w,XEvent *event,Region region){ 579 GLwDrawingAreaCallbackStruct cb; 580 if(!XtIsRealized((Widget)w)) return; 581 cb.reason=GLwCR_EXPOSE; 582 cb.event=event; 583 cb.width=w->core.width; 584 cb.height=w->core.height; 585 XtCallCallbackList((Widget)w,w->glwDrawingArea.exposeCallback,&cb); 586 } 587 588 589 590static void Resize(GLwDrawingAreaWidget glw){ 591 GLwDrawingAreaCallbackStruct cb; 592 if(!XtIsRealized((Widget)glw)) return; 593 cb.reason=GLwCR_RESIZE; 594 cb.event=NULL; 595 cb.width=glw->core.width; 596 cb.height=glw->core.height; 597 XtCallCallbackList((Widget)glw,glw->glwDrawingArea.resizeCallback,&cb); 598 } 599 600 601 602static void Destroy(GLwDrawingAreaWidget glw){ 603 Window *windowsReturn; 604 Widget parentShell; 605 Status status; 606 int countReturn; 607 register int i; 608 609 if(glw->glwDrawingArea.myList && glw->glwDrawingArea.attribList){ 610 XtFree((XtPointer)glw->glwDrawingArea.attribList); 611 } 612 613 if(glw->glwDrawingArea.myVisual && glw->glwDrawingArea.visualInfo){ 614 XtFree((XtPointer)glw->glwDrawingArea.visualInfo); 615 } 616 617 /* if my colormap was installed, remove it */ 618 if(glw->glwDrawingArea.installColormap){ 619 620 /* Get parent shell */ 621 for(parentShell=XtParent(glw); parentShell&&!XtIsShell(parentShell); parentShell=XtParent(parentShell)); 622 623 if(parentShell && XtWindow(parentShell)){ 624 625 /* make sure there is a property */ 626 status=XGetWMColormapWindows(XtDisplay(parentShell),XtWindow(parentShell),&windowsReturn,&countReturn); 627 628 /* if no property, just return. If there was a property, continue */ 629 if(status){ 630 631 /* search for a match */ 632 for(i=0; i<countReturn; i++){ 633 if(windowsReturn[i]==XtWindow(glw)){ 634 635 /* we found a match, now copy the rest down */ 636 for(i++; i<countReturn; i++){ windowsReturn[i-1]=windowsReturn[i]; } 637 638 XSetWMColormapWindows(XtDisplay(parentShell),XtWindow(parentShell),windowsReturn,countReturn-1); 639 break; 640 } 641 } 642 XtFree((char *)windowsReturn); 643 } 644 } 645 } 646 } 647 648 649 650/* Action routine for keyboard and mouse events */ 651static void glwInput(GLwDrawingAreaWidget glw,XEvent *event,String *params,Cardinal *numParams){ 652 GLwDrawingAreaCallbackStruct cb; 653 cb.reason=GLwCR_INPUT; 654 cb.event=event; 655 cb.width=glw->core.width; 656 cb.height=glw->core.height; 657 XtCallCallbackList((Widget)glw,glw->glwDrawingArea.inputCallback,&cb); 658 } 659 660 661#ifdef __GLX_MOTIF 662 663/* Create routine */ 664Widget GLwCreateMDrawingArea(Widget parent, char *name,ArgList arglist,Cardinal argcount){ 665 return XtCreateWidget(name,glwMDrawingAreaWidgetClass, parent, arglist,argcount); 666 } 667 668#endif 669 670 671#ifndef __GLX_MOTIF 672 673/* Make context current */ 674void GLwDrawingAreaMakeCurrent(Widget w,GLXContext ctx){ 675 glXMakeCurrent(XtDisplay(w),XtWindow(w),ctx); 676 } 677 678 679/* Swap buffers convenience function */ 680void GLwDrawingAreaSwapBuffers(Widget w){ 681 glXSwapBuffers(XtDisplay(w),XtWindow(w)); 682 } 683 684#endif 685