home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Linux / Divers / freedraft.tar.gz / freedraft.tar / FREEdraft-050298 / HACKV / fd_vbglcnv.cpp next >
C/C++ Source or Header  |  1998-05-01  |  33KB  |  1,247 lines

  1. //===============================================================
  2. // vbaseGLCanvas - a basic GL window canvas for drawing
  3. //
  4. // Copyright (C) 1995,1996  Bruce E. Wampler
  5. //
  6. // This file is part of the V C++ GUI Framework, and is covered
  7. // under the terms of the GNU Library General Public License,
  8. // Version 2. This library has NO WARRANTY. See the source file
  9. // vapp.cxx for more complete information about license terms.
  10. //===============================================================
  11.  
  12. #include <iostream.h>
  13.  
  14. // @@#include <v/vbglcnv.h>        // our header
  15. #include "fd_vbglcnv.h"        // our header
  16.  
  17. #include <v/vctlclrs.h>
  18.  
  19. extern "C"
  20. {
  21.  
  22. // OpenGL stuff here
  23.  
  24. #ifdef Motif
  25. #include <Xm/ScrollBar.h>
  26. #include <Xm/DrawingA.h>
  27. #define sbWidgetClass xmScrollBarWidgetClass
  28. #define sbThickness 15
  29. #else
  30. #include <X11/Xaw/Paned.h>
  31.  
  32. #ifdef USE3D
  33. #include <v/awscl3d.h>
  34. #define sbWidgetClass scrollbar3dWidgetClass
  35. #define sbThickness 15
  36. #else
  37. #include <X11/Xaw/Scrollbar.h>
  38. #define sbWidgetClass scrollbarWidgetClass
  39. #define sbThickness 10
  40. #endif
  41. #endif
  42.  
  43. #include <v/canvas.h>        // our own canvas widget
  44.  
  45. }
  46. #include <v/vapp.h>        // need access to the app
  47. #include <v/vwindow.h>        // we are part of a vWindow
  48.  
  49.     VCursor vBaseGLCanvasPane::_currentCursor = -1;    // for cursor
  50.  
  51. // Put the X dependent Cursor tables here...
  52.  
  53.    static unsigned int VtoXmap[] =
  54.       {
  55.     XC_X_cursor,  XC_top_left_arrow, XC_center_ptr, XC_crosshair,
  56.     XC_sb_h_double_arrow, XC_hand2, XC_xterm, XC_icon,
  57.     XC_sb_v_double_arrow, XC_pencil, XC_question_arrow,
  58.     XC_sizing, XC_watch, XC_X_cursor
  59.       };
  60.  
  61.     static Cursor XCursors[maxCursors+1];
  62.  
  63.     XVisualInfo* vBaseGLCanvasPane::_visinfo = 0;    // one time visual
  64.     int vBaseGLCanvasPane::_doubleBuffer = 0;        // if we have double buffering
  65.     unsigned int vBaseGLCanvasPane::_vGLmode = 0;
  66.  
  67. //================>>> vBaseGLCanvasPane::vBaseGLCanvasPane <<<========================
  68.   vBaseGLCanvasPane::vBaseGLCanvasPane(unsigned int vGLmode,
  69.    PaneType pt) : vPane(pt)
  70.   {
  71.     SysDebug(Constructor,"vBaseGLCanvasPane::vBaseGLCanvasPane() constructor\n")
  72.  
  73.     const unsigned int defGLmode = (vGL_RGB | vGL_DoubleBuffer);
  74.  
  75.     if (_currentCursor == -1)        // Do we need to create cursors?
  76.       {
  77.     _currentCursor = CA_None;
  78.     for (int i = 0 ; i <= maxCursors ; ++i)  // Create all cursors
  79.       {
  80.         XCursors[i] = XCreateFontCursor(theApp->display(),VtoXmap[i]);
  81.         // Get the fg and bg to make cursor match
  82.       }
  83.       }
  84.  
  85.     // One shot initialization of X Visual
  86.  
  87.     if (_visinfo == 0)    // Haven't gotten a visual yet
  88.       {
  89.     _vGLmode = ((vGLmode == vGL_Default) ? defGLmode : vGLmode);
  90.  
  91.     if (_vGLmode & vGL_Indexed)    // Indexed mode *********************
  92.       {
  93.         _visinfo = chooseIndexed(_vGLmode);
  94.         if (_visinfo == 0 && (_vGLmode & vGL_DoubleBuffer))
  95.           {
  96.         _vGLmode &= ~vGL_DoubleBuffer;    // try without double buffer
  97.         _visinfo = chooseIndexed(_vGLmode);
  98.           }
  99.       }
  100.     else                // RGB mode ********************
  101.       {
  102.         _visinfo = chooseRGB(_vGLmode);
  103.         if (_visinfo == 0 && (_vGLmode & vGL_Alpha))    // try to get rid of this
  104.           {
  105.         _vGLmode &= ~vGL_Alpha;    // zap the alpha plane
  106.         _visinfo = chooseRGB(_vGLmode);
  107.           }
  108.         if (_visinfo == 0 && (_vGLmode & vGL_DoubleBuffer))
  109.           {
  110.         _vGLmode &= ~vGL_DoubleBuffer;    // try without double buffer
  111.         _visinfo = chooseRGB(_vGLmode);
  112.           }
  113.       }
  114.  
  115.     if (_visinfo == 0)
  116.         XtAppError(theApp->appContext(), "Can't create Visual for GL.");
  117.     else
  118.         _doubleBuffer = (_vGLmode & vGL_DoubleBuffer);
  119.       }
  120.   }
  121.  
  122. //================>>> vBaseGLCanvasPane::~vBaseGLCanvasPane <<<===================
  123.   vBaseGLCanvasPane::~vBaseGLCanvasPane()
  124.   {
  125.     SysDebug(Destructor,"vBaseGLCanvasPane::~vBaseGLCanvasPane() destructor\n")
  126.   }
  127.  
  128. //==================>>> vBaseGLCanvasPane::chooseIndexed <<<=======================
  129.   XVisualInfo* vBaseGLCanvasPane::chooseIndexed(unsigned int glMode)
  130.   {
  131.  
  132.     static int bufSizeList[] = {16, 12, 8, 4, 2, 1, 0};
  133.     int list[32];
  134.     int n = 0;
  135.     XVisualInfo* vi;
  136.  
  137.     list[n++] = GLX_BUFFER_SIZE;
  138.     list[n++] = 1;        // we will dynamically change this
  139.     if (glMode & vGL_DoubleBuffer)
  140.       {
  141.     list[n++] = GLX_DOUBLEBUFFER;
  142.       }
  143.     if (glMode & vGL_Stereo)
  144.       {
  145.     list[n++] = GLX_STEREO;
  146.       }
  147.     if (glMode & vGL_Depth)
  148.       {
  149.     list[n++] = GLX_DEPTH_SIZE;
  150.     list[n++] = 1;
  151.       }
  152.     if (glMode & vGL_Stencil)
  153.       {
  154.     list[n++] = GLX_STENCIL_SIZE;
  155.     list[n++] = 1;
  156.       }
  157.     list[n] = (int) None; /* terminate list */
  158.  
  159.     /* glXChooseVisual specify GLX_BUFFER_SIZE prefers the
  160.     "smallest index buffer of at least the specified size".
  161.     This would be reasonable if GLUT allowed the user to
  162.     specify the required buffe size, but GLUT's display mode
  163.     is too simplistic (easy to use?). GLUT should try to find
  164.     the "largest".  So start with a large buffer size and
  165.     shrink until we find a matching one that exists. */
  166.  
  167.     for (int i = 0; bufSizeList[i]; i++)
  168.       {
  169.     // Assumes list[1] is where GLX_BUFFER_SIZE parameter is.
  170.     list[1] = bufSizeList[i];
  171.     vi = glXChooseVisual(theApp->display(), 
  172.         DefaultScreen(theApp->display()), list);
  173.     if (vi)
  174.       {
  175.         return vi;
  176.       }
  177.       }
  178.     return 0;
  179.   }
  180.  
  181. //==================>>> vBaseGLCanvasPane::chooseRGB <<<=======================
  182.   XVisualInfo* vBaseGLCanvasPane::chooseRGB(unsigned int glMode)
  183.   {
  184.  
  185.     int list[32];
  186.     int n = 0;
  187.     XVisualInfo* vi;
  188.  
  189.     list[n++] = GLX_RGBA;
  190.     list[n++] = GLX_RED_SIZE;
  191.     list[n++] = 1;
  192.     list[n++] = GLX_GREEN_SIZE;
  193.     list[n++] = 1;
  194.     list[n++] = GLX_BLUE_SIZE;
  195.     list[n++] = 1;
  196.     if (glMode & vGL_Alpha)
  197.       {
  198.     list[n++] = GLX_ALPHA_SIZE;
  199.     list[n++] = 1;
  200.       }
  201.  
  202.     if (glMode & vGL_DoubleBuffer)
  203.       {
  204.     list[n++] = GLX_DOUBLEBUFFER;
  205.       }
  206.     if (glMode & vGL_Stereo)
  207.       {
  208.     list[n++] = GLX_STEREO;
  209.       }
  210.     if (glMode & vGL_Depth)
  211.       {
  212.     list[n++] = GLX_DEPTH_SIZE;
  213.     list[n++] = 1;
  214.       }
  215.     if (glMode & vGL_Stencil)
  216.       {
  217.     list[n++] = GLX_STENCIL_SIZE;
  218.     list[n++] = 1;
  219.       }
  220.     if (glMode & vGL_Accum)
  221.       {
  222.     list[n++] = GLX_ACCUM_RED_SIZE;
  223.     list[n++] = 1;
  224.     list[n++] = GLX_ACCUM_GREEN_SIZE;
  225.     list[n++] = 1;
  226.     list[n++] = GLX_ACCUM_BLUE_SIZE;
  227.     list[n++] = 1;
  228.     if (glMode & vGL_Alpha)
  229.       {
  230.         list[n++] = GLX_ACCUM_ALPHA_SIZE;
  231.         list[n++] = 1;
  232.       }
  233.       }
  234.  
  235.     list[n] = (int) None; /* terminate list */
  236.  
  237.     vi = glXChooseVisual(theApp->display(), 
  238.         DefaultScreen(theApp->display()), list);
  239.     return vi;
  240.   }
  241.  
  242. //==================>>> vBaseGLCanvasPane::initialize <<<==========================
  243.   void vBaseGLCanvasPane::initialize(vWindow* pWindow, Widget pWidget)
  244.   {
  245.  
  246.     XtCallbackRec HscrollProcList[] =
  247.       {
  248.     { CHScrollProcCB, this },
  249.     { (XtCallbackProc) 0, (XtPointer) 0}
  250.       };
  251.     XtCallbackRec VscrollProcList[] =
  252.       {
  253.     { CVScrollProcCB, this },
  254.     { (XtCallbackProc) 0, (XtPointer) 0}
  255.       };
  256.  
  257. #ifndef Motif        // ATHENA
  258.     XtCallbackRec HjumpProcList[] =
  259.       {
  260.     { CHJumpProcCB, this },
  261.     { (XtCallbackProc) 0, (XtPointer) 0}
  262.       };
  263.  
  264.     XtCallbackRec VjumpProcList[] =
  265.       {
  266.     { CVJumpProcCB, this },
  267.     { (XtCallbackProc) 0, (XtPointer) 0}
  268.       };
  269. #endif
  270.  
  271.     _HScrlShown = 100;    //@@@@
  272.     _HScrlTop =  1;
  273.     _VScrlShown = 100;
  274.     _VScrlTop =  1;
  275.  
  276.      // now, build the menu items in the widget provided
  277.  
  278.     vPane::initialize(pWindow,pWidget);    // initialize base class
  279.  
  280.     _drawCanvas = XtVaCreateManagedWidget(
  281.     "vBaseGLCanvasPane",
  282.     canvasWidgetClass,    // widget class 
  283.     _baseW,            // parent widget
  284. #ifdef Motif
  285.     XmNallowResize,1,
  286. #else
  287.     XtNshowGrip, FALSE,
  288.     XtNallowResize,1,
  289. #endif
  290.     XtNhSpace, 1,
  291.     XtNvSpace, 1,
  292.     XtNheight,(_parentWin->_WinHeight)+16,
  293.     XtNwidth,(_parentWin->_WinWidth)+16,
  294.     NULL);            // argument list
  295.  
  296.      
  297.     // --------------------------------------------------------------
  298.     _hasFocus = 0;    // we don't start out with focus
  299.     _mouseDown = 0;    // mouse is not down
  300.  
  301.     Dimension curW, curH;
  302.  
  303.     _drawWindow = XtVaCreateManagedWidget(
  304.     "vCanvasDrawGL",        // widget name
  305.     glwDrawingAreaWidgetClass,    // widget class 
  306.     _drawCanvas,        // parent widget
  307.     GLwNvisualInfo, _visinfo,
  308.     XtNheight, _parentWin->_WinHeight,
  309.     XtNwidth, _parentWin->_WinWidth,
  310.     NULL);            // argument list
  311.  
  312.  
  313.     // --------------------------------------------------------------
  314.  
  315.  
  316. #ifdef Motif
  317.     _drawVScroll = XtVaCreateManagedWidget(
  318.     "vCanvasVScroll",                // name
  319.     sbWidgetClass,            // class
  320.     _drawCanvas,            // parent
  321.  
  322.     XmNvalueChangedCallback, VscrollProcList,    // callback for scrolling
  323.     XmNdecrementCallback, VscrollProcList,    // callback for scrolling
  324.     XmNincrementCallback, VscrollProcList,    // callback for scrolling
  325.     XmNpageDecrementCallback, VscrollProcList,    // callback for scrolling
  326.     XmNpageIncrementCallback, VscrollProcList,    // callback for scrolling
  327.  
  328.     XmNheight, _parentWin->_WinHeight,
  329.     XmNwidth, sbThickness,    // scrollbar param
  330.     XmNorientation,XmVERTICAL,
  331.     XmNmaximum,100,
  332.     NULL);
  333.  
  334.     _drawHScroll = XtVaCreateManagedWidget(
  335.     "vCanvasHScroll",
  336.     sbWidgetClass,
  337.     _drawCanvas,
  338.  
  339.     XmNvalueChangedCallback, HscrollProcList,    // callback for scrolling
  340.     XmNdecrementCallback, HscrollProcList,    // callback for scrolling
  341.     XmNincrementCallback, HscrollProcList,    // callback for scrolling
  342.     XmNpageDecrementCallback, HscrollProcList,    // callback for scrolling
  343.     XmNpageIncrementCallback, HscrollProcList,    // callback for scrolling
  344.  
  345.     XmNorientation,XmHORIZONTAL,
  346.     XmNheight, sbThickness,    // scrollbar param
  347.     XmNwidth, _parentWin->_WinWidth,
  348.     XmNmaximum,100,
  349.     NULL);
  350.  
  351. #else
  352.     _drawVScroll = XtVaCreateManagedWidget(
  353.     "vCanvasVScroll",                // name
  354.     sbWidgetClass,            // class
  355.     _drawCanvas,            // parent
  356.     XtNscrollProc, VscrollProcList,    // callback for scrolling
  357.     XtNjumpProc, VjumpProcList,    // callback for scrolling
  358.     XtNheight, _parentWin->_WinHeight,
  359.     XtNthickness, sbThickness,    // scrollbar param
  360. #ifdef USE3D
  361.     XtNbackground,_vControlFace,
  362.     XtNscrollbar3dBackground, _vControlBG,
  363. #endif
  364.     NULL);
  365.  
  366.     _drawHScroll = XtVaCreateManagedWidget(
  367.     "vCanvasHScroll",
  368.     sbWidgetClass,
  369.     _drawCanvas,
  370.     XtNscrollProc, HscrollProcList,    // callback for scrolling
  371.     XtNjumpProc, HjumpProcList,    // callback for scrolling
  372.     XtNorientation,XtorientHorizontal,    // scrollbar param
  373.     XtNthickness, sbThickness,    // scrollbar param
  374.     XtNwidth, _parentWin->_WinWidth,
  375. #ifdef USE3D
  376.     XtNbackground,_vControlFace,
  377.     XtNscrollbar3dBackground, _vControlBG,
  378. #endif
  379.     NULL);
  380.  
  381. #endif
  382.  
  383.  
  384.     // handle exposure events - requires redrawing
  385.  
  386.     XtAddEventHandler(_drawWindow, ExposureMask, 0,
  387.     CExposeEV,(XtPointer)this);
  388.  
  389.     // The graphics init event
  390.     XtAddCallback(_drawWindow,GLwNginitCallback, CgraphicsInit,(XtPointer)this);
  391.  
  392.     // get mouse events
  393.     XtAddEventHandler(_drawWindow, ButtonPressMask, 0,
  394.     CMouseDownEV,(XtPointer)this);
  395.     XtAddEventHandler(_drawWindow, PointerMotionMask, 0,
  396.     CMouseMoveEV,(XtPointer)this);
  397.     XtAddEventHandler(_drawWindow, ButtonReleaseMask, 0,
  398.     CMouseUpEV,(XtPointer)this);
  399.     XtAddEventHandler(_drawWindow, EnterWindowMask, 0,
  400.     CEnterEV,(XtPointer)this);
  401.     XtAddEventHandler(_drawWindow, LeaveWindowMask, 0,
  402.     CLeaveEV,(XtPointer)this);
  403.  
  404. #ifdef Motif
  405.     XtAddEventHandler(_drawWindow,KeyPressMask, 0,
  406.     CNVKeyInEV,(XtPointer)this);
  407. #endif
  408.  
  409.     XtAddCallback(_drawCanvas, XtNcallback, CchangeCB, (XtPointer)this);
  410.  
  411.     _HOn = _VOn = 0;            // both start out on
  412.  
  413.     SetHScroll(_HScrlShown, 0);    // initial values for scroll bar
  414.     SetVScroll(_VScrlShown, 0);
  415.  
  416.     XtUnmanageChild(_drawHScroll);    // Unmanage the widget
  417.     XtUnmanageChild(_drawVScroll);    // Unmanage the widget
  418.  
  419.     XtVaGetValues(_drawCanvas,        // get values for the draw canvas
  420.     XtNwidth, &curW,        // its new h and w
  421.     XtNheight, &curH,
  422.     NULL);
  423.  
  424.     _parentWin->_WinHeight = _height = curH;    // update the local stuff
  425.     _parentWin->_WinWidth = _width = curW;
  426.  
  427.     glxContext = 0;
  428.     _Drawable = 0;
  429.   }
  430.  
  431. //==================>>> vBaseGLCanvasPane::graphicsInit <<<========================
  432.   void vBaseGLCanvasPane::graphicsInit(void)
  433.   {
  434.     XVisualInfo *visinfo;
  435.  
  436.     // Perform only the most basic operations, including getting the context
  437.  
  438.     XtVaGetValues(_drawWindow, GLwNvisualInfo, &visinfo, NULL);
  439.  
  440.     glxContext = glXCreateContext(theApp->display(), visinfo,
  441.         0,                    // No sharing.
  442.         1);                    // Direct rendering if possible.
  443.  
  444.     vglMakeCurrent();
  445.   }
  446.  
  447. //==================>>> vBaseGLCanvasPane::graphicsInit <<<========================
  448.   void vBaseGLCanvasPane::vglFlush(void)
  449.   {
  450.     
  451.     if (_doubleBuffer)
  452.     glXSwapBuffers(theApp->display(), XtWindow(_drawWindow));
  453.     else
  454.     glFlush();
  455.  
  456.     /* Avoid indirect rendering latency from queuing. */
  457.     if (!glXIsDirect(theApp->display(), glxContext))
  458.     glFinish();
  459.  
  460.  
  461.   }
  462.  
  463. //==================>>> vBaseGLCanvasPane::ChangeCB <<<========================
  464.   void vBaseGLCanvasPane::ChangeCB(void)
  465.   {
  466.     Dimension curW, curH;
  467.  
  468.     XtVaGetValues(_drawWindow,        // get values for the draw canvas
  469.     XtNwidth, &curW,        // its new h and w
  470.     XtNheight, &curH,
  471.     NULL);
  472.  
  473.     if (curW > 0x7FFF)            // supposed to be unsigned, but
  474.     curW = 0;            // can get confused
  475.     if (curH > 0x7FFF)            // supposed to be unsigned, but
  476.     curH = 0;            // can get confused
  477.     _parentWin->_WinHeight = _height = curH;
  478.     _parentWin->_WinWidth = _width = curW;
  479.  
  480.     Resize((int)curH, (int)curW);    // Call the virtual function
  481.  
  482.   }
  483.  
  484. //====================>>> vBaseGLCanvasPane::ShowPane <<<======================
  485.   void vBaseGLCanvasPane::ShowPane(int OnOrOff)
  486.   {
  487.     if (OnOrOff)
  488.       {
  489.     XtManageChild(_drawCanvas);
  490.       }
  491.     else
  492.       {
  493.     XtUnmanageChild(_drawCanvas);
  494.       }
  495.   }
  496.  
  497. //=====================>>> vBaseGLCanvasPane::SetWidthHeight <<<============================
  498.   void vBaseGLCanvasPane::SetWidthHeight(int width, int height)
  499.   {
  500.     Dimension curW = width;
  501.     Dimension curH = height;
  502.  
  503.     _parentWin->_WinHeight = _height = curH;
  504.     _width = curW;
  505.     _parentWin->_WinWidth = _width + 16;
  506.  
  507.     XtVaSetValues(_baseW,            // parent widget
  508.     XtNwidth, curW+16,
  509.     NULL);
  510.    
  511.     XtVaSetValues(_drawCanvas,    // get values for the draw canvas
  512.     XtNwidth, curW,        // its new h and w
  513.     XtNheight, curH,
  514.     NULL);
  515.  
  516.   }
  517.  
  518. //------------------------- cursor Stuff ---------------------------------
  519. //=====================>>> vBaseGLCanvasPane::SetCursor <<<============================
  520.   void vBaseGLCanvasPane::SetCursor(VCursor id)
  521.   {
  522.     // Set to current cursor
  523.  
  524.     if (id < CA_None || id > VC_LAST)
  525.       {
  526.     SysDebug1(BadVals,"vBaseGLCanvasPane::SetCursor(id=%d)\n",id)
  527.     return;
  528.       }
  529.  
  530.     if ((unsigned)id == CA_None)        // special case
  531.     UnSetCursor();
  532.  
  533.     SysDebug1(WindowEvents,"vBaseGLCanvasPane::SetCursor(id=%d)\n",id)
  534.  
  535.     _currentCursor = id;
  536.  
  537.     XDefineCursor(theApp->display(), XtWindow(_drawWindow), XCursors[id]);
  538.   }
  539.  
  540. //=====================>>> vBaseGLCanvasPane::UnSetCursor <<<============================
  541.   void vBaseGLCanvasPane::UnSetCursor(void)
  542.   {
  543.     XUndefineCursor(theApp->display(), XtWindow(_drawWindow));
  544.     _currentCursor = CA_None;
  545.   }
  546.  
  547. //------------------------- Scrolling Stuff ---------------------------------
  548. //====================>>> vBaseGLCanvasPane::HJumpProcCB <<<=========================
  549.   void vBaseGLCanvasPane::HJumpProcCB(float fpercent, int motifValue)
  550.   {
  551.     // This is called with a fraction from 0 to 1.0 indicating
  552.     // how far the user has moved the scroll bar left or right.
  553.     // I can't get the Athena scroll widget to work how I want, so
  554.     // I'll live with how it seems to want to work: the shown
  555.     // fraction only is "correct" when it will all fit. The top
  556.     // will always be right - but 100 is at the bottom with the
  557.     // shown drawn out of the scroll box. Sigh...
  558.  
  559.     int shown = _HScrlShown;
  560.     int max_top = 100 - shown;
  561.     int top;
  562.  
  563. #ifdef Motif
  564.     int percent = (int)motifValue;
  565. #else
  566.     int percent = (int)(fpercent * 100.);
  567. #endif
  568.  
  569.     if (percent > max_top)
  570.       {
  571.     percent = max_top;
  572.       }
  573.  
  574.     if (max_top == 0)
  575.     top = 0;
  576.     else
  577.     top = (percent * 100) / max_top;
  578.  
  579.     if (top != _HScrlTop)    // actually changed things
  580.       {
  581.     HPage(shown, top);
  582.       }
  583.   }
  584.  
  585. //=======================>>> vBaseGLCanvasPane::HPage <<<============================
  586.   void vBaseGLCanvasPane::HPage(int Shown, int Top)
  587.   {
  588.     // This is the main way a user app gets scrolling events, and
  589.     // will usually override this guy to handle what is actually
  590.     // drawn in the canvas window.
  591.     // This should then be called to actually change the display.
  592.  
  593.     SysDebug2(WindowEvents,"vBaseGLCanvasPane::HPage(Shown: %d, Top: %d)\n",Shown, Top);
  594.  
  595.     SetHScroll(Shown,Top);
  596.   }
  597.  
  598. //=======================>>> vBaseGLCanvasPane::HScroll <<<==========================
  599.   void vBaseGLCanvasPane::HScroll(int step)
  600.   {
  601.     // This is the way the user app gets step events - either page or
  602.     // single step events. The default doesn't have to do anything.
  603.  
  604.     SysDebug1(WindowEvents,"vBaseGLCanvasPane::HScroll(%d)\n",step);
  605.  
  606.   }
  607.  
  608. //=====================>>> vBaseGLCanvasPane::ShowHScroll <<<=========================
  609.   void vBaseGLCanvasPane::ShowHScroll(int OnOff)
  610.   {
  611.     if (OnOff)            // Turn on
  612.       {
  613.     if (_HOn)        // Already on
  614.         return;
  615.     _HOn = 1;
  616.     XtManageChild(_drawHScroll);    // Unmanage the widget
  617.       }
  618.     else            // Turn off
  619.       {
  620.     if (!_HOn)        // Already off
  621.         return;
  622.     _HOn = 0;
  623.     XtUnmanageChild(_drawHScroll);    // Unmanage the widget
  624.       }
  625.  
  626.     Dimension curW, curH;
  627.  
  628.     XtVaGetValues(_drawWindow,        // get values for the draw canvas
  629.     XtNwidth, &curW,        // its new h and w
  630.     XtNheight, &curH,
  631.     NULL);
  632.  
  633.     _parentWin->_WinHeight = _height = curH;    // update the local stuff
  634.     _parentWin->_WinWidth = _width = curW;
  635.  
  636.     XClearArea(XtDisplay(_drawWindow), XtWindow(_drawWindow),
  637.     0, 0, _width, _height, 1);
  638.  
  639.   }
  640.  
  641. //=====================>>> vBaseGLCanvasPane::ShowVScroll <<<=========================
  642.   void vBaseGLCanvasPane::ShowVScroll(int OnOff)
  643.   {
  644.     if (OnOff)            // Turn on
  645.       {
  646.     if (_VOn)        // Already on
  647.         return;
  648.     _VOn = 1;
  649.     XtManageChild(_drawVScroll);    // Unmanage the widget
  650.       }
  651.     else            // Turn off
  652.       {
  653.     if (!_VOn)        // Already off
  654.         return;
  655.     _VOn = 0;
  656.     XtUnmanageChild(_drawVScroll);    // Unmanage the widget
  657.       }
  658.  
  659.     Dimension curW, curH;
  660.  
  661.     XtVaGetValues(_drawWindow,        // get values for the draw canvas
  662.     XtNwidth, &curW,        // its new h and w
  663.     XtNheight, &curH,
  664.     NULL);
  665.  
  666.     _parentWin->_WinHeight = _height = curH;    // update the local stuff
  667.     _parentWin->_WinWidth = _width = curW;
  668.     XClearArea(XtDisplay(_drawWindow), XtWindow(_drawWindow),
  669.     0, 0, _width, _height, 1);
  670.   }
  671.  
  672. //=====================>>> vBaseGLCanvasPane::SetHScroll <<<=========================
  673.   void vBaseGLCanvasPane::SetHScroll(int Shown, int Top)
  674.   {
  675.     // Make sure we are setting to valid values, and are changing things!
  676.  
  677.     if (Shown < 0 || Shown > 100 || Top < 0 || Top > 100)
  678.     return;
  679.  
  680.     _HScrlShown = Shown;
  681.     if (Shown < 5)        // it must be something that shows
  682.     _HScrlShown = 5;
  683.  
  684.     if (Shown == 100)        // Map top to space we have available
  685.     _HScrlTop = 0;
  686.     else
  687.     _HScrlTop = Top;
  688.  
  689.     DrawHScroll(_HScrlShown, _HScrlTop);
  690.  
  691.   }
  692.  
  693. //=====================>>> vBaseGLCanvasPane::DrawHScroll <<<========================
  694.   void vBaseGLCanvasPane::DrawHScroll(int Shown, int Top)
  695.   {
  696.     Arg args[3];        // Used to pass float value
  697.  
  698. #ifdef Motif
  699.     float shown = (float) Shown;
  700.     int iTop;
  701.  
  702.     if (Top == 0)
  703.     iTop = 0;
  704.     else if (Top == 100)
  705.     iTop = 100 - Shown;
  706.     else
  707.     iTop = (int) ((100. - shown)*((float)Top / 100.));
  708.  
  709.     XtVaSetValues(_drawHScroll,
  710.     XmNsliderSize,Shown,
  711.     XmNvalue,iTop,
  712.     NULL);
  713. #else
  714.     union
  715.       {
  716.     XtArgVal arg_value;
  717.     float float_value;
  718.       } shown_value, top_value;
  719.  
  720.     float shown = float(Shown) / 100.;
  721.     float top;
  722.  
  723.     if (Top == 0)
  724.     top = 0.;
  725.     else
  726.     top = (1. - shown)*(float(Top) / 100.);
  727.  
  728.     shown_value.float_value = shown;
  729.     top_value.float_value = top;
  730.  
  731.     if (sizeof (float) > sizeof (XtArgVal))
  732.       {
  733.     XtSetArg(args[0], XtNtopOfThumb, &top_value);
  734.     XtSetArg(args[1], XtNshown, &shown_value);
  735.       }
  736.     else
  737.       {
  738.     XtSetArg(args[0], XtNtopOfThumb, top_value.arg_value);
  739.     XtSetArg(args[1], XtNshown, shown_value.arg_value);
  740.       }
  741.  
  742.     XtSetValues(_drawHScroll, args, 2);        // change it!
  743. #endif
  744.  
  745.   }
  746.  
  747. //====================>>> vBaseGLCanvasPane::VJumpProcCB <<<=======================
  748.   void vBaseGLCanvasPane::VJumpProcCB(float fpercent, int motifValue)
  749.   {
  750.     // This code must be used with the 3D Widgets since they
  751.     // actually give the correct values -- we need to map
  752.     // the value supplied from the wiget to a 0 - 100 range
  753.     // required by the V specs.
  754.  
  755.  
  756.     int shown = _VScrlShown;
  757.     int max_top = 100 - shown;
  758.     int top;
  759.  
  760. #ifdef Motif
  761.     int percent = (int)motifValue;
  762. #else
  763.     int percent = (int)(fpercent * 100.);
  764. #endif
  765.  
  766.     if (percent > max_top)
  767.       {
  768.     percent = max_top;
  769.       }
  770.  
  771.     if (max_top == 0)
  772.     top = 0;
  773.     else
  774.     top = (percent * 100) / max_top;
  775.  
  776.     if (top != _VScrlTop)    // actually changed things
  777.       {
  778.     VPage(shown, top);
  779.       }
  780.   }
  781.  
  782. //========================>>> vBaseGLCanvasPane::VPage <<<===========================
  783.   void vBaseGLCanvasPane::VPage(int Shown, int Top)
  784.   {
  785.  
  786.     SysDebug2(WindowEvents,"vBaseGLCanvasPane::VPage(Shown: %d, Top: %d)\n",Shown, Top);
  787.  
  788.     SetVScroll(Shown,Top);
  789.  
  790.   }
  791.  
  792. //========================>>> vBaseGLCanvasPane::VScroll <<<=========================
  793.   void vBaseGLCanvasPane::VScroll(int step)
  794.   {
  795.     // This is the way the user app gets step events - either page or
  796.     // single step events. The default doesn't have to do anything.
  797.  
  798.     SysDebug1(WindowEvents,"vBaseGLCanvasPane::VScroll(%d)\n",step);
  799.  
  800.   }
  801.  
  802. //=====================>>> vBaseGLCanvasPane::GetVScroll <<<=========================
  803.   int vBaseGLCanvasPane::GetVScroll(int& Shown, int& Top)
  804.   {
  805.     Shown = _VScrlShown; Top = _VScrlTop;
  806.     return _VOn;
  807.   }
  808.  
  809. //=====================>>> vBaseGLCanvasPane::GetHScroll <<<=========================
  810.   int vBaseGLCanvasPane::GetHScroll(int& Shown, int& Top)
  811.   {
  812.     Shown = _HScrlShown; Top = _HScrlTop;
  813.     return _HOn;
  814.   }
  815.  
  816. //=====================>>> vBaseGLCanvasPane::SetVScroll <<<=========================
  817.   void vBaseGLCanvasPane::SetVScroll(int Shown, int Top)
  818.   {
  819.     // Make sure we are setting to valid values, and are changing things!
  820.  
  821.     if (Shown < 0 || Shown > 100 || Top < 0 || Top > 100)
  822.     return;
  823.  
  824.     _VScrlShown = Shown;
  825.     if (Shown < 5)
  826.     _VScrlShown = 5;
  827.  
  828.     if (Shown == 100)        // Map top to space we have available
  829.     _VScrlTop = 0;
  830.     else
  831.     _VScrlTop = Top;
  832.  
  833.     DrawVScroll(_VScrlShown, _VScrlTop);
  834.   }
  835.  
  836. //======================>>> vBaseGLCanvasPane::DrawVScroll <<<=======================
  837.   void vBaseGLCanvasPane::DrawVScroll(int Shown, int Top)
  838.   {
  839.  
  840. #ifdef Motif
  841.     float shown = (float) Shown;
  842.     int iTop;
  843.  
  844.     if (Top == 0)
  845.     iTop = 0;
  846.     else if (Top == 100)
  847.     iTop = 100 - Shown;
  848.     else
  849.     iTop = (int) ((100. - shown)*((float)Top / 100.));
  850.     
  851.     XtVaSetValues(_drawVScroll,
  852.     XmNsliderSize,Shown,
  853.     XmNvalue,iTop,
  854.     NULL);
  855. #else
  856.     Arg args[3];        // Used to pass float value
  857.  
  858.     union
  859.       {
  860.     XtArgVal arg_value;
  861.     float float_value;
  862.       } shown_value, top_value;
  863.  
  864.     float shown = float(Shown) / 100.;
  865.     float top;
  866.  
  867.  
  868.     if (Top == 0)
  869.     top = 0.;
  870.     else
  871.     top = (1. - shown)*(float(Top) / 100.);
  872.  
  873.     shown_value.float_value = shown;
  874.     top_value.float_value = top;
  875.  
  876.     if (sizeof (float) > sizeof (XtArgVal))
  877.       {
  878.     XtSetArg(args[0], XtNtopOfThumb, &top_value);
  879.     XtSetArg(args[1], XtNshown, &shown_value);
  880.       }
  881.     else
  882.       {
  883.     XtSetArg(args[0], XtNtopOfThumb, top_value.arg_value);
  884.     XtSetArg(args[1], XtNshown, shown_value.arg_value);
  885.       }
  886.  
  887.     XtSetValues(_drawVScroll, args, 2);        // change it!
  888. #endif
  889.  
  890.   }
  891.  
  892. //====================>>> vBaseGLCanvasPane::HScrollProcCB <<<=======================
  893.   void vBaseGLCanvasPane::HScrollProcCB(int position)
  894.   {
  895.     if (position  > 0)        // Scroll right a page
  896.     HScroll(1);
  897.     else
  898.     HScroll(-1);        // Scroll left a page
  899.   }
  900.  
  901. //====================>>> vBaseGLCanvasPane::VScrollProcCB <<<=======================
  902.   void vBaseGLCanvasPane::VScrollProcCB(int position)
  903.   {
  904.     if (position  > 0)        // scroll list down one page
  905.     VScroll(1);
  906.     else
  907.     VScroll(-1);        // scroll list up one page
  908.   }
  909.  
  910. //=====================>>> vBaseGLCanvasPane::ExposeEV <<<==========================
  911.   void vBaseGLCanvasPane::ExposeEV(int x, int y, int width, int height)
  912.   {
  913.     Redraw(x, y , width, height);
  914.   }
  915.  
  916. //=====================>>> vBaseGLCanvasPane::EnterFocus <<<========================
  917.   void vBaseGLCanvasPane::EnterFocus()
  918.   {
  919.     SysDebug(WindowEvents,"vBaseGLCanvasPane::EnterFocus()\n")
  920.     if ((unsigned)_currentCursor != CA_None)
  921.     SetCursor(_currentCursor);
  922.   }
  923.  
  924. //=====================>>> vBaseGLCanvasPane::EnterEV <<<==========================
  925.   void vBaseGLCanvasPane::EnterEV()
  926.   {
  927.     if (_hasFocus)        // don't double enter focus
  928.     return;
  929.     _hasFocus = 1;
  930.  
  931. #ifdef Motif
  932.     XmProcessTraversal(_drawWindow,XmTRAVERSE_CURRENT);    // Xm bug, call twice!
  933.     XmProcessTraversal(_drawWindow,XmTRAVERSE_CURRENT);
  934. #endif
  935.  
  936.     EnterFocus();        // call the virtual function
  937.   }
  938.  
  939. //=====================>>> vBaseGLCanvasPane::LeaveFocus <<<=======================
  940.   void vBaseGLCanvasPane::LeaveFocus()
  941.   {
  942.     SysDebug(WindowEvents,"vBaseGLCanvasPane::LeaveFocus()\n")
  943.   }
  944.  
  945. //=====================>>> vBaseGLCanvasPane::LeaveEV <<<==========================
  946.   void vBaseGLCanvasPane::LeaveEV()
  947.   {
  948.     if (!_hasFocus)        // don't double leave focus
  949.     return;
  950.     _hasFocus = 0;
  951.  
  952.     LeaveFocus();        // call the virtual function
  953.   }
  954.  
  955. //=====================>>> vBaseGLCanvasPane::MouseDownEV <<<=======================
  956.   void vBaseGLCanvasPane::MouseDownEV(int x, int y, int button)
  957.   {
  958.     // We track mouse down internally - X should do it, but
  959.     // sometimes it seems to get the mouse down withoud sending
  960.     // the event, making MouseMove not work as advertised.
  961.  
  962. cerr << "vBaseGLCanvasPans::MouseDownEV() " << endl;
  963.  
  964.     if (_mouseDown)
  965.     return;
  966.     _mouseDown = 1;
  967.     MouseDown(x,y,button);
  968.   }
  969.  
  970. //=====================>>> vBaseGLCanvasPane::MouseUpEV <<<=========================
  971.   void vBaseGLCanvasPane::MouseUpEV(int x, int y, int button)
  972.   {
  973. cerr << "vBaseGLCanvasPans::MouseUpEV() " << endl;
  974.  
  975.     if (!_mouseDown)
  976.     return;
  977.     _mouseDown = 0;
  978.     MouseUp(x,y,button);
  979.   }
  980.  
  981. //=====================>>> vBaseGLCanvasPane::MouseMoveEV <<<=======================
  982.   void vBaseGLCanvasPane::MouseMoveEV(int x, int y, int button)
  983.   {
  984.     if (_mouseDown && button != 0)        // only if down
  985.     MouseMove(x,y,button);
  986.     else
  987.       {
  988.     MouseMotion(x,y);
  989.       }
  990.   }
  991.  
  992. //=====================>>> vBaseGLCanvasPane::MouseDown <<<==========================
  993.   void vBaseGLCanvasPane::MouseDown(int x, int y, int button)
  994.   {
  995.     // Mouse events in vBaseGLCanvasPane are no-ops.
  996.  
  997. cerr << "vBaseGLCanvasPane::MouseDown()" << endl;
  998.  
  999.     SysDebug3(MouseEvents,"vBaseGLCanvasPane::MouseDown(x:%d,y:%d,btn:%d)\n",x,y,button)
  1000.   }
  1001.  
  1002. //=====================>>> vBaseGLCanvasPane::MouseUp <<<============================
  1003.   void vBaseGLCanvasPane::MouseUp(int x, int y, int button)
  1004.   {
  1005.     // Mouse events in vBaseGLCanvasPane are no-ops.
  1006.  
  1007.     SysDebug3(MouseEvents,"vBaseGLCanvasPane::MouseUp(x:%d,y:%d,btn:%d)\n",x,y,button)
  1008.   }
  1009.  
  1010. //=====================>>> vBaseGLCanvasPane::MouseMove <<<==========================
  1011.   void vBaseGLCanvasPane::MouseMove(int x, int y, int button)
  1012.   {
  1013.     // Mouse events in vBaseGLCanvasPane are no-ops.
  1014.  
  1015.     SysDebug3(MouseEvents,"vBaseGLCanvasPane::MouseMove(x:%d,y:%d,btn:%d)\n",x,y,button)
  1016.   }
  1017.  
  1018. //=======================>>> vBaseGLCanvasPane::Redraw <<<==========================
  1019.   void vBaseGLCanvasPane::Redraw(int x, int y, int width, int height)
  1020.   {
  1021.     // Redraw in vBaseGLCanvasPane is a no-op.
  1022.     
  1023. #ifdef vDEBUG        // Don't have a SysDebug4 macro, so do it by hand
  1024.     if (DebugState.WindowEvents && DebugState.System)
  1025.     fprintf(stderr,"vBaseGLCanvasPane::Redraw(x=%d, y=%d, w=%d, h=%d)\n",x,y,width,height);
  1026. #endif
  1027.  
  1028.   }
  1029.  
  1030. //=====================>>> vBaseGLCanvasPane::Resize <<<============================
  1031.   void vBaseGLCanvasPane::Resize(int newH, int newW)
  1032.   {
  1033.     // This is the routine the user will override to intercept size changes
  1034.  
  1035.     vglMakeCurrent();
  1036.     glXWaitX();
  1037.     glViewport(0,0,newW,newH);
  1038.  
  1039.   }
  1040.  
  1041. extern "C"
  1042. {
  1043. //==============================>>> CchangeCB <<<==============================
  1044.   void CchangeCB(Widget w, XtPointer client_data, XtPointer call_data)
  1045.   { 
  1046.     //    change callback
  1047.     //
  1048.     // client_data will have the this pointer of our object
  1049.     // call_data will point to a structure that handles
  1050.     // resize, scrollbars, and exposure
  1051.  
  1052.     ((vBaseGLCanvasPane*)client_data)->ChangeCB();
  1053.   }
  1054.  
  1055. //============================>>> CHJumpProcCB <<<=============================
  1056.   void CHJumpProcCB(Widget w, XtPointer This, XtPointer pc_ptr)
  1057.   {
  1058.     float percent = *(float*)pc_ptr;    // get the percent back
  1059.  
  1060.     ((vBaseGLCanvasPane*)This)->HJumpProcCB(percent,0);
  1061.   }
  1062.  
  1063. //============================>>> CHScollProcCB <<<=============================
  1064.   void CHScrollProcCB(Widget w, XtPointer This, XtPointer position)
  1065.   {
  1066. #ifdef Motif
  1067.     XmScrollBarCallbackStruct* cbp = (XmScrollBarCallbackStruct*)position;
  1068.     switch (cbp->reason)
  1069.       {
  1070.     case XmCR_DECREMENT:
  1071.     case XmCR_PAGE_DECREMENT:
  1072.       {
  1073.         ((vBaseGLCanvasPane*)This)->HScrollProcCB(-1);
  1074.         break;
  1075.       }
  1076.     case XmCR_INCREMENT:
  1077.     case XmCR_PAGE_INCREMENT:
  1078.       {
  1079.         ((vBaseGLCanvasPane*)This)->HScrollProcCB(1);
  1080.         break;
  1081.       }
  1082.     case XmCR_VALUE_CHANGED:
  1083.       {
  1084.         ((vBaseGLCanvasPane*)This)->HJumpProcCB(0.0, cbp->value);
  1085.         break;
  1086.       }
  1087.       }
  1088. #else
  1089.     int pos = (int)position;
  1090.     ((vBaseGLCanvasPane*)This)->HScrollProcCB(pos);
  1091. #endif
  1092.   }
  1093.  
  1094. //============================>>> CJumpProcCB <<<=============================
  1095.   void CVJumpProcCB(Widget w, XtPointer This, XtPointer pc_ptr)
  1096.   {
  1097.     float percent = *(float*)pc_ptr;    // get the percent back
  1098.  
  1099.     ((vBaseGLCanvasPane*)This)->VJumpProcCB(percent,0);
  1100.   }
  1101.  
  1102. //============================>>> CVScollProcCB <<<=============================
  1103.   void CVScrollProcCB(Widget w, XtPointer This, XtPointer position)
  1104.   {
  1105. #ifdef Motif
  1106.     XmScrollBarCallbackStruct* cbp = (XmScrollBarCallbackStruct*)position;
  1107.     switch (cbp->reason)
  1108.       {
  1109.     case XmCR_DECREMENT:
  1110.     case XmCR_PAGE_DECREMENT:
  1111.       {
  1112.         ((vBaseGLCanvasPane*)This)->VScrollProcCB(-1);
  1113.         break;
  1114.       }
  1115.     case XmCR_INCREMENT:
  1116.     case XmCR_PAGE_INCREMENT:
  1117.       {
  1118.         ((vBaseGLCanvasPane*)This)->VScrollProcCB(1);
  1119.         break;
  1120.       }
  1121.     case XmCR_VALUE_CHANGED:
  1122.       {
  1123.         ((vBaseGLCanvasPane*)This)->VJumpProcCB(0.0, cbp->value);
  1124.         break;
  1125.       }
  1126.       }
  1127. #else
  1128.     int pos = (int)position;
  1129.     ((vBaseGLCanvasPane*)This)->VScrollProcCB(pos);
  1130. #endif
  1131.   }
  1132.  
  1133. //==============================>>> CExposeEV <<<==============================
  1134.   void CExposeEV(Widget w, XtPointer client_data, XEvent* event, char *x)
  1135.   { 
  1136.  
  1137. #ifndef Motif        // ATHENA
  1138.  
  1139.     //    Exposure event
  1140.     //
  1141.     // client_data will have the this pointer of our object
  1142.  
  1143.     XExposeEvent* xp;
  1144.  
  1145.     xp = (XExposeEvent*)event;
  1146.  
  1147.     if (xp->count != 0)        // ignore all but last expose event
  1148.     return;
  1149.  
  1150.     ((vBaseGLCanvasPane*)client_data)->ExposeEV(xp->x, xp->y, xp->width, xp->height);
  1151. #endif
  1152.   }
  1153.  
  1154. //==============================>>> CgraphicsInit <<<=============================
  1155.   void CgraphicsInit(Widget w, XtPointer clientData, XtPointer call)
  1156.   {
  1157.     ((vBaseGLCanvasPane*)clientData)->graphicsInit();
  1158.   }
  1159.  
  1160. //==============================>>> CEnterEV <<<=============================
  1161.   void CEnterEV(Widget w, XtPointer client_data, XEvent* event, char *x)
  1162.   { 
  1163.     //    Enter event
  1164.     //
  1165.     // client_data will have the this pointer of our object
  1166.  
  1167.     ((vBaseGLCanvasPane*)client_data)->EnterEV();
  1168.   }
  1169.  
  1170. //==============================>>> CLeaveEV <<<==============================
  1171.   void CLeaveEV(Widget w, XtPointer client_data, XEvent* event, char *x)
  1172.   { 
  1173.     //    Leave event
  1174.     //
  1175.     // client_data will have the this pointer of our object
  1176.  
  1177.     ((vBaseGLCanvasPane*)client_data)->LeaveEV();
  1178.   }
  1179.  
  1180. //=============================>>> CMouseDownEV <<<============================
  1181.   void CMouseDownEV(Widget w, XtPointer client_data, XEvent* event, char *x)
  1182.   { 
  1183.     // Mouse down event
  1184. #ifndef Motif
  1185.     XButtonEvent* xp;
  1186.  
  1187.     xp = (XButtonEvent*)event;
  1188.  
  1189.     ((vBaseGLCanvasPane*)client_data)->MouseDownEV(xp->x, xp->y, xp->button);
  1190. #endif
  1191.   }
  1192.  
  1193. //==============================>>> CMouseUpEV <<<===========================
  1194.   void CMouseUpEV(Widget w, XtPointer client_data, XEvent* event, char *x)
  1195.   { 
  1196. #ifndef Motif
  1197.     // Mouse up event
  1198.     XButtonEvent* xp;
  1199.  
  1200.     xp = (XButtonEvent*)event;
  1201.  
  1202.     ((vBaseGLCanvasPane*)client_data)->MouseUpEV(xp->x, xp->y, xp->button);
  1203. #endif
  1204.   }
  1205.  
  1206. //============================>>> CMouseMoveEV <<<==========================
  1207.   void CMouseMoveEV(Widget w, XtPointer client_data, XEvent* event, char *x)
  1208.   { 
  1209. #ifndef Motif
  1210.     // Mouse down event
  1211.     XMotionEvent* xp;
  1212.  
  1213.     xp = (XMotionEvent*)event;
  1214.  
  1215.     int button = 0;        // assume button 1
  1216.  
  1217.     if (xp->state & Button1Mask)
  1218.     button = 1;
  1219.     else if (xp->state & Button2Mask)
  1220.     button = 2;
  1221.     else if (xp->state & Button3Mask)
  1222.     button = 3;
  1223.  
  1224.     ((vBaseGLCanvasPane*)client_data)->MouseMoveEV(xp->x, xp->y, button);
  1225. #endif
  1226.   }
  1227.  
  1228. //============================>>> CNVKeyInEV <<<==========================
  1229.   void CNVKeyInEV(Widget w, XtPointer client_data, XEvent* event, char *x)
  1230.   { 
  1231.     //    KeyPress Event Handler
  1232.     //
  1233.     // client_data will have the this pointer of our object
  1234.  
  1235. #ifdef Motif
  1236. fprintf(stderr,"CNVKeyin\n");
  1237. #else
  1238. //  XKeyPressedEvent *kp;
  1239. //
  1240. //  kp = (XKeyPressedEvent*)event;
  1241. //  vWindow* thisWindow = (vWindow*) client_data;    // get back this
  1242. //
  1243. //  thisWindow->KeyInEV(kp->keycode, kp->state);
  1244. #endif
  1245.   }
  1246. }
  1247.