140dd5a57Smrg/*
240dd5a57Smrg * (c) Copyright 1993, Silicon Graphics, Inc.
340dd5a57Smrg * ALL RIGHTS RESERVED
440dd5a57Smrg * Permission to use, copy, modify, and distribute this software for
540dd5a57Smrg * any purpose and without fee is hereby granted, provided that the above
640dd5a57Smrg * copyright notice appear in all copies and that both the copyright notice
740dd5a57Smrg * and this permission notice appear in supporting documentation, and that
840dd5a57Smrg * the name of Silicon Graphics, Inc. not be used in advertising
940dd5a57Smrg * or publicity pertaining to distribution of the software without specific,
1040dd5a57Smrg * written prior permission.
1140dd5a57Smrg *
1240dd5a57Smrg * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
1340dd5a57Smrg * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
1440dd5a57Smrg * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
1540dd5a57Smrg * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
1640dd5a57Smrg * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
1740dd5a57Smrg * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
1840dd5a57Smrg * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
1940dd5a57Smrg * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
2040dd5a57Smrg * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
2140dd5a57Smrg * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
2240dd5a57Smrg * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
2340dd5a57Smrg * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
2440dd5a57Smrg *
2540dd5a57Smrg *
2640dd5a57Smrg * US Government Users Restricted Rights
2740dd5a57Smrg * Use, duplication, or disclosure by the Government is subject to
2840dd5a57Smrg * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
2940dd5a57Smrg * (c)(1)(ii) of the Rights in Technical Data and Computer Software
3040dd5a57Smrg * clause at DFARS 252.227-7013 and/or in similar or successor
3140dd5a57Smrg * clauses in the FAR or the DOD or NASA FAR Supplement.
3240dd5a57Smrg * Unpublished-- rights reserved under the copyright laws of the
3340dd5a57Smrg * United States.  Contractor/manufacturer is Silicon Graphics,
3440dd5a57Smrg * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
3540dd5a57Smrg *
3640dd5a57Smrg * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
3740dd5a57Smrg */
3840dd5a57Smrg
3940dd5a57Smrg/*
4040dd5a57Smrg *
4140dd5a57Smrg * This file has been slightly modified from the original for use with Mesa
4240dd5a57Smrg *
4340dd5a57Smrg *     Jeroen van der Zijp
4440dd5a57Smrg *
4540dd5a57Smrg *     jvz@cyberia.cfdrc.com
4640dd5a57Smrg *
4740dd5a57Smrg */
4840dd5a57Smrg#include <X11/IntrinsicP.h>
4940dd5a57Smrg#include <X11/StringDefs.h>
5040dd5a57Smrg#include <GL/glx.h>
5140dd5a57Smrg#include <GL/gl.h>
5240dd5a57Smrg#ifdef __GLX_MOTIF
5340dd5a57Smrg#include <Xm/PrimitiveP.h>
5440dd5a57Smrg#include "GLwMDrawAP.h"
5540dd5a57Smrg#else
5640dd5a57Smrg#include "GLwDrawAP.h"
5740dd5a57Smrg#endif
5840dd5a57Smrg#include <assert.h>
5940dd5a57Smrg#include <stdio.h>
6040dd5a57Smrg
6140dd5a57Smrg#ifdef __GLX_MOTIF
6240dd5a57Smrg#define GLwDrawingAreaWidget             GLwMDrawingAreaWidget
6340dd5a57Smrg#define GLwDrawingAreaClassRec           GLwMDrawingAreaClassRec
6440dd5a57Smrg#define glwDrawingAreaClassRec           glwMDrawingAreaClassRec
6540dd5a57Smrg#define glwDrawingAreaWidgetClass        glwMDrawingAreaWidgetClass
6640dd5a57Smrg#define GLwDrawingAreaRec                GLwMDrawingAreaRec
6740dd5a57Smrg#endif
6840dd5a57Smrg
6940dd5a57Smrg#define ATTRIBLIST_SIZE 32
7040dd5a57Smrg
7140dd5a57Smrg#define offset(field) XtOffset(GLwDrawingAreaWidget,glwDrawingArea.field)
7240dd5a57Smrg
7340dd5a57Smrg
7440dd5a57Smrg/* forward definitions */
7540dd5a57Smrgstatic void createColormap(GLwDrawingAreaWidget w,int offset,XrmValue *value);
7640dd5a57Smrgstatic void Initialize(GLwDrawingAreaWidget req,GLwDrawingAreaWidget neww,ArgList args,Cardinal *num_args);
7740dd5a57Smrgstatic void Realize(Widget w,Mask *valueMask,XSetWindowAttributes *attributes);
7840dd5a57Smrgstatic void Redraw(GLwDrawingAreaWidget w,XEvent *event,Region region);
7940dd5a57Smrgstatic void Resize(GLwDrawingAreaWidget glw);
8040dd5a57Smrgstatic void Destroy(GLwDrawingAreaWidget glw);
8140dd5a57Smrgstatic void glwInput(GLwDrawingAreaWidget glw,XEvent *event,String *params,Cardinal *numParams);
8240dd5a57Smrg
8340dd5a57Smrg
8440dd5a57Smrg
8540dd5a57Smrgstatic char defaultTranslations[] =
8640dd5a57Smrg#ifdef __GLX_MOTIF
8740dd5a57Smrg     "<Key>osfHelp:PrimitiveHelp() \n"
8840dd5a57Smrg#endif
8940dd5a57Smrg    "<KeyDown>:   glwInput() \n\
9040dd5a57Smrg     <KeyUp>:     glwInput() \n\
9140dd5a57Smrg     <BtnDown>:   glwInput() \n\
9240dd5a57Smrg     <BtnUp>:     glwInput() \n\
9340dd5a57Smrg     <BtnMotion>: glwInput() ";
9440dd5a57Smrg
9540dd5a57Smrg
9640dd5a57Smrgstatic XtActionsRec actions[] = {
9740dd5a57Smrg  {"glwInput",(XtActionProc)glwInput},                /* key or mouse input */
9840dd5a57Smrg  };
9940dd5a57Smrg
10040dd5a57Smrg
10140dd5a57Smrg/*
10240dd5a57Smrg * There is a bit of unusual handling of the resources here.
10340dd5a57Smrg * Because Xt insists on allocating the colormap resource when it is
10440dd5a57Smrg * processing the core resources (even if we redeclare the colormap
10540dd5a57Smrg * resource here, we need to do a little trick.  When Xt first allocates
10640dd5a57Smrg * the colormap, we allow it to allocate the default one, since we have
10740dd5a57Smrg * not yet determined the appropriate visual (which is determined from
10840dd5a57Smrg * resources parsed after the colormap).  We also let it allocate colors
10940dd5a57Smrg * in that default colormap.
11040dd5a57Smrg *
11140dd5a57Smrg * In the initialize proc we calculate the actual visual.  Then, we
11240dd5a57Smrg * reobtain the colormap resource using XtGetApplicationResources in
11340dd5a57Smrg * the initialize proc.  If requested, we also reallocate colors in
11440dd5a57Smrg * that colormap using the same method.
11540dd5a57Smrg */
11640dd5a57Smrg
11740dd5a57Smrgstatic XtResource resources[] = {
11840dd5a57Smrg  /* The GLX attributes.  Add any new attributes here */
11940dd5a57Smrg
12040dd5a57Smrg  {GLwNbufferSize, GLwCBufferSize, XtRInt, sizeof (int),
12140dd5a57Smrg       offset(bufferSize), XtRImmediate, (XtPointer) 0},
12240dd5a57Smrg
12340dd5a57Smrg  {GLwNlevel, GLwCLevel, XtRInt, sizeof (int),
12440dd5a57Smrg       offset(level), XtRImmediate, (XtPointer) 0},
12540dd5a57Smrg
12640dd5a57Smrg  {GLwNrgba, GLwCRgba, XtRBoolean, sizeof (Boolean),
12740dd5a57Smrg       offset(rgba), XtRImmediate, (XtPointer) FALSE},
12840dd5a57Smrg
12940dd5a57Smrg  {GLwNdoublebuffer, GLwCDoublebuffer, XtRBoolean, sizeof (Boolean),
13040dd5a57Smrg       offset(doublebuffer), XtRImmediate, (XtPointer) FALSE},
13140dd5a57Smrg
13240dd5a57Smrg  {GLwNstereo, GLwCStereo, XtRBoolean, sizeof (Boolean),
13340dd5a57Smrg       offset(stereo), XtRImmediate, (XtPointer) FALSE},
13440dd5a57Smrg
13540dd5a57Smrg  {GLwNauxBuffers, GLwCAuxBuffers, XtRInt, sizeof (int),
13640dd5a57Smrg       offset(auxBuffers), XtRImmediate, (XtPointer) 0},
13740dd5a57Smrg
13840dd5a57Smrg  {GLwNredSize, GLwCColorSize, XtRInt, sizeof (int),
13940dd5a57Smrg       offset(redSize), XtRImmediate, (XtPointer) 1},
14040dd5a57Smrg
14140dd5a57Smrg  {GLwNgreenSize, GLwCColorSize, XtRInt, sizeof (int),
14240dd5a57Smrg       offset(greenSize), XtRImmediate, (XtPointer) 1},
14340dd5a57Smrg
14440dd5a57Smrg  {GLwNblueSize, GLwCColorSize, XtRInt, sizeof (int),
14540dd5a57Smrg       offset(blueSize), XtRImmediate, (XtPointer) 1},
14640dd5a57Smrg
14740dd5a57Smrg  {GLwNalphaSize, GLwCAlphaSize, XtRInt, sizeof (int),
14840dd5a57Smrg       offset(alphaSize), XtRImmediate, (XtPointer) 0},
14940dd5a57Smrg
15040dd5a57Smrg  {GLwNdepthSize, GLwCDepthSize, XtRInt, sizeof (int),
15140dd5a57Smrg       offset(depthSize), XtRImmediate, (XtPointer) 0},
15240dd5a57Smrg
15340dd5a57Smrg  {GLwNstencilSize, GLwCStencilSize, XtRInt, sizeof (int),
15440dd5a57Smrg       offset(stencilSize), XtRImmediate, (XtPointer) 0},
15540dd5a57Smrg
15640dd5a57Smrg  {GLwNaccumRedSize, GLwCAccumColorSize, XtRInt, sizeof (int),
15740dd5a57Smrg       offset(accumRedSize), XtRImmediate, (XtPointer) 0},
15840dd5a57Smrg
15940dd5a57Smrg  {GLwNaccumGreenSize, GLwCAccumColorSize, XtRInt, sizeof (int),
16040dd5a57Smrg       offset(accumGreenSize), XtRImmediate, (XtPointer) 0},
16140dd5a57Smrg
16240dd5a57Smrg  {GLwNaccumBlueSize, GLwCAccumColorSize, XtRInt, sizeof (int),
16340dd5a57Smrg       offset(accumBlueSize), XtRImmediate, (XtPointer) 0},
16440dd5a57Smrg
16540dd5a57Smrg  {GLwNaccumAlphaSize, GLwCAccumAlphaSize, XtRInt, sizeof (int),
16640dd5a57Smrg       offset(accumAlphaSize), XtRImmediate, (XtPointer) 0},
16740dd5a57Smrg
16840dd5a57Smrg  /* the attribute list */
16940dd5a57Smrg  {GLwNattribList, GLwCAttribList, XtRPointer, sizeof(int *),
17040dd5a57Smrg       offset(attribList), XtRImmediate, (XtPointer) NULL},
17140dd5a57Smrg
17240dd5a57Smrg  /* the visual info */
17340dd5a57Smrg  {GLwNvisualInfo, GLwCVisualInfo, GLwRVisualInfo, sizeof (XVisualInfo *),
17440dd5a57Smrg       offset(visualInfo), XtRImmediate, (XtPointer) NULL},
17540dd5a57Smrg
17640dd5a57Smrg  /* miscellaneous resources */
17740dd5a57Smrg  {GLwNinstallColormap, GLwCInstallColormap, XtRBoolean, sizeof (Boolean),
17840dd5a57Smrg       offset(installColormap), XtRImmediate, (XtPointer) TRUE},
17940dd5a57Smrg
18040dd5a57Smrg  {GLwNallocateBackground, GLwCAllocateColors, XtRBoolean, sizeof (Boolean),
18140dd5a57Smrg       offset(allocateBackground), XtRImmediate, (XtPointer) FALSE},
18240dd5a57Smrg
18340dd5a57Smrg  {GLwNallocateOtherColors, GLwCAllocateColors, XtRBoolean, sizeof (Boolean),
18440dd5a57Smrg       offset(allocateOtherColors), XtRImmediate, (XtPointer) FALSE},
18540dd5a57Smrg
18640dd5a57Smrg  {GLwNinstallBackground, GLwCInstallBackground, XtRBoolean, sizeof (Boolean),
18740dd5a57Smrg       offset(installBackground), XtRImmediate, (XtPointer) TRUE},
18840dd5a57Smrg
18940dd5a57Smrg  {GLwNginitCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList),
19040dd5a57Smrg       offset(ginitCallback), XtRImmediate, (XtPointer) NULL},
19140dd5a57Smrg
19240dd5a57Smrg  {GLwNinputCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList),
19340dd5a57Smrg       offset(inputCallback), XtRImmediate, (XtPointer) NULL},
19440dd5a57Smrg
19540dd5a57Smrg  {GLwNresizeCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList),
19640dd5a57Smrg       offset(resizeCallback), XtRImmediate, (XtPointer) NULL},
19740dd5a57Smrg
19840dd5a57Smrg  {GLwNexposeCallback, GLwCCallback, XtRCallback, sizeof (XtCallbackList),
19940dd5a57Smrg       offset(exposeCallback), XtRImmediate, (XtPointer) NULL},
20040dd5a57Smrg
20140dd5a57Smrg  /* Changes to Motif primitive resources */
20240dd5a57Smrg#ifdef __GLX_MOTIF
20340dd5a57Smrg  {XmNtraversalOn, XmCTraversalOn, XmRBoolean, sizeof (Boolean),
20440dd5a57Smrg   XtOffset (GLwDrawingAreaWidget, primitive.traversal_on), XmRImmediate,
20540dd5a57Smrg   (XtPointer)FALSE},
20640dd5a57Smrg
20740dd5a57Smrg  /* highlighting is normally disabled, as when Motif tries to disable
20840dd5a57Smrg   * highlighting, it tries to reset the color back to the parent's
20940dd5a57Smrg   * background (usually Motif blue).  Unfortunately, that is in a
21040dd5a57Smrg   * different colormap, and doesn't work too well.
21140dd5a57Smrg   */
21240dd5a57Smrg  {XmNhighlightOnEnter, XmCHighlightOnEnter, XmRBoolean, sizeof (Boolean),
21340dd5a57Smrg   XtOffset (GLwDrawingAreaWidget, primitive.highlight_on_enter),
21440dd5a57Smrg   XmRImmediate, (XtPointer) FALSE},
21540dd5a57Smrg
21640dd5a57Smrg  {XmNhighlightThickness, XmCHighlightThickness, XmRHorizontalDimension,
21740dd5a57Smrg   sizeof (Dimension),
21840dd5a57Smrg   XtOffset (GLwDrawingAreaWidget, primitive.highlight_thickness),
21940dd5a57Smrg   XmRImmediate, (XtPointer) 0},
22040dd5a57Smrg#endif
22140dd5a57Smrg  };
22240dd5a57Smrg
22340dd5a57Smrg
22440dd5a57Smrg/*
22540dd5a57Smrg** The following resources are reobtained using XtGetApplicationResources
22640dd5a57Smrg** in the initialize proc.
22740dd5a57Smrg*/
22840dd5a57Smrg
22940dd5a57Smrg/* The colormap */
23040dd5a57Smrgstatic XtResource initializeResources[] = {
23140dd5a57Smrg  /* reobtain the colormap with the new visual */
23240dd5a57Smrg  {XtNcolormap, XtCColormap, XtRColormap, sizeof(Colormap),
23340dd5a57Smrg   XtOffset(GLwDrawingAreaWidget, core.colormap),
23440dd5a57Smrg   XtRCallProc,(XtPointer) createColormap},
23540dd5a57Smrg  };
23640dd5a57Smrg
23740dd5a57Smrg
23840dd5a57Smrg/* reallocate any colors we need in the new colormap */
23940dd5a57Smrg
24040dd5a57Smrg/* The background is obtained only if the allocateBackground resource is TRUE*/
24140dd5a57Smrgstatic XtResource backgroundResources[] = {
24240dd5a57Smrg#ifdef __GLX_MOTIF
24340dd5a57Smrg  {XmNbackground, XmCBackground,XmRPixel,
24440dd5a57Smrg   sizeof(Pixel),XtOffset(GLwDrawingAreaWidget,core.background_pixel),
24540dd5a57Smrg   XmRString,(XtPointer)"lightgrey"},
24640dd5a57Smrg   /*XmRCallProc,(XtPointer)_XmBackgroundColorDefault},*/
24740dd5a57Smrg
24840dd5a57Smrg  {XmNbackgroundPixmap,XmCPixmap,XmRXmBackgroundPixmap,
24940dd5a57Smrg   sizeof(Pixmap),XtOffset(GLwDrawingAreaWidget,core.background_pixmap),
25040dd5a57Smrg   XmRImmediate,(XtPointer)XmUNSPECIFIED_PIXMAP},
25140dd5a57Smrg
25240dd5a57Smrg#else
25340dd5a57Smrg  {XtNbackground,XtCBackground,XtRPixel,sizeof(Pixel),
25440dd5a57Smrg   XtOffset(GLwDrawingAreaWidget,core.background_pixel),
25540dd5a57Smrg   XtRString,(XtPointer)"lightgrey"},
25640dd5a57Smrg   /*XtRString,(XtPointer)"XtDefaultBackground"},*/
25740dd5a57Smrg
25840dd5a57Smrg  {XtNbackgroundPixmap, XtCPixmap, XtRPixmap, sizeof(Pixmap),
25940dd5a57Smrg   XtOffset(GLwDrawingAreaWidget,core.background_pixmap),
26040dd5a57Smrg   XtRImmediate,(XtPointer)XtUnspecifiedPixmap},
26140dd5a57Smrg#endif
26240dd5a57Smrg  };
26340dd5a57Smrg
26440dd5a57Smrg
26540dd5a57Smrg
26640dd5a57Smrg/* The other colors such as the foreground are allocated only if
26740dd5a57Smrg * allocateOtherColors are set.  These resources only exist in Motif.
26840dd5a57Smrg */
26940dd5a57Smrg#ifdef __GLX_MOTIF
27040dd5a57Smrgstatic XtResource otherColorResources[] = {
27140dd5a57Smrg  {XmNforeground,XmCForeground,XmRPixel,
27240dd5a57Smrg   sizeof(Pixel),XtOffset(GLwDrawingAreaWidget,primitive.foreground),
27340dd5a57Smrg   XmRString,(XtPointer)"lightgrey"},
27440dd5a57Smrg   /*XmRCallProc, (XtPointer) _XmForegroundColorDefault},*/
27540dd5a57Smrg
27640dd5a57Smrg  {XmNhighlightColor,XmCHighlightColor,XmRPixel,sizeof(Pixel),
27740dd5a57Smrg   XtOffset(GLwDrawingAreaWidget,primitive.highlight_color),
27840dd5a57Smrg   XmRString,(XtPointer)"lightgrey"},
27940dd5a57Smrg   /*XmRCallProc,(XtPointer)_XmHighlightColorDefault},*/
28040dd5a57Smrg
28140dd5a57Smrg  {XmNhighlightPixmap,XmCHighlightPixmap,XmRPrimHighlightPixmap,
28240dd5a57Smrg   sizeof(Pixmap),
28340dd5a57Smrg   XtOffset(GLwDrawingAreaWidget,primitive.highlight_pixmap),
28440dd5a57Smrg   XmRImmediate,(XtPointer)XmUNSPECIFIED_PIXMAP},
28540dd5a57Smrg   /*XmRCallProc,(XtPointer)_XmPrimitiveHighlightPixmapDefault},*/
28640dd5a57Smrg  };
28740dd5a57Smrg#endif
28840dd5a57Smrg
28940dd5a57Smrg
29040dd5a57Smrg#undef offset
29140dd5a57Smrg
29240dd5a57Smrg
29340dd5a57SmrgGLwDrawingAreaClassRec glwDrawingAreaClassRec = {
29440dd5a57Smrg  { /* core fields */
29540dd5a57Smrg#ifdef __GLX_MOTIF
29640dd5a57Smrg    /* superclass                */        (WidgetClass) &xmPrimitiveClassRec,
29740dd5a57Smrg    /* class_name                */        "GLwMDrawingArea",
29840dd5a57Smrg#else /* not __GLX_MOTIF */
29940dd5a57Smrg    /* superclass                */        (WidgetClass) &widgetClassRec,
30040dd5a57Smrg    /* class_name                */        "GLwDrawingArea",
30140dd5a57Smrg#endif /* __GLX_MOTIF */
30240dd5a57Smrg    /* widget_size               */        sizeof(GLwDrawingAreaRec),
30340dd5a57Smrg    /* class_initialize          */        NULL,
30440dd5a57Smrg    /* class_part_initialize     */        NULL,
30540dd5a57Smrg    /* class_inited              */        FALSE,
30640dd5a57Smrg    /* initialize                */        (XtInitProc) Initialize,
30740dd5a57Smrg    /* initialize_hook           */        NULL,
30840dd5a57Smrg    /* realize                   */        Realize,
30940dd5a57Smrg    /* actions                   */        actions,
31040dd5a57Smrg    /* num_actions               */        XtNumber(actions),
31140dd5a57Smrg    /* resources                 */        resources,
31240dd5a57Smrg    /* num_resources             */        XtNumber(resources),
31340dd5a57Smrg    /* xrm_class                 */        NULLQUARK,
31440dd5a57Smrg    /* compress_motion           */        TRUE,
31540dd5a57Smrg    /* compress_exposure         */        TRUE,
31640dd5a57Smrg    /* compress_enterleave       */        TRUE,
31740dd5a57Smrg    /* visible_interest          */        TRUE,
31840dd5a57Smrg    /* destroy                   */        (XtWidgetProc) Destroy,
31940dd5a57Smrg    /* resize                    */        (XtWidgetProc) Resize,
32040dd5a57Smrg    /* expose                    */        (XtExposeProc) Redraw,
32140dd5a57Smrg    /* set_values                */        NULL,
32240dd5a57Smrg    /* set_values_hook           */        NULL,
32340dd5a57Smrg    /* set_values_almost         */        XtInheritSetValuesAlmost,
32440dd5a57Smrg    /* get_values_hook           */        NULL,
32540dd5a57Smrg    /* accept_focus              */        NULL,
32640dd5a57Smrg    /* version                   */        XtVersion,
32740dd5a57Smrg    /* callback_private          */        NULL,
32840dd5a57Smrg    /* tm_table                  */        defaultTranslations,
32940dd5a57Smrg    /* query_geometry            */        XtInheritQueryGeometry,
33040dd5a57Smrg    /* display_accelerator       */        XtInheritDisplayAccelerator,
33140dd5a57Smrg    /* extension                 */        NULL
33240dd5a57Smrg  },
33340dd5a57Smrg#ifdef __GLX_MOTIF /* primitive resources */
33440dd5a57Smrg  {
33540dd5a57Smrg    /* border_highlight          */        XmInheritBorderHighlight,
33640dd5a57Smrg    /* border_unhighlight        */        XmInheritBorderUnhighlight,
33740dd5a57Smrg    /* translations              */        XtInheritTranslations,
33840dd5a57Smrg    /* arm_and_activate          */        NULL,
33940dd5a57Smrg    /* get_resources             */        NULL,
34040dd5a57Smrg    /* num get_resources         */        0,
34140dd5a57Smrg    /* extension                 */        NULL,
34240dd5a57Smrg  }
34340dd5a57Smrg#endif
34440dd5a57Smrg  };
34540dd5a57Smrg
34640dd5a57SmrgWidgetClass glwDrawingAreaWidgetClass=(WidgetClass)&glwDrawingAreaClassRec;
34740dd5a57Smrg
34840dd5a57Smrg
34940dd5a57Smrg
35040dd5a57Smrgstatic void error(Widget w,char* string){
35140dd5a57Smrg  char buf[100];
35240dd5a57Smrg#ifdef __GLX_MOTIF
35340dd5a57Smrg  sprintf(buf,"GLwMDrawingArea: %s\n",string);
35440dd5a57Smrg#else
35540dd5a57Smrg  sprintf(buf,"GLwDrawingArea: %s\n",string);
35640dd5a57Smrg#endif
35740dd5a57Smrg  XtAppError(XtWidgetToApplicationContext(w),buf);
35840dd5a57Smrg  }
35940dd5a57Smrg
36040dd5a57Smrg
36140dd5a57Smrgstatic void warning(Widget w,char* string){
36240dd5a57Smrg  char buf[100];
36340dd5a57Smrg#ifdef __GLX_MOTIF
36440dd5a57Smrg  sprintf (buf, "GLwMDraw: %s\n", string);
36540dd5a57Smrg#else
36640dd5a57Smrg  sprintf (buf, "GLwDraw: %s\n", string);
36740dd5a57Smrg#endif
36840dd5a57Smrg  XtAppWarning(XtWidgetToApplicationContext(w), buf);
36940dd5a57Smrg  }
37040dd5a57Smrg
37140dd5a57Smrg
37240dd5a57Smrg
37340dd5a57Smrg/* Initialize the attribList based on the attributes */
37440dd5a57Smrgstatic void createAttribList(GLwDrawingAreaWidget w){
37540dd5a57Smrg  int *ptr;
37640dd5a57Smrg  w->glwDrawingArea.attribList = (int*)XtMalloc(ATTRIBLIST_SIZE*sizeof(int));
37740dd5a57Smrg  if(!w->glwDrawingArea.attribList){
37840dd5a57Smrg    error((Widget)w,"Unable to allocate attribute list");
37940dd5a57Smrg    }
38040dd5a57Smrg  ptr = w->glwDrawingArea.attribList;
38140dd5a57Smrg  *ptr++ = GLX_BUFFER_SIZE;
38240dd5a57Smrg  *ptr++ = w->glwDrawingArea.bufferSize;
38340dd5a57Smrg  *ptr++ = GLX_LEVEL;
38440dd5a57Smrg  *ptr++ = w->glwDrawingArea.level;
38540dd5a57Smrg  if(w->glwDrawingArea.rgba) *ptr++ = GLX_RGBA;
38640dd5a57Smrg  if(w->glwDrawingArea.doublebuffer) *ptr++ = GLX_DOUBLEBUFFER;
38740dd5a57Smrg  if(w->glwDrawingArea.stereo) *ptr++ = GLX_STEREO;
38840dd5a57Smrg  *ptr++ = GLX_AUX_BUFFERS;
38940dd5a57Smrg  *ptr++ = w->glwDrawingArea.auxBuffers;
39040dd5a57Smrg  *ptr++ = GLX_RED_SIZE;
39140dd5a57Smrg  *ptr++ = w->glwDrawingArea.redSize;
39240dd5a57Smrg  *ptr++ = GLX_GREEN_SIZE;
39340dd5a57Smrg  *ptr++ = w->glwDrawingArea.greenSize;
39440dd5a57Smrg  *ptr++ = GLX_BLUE_SIZE;
39540dd5a57Smrg  *ptr++ = w->glwDrawingArea.blueSize;
39640dd5a57Smrg  *ptr++ = GLX_ALPHA_SIZE;
39740dd5a57Smrg  *ptr++ = w->glwDrawingArea.alphaSize;
39840dd5a57Smrg  *ptr++ = GLX_DEPTH_SIZE;
39940dd5a57Smrg  *ptr++ = w->glwDrawingArea.depthSize;
40040dd5a57Smrg  *ptr++ = GLX_STENCIL_SIZE;
40140dd5a57Smrg  *ptr++ = w->glwDrawingArea.stencilSize;
40240dd5a57Smrg  *ptr++ = GLX_ACCUM_RED_SIZE;
40340dd5a57Smrg  *ptr++ = w->glwDrawingArea.accumRedSize;
40440dd5a57Smrg  *ptr++ = GLX_ACCUM_GREEN_SIZE;
40540dd5a57Smrg  *ptr++ = w->glwDrawingArea.accumGreenSize;
40640dd5a57Smrg  *ptr++ = GLX_ACCUM_BLUE_SIZE;
40740dd5a57Smrg  *ptr++ = w->glwDrawingArea.accumBlueSize;
40840dd5a57Smrg  *ptr++ = GLX_ACCUM_ALPHA_SIZE;
40940dd5a57Smrg  *ptr++ = w->glwDrawingArea.accumAlphaSize;
41040dd5a57Smrg  *ptr++ = None;
41140dd5a57Smrg  assert((ptr-w->glwDrawingArea.attribList)<ATTRIBLIST_SIZE);
41240dd5a57Smrg  }
41340dd5a57Smrg
41440dd5a57Smrg
41540dd5a57Smrg
41640dd5a57Smrg/* Initialize the visualInfo based on the attribute list */
41740dd5a57Smrgstatic void createVisualInfo(GLwDrawingAreaWidget w){
41840dd5a57Smrg  assert(w->glwDrawingArea.attribList);
41940dd5a57Smrg  w->glwDrawingArea.visualInfo=glXChooseVisual(XtDisplay(w),XScreenNumberOfScreen(XtScreen(w)),w->glwDrawingArea.attribList);
42040dd5a57Smrg  if(!w->glwDrawingArea.visualInfo) error((Widget)w,"requested visual not supported");
42140dd5a57Smrg  }
42240dd5a57Smrg
42340dd5a57Smrg
42440dd5a57Smrg
42540dd5a57Smrg/* Initialize the colormap based on the visual info.
42640dd5a57Smrg * This routine maintains a cache of visual-infos to colormaps.  If two
42740dd5a57Smrg * widgets share the same visual info, they share the same colormap.
42840dd5a57Smrg * This function is called by the callProc of the colormap resource entry.
42940dd5a57Smrg */
43040dd5a57Smrgstatic void createColormap(GLwDrawingAreaWidget w,int offset,XrmValue *value){
43140dd5a57Smrg  static struct cmapCache { Visual *visual; Colormap cmap; } *cmapCache;
43240dd5a57Smrg  static int cacheEntries=0;
43340dd5a57Smrg  static int cacheMalloced=0;
43440dd5a57Smrg  register int i;
43540dd5a57Smrg
43640dd5a57Smrg  assert(w->glwDrawingArea.visualInfo);
43740dd5a57Smrg
43840dd5a57Smrg  /* see if we can find it in the cache */
43940dd5a57Smrg  for(i=0; i<cacheEntries; i++){
44040dd5a57Smrg    if(cmapCache[i].visual==w->glwDrawingArea.visualInfo->visual){
44140dd5a57Smrg      value->addr=(XtPointer)(&cmapCache[i].cmap);
44240dd5a57Smrg      return;
44340dd5a57Smrg      }
44440dd5a57Smrg    }
44540dd5a57Smrg
44640dd5a57Smrg  /* not in the cache, create a new entry */
44740dd5a57Smrg  if(cacheEntries >= cacheMalloced){
44840dd5a57Smrg    /* need to malloc a new one.  Since we are likely to have only a
44940dd5a57Smrg     * few colormaps, we allocate one the first time, and double
45040dd5a57Smrg     * each subsequent time.
45140dd5a57Smrg     */
45240dd5a57Smrg    if(cacheMalloced==0){
45340dd5a57Smrg      cacheMalloced=1;
45440dd5a57Smrg      cmapCache=(struct cmapCache*)XtMalloc(sizeof(struct cmapCache));
45540dd5a57Smrg      }
45640dd5a57Smrg    else{
45740dd5a57Smrg      cacheMalloced<<=1;
45840dd5a57Smrg      cmapCache=(struct cmapCache*)XtRealloc((char*)cmapCache,sizeof(struct cmapCache)*cacheMalloced);
45940dd5a57Smrg      }
46040dd5a57Smrg    }
46140dd5a57Smrg
46240dd5a57Smrg  cmapCache[cacheEntries].cmap=XCreateColormap(XtDisplay(w),
46340dd5a57Smrg                                               RootWindow(XtDisplay(w),
46440dd5a57Smrg                                               w->glwDrawingArea.visualInfo->screen),
46540dd5a57Smrg                                               w->glwDrawingArea.visualInfo->visual,
46640dd5a57Smrg                                               AllocNone);
46740dd5a57Smrg  cmapCache[cacheEntries].visual=w->glwDrawingArea.visualInfo->visual;
46840dd5a57Smrg  value->addr=(XtPointer)(&cmapCache[cacheEntries++].cmap);
46940dd5a57Smrg  }
47040dd5a57Smrg
47140dd5a57Smrg
47240dd5a57Smrg
47340dd5a57Smrgstatic void Initialize(GLwDrawingAreaWidget req,GLwDrawingAreaWidget neww,ArgList args,Cardinal *num_args){
47440dd5a57Smrg
47540dd5a57Smrg  /* fix size */
47640dd5a57Smrg  if(req->core.width==0) neww->core.width=100;
47740dd5a57Smrg  if(req->core.height==0) neww->core.width=100;
47840dd5a57Smrg
47940dd5a57Smrg  /* create the attribute list if needed */
48040dd5a57Smrg  neww->glwDrawingArea.myList=FALSE;
48140dd5a57Smrg  if(neww->glwDrawingArea.attribList==NULL){
48240dd5a57Smrg    neww->glwDrawingArea.myList=TRUE;
48340dd5a57Smrg    createAttribList(neww);
48440dd5a57Smrg    }
48540dd5a57Smrg
48640dd5a57Smrg  /* Gotta have it */
48740dd5a57Smrg  assert(neww->glwDrawingArea.attribList);
48840dd5a57Smrg
48940dd5a57Smrg  /* determine the visual info if needed */
49040dd5a57Smrg  neww->glwDrawingArea.myVisual=FALSE;
49140dd5a57Smrg  if(neww->glwDrawingArea.visualInfo==NULL){
49240dd5a57Smrg    neww->glwDrawingArea.myVisual=TRUE;
49340dd5a57Smrg    createVisualInfo(neww);
49440dd5a57Smrg    }
49540dd5a57Smrg
49640dd5a57Smrg  /* Gotta have that too */
49740dd5a57Smrg  assert(neww->glwDrawingArea.visualInfo);
49840dd5a57Smrg
49940dd5a57Smrg  neww->core.depth=neww->glwDrawingArea.visualInfo->depth;
50040dd5a57Smrg
50140dd5a57Smrg  /* Reobtain the colormap and colors in it using XtGetApplicationResources*/
50240dd5a57Smrg  XtGetApplicationResources((Widget)neww,neww,initializeResources,XtNumber(initializeResources),args,*num_args);
50340dd5a57Smrg
50440dd5a57Smrg  /* obtain the color resources if appropriate */
50540dd5a57Smrg  if(req->glwDrawingArea.allocateBackground){
50640dd5a57Smrg    XtGetApplicationResources((Widget)neww,neww,backgroundResources,XtNumber(backgroundResources),args,*num_args);
50740dd5a57Smrg    }
50840dd5a57Smrg
50940dd5a57Smrg#ifdef __GLX_MOTIF
51040dd5a57Smrg  if(req->glwDrawingArea.allocateOtherColors){
51140dd5a57Smrg    XtGetApplicationResources((Widget)neww,neww,otherColorResources,XtNumber(otherColorResources),args,*num_args);
51240dd5a57Smrg    }
51340dd5a57Smrg#endif
51440dd5a57Smrg  }
51540dd5a57Smrg
51640dd5a57Smrg
51740dd5a57Smrg
51840dd5a57Smrgstatic void Realize(Widget w,Mask *valueMask,XSetWindowAttributes *attributes){
51940dd5a57Smrg  register GLwDrawingAreaWidget glw=(GLwDrawingAreaWidget)w;
52040dd5a57Smrg  GLwDrawingAreaCallbackStruct cb;
52140dd5a57Smrg  Widget parentShell;
52240dd5a57Smrg  Status status;
52340dd5a57Smrg  Window windows[2],*windowsReturn,*windowList;
52440dd5a57Smrg  int countReturn,i;
52540dd5a57Smrg
52640dd5a57Smrg  /* if we haven't requested that the background be both installed and
52740dd5a57Smrg   * allocated, don't install it.
52840dd5a57Smrg   */
52940dd5a57Smrg  if(!(glw->glwDrawingArea.installBackground && glw->glwDrawingArea.allocateBackground)){
53040dd5a57Smrg    *valueMask&=~CWBackPixel;
53140dd5a57Smrg    }
53240dd5a57Smrg
53340dd5a57Smrg  XtCreateWindow(w,(unsigned int)InputOutput,glw->glwDrawingArea.visualInfo->visual,*valueMask,attributes);
53440dd5a57Smrg
53540dd5a57Smrg  /* if appropriate, call XSetWMColormapWindows to install the colormap */
53640dd5a57Smrg  if(glw->glwDrawingArea.installColormap){
53740dd5a57Smrg
53840dd5a57Smrg    /* Get parent shell */
53940dd5a57Smrg    for(parentShell=XtParent(w); parentShell&&!XtIsShell(parentShell); parentShell=XtParent(parentShell));
54040dd5a57Smrg
54140dd5a57Smrg    if(parentShell && XtWindow(parentShell)){
54240dd5a57Smrg
54340dd5a57Smrg      /* check to see if there is already a property */
54440dd5a57Smrg      status=XGetWMColormapWindows(XtDisplay(parentShell),XtWindow(parentShell),&windowsReturn,&countReturn);
54540dd5a57Smrg
54640dd5a57Smrg      /* if no property, just create one */
54740dd5a57Smrg      if(!status){
54840dd5a57Smrg        windows[0]=XtWindow(w);
54940dd5a57Smrg        windows[1]=XtWindow(parentShell);
55040dd5a57Smrg        XSetWMColormapWindows(XtDisplay(parentShell),XtWindow(parentShell),windows,2);
55140dd5a57Smrg        }
55240dd5a57Smrg
55340dd5a57Smrg      /* there was a property, add myself to the beginning */
55440dd5a57Smrg      else{
55540dd5a57Smrg        windowList=(Window *)XtMalloc((sizeof(Window))*(countReturn+1));
55640dd5a57Smrg        windowList[0]=XtWindow(w);
55740dd5a57Smrg        for(i=0; i<countReturn; i++) windowList[i+1]=windowsReturn[i];
55840dd5a57Smrg        XSetWMColormapWindows(XtDisplay(parentShell),XtWindow(parentShell),windowList,countReturn+1);
55940dd5a57Smrg        XtFree((char*)windowList);
56040dd5a57Smrg        XtFree((char*)windowsReturn);
56140dd5a57Smrg        }
56240dd5a57Smrg      }
56340dd5a57Smrg    else{
56440dd5a57Smrg      warning(w,"Could not set colormap property on parent shell");
56540dd5a57Smrg      }
56640dd5a57Smrg    }
56740dd5a57Smrg
56840dd5a57Smrg  /* Invoke callbacks */
56940dd5a57Smrg  cb.reason=GLwCR_GINIT;
57040dd5a57Smrg  cb.event=NULL;
57140dd5a57Smrg  cb.width=glw->core.width;
57240dd5a57Smrg  cb.height=glw->core.height;
57340dd5a57Smrg  XtCallCallbackList((Widget)glw,glw->glwDrawingArea.ginitCallback,&cb);
57440dd5a57Smrg  }
57540dd5a57Smrg
57640dd5a57Smrg
57740dd5a57Smrg
57840dd5a57Smrgstatic void Redraw(GLwDrawingAreaWidget w,XEvent *event,Region region){
57940dd5a57Smrg  GLwDrawingAreaCallbackStruct cb;
58040dd5a57Smrg  if(!XtIsRealized((Widget)w)) return;
58140dd5a57Smrg  cb.reason=GLwCR_EXPOSE;
58240dd5a57Smrg  cb.event=event;
58340dd5a57Smrg  cb.width=w->core.width;
58440dd5a57Smrg  cb.height=w->core.height;
58540dd5a57Smrg  XtCallCallbackList((Widget)w,w->glwDrawingArea.exposeCallback,&cb);
58640dd5a57Smrg  }
58740dd5a57Smrg
58840dd5a57Smrg
58940dd5a57Smrg
59040dd5a57Smrgstatic void Resize(GLwDrawingAreaWidget glw){
59140dd5a57Smrg  GLwDrawingAreaCallbackStruct cb;
59240dd5a57Smrg  if(!XtIsRealized((Widget)glw)) return;
59340dd5a57Smrg  cb.reason=GLwCR_RESIZE;
59440dd5a57Smrg  cb.event=NULL;
59540dd5a57Smrg  cb.width=glw->core.width;
59640dd5a57Smrg  cb.height=glw->core.height;
59740dd5a57Smrg  XtCallCallbackList((Widget)glw,glw->glwDrawingArea.resizeCallback,&cb);
59840dd5a57Smrg  }
59940dd5a57Smrg
60040dd5a57Smrg
60140dd5a57Smrg
60240dd5a57Smrgstatic void Destroy(GLwDrawingAreaWidget glw){
60340dd5a57Smrg  Window *windowsReturn;
60440dd5a57Smrg  Widget parentShell;
60540dd5a57Smrg  Status status;
60640dd5a57Smrg  int countReturn;
60740dd5a57Smrg  register int i;
60840dd5a57Smrg
60940dd5a57Smrg  if(glw->glwDrawingArea.myList && glw->glwDrawingArea.attribList){
61040dd5a57Smrg    XtFree((XtPointer)glw->glwDrawingArea.attribList);
61140dd5a57Smrg    }
61240dd5a57Smrg
61340dd5a57Smrg  if(glw->glwDrawingArea.myVisual && glw->glwDrawingArea.visualInfo){
61440dd5a57Smrg    XtFree((XtPointer)glw->glwDrawingArea.visualInfo);
61540dd5a57Smrg    }
61640dd5a57Smrg
61740dd5a57Smrg  /* if my colormap was installed, remove it */
61840dd5a57Smrg  if(glw->glwDrawingArea.installColormap){
61940dd5a57Smrg
62040dd5a57Smrg    /* Get parent shell */
62140dd5a57Smrg    for(parentShell=XtParent(glw); parentShell&&!XtIsShell(parentShell); parentShell=XtParent(parentShell));
62240dd5a57Smrg
62340dd5a57Smrg    if(parentShell && XtWindow(parentShell)){
62440dd5a57Smrg
62540dd5a57Smrg      /* make sure there is a property */
62640dd5a57Smrg      status=XGetWMColormapWindows(XtDisplay(parentShell),XtWindow(parentShell),&windowsReturn,&countReturn);
62740dd5a57Smrg
62840dd5a57Smrg      /* if no property, just return.  If there was a property, continue */
62940dd5a57Smrg      if(status){
63040dd5a57Smrg
63140dd5a57Smrg        /* search for a match */
63240dd5a57Smrg        for(i=0; i<countReturn; i++){
63340dd5a57Smrg          if(windowsReturn[i]==XtWindow(glw)){
63440dd5a57Smrg
63540dd5a57Smrg            /* we found a match, now copy the rest down */
63640dd5a57Smrg            for(i++; i<countReturn; i++){ windowsReturn[i-1]=windowsReturn[i]; }
63740dd5a57Smrg
63840dd5a57Smrg            XSetWMColormapWindows(XtDisplay(parentShell),XtWindow(parentShell),windowsReturn,countReturn-1);
63940dd5a57Smrg            break;
64040dd5a57Smrg            }
64140dd5a57Smrg          }
64240dd5a57Smrg        XtFree((char *)windowsReturn);
64340dd5a57Smrg        }
64440dd5a57Smrg      }
64540dd5a57Smrg    }
64640dd5a57Smrg  }
64740dd5a57Smrg
64840dd5a57Smrg
64940dd5a57Smrg
65040dd5a57Smrg/* Action routine for keyboard and mouse events */
65140dd5a57Smrgstatic void glwInput(GLwDrawingAreaWidget glw,XEvent *event,String *params,Cardinal *numParams){
65240dd5a57Smrg  GLwDrawingAreaCallbackStruct cb;
65340dd5a57Smrg  cb.reason=GLwCR_INPUT;
65440dd5a57Smrg  cb.event=event;
65540dd5a57Smrg  cb.width=glw->core.width;
65640dd5a57Smrg  cb.height=glw->core.height;
65740dd5a57Smrg  XtCallCallbackList((Widget)glw,glw->glwDrawingArea.inputCallback,&cb);
65840dd5a57Smrg  }
65940dd5a57Smrg
66040dd5a57Smrg
66140dd5a57Smrg#ifdef __GLX_MOTIF
66240dd5a57Smrg
66340dd5a57Smrg/* Create routine */
66440dd5a57SmrgWidget GLwCreateMDrawingArea(Widget parent, char *name,ArgList arglist,Cardinal argcount){
66540dd5a57Smrg  return XtCreateWidget(name,glwMDrawingAreaWidgetClass, parent, arglist,argcount);
66640dd5a57Smrg  }
66740dd5a57Smrg
66840dd5a57Smrg#endif
66940dd5a57Smrg
67040dd5a57Smrg
67140dd5a57Smrg#ifndef __GLX_MOTIF
67240dd5a57Smrg
67340dd5a57Smrg/* Make context current */
67440dd5a57Smrgvoid GLwDrawingAreaMakeCurrent(Widget w,GLXContext ctx){
67540dd5a57Smrg  glXMakeCurrent(XtDisplay(w),XtWindow(w),ctx);
67640dd5a57Smrg  }
67740dd5a57Smrg
67840dd5a57Smrg
67940dd5a57Smrg/* Swap buffers convenience function */
68040dd5a57Smrgvoid GLwDrawingAreaSwapBuffers(Widget w){
68140dd5a57Smrg  glXSwapBuffers(XtDisplay(w),XtWindow(w));
68240dd5a57Smrg  }
68340dd5a57Smrg
68440dd5a57Smrg#endif
685