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