home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pentlk11.zip / WRTSAMPL.C < prev    next >
C/C++ Source or Header  |  1994-01-13  |  78KB  |  1,627 lines

  1. /******************************************************************************
  2. *                                                                             *
  3. *  File Name   : WRTSAMPL.C                                                   *
  4. *                                                                             *
  5. *  Description : Example of WRT APIs                                          *
  6. *                                                                             *
  7. *  Function:  This is a sample of all Wrt APIs                                *
  8. *                                                                             *
  9. *  Copyright (C) 1993 IBM Corporation                                         *
  10. *                                                                             *
  11. *      DISCLAIMER OF WARRANTIES.  The following [enclosed] code is            *
  12. *      sample code created by IBM Corporation. This sample code is not        *
  13. *      part of any standard or IBM product and is provided to you solely      *
  14. *      for  the purpose of assisting you in the development of your           *
  15. *      applications.  The code is provided "AS IS", without                   *
  16. *      warranty of any kind.  IBM shall not be liable for any damages         *
  17. *      arising out of your use of the sample code, even if they have been     *
  18. *      advised of the possibility of such damages.                            * 
  19. *                                                                             *
  20. *******************************************************************************/
  21.  
  22. #define INCL_DOS
  23. #define INCL_PM
  24. #define INCL_GPI
  25. #define INCL_DOSMEMMGR
  26. #define  INCL_WINLOAD
  27. #define  INCL_DOSPROCESS
  28. #define  INCL_DOSSEMAPHORES
  29. #include <os2.h>
  30.  
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include <stdio.h>
  34. #include <process.h>
  35.  
  36. #include <penpm.h>
  37.  
  38. #define  WRTSAMPL_MAIN
  39. #include "wrtsampl.h"
  40. HWND       hwndClient;
  41. HWND       hwndFrame;
  42. HWND       hwndTFrame;
  43. HAB        habTMain;
  44. HWND       hwndT2Frame;          /* For the LiftOff thread. */
  45. HAB        habT2Main;            /* For the LiftOff thread. */
  46. ULONG      uMsgLeft = 0L;
  47. TID        tidLiftOffT;
  48. SHORT      sLastP = 0;           /* Last pressure of the point on the line */
  49. SHORT      sCurrP = 0;           /* Current pressure of the point on the line */
  50. LONG       lLastWidth = 1L;      /* Last width of line drawned */
  51.  
  52.  
  53. int main()
  54. {
  55.   HMQ   hmqMain;
  56.   QMSG  qmsgMain;
  57.   ULONG flCreate;
  58.  
  59.   /****************************************************************************/
  60.   /* Initialize PM for this program and create its PM message queue.          */
  61.   /****************************************************************************/
  62.   habMain = WinInitialize( (ULONG) NULL );
  63.   hmqMain = WinCreateMsgQueue( habMain, 0L );
  64.  
  65.  
  66.   /****************************************************************************/
  67.   /* Register "ClientWndProc" as the handling procedure for the "MyClient"    */
  68.   /* class window.                                                            */
  69.   /****************************************************************************/
  70.   WinRegisterClass( habMain,
  71.                     "MyClient",
  72.                     (PFNWP)ClientWndProc,
  73.                     CS_SIZEREDRAW,
  74.                     0UL );
  75.  
  76.   /****************************************************************************/
  77.   /* Tell PM that we want the standard frame window, but we will set the      */
  78.   /* the size and position the frame window.  This frame window will          */
  79.   /* surround a "MyClient" class client window.                               */
  80.   /****************************************************************************/
  81.     flCreate =  FCF_STANDARD & ~FCF_SHELLPOSITION;
  82.  
  83.   hwndFrame = WinCreateStdWindow( HWND_DESKTOP,
  84.                                   0L,
  85.                                   (PULONG)&flCreate,
  86.                                   "MyClient",
  87.                                   "wrtsampl",
  88.                                   0L,
  89.                                   (HMODULE)NULL,
  90.                                   ID_MAIN,
  91.                                   (PHWND)&hwndClient );
  92.  
  93.   /****************************************************************************/
  94.   /* Tell PM to display our window at the designated size and place           */
  95.   /****************************************************************************/
  96.   WinSetWindowPos( hwndFrame,
  97.                    HWND_TOP,
  98.                    50,50,550,380,
  99.                    SWP_SIZE | SWP_MOVE | SWP_ACTIVATE | SWP_SHOW );
  100.  
  101.  
  102.   /****************************************************************************/
  103.   /* This while loop waits for messages from PM.  If not a WM_CLOSE msg,      */
  104.   /* then we dispatch the message to our client window procedure.             */
  105.   /****************************************************************************/
  106.   while( WinGetMsg( habMain, &qmsgMain, (HWND) NULL, 0, 0 ) )
  107.   {
  108.     WinDispatchMsg( habMain, &qmsgMain );
  109.   }
  110.  
  111.   /****************************************************************************/
  112.   /* We will drop out of the while loop if the program receives a WM_CLOSE    */
  113.   /* message.  We must destroy our PM resources and return to the             */
  114.   /* invoking procedure.                                                      */
  115.   /****************************************************************************/
  116.   WinDestroyWindow( hwndFrame );
  117.   WinDestroyMsgQueue( hmqMain );
  118.   WinTerminate( habMain );
  119.   return( 0 );
  120. }
  121.  
  122. MRESULT EXPENTRY ClientWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  123. {
  124.   HPS               hpsPaint;
  125.   RECTL             rcClient;
  126.   ULONG             ulBuflen, ulOptions, flAuxData;
  127.   PSTROKEDATA       psdCurStroke;
  128.   ULONG             ulfButton;
  129.   APIRET            irc;               /* return code from Wrt APIs           */
  130.   ULONG             ulLocatorID;       /* variable for Locator IDs            */
  131.   WRTDISPLAYDEVINFO dcInfo;            /* Display capabilities structure      */
  132.   ULONG             ulDisplayID;       /* variable for Display IDs            */
  133.   WRTSYSTEMINFO     scInfo;            /* System capabilities structure       */
  134.   CHAR              cbuffer[MAXCBUFFER];
  135.   LONG              lvalue;            /* variable to hold system value       */
  136.   ULONG             ulid;
  137.   INT               i;
  138.   POINTL            ptlXY;
  139.   SHORT             *psCurrP;             /* pointer to get the pressure during WM_LIFTOFF */
  140.   static SWP        swpClient;
  141.   static HPOINTER   hptrClient;
  142.   static HPS        hpsClient;
  143.   static ULONG      MouMovCount = 0L;
  144.   static ULONG      MouseDivide =1L;
  145.   static BOOL       btoggle_mouse_sense = FALSE;
  146.   static BOOL       btoggle_strick_mous = FALSE;
  147.   static BOOL       bTouchDown = FALSE;
  148.   static BOOL       fButton1Down = FALSE;
  149.   static BOOL       fButton2Down = FALSE;
  150.  
  151.   switch( msg )
  152.   {
  153.     case WM_CREATE:
  154.     {
  155.       /************************************************************************/
  156.       /* The APIs being used in this procedure depend on the Pen for OS/2     */
  157.       /* subsystem being correctly initialized.  Thus we check to make sure   */
  158.       /* Pen for OS/2 is up before we do anything else.                       */
  159.       /************************************************************************/
  160.  
  161.       if( ( irc = WrtWaitActive ( WRT_IMMEDIATE_RETURN ) ) != WRT_NO_ERROR )
  162.       {
  163.         /**********************************************************************/
  164.         /* If Pen for OS/2 is NOT active then put up a message box and        */
  165.         /* terminate the program.                                             */
  166.         /**********************************************************************/
  167.         WinLoadString (
  168.                         habMain,
  169.                         NULLHANDLE,
  170.                         WRTERR_NOT_ACTIVE,
  171.                         MAXCBUFFER,
  172.                         cbuffer
  173.                         );
  174.         WinMessageBox( HWND_DESKTOP,
  175.                        hwnd,
  176.                        cbuffer,
  177.                        NULL, 1, MB_OK );
  178.         WinSendMsg ( hwnd, WM_CLOSE, NULL, NULL );
  179.         return( 0 );
  180.       } /* endif */
  181.       _beginthread ( BackThread,
  182.                            NULL,
  183.                            16384,
  184.                            NULL
  185.                          );
  186.       tidLiftOffT = _beginthread ( LiftOffThread,
  187.                            NULL,
  188.                            16384,
  189.                            NULL
  190.                          );
  191.       /* initialize structure size to save time */
  192.       apdExtra.cbStructSize = sizeof ( AUXPOINTDATA );
  193.       edInfo.cbStructSize = sizeof ( WRTEVENTDATA );
  194.  
  195.       /************************************************************************/
  196.       /* Initialize the ldiarr with all the locator information so it can be  */
  197.       /* used during WM_SENSOR_MOVE                                           */
  198.       /************************************************************************/
  199.       /************************************************************************/
  200.       /*  Find out how many locators the system has by querying the           */
  201.       /*  locator capabilities API with ulLocatorID = 0L.                     */
  202.       /*  The API will write the number of locator IDs in the system in       */
  203.       /*  the variable ulLocatorID.                                           */
  204.       /************************************************************************/
  205.       ulLocatorID = 0L;
  206.       irc = WrtQueryLocatorCaps ( &ulLocatorID, NULL );
  207.       if ( irc != WRT_NO_ERROR )
  208.       {
  209.         /**********************************************************************/
  210.         /* ERROR from API                                                     */
  211.         /**********************************************************************/
  212.         DisplayError ( hwnd, irc );
  213.       } else
  214.       {
  215.         /**********************************************************************/
  216.         /* Find out if locator are greater than zero                          */
  217.         /**********************************************************************/
  218.         if ( ulLocatorID == 0L ) 
  219.         {
  220.           WinMessageBox( HWND_DESKTOP,
  221.                           hwnd,
  222.                           "WrtQueryLocatorCaps return 0 locators",
  223.                           NULL, 1, MB_OK );
  224.         } else 
  225.         {
  226.           /********************************************************************/
  227.           /* Display the Capabilities for all the locator in the system       */
  228.           /********************************************************************/
  229.           for ( ; ulLocatorID > 0L; ulLocatorID-- )
  230.           {
  231.             /******************************************************************/
  232.             /* The cbStructureSize variable in the WRTLOCATORDEVINFO          */
  233.             /* structure must be initialize to the size of the                */
  234.             /* WRTLOCATORDEVINFO structure before querying the locator        */
  235.             /* capabilities.                                                  */
  236.             /******************************************************************/
  237.             ldiarr[ulLocatorID].cbStructSize = sizeof ( ldiarr[ulLocatorID] );
  238.  
  239.             /******************************************************************/
  240.             /* ulLocatorID variable has the ID of the locator that you        */
  241.             /* want to query                                                  */
  242.             /******************************************************************/
  243.             irc = WrtQueryLocatorCaps ( &ulLocatorID, &ldiarr[ulLocatorID] );
  244.  
  245.             if ( irc == WRT_NO_ERROR ) 
  246.             {
  247.               /****************************************************************/
  248.               /*  good return from API                                        */
  249.               /*  mark good locator array as good                             */
  250.               /****************************************************************/
  251.               blocarr[ulLocatorID] = TRUE;
  252.             } else 
  253.             {
  254.               /****************************************************************/
  255.               /* ERROR from API                                               */
  256.               /****************************************************************/
  257.               DisplayError ( hwnd, irc );
  258.             } /* endif */
  259.           } /* endfor */
  260.         } /* endif */
  261.       } /* endif */
  262.       
  263.       /************************************************************************/
  264.       /* post message to see what is active in the system                     */
  265.       /************************************************************************/
  266.       WinPostMsg(hwnd, ID_DISP, NULL, NULL);
  267.  
  268.       /************************************************************************/
  269.       /* Load the "Blob" pointer we are going to use instead of the system    */
  270.       /* pointer when the pointer is over the client area.                    */
  271.       /************************************************************************/
  272.       hptrClient = WinLoadPointer( HWND_DESKTOP, 0L, PTR_BLOB );
  273.  
  274.       break;
  275.     }
  276.  
  277.     /**************************************************************************/
  278.     /* Pen for OS/2 messages                                                  */
  279.     /**************************************************************************/
  280.     case WM_TOUCHDOWN:
  281.     {
  282.       /************************************************************************/
  283.       /* Ensure that the client window is active.                             */
  284.       /************************************************************************/
  285.       WinSetActiveWindow( HWND_DESKTOP, hwnd );
  286.  
  287.       /************************************************************************/
  288.       /* We are going to keep a count of mouse moves that make will make      */
  289.       /* up this stroke.                                                      */
  290.       /************************************************************************/
  291.       MouMovCount  = 0L;
  292.  
  293.       /************************************************************************/
  294.       /* Set the lLastWidth to 1 pel wide to start with                       */
  295.       /************************************************************************/
  296.       lLastWidth = 1L;
  297.  
  298.       /************************************************************************/
  299.       /* Tell PM that ALL pointer messages should come to this window.        */
  300.       /************************************************************************/
  301.       WinSetCapture( HWND_DESKTOP, hwnd ) ;
  302.  
  303.       /************************************************************************/
  304.       /* Determine where on the DESKTOP the client window is currently.       */
  305.       /* This will be used to make sure we do not draw strokes that go        */
  306.       /* outside our client window.                                           */
  307.       /************************************************************************/
  308.       WinQueryWindowPos( hwnd, &swpClient );
  309.  
  310.       /************************************************************************/
  311.       /* Get event data pointer from mp2                                      */
  312.       /************************************************************************/
  313.       pedInfo = (PWRTEVENTDATA)PVOIDFROMMP ( mp2 );
  314.  
  315.       /************************************************************************/
  316.       /* Check to see if we have the LOCATOR information set up               */
  317.       /************************************************************************/
  318.       if ( blocarr[pedInfo->ulLocatorID] == TRUE ) 
  319.       {
  320.         ulocindx = pedInfo->ulLocatorID;
  321.  
  322.         /* Set the MouseDivide variable */
  323.           switch ( ldiarr[ulocindx].ulLocatorType )  
  324.         {                                            
  325.            case LT_PEN:                              
  326.                    MouseDivide = (ldiarr[ulocindx].ulValidityFlags & ADF_SCREENZ) ? 4L : 1L ;
  327.                    break;                            
  328.            case LT_TOUCH:                            
  329.            case LT_MOUSE:                            
  330.            case LT_OTHER:                            
  331.                    MouseDivide = 1L;                 
  332.                    break;                            
  333.         } /* endswitch */
  334.       } /* endif */
  335.       /************************************************************************/
  336.       /* Mask out the mouse button from the EventStatus flag.                 */
  337.       /************************************************************************/
  338.       ulfButton = pedInfo->flEventStatus & WRT_MBUTTON_MASK;
  339.  
  340.       if( ulfButton & WRT_MBUTTON2 )
  341.       {
  342.         /**********************************************************************/
  343.         /* Set the Mouse state to mouse button 2 down                         */
  344.         /**********************************************************************/
  345.         fButton1Down  = FALSE;
  346.         fButton2Down  = TRUE;
  347.       }
  348.       else
  349.       {
  350.         /**********************************************************************/
  351.         /* Set the Mouse state to mouse button 1 down                         */
  352.         /**********************************************************************/
  353.         fButton1Down  = TRUE;
  354.         fButton2Down  = FALSE;
  355.       }
  356.  
  357.       hpsClient = WinGetPS ( hwnd );
  358.  
  359.       /************************************************************************/
  360.       /* Get the mouse coordinates                                            */
  361.       /************************************************************************/
  362.       ptlXY.x = (SHORT)MOUSEMSG(&msg)->x ;
  363.       ptlXY.y = (SHORT)MOUSEMSG(&msg)->y ;
  364.  
  365.       /**************************************************************************/
  366.       /* if fButton1Down is set to zero it means that fButton2Down is to to one */
  367.       /* and we are in erase mode. Set the ink to the background to erase       */
  368.       /**************************************************************************/
  369.       GpiSetColor( hpsClient, fButton1Down ? CLR_NEUTRAL : CLR_BACKGROUND );
  370.  
  371.       GpiMove( hpsClient, &ptlXY );
  372.  
  373.       /************************************************************************/
  374.       /* Tell the Pen for OS/2 subsystem that we want                         */
  375.       /* 1) no button down message TDN_INFINITE,                              */
  376.       /* 2) as many mouse moves message as possible TDN_HIFREQ_MOUSEMOVE, and */
  377.       /* 2A)as many sensor move messages as possible TDN_SENSOR_MOVE          */
  378.       /* 3) that we will take care of inking any strokes TDN_NO_INK_STROKE.   */
  379.       /************************************************************************/
  380.       /************************************************************************/
  381.       /*  Find out if mouse move is on or sense move is on                    */
  382.       /************************************************************************/
  383.       if ( btoggle_mouse_sense ) 
  384.       {
  385.        return((MRESULT) ( TDN_INFINITE | TDN_NO_INK_STROKE |
  386.                          TDN_SENSOR_MOVE ));
  387.       } else 
  388.       {
  389.         return((MRESULT) (TDN_INFINITE | TDN_NO_INK_STROKE |
  390.                           TDN_HIFREQ_MOUSEMOVE ));
  391.       } /* endif */
  392.     }
  393.  
  394.     /**************************************************************************/
  395.     /* Pen for OS/2 message                                                   */
  396.     /**************************************************************************/
  397.     case WM_LIFTOFF:
  398.     {
  399.       /************************************************************************/
  400.       /* Tell PM to resume routing pointer messages to the windows that       */
  401.       /* the pointer goes over.                                               */
  402.       /************************************************************************/
  403.       WinSetCapture( HWND_DESKTOP, (HWND) NULL ) ;
  404.  
  405.       /************************************************************************/
  406.       /* Get the WRT event Data to see if the STROKE DATA is valid            */
  407.       /************************************************************************/
  408.       pedInfo = (PWRTEVENTDATA)PVOIDFROMMP ( mp2 );
  409.  
  410.       if( ( pedInfo->flEventStatus & WRT_STROKE_AVAIL ) )
  411.       {
  412.         /* Post message to display the information of the EVENT data structure */
  413.         if ( btoggle_event )
  414.         {
  415.           WinPostMsg ( hwndTFrame, ID_TEVENT, NULL, NULL );
  416.         } /* endif */
  417.  
  418.         /************************************************************************/
  419.         /* There is stroke data, query the size of the data, when put in        */
  420.         /* a POINTL array of screen coordinates.                               */
  421.         /************************************************************************/
  422.         ulOptions = QSD_SCALE;     /* return in screen resolution */
  423.         ulBuflen = 0L;
  424.   
  425.         /*********************************************************************************/
  426.         /* Get the screen Z information for every point                                  */
  427.         /* if ldiarr[ulocindx].ulValidityFlags & ADF_SCREENZ is true else do not get any */
  428.         /*********************************************************************************/
  429.         flAuxData = (ldiarr[ulocindx].ulValidityFlags & ADF_SCREENZ) ? ADF_SCREENZ : 0L ;
  430.   
  431.         irc = WrtQueryStrokeData ( NULL, &ulBuflen, hwnd, ulOptions, 
  432.                                    0UL, 0UL,
  433.                                    flAuxData   /* get the AUX data per point identify in flAuxData */
  434.                                    );
  435.         if( irc != WRT_NO_ERROR )
  436.         {
  437.           DisplayError ( hwnd, irc );
  438.         }
  439.         else
  440.         {
  441.           if( !ulBuflen )
  442.           {
  443.             WinMessageBox( HWND_DESKTOP, hwnd, "Zero ulBuflen", NULL, 1, MB_OK);
  444.           }
  445.           else
  446.           {
  447.             /********************************************************************/
  448.             /* Alloc the memory for the stroke buffer and then call Pen for OS/2*/
  449.             /* to fill in the buffer.                                           */
  450.             /********************************************************************/
  451.             if( ( psdCurStroke = (PSTROKEDATA) malloc( ulBuflen ) ) == NULL )
  452.             {
  453.               WinMessageBox( HWND_DESKTOP, hwnd, "malloc error",
  454.                              NULL, 1, MB_OK );
  455.             }
  456.             else
  457.             {
  458.               psdCurStroke->cbStructSize = sizeof ( STROKEDATA );
  459.               irc = WrtQueryStrokeData ( (PBYTE)psdCurStroke,
  460.                                          &ulBuflen, hwnd, ulOptions,
  461.                                          0UL, 0UL,  /*  scaled to screen        */
  462.                                          flAuxData   /* get the AUX data per point identify in flAuxData */
  463.                                          );
  464.               if( irc != WRT_NO_ERROR )
  465.               {
  466.                 DisplayError ( hwnd, irc );
  467.               }
  468.               else
  469.               {
  470.                 uMsgLeft++;
  471.                 if ( uMsgLeft > 90L ) 
  472.                 {
  473.                    /* Move the priority of the Lift Off Thread higher because     */
  474.                    /* we are running out of message queues since we only have 100 */
  475.                    DosSetPrty ( PRTYS_THREAD, PRTYC_REGULAR, 31, tidLiftOffT );
  476.                 } /* endif */
  477.                 WinPostMsg ( hwndT2Frame, ID_TLIFTOFF, MPFROMP ( psdCurStroke ), MPFROMCHAR ( fButton1Down ) );
  478.               } /* endif */
  479.             } /* endif */
  480.           } /* endif */
  481.         } /* endif */
  482.       } /* endif */
  483.       /************************************************************************/
  484.       /* Reset our flags                                                      */
  485.       /************************************************************************/
  486.       fButton1Down = FALSE;
  487.       fButton2Down = FALSE;
  488.       bTouchDown = FALSE;
  489.       MouMovCount = 0;
  490.       WinReleasePS ( hpsClient );
  491.       return( (MRESULT) LO_STROKE_PROCESSED );
  492.     }
  493.  
  494.     case WM_MOUSEMOVE:
  495.     case WM_SENSOR_MOVE:
  496.     {
  497.       /************************************************************************/
  498.       /* We are over our client window, change pointer bitmap to our          */
  499.       /* "BLOB" pointer bitmap.                                               */
  500.       /************************************************************************/
  501.       WinSetPointer( HWND_DESKTOP, hptrClient );
  502.  
  503.       if( !fButton1Down && !fButton2Down )
  504.       {
  505.         return( (MRESULT) FALSE );
  506.       } /* endif */
  507.       /************************************************************/
  508.       /* get the event data to check if the stroke buffer is full */
  509.       /* if the stroke buffer is full. The stroke buffer is 1000  */
  510.       /* which is about nine(9) seconds of data                   */
  511.       /************************************************************/
  512.       if ( msg == WM_SENSOR_MOVE ) /* if is a WM_SENSOR_MOVE the event data is             */
  513.       {                            /* in mp2 and you do not need to call WrtQueryEventData */
  514.          pedInfo = (PWRTEVENTDATA)PVOIDFROMMP ( mp2 );
  515.       } else
  516.       {
  517.         /*******************************************************/
  518.         /* initialize structure size at WM_CREATE to save time */
  519.         /* edInfo.cbStructSize = sizeof ( WRTEVENTDATA );      */
  520.         /*******************************************************/
  521.         WrtQueryEventData ( &edInfo );
  522.         pedInfo = &edInfo;
  523.       } /* endif */
  524.       if ( pedInfo->flEventStatus & WRT_BUFFER_OVERRUN )
  525.       {
  526.         return( (MRESULT) FALSE ); /* if the buffer is full do not draw any more points */
  527.       } /* endif */
  528.  
  529.       MouMovCount++;
  530.       /*******************************************************************************/
  531.       /* processing every other mouse move to speed up the inking with the          */
  532.       /* movement of the PEN. On WM_LIFTOFF return we set the value of              */
  533.       /* TDN_HIFREQ_MOUSEMOVE to force the system to give us all the mouse moves    */
  534.       /* but on slower machines it is too fast for the ink to keep up with the      */
  535.       /* user. By setting TDN_HIFREQ_MOUSEMOVE and dividing by 2 you are guaranty   */
  536.       /* to draw every other point. With out TDN_HIFREQ_MOUSEMOVE PM may throw away */
  537.       /* as many WM_MOUSEMOVE as it needs to on buffer overflow.                    */
  538.       /* The same is true when on WM_LIFTOFF you return TDN_SENSOR_MOVE             */
  539.       /*******************************************************************************/
  540.       if ( (MouMovCount % MouseDivide ) )   
  541.       {                                      
  542.         return( (MRESULT) TRUE );            
  543.       } /* endif */
  544.  
  545.       /************************************************************************/
  546.       /* Get the mouse coordinates                                            */
  547.       /************************************************************************/
  548.       ptlXY.x = (SHORT)MOUSEMSG ( &msg )->x;
  549.       ptlXY.y = (SHORT)MOUSEMSG ( &msg )->y;
  550.  
  551.       if ( msg == WM_SENSOR_MOVE ) 
  552.       {
  553.         /**********************************************************************/
  554.         /* map sensor coordinates to screen coordinates                       */
  555.         /**********************************************************************/
  556.         irc = WrtMapPointLong (
  557.                         hwnd,    /* coordinates are made relative to window */
  558.                         &ptlXY,     /* address of POINTL containing X/Y coord. */
  559.                         MP_SCALE,/* scale to coordinates in the ulX and ulY */
  560.                                  /* ulXInput if MP_RESOLUTION               */
  561.                         ldiarr[ulocindx].ulSensorXpts,     
  562.                                  /* ulYInput if MP_RESOLUTION               */
  563.                         ldiarr[ulocindx].ulSensorYpts,     
  564.                         0L,      /* ulXOutput if MP_RESOLUTION              */
  565.                         0L,      /* ulYOutput if MP_RESOLUTION              */
  566.                         1        /* one pair of coordinates                 */
  567.                         );
  568.         if ( irc != WRT_NO_ERROR )
  569.         {
  570.           DisplayError ( hwnd, irc );
  571.           return( (MRESULT) FALSE );
  572.         } /* endif */
  573.       } /* endif */
  574.  
  575.       /*************************************************************************/
  576.       /* get the AUX data. I will use the the AUXPOINTDATA.sScrZ to figure out */
  577.       /* the ink width. the the more pressured applied the wider the ink       */
  578.       /*************************************************************************/
  579.       /*******************************************/
  580.       /* find out if AUXPOINTDATA.sScrZ is valid */
  581.       /*******************************************/
  582.       if ( (ldiarr[ulocindx].ulValidityFlags & ADF_SCREENZ) )
  583.       {
  584.         /*******************************************/
  585.         /* AUXPOINTDATA.sScrZ is valid             */
  586.         /*******************************************/
  587.         /*******************************************************/
  588.         /* initialize structure size at WM_CREATE to save time */
  589.         /* apdExtra.cbStructSize = sizeof ( AUXPOINTDATA );    */
  590.         /*******************************************************/
  591.  
  592.         if ( !btoggle_aux ) /* if btoggle_aux is TRUE I already got the AUX DATA */
  593.         {                   /* so do not do it again                             */
  594.           /*******************************************************/
  595.           /* initialize structure size at WM_CREATE to save time */
  596.           /* apdExtra.cbStructSize = sizeof ( AUXPOINTDATA );    */
  597.           /*******************************************************/
  598.           WrtQueryPointAuxData ( &apdExtra );
  599.         } /* endif */
  600.         sCurrP = apdExtra.sScrZ;  /* get the current pressure */
  601.         if ( !bTouchDown )
  602.         {
  603.            bTouchDown = TRUE;
  604.            /* First move after a WM_TOUCHDOWN initialize sLastP */
  605.            sLastP = sCurrP;
  606.         }   /* endif */
  607.  
  608.         /***********************************************************************/
  609.         /*  the smaller AUXPOINTDATA.sScrZ the closer you are to the surface   */
  610.         /* once you go negative value you are applying pressure to the screen  */
  611.         /***********************************************************************/
  612.         lLastWidth += (sLastP > sCurrP) ? (1) : (-1);
  613.  
  614.         /***********************************************************************/
  615.         /* for this example I do not want the width to get bigger than 16 pels */
  616.         /* and the width should never be allow to be less than 1 pel.          */
  617.         /***********************************************************************/
  618.         lLastWidth = ( lLastWidth <= 16L ) ? lLastWidth : 16L;
  619.         lLastWidth = ( lLastWidth > 0L ) ? lLastWidth : 1L;
  620.  
  621.         sLastP = sCurrP;      /* set the last pressure to the current pressure */
  622.  
  623.         /*************************************************/
  624.         /* Set the current geometric line-width.         */
  625.         /* This width is only used in the GpiStrokePath  */
  626.         /*************************************************/
  627.         GpiSetLineWidthGeom ( hpsClient, lLastWidth );
  628.   
  629.         /*********************************************/
  630.         /* Begins a figure that has  geometric width */
  631.         /*********************************************/
  632.         GpiBeginPath ( hpsClient, 1L );
  633.   
  634.         /************************/
  635.         /* The figure is a line */
  636.         /************************/
  637.         GpiLine ( hpsClient, &ptlXY );
  638.   
  639.         /********************************************/
  640.         /* Ends the figure that has geometric width */
  641.         /********************************************/
  642.         GpiEndPath ( hpsClient );
  643.   
  644.         /***************************************************/
  645.         /* draws the figures with the geometric line-width */
  646.         /* and fills it in                                 */
  647.         /***************************************************/
  648.         GpiStrokePath ( hpsClient, 1L, 0L );
  649.       } else
  650.       {
  651.         /*****************************/
  652.         /* The draw a line is a line */
  653.         /*****************************/
  654.         GpiLine ( hpsClient, &ptlXY );
  655.       } /* endif */
  656.  
  657.       /******************************************************************/
  658.       /* You can move this to the begining of WM_MOUSEMOVE              */
  659.       /* so you can display the information before WM_TOUCHDOWN.          */
  660.       /* This way if the btoggle_aux or btoggle_event is set            */
  661.       /* you can see the information change before touchdown            */
  662.       /******************************************************************/
  663.       /* if btoogle_aux is TRUE  get the AUX structure                  */
  664.       /******************************************************************/
  665.       if ( btoggle_aux )
  666.       {
  667.         /*******************************************************/
  668.         /* initialize structure size at WM_CREATE to save time */
  669.         /* apdExtra.cbStructSize = sizeof ( AUXPOINTDATA );    */
  670.         /*******************************************************/
  671.         WrtQueryPointAuxData ( &apdExtra );
  672.         WinPostMsg ( hwndTFrame, ID_TAUX, NULL, NULL );
  673.       } /* endif */
  674.       /******************************************************************/
  675.       /* if btoogle_event is TRUE  get the event structure              */
  676.       /******************************************************************/
  677.       if ( btoggle_event )
  678.       {
  679.         WinPostMsg ( hwndTFrame, ID_TEVENT, NULL, NULL );
  680.       } /* endif */
  681.  
  682.       return( (MRESULT) TRUE );
  683.     }
  684.  
  685.     case WM_WRT_SYSVALUECHANGED:
  686.     {
  687.       switch ( LONGFROMMP (mp1) )
  688.       {
  689.          case VT_PPMSV:
  690.             /* some program changed a system value */
  691.             ulid = LONGFROMMP (mp2);
  692.             for ( i= 0; i< QSVALUESIZE; i++ )
  693.             {
  694.                if ( qsvalue[i].valueid == ulid )
  695.                {
  696.                   break;
  697.                } /* endif */
  698.             } /* endfor */
  699.             if ( i < QSVALUESIZE )
  700.             {
  701.               sprintf ( cbuffer, "%s [%ld] System Variable got changed",
  702.                        qsvalue[i].valname, ulid );
  703.             } else 
  704.             {
  705.               sprintf ( cbuffer, "Error [%ld] is not a valid System Variable ID",
  706.                         ulid );
  707.             } /* endif */
  708.             WinMessageBox( HWND_DESKTOP,
  709.                            hwnd,
  710.                            cbuffer,
  711.                            NULL, 1, MB_OK );
  712.             break;
  713.          case VT_PPMID:
  714.             /* some program change a Device Variable */
  715.             ulid = LONGFROMMP (mp2);
  716.             for ( i= 0; i< PPMIDSIZE; i++ )
  717.             {
  718.                if ( ppmid[i].ValueID == ulid )
  719.                {
  720.                   break;
  721.                } /* endif */
  722.             } /* endfor */
  723.             if ( i < PPMIDSIZE )
  724.             {
  725.               sprintf ( cbuffer, "%s [%ld] Device Variable got changed",
  726.                        ppmid[i].name, ulid );
  727.             } else 
  728.             {
  729.               sprintf ( cbuffer, "Error [%ld] is not a valid Device Variable ID",
  730.                         ulid );
  731.             } /* endif */
  732.             WinMessageBox( HWND_DESKTOP,
  733.                            hwnd,
  734.                            cbuffer,
  735.                            NULL, 1, MB_OK );
  736.             break;
  737.       } /* endswitch */
  738.       break;
  739.     }
  740.     case WM_PAINT:
  741.     {
  742.       hpsPaint = WinBeginPaint( hwnd, (HPS) NULL, &rcClient );
  743.       WinQueryWindowRect ( hwnd, &rcClient );
  744.       WinFillRect( hpsPaint, &rcClient, SYSCLR_WINDOW );
  745.       WinEndPaint( hpsPaint );
  746.       break;
  747.     }
  748.  
  749.     case ID_DISP:
  750.     {
  751.        /*******************************************************************/
  752.        /* 1.Find out if there are any Button Caps                         */
  753.        /*   if no button disable the query button menu                    */
  754.        /* 2.Find out if there are any Locator Caps                        */
  755.        /*   if no locator disable query Locator Caps                      */
  756.        /*******************************************************************/
  757.        scInfo.cbStructSize = sizeof ( scInfo );
  758.  
  759.        irc = WrtQuerySystemCaps ( &scInfo );
  760.  
  761.        if ( irc == WRT_NO_ERROR ) 
  762.        {
  763.           if ( scInfo.ulNumButtons == 0L )
  764.           {
  765.            /***************************************************************/
  766.            /* disable the query Button menu                               */
  767.            /***************************************************************/
  768.            WinSendDlgItemMsg (
  769.                              hwndFrame
  770.                             ,(ULONG) FID_MENU
  771.                             ,(ULONG) MM_SETITEMATTR
  772.                             ,MPFROM2SHORT ( ID_BCAPS, TRUE )
  773.                             ,MPFROM2SHORT ( MIA_DISABLED, MIA_DISABLED )
  774.                             );
  775.           } /* endif */
  776.           
  777.           if ( scInfo.ulNumLocators == 0L )
  778.           {
  779.            /***************************************************************/
  780.            /* disable the query Locator menu                              */
  781.            /***************************************************************/
  782.            WinSendDlgItemMsg (
  783.                              hwndFrame
  784.                             ,(ULONG) FID_MENU
  785.                             ,(ULONG) MM_SETITEMATTR
  786.                             ,MPFROM2SHORT ( ID_LCAPS, TRUE )
  787.                             ,MPFROM2SHORT ( MIA_DISABLED, MIA_DISABLED )
  788.                             );
  789.           } /* endif */
  790.  
  791.           if ( scInfo.ulNumDisplays == 0L )
  792.           {
  793.             /**************************************************************/
  794.             /* disable the query display menu                             */
  795.             /**************************************************************/
  796.             WinSendDlgItemMsg (
  797.                               hwndFrame
  798.                              ,(ULONG) FID_MENU
  799.                              ,(ULONG) MM_SETITEMATTR
  800.                              ,MPFROM2SHORT ( ID_DCAPS, TRUE )
  801.                              ,MPFROM2SHORT ( MIA_DISABLED, MIA_DISABLED )
  802.                              );
  803.             /**************************************************************/
  804.             /* disable the backlight menu                                 */
  805.             /**************************************************************/
  806.             WinSendDlgItemMsg (
  807.                               hwndFrame
  808.                              ,(ULONG) FID_MENU
  809.                              ,(ULONG) MM_SETITEMATTR
  810.                              ,MPFROM2SHORT ( ID_BACKL, TRUE )
  811.                              ,MPFROM2SHORT ( MIA_DISABLED, MIA_DISABLED )
  812.                              );
  813.           } else
  814.           {
  815.             /**************************************************************/
  816.             /* Find out if the Backlight is supported                     */
  817.             /* 1.Find out if any of the display attached support backlight*/
  818.             /*       if no backlight supported disable backlight menu     */
  819.             /**************************************************************/
  820.             ulDisplayID = 0L;
  821.             irc = WrtQueryDisplayCaps ( &ulDisplayID, NULL );
  822.             if ( irc != WRT_NO_ERROR )
  823.             {
  824.               /************************************************************/
  825.               /* ERROR from API                                           */
  826.               /************************************************************/
  827.               DisplayError ( hwnd, irc );
  828.             } else
  829.             {
  830.               /************************************************************/
  831.               /* Find out if any of the display support the backlight     */
  832.               /************************************************************/
  833.               i = 0;
  834.               for ( ; ulDisplayID > 0L; ulDisplayID-- )
  835.               {
  836.                 /**********************************************************/
  837.                 /* The cbStructureSize variable in the WRTDISPLAYDEVINFO  */
  838.                 /* structure must be initialize to the size of the        */
  839.                 /* WRTDISPLAYDEVINFO structure before querying the Display*/
  840.                 /* capabilities.                                          */
  841.                 /**********************************************************/
  842.                 dcInfo.cbStructSize = sizeof ( dcInfo );
  843.     
  844.                 /**********************************************************/
  845.                 /* ulDisplayID variable has the ID of the Display that you*/
  846.                 /* want to query                                          */
  847.                 /**********************************************************/
  848.                 irc = WrtQueryDisplayCaps ( &ulDisplayID, &dcInfo );
  849.     
  850.                 if ( irc == WRT_NO_ERROR ) 
  851.                 { 
  852.                   irc = WrtQueryInputDeviceVariable ( dcInfo.pszDriverName,
  853.                                                       dcInfo.pszDeviceName,
  854.                                                       PPMID_BACKLIGHTBLANK,
  855.                                                       &lvalue,
  856.                                                       NULL,
  857.                                                       NULL
  858.                                                      );
  859.                   if ( irc == WRT_NO_ERROR )
  860.                   {
  861.                     /* save the display ID for use in the BACKLIGHT DLG */
  862.                     ulbacklight_displayID[i++] = ulDisplayID;
  863.                   } /* endif */
  864.                 } else 
  865.                 {
  866.                   /********************************************************/
  867.                   /* ERROR from API                                       */
  868.                   /********************************************************/
  869.                   DisplayError ( hwnd, irc );
  870.                 } /* endif */
  871.               } /* endfor */
  872.               ulbacklight_displayID[i] = 0L;
  873.               if ( i == 0 )
  874.               {
  875.                 /**********************************************************/
  876.                 /* No display with backlight support found                */
  877.                 /* disable the backlight menu                             */
  878.                 /**********************************************************/
  879.                 WinSendDlgItemMsg (
  880.                                   hwndFrame
  881.                                  ,(ULONG) FID_MENU
  882.                                  ,(ULONG) MM_SETITEMATTR
  883.                                  ,MPFROM2SHORT ( ID_BACKL, TRUE )
  884.                                  ,MPFROM2SHORT ( MIA_DISABLED, MIA_DISABLED )
  885.                                  );
  886.               } /* endif */
  887.             } /* endif */
  888.           } /* endif */
  889.        } else 
  890.        {
  891.          /*****************************************************************/
  892.          /* ERROR from API                                                */
  893.          /*****************************************************************/
  894.          DisplayError ( hwnd, irc );
  895.        } /* endif */
  896.  
  897.       break;
  898.     }
  899.  
  900.     case WM_COMMAND:
  901.     {
  902.       switch ( SHORT1FROMMP(mp1) )
  903.       {
  904.         case ID_CLEAR:
  905.         {
  906.           /********************************************************************/
  907.           /* If there was a clear cmd, then tell the procedure to clear       */
  908.           /* the client window, and clear the memory bitmap now.              */
  909.           /********************************************************************/
  910.           WinInvalidateRect( hwndClient, NULL, TRUE );
  911.  
  912.           break;
  913.         }
  914.  
  915.         case ID_EXIT:
  916.           WinSendMsg(hwnd, WM_CLOSE, NULL, NULL);
  917.           break;
  918.  
  919.        /***********************************************************************/
  920.        /* Toggle between mouse mode and sense mode                            */
  921.        /***********************************************************************/
  922.        case ID_FULL:
  923.           btoggle_mouse_sense = btoggle_mouse_sense ^ 1;     /* toggle variable */
  924.           WinSendDlgItemMsg (
  925.                               hwndFrame
  926.                              ,(ULONG) FID_MENU
  927.                              ,(ULONG) MM_SETITEMATTR
  928.                              ,MPFROM2SHORT ( ID_FULL, TRUE )
  929.                              ,MPFROM2SHORT ( MIA_CHECKED, btoggle_mouse_sense ? MIA_CHECKED : 0 )
  930.                              );
  931.           break;
  932.        /***********************************************************************/
  933.        /* Toggle between display Aux Data and not display Aux Data            */
  934.        /***********************************************************************/
  935.        case ID_AUX:
  936.           btoggle_aux = btoggle_aux ^ 1;     /* toggle variable */
  937.           WinSendDlgItemMsg (
  938.                             hwndFrame
  939.                            ,(ULONG) FID_MENU
  940.                            ,(ULONG) MM_SETITEMATTR
  941.                            ,MPFROM2SHORT ( ID_AUX, TRUE )
  942.                            ,MPFROM2SHORT ( MIA_CHECKED, btoggle_aux ? MIA_CHECKED : 0 )
  943.                            );
  944.  
  945.           if ( !btoggle_aux )
  946.           {
  947.                AUXTEST = 0;
  948.                WinDismissDlg ( hwndAuxDLG, EXIT );
  949.           } /* endif */
  950.           break;
  951.        /***********************************************************************/
  952.        /* Toggle between display Event Data and not display Event Data        */
  953.        /***********************************************************************/
  954.        case ID_EVENT:
  955.           btoggle_event = btoggle_event ^ 1;     /* toggle variable */
  956.           WinSendDlgItemMsg (
  957.                             hwndFrame
  958.                            ,(ULONG) FID_MENU
  959.                            ,(ULONG) MM_SETITEMATTR
  960.                            ,MPFROM2SHORT ( ID_EVENT, TRUE )
  961.                            ,MPFROM2SHORT ( MIA_CHECKED, btoggle_event ? MIA_CHECKED : 0 )
  962.                            );
  963.           if ( !btoggle_event )
  964.           {
  965.                EVENTTEST = 0;
  966.                WinDismissDlg ( hwndEventDLG, EXIT );
  967.           } /* endif */
  968.           break;
  969.        /***********************************************************************/
  970.        /* System Capability                                                   */
  971.        /***********************************************************************/
  972.        case ID_SCAPS:
  973.             /******************************************************************/
  974.             /* The cbStructureSize variable in the WRTSYSTEMINFO              */
  975.             /* structure must be initialize to the size of the                */
  976.             /* WRTSYSTEMINFO structure before querying the System             */
  977.             /* capabilities.                                                  */
  978.             /******************************************************************/
  979.             scInfo.cbStructSize = sizeof ( scInfo );
  980.   
  981.             irc = WrtQuerySystemCaps ( &scInfo );
  982.   
  983.             if ( irc == WRT_NO_ERROR ) 
  984.             {
  985.               /****************************************************************/
  986.               /*  good return from API                                        */
  987.               /*  display the System capabilities                             */
  988.               /****************************************************************/
  989.               WinDlgBox(HWND_DESKTOP,
  990.                              hwnd,
  991.                              SysCapDlgProc,
  992.                              0UL,
  993.                              IDD_SCDLG,
  994.                              &scInfo);
  995.             } else 
  996.             {
  997.               /****************************************************************/
  998.               /* ERROR from API                                               */
  999.               /****************************************************************/
  1000.               DisplayError ( hwnd, irc );
  1001.             } /* endif */
  1002.           break;
  1003.   
  1004.        /***********************************************************************/
  1005.        /* Locator Capability                                                  */
  1006.        /***********************************************************************/
  1007.        case ID_LCAPS:
  1008.             WinDlgBox(HWND_DESKTOP,
  1009.                            hwnd,
  1010.                            LocCapDlgProc,
  1011.                            0UL,
  1012.                            IDD_LCDLG,
  1013.                            NULL );
  1014.           break;
  1015.        /***********************************************************************/
  1016.        /* Button  Capability                                                  */
  1017.        /***********************************************************************/
  1018.        case ID_BCAPS:
  1019.             WinDlgBox(HWND_DESKTOP,
  1020.                            hwnd,
  1021.                            ButCapDlgProc,
  1022.                            0UL,
  1023.                            IDD_BCDLG,
  1024.                            NULL );
  1025.           break;
  1026.        /***********************************************************************/
  1027.        /* Display Capability                                                  */
  1028.        /***********************************************************************/
  1029.        case ID_DCAPS:
  1030.             WinDlgBox(HWND_DESKTOP,
  1031.                            hwnd,
  1032.                            DisCapDlgProc,
  1033.                            0UL,
  1034.                            IDD_DCDLG,
  1035.                            NULL );
  1036.           break;
  1037.        /***********************************************************************/
  1038.        /* Query System Values                                                 */
  1039.        /***********************************************************************/
  1040.        case ID_QSVAL:
  1041.             /******************************************************************/
  1042.             /*  display the System values                                     */
  1043.             /******************************************************************/
  1044.             WinDlgBox ( HWND_DESKTOP,
  1045.                               hwnd,
  1046.                               SysValDlgProc,
  1047.                               0UL,
  1048.                               IDD_SVDLG,
  1049.                               NULL);
  1050.           break;
  1051.   
  1052.        /***********************************************************************/
  1053.        /* Set   System Values                                                 */
  1054.        /***********************************************************************/
  1055.        case ID_SSVAL:
  1056.             /******************************************************************/
  1057.             /*  Call dialog to set the system value.                          */
  1058.             /*  WARNING: Changing the system value will affect the system     */
  1059.             /******************************************************************/
  1060.             WinDlgBox(HWND_DESKTOP,
  1061.                            hwnd,
  1062.                            SSysVlDlgProc,
  1063.                            0UL,
  1064.                            IDD_SSDLG,
  1065.                            NULL );
  1066.           break;
  1067.        /***********************************************************************/
  1068.        /* Write System Values                                                 */
  1069.        /***********************************************************************/
  1070.        case ID_WSVAL:
  1071.             /******************************************************************/
  1072.             /*  Call dialog to write a system value.                          */
  1073.             /*  WARNING: Changing the system value will affect the system     */
  1074.             /******************************************************************/
  1075.             WinDlgBox(HWND_DESKTOP,
  1076.                            hwnd,
  1077.                            WSysVlDlgProc,
  1078.                            0UL,
  1079.                            IDD_WSDLG,
  1080.                            NULL );
  1081.           break;
  1082.        /***********************************************************************/
  1083.        /* Read  System Values                                                 */
  1084.        /***********************************************************************/
  1085.        case ID_RSVAL:
  1086.             /******************************************************************/
  1087.             /*  Call dialog to Read  a system value.                          */
  1088.             /*  WARNING: Changing the system value will affect the system     */
  1089.             /******************************************************************/
  1090.             WinDlgBox(HWND_DESKTOP,
  1091.                            hwnd,
  1092.                            RSysVlDlgProc,
  1093.                            0UL,
  1094.                            IDD_RSDLG,
  1095.                            NULL );
  1096.           break;
  1097.        /***********************************************************************/
  1098.        /* Enumerate Input Drivers                                             */
  1099.        /***********************************************************************/
  1100.        case ID_ENUDR:
  1101.             /* Find out how many input driver there are */
  1102.             ulNumDrivers = 0L;
  1103.             irc = WrtEnumInputDrivers ( &ulNumDrivers, NULL );
  1104.             if ( irc != WRT_NO_ERROR )
  1105.             {
  1106.                DisplayError ( hwnd, irc );
  1107.             } else
  1108.             {
  1109.               if ( ulNumDrivers > 10L )
  1110.               {
  1111.                 sprintf ( cbuffer, "Too many drivers[%ld] for my ARRAY",
  1112.                         ulNumDrivers );
  1113.                 WinMessageBox( HWND_DESKTOP,
  1114.                                hwnd,
  1115.                                cbuffer,
  1116.                                NULL, 1, MB_OK );
  1117.               } else
  1118.               {
  1119.                 if ( ulNumDrivers == 0L )
  1120.                 {
  1121.                   WinMessageBox( HWND_DESKTOP,
  1122.                                   hwnd,
  1123.                                   "WrtEnumInputDrivers return 0 drivers",
  1124.                                   NULL, 1, MB_OK );
  1125.                 } else
  1126.                 {
  1127.                   irc = WrtEnumInputDrivers ( &ulNumDrivers, szDriverName );
  1128.                   if ( irc == WRT_NO_ERROR ) 
  1129.                   {
  1130.                     WinDlgBox(HWND_DESKTOP,
  1131.                                    hwnd,
  1132.                                    EnumDrvDlgProc,
  1133.                                    0UL,
  1134.                                    IDD_EIDLG,
  1135.                                    NULL );
  1136.                   } else 
  1137.                   {
  1138.                      DisplayError ( hwnd, irc );
  1139.                   } /* endif */
  1140.                 } /* endif */
  1141.               } /* endif */
  1142.             } /* endif */
  1143.           break;
  1144.        /***********************************************************************/
  1145.        /* Query Input Device Names                                            */
  1146.        /***********************************************************************/
  1147.        case ID_QDNAM:
  1148.                   WinDlgBox(HWND_DESKTOP,
  1149.                                  hwnd,
  1150.                                  QInDevNDlgProc,
  1151.                                  0UL,
  1152.                                  IDD_DNDLG,
  1153.                                  NULL );
  1154.           break; 
  1155.   
  1156.        /***********************************************************************/
  1157.        /* Query Input Device Variable                                         */
  1158.        /***********************************************************************/
  1159.        case ID_QDVAR:
  1160.                   WinDlgBox(HWND_DESKTOP,
  1161.                                  hwnd,
  1162.                                  QInpDevDlgProc,
  1163.                                  0UL,
  1164.                                  IDD_QVDLG,
  1165.                                  NULL );
  1166.           break;
  1167.        /***********************************************************************/
  1168.        /* Set   Input Device Variable                                         */
  1169.        /***********************************************************************/
  1170.        case ID_SDVAR:
  1171.                   WinDlgBox(HWND_DESKTOP,
  1172.                                  hwnd,
  1173.                                  SInpDevDlgProc,
  1174.                                  0UL,
  1175.                                  IDD_SNDLG,
  1176.                                  NULL );
  1177.           break;
  1178.        /***********************************************************************/
  1179.        /* Set Strict Emulation                                                */
  1180.        /***********************************************************************/
  1181.        case ID_SEMUL:
  1182.           btoggle_strick_mous = btoggle_strick_mous ^ 1;     /* toggle variable */
  1183.           WinSendDlgItemMsg (
  1184.                                hwndFrame
  1185.                               ,(ULONG) FID_MENU
  1186.                               ,(ULONG) MM_SETITEMATTR
  1187.                               ,MPFROM2SHORT ( ID_SEMUL, TRUE )
  1188.                               ,MPFROM2SHORT ( MIA_CHECKED, btoggle_strick_mous ? MIA_CHECKED : 0 )
  1189.                               );
  1190.           irc = WrtSetStrictEmulation ( hwnd,btoggle_strick_mous ? SSE_SET : SSE_RESET );
  1191.           if ( irc != WRT_NO_ERROR ) 
  1192.           {
  1193.             DisplayError ( hwnd, irc );
  1194.           } /* endif */
  1195.           break;
  1196.        /***********************************************************************/
  1197.        /* ON/OFF Backlight                                                    */
  1198.        /***********************************************************************/
  1199.        case ID_BACKL:
  1200.             WinDlgBox(HWND_DESKTOP,
  1201.                            hwnd,
  1202.                            BACKLTDlgProc,
  1203.                            0UL,
  1204.                            IDD_BLDLG,
  1205.                            NULL );
  1206.           break;
  1207.       }
  1208.       break;
  1209.     }
  1210.  
  1211.     default:
  1212.     {
  1213.       return( WinDefWindowProc( hwnd, msg, mp1, mp2 ) );
  1214.     }
  1215.   }
  1216.   return( (MRESULT) FALSE );
  1217. }
  1218.  
  1219.  
  1220. VOID BackThread ( VOID * arg )
  1221. {
  1222.   HMQ   hmqTMain;
  1223.   QMSG  qmsgTMain;
  1224.  
  1225.   /****************************************************************************/
  1226.   /* Initialize PM for this program and create its PM message queue.          */
  1227.   /* The message queue is set to 100 because the thread will be running at    */
  1228.   /* idle item and the main thread will be posting messages for every .       */
  1229.   /* mouse move. Still you may loose some data because of queue overflow.     */
  1230.   /****************************************************************************/
  1231.   habTMain = WinInitialize( (ULONG) NULL );
  1232.   hmqTMain = WinCreateMsgQueue( habTMain, 100L );
  1233.  
  1234.  
  1235.   /****************************************************************************/
  1236.   /* Register "ThreadWndProc" as the handling procedure for the               */
  1237.   /* "Object Class" class window.                                             */
  1238.   /****************************************************************************/
  1239.   WinRegisterClass( habTMain,
  1240.                   (PSZ)"Object Class",
  1241.                   (PFNWP)ThreadWndProc,
  1242.                   0L,
  1243.                   0L );
  1244.  
  1245.  
  1246.   hwndTFrame = WinCreateWindow(HWND_OBJECT,             /* Create an Object Window */
  1247.                                (PSZ)"Object Class",
  1248.                                NULL,
  1249.                                0L,
  1250.                                0,
  1251.                                0,
  1252.                                0,
  1253.                                0,
  1254.                                0L,
  1255.                                HWND_TOP,
  1256.                                OBJECTID1,
  1257.                                NULL,
  1258.                                NULL);
  1259.   /********************************************************************************/
  1260.   /* Set this thread's priority to idle class                                     */
  1261.   /* If you want to set the thread priority lower than default uncomment the      */
  1262.   /* DosSetPrty statement. The lower the priority the more time you give to other */
  1263.   /* threads (WM_MOUSEMOVE message thread                                         */
  1264.   /********************************************************************************/
  1265.   /* DosSetPrty ( PRTYS_THREAD, PRTYC_IDLETIME, 31, 0 ); */
  1266.  
  1267.   /****************************************************************************/
  1268.   /* This while loop waits for messages from PM.  If not a WM_CLOSE msg,      */
  1269.   /* then we dispatch the message to our client window procedure.             */
  1270.   /****************************************************************************/
  1271.   while( WinGetMsg( habTMain, &qmsgTMain, (HWND) NULL, 0, 0 ) )
  1272.   {
  1273.     WinDispatchMsg( habTMain, &qmsgTMain );
  1274.   }
  1275.  
  1276.   /****************************************************************************/
  1277.   /* We will drop out of the while loop if the program receives a WM_CLOSE    */
  1278.   /* message.  We must destroy our PM resources and return to the             */
  1279.   /* invoking procedure.                                                      */
  1280.   /****************************************************************************/
  1281.   WinDestroyWindow( hwndTFrame );
  1282.   WinDestroyMsgQueue( hmqTMain );
  1283.   WinTerminate( habTMain );
  1284.  
  1285. }
  1286. MRESULT EXPENTRY ThreadWndProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  1287. {
  1288.   CHAR      cbuffer[MAXCBUFFER];
  1289.   INT       i;
  1290.  
  1291.   switch( msg )
  1292.   {
  1293.     case ID_TAUX:
  1294.          if ( AUXTEST == 0 ) 
  1295.          {
  1296.            hwndAuxDLG = WinLoadDlg ( HWND_DESKTOP,
  1297.                            hwnd,
  1298.                            AUXPNTDlgProc,
  1299.                            0L,
  1300.                            IDD_PADLG,
  1301.                            NULL );
  1302.            AUXTEST = 1;
  1303.          } else 
  1304.          {
  1305.            /****************************************************************/
  1306.            /* ulocindx will be pointing to the last locator device that    */
  1307.            /* did a WM_TOUCHDOWN. When changing from a pen to a finger you */
  1308.            /* must do at least one touchdown before ulocindx changes from  */
  1309.            /* the pen to the finger                                        */
  1310.            /****************************************************************/
  1311.            if ( ldiarr[ulocindx].ulValidityFlags & ADF_TIMESTAMP )
  1312.            {
  1313.               sprintf ( cbuffer, "%ld", apdExtra.ulTimestamp );
  1314.               WinSetDlgItemText ( hwndAuxDLG, wrtelc02, cbuffer );
  1315.            } /* endif */
  1316.  
  1317.            if ( ldiarr[ulocindx].ulValidityFlags & ADF_FLAGS )
  1318.            {
  1319.              sprintf ( cbuffer, "%#x", apdExtra.usFlags );
  1320.              WinSetDlgItemText ( hwndAuxDLG, wrtelc03, cbuffer );
  1321.            } /* endif */
  1322.  
  1323.            if ( ldiarr[ulocindx].ulValidityFlags & ADF_USER )
  1324.            {
  1325.              sprintf ( cbuffer, "%d", apdExtra.usUser );
  1326.              WinSetDlgItemText ( hwndAuxDLG, wrtelc04, cbuffer );
  1327.            } /* endif */
  1328.  
  1329.            if ( ldiarr[ulocindx].ulValidityFlags & ADF_SCREENZ )
  1330.            {
  1331.              sprintf ( cbuffer, "%d", apdExtra.sScrZ );
  1332.              WinSetDlgItemText ( hwndAuxDLG, wrtelc05, cbuffer );
  1333.            } /* endif */
  1334.  
  1335.            if ( ldiarr[ulocindx].ulValidityFlags & ADF_DEVZ )
  1336.            {
  1337.             sprintf ( cbuffer, "%d", apdExtra.sDevZ );
  1338.             WinSetDlgItemText ( hwndAuxDLG, wrtelc06, cbuffer );
  1339.            } /* endif */
  1340.  
  1341.            if ( ldiarr[ulocindx].ulValidityFlags & ADF_ANGLE )
  1342.            {
  1343.              sprintf ( cbuffer, "%d", apdExtra.sAngle );
  1344.              WinSetDlgItemText ( hwndAuxDLG, wrtelc07, cbuffer );
  1345.            } /* endif */
  1346.  
  1347.            if ( ldiarr[ulocindx].ulValidityFlags & ADF_ROTATION )
  1348.            {
  1349.              sprintf ( cbuffer, "%d", apdExtra.sRotation );
  1350.              WinSetDlgItemText ( hwndAuxDLG, wrtelc08, cbuffer );
  1351.            } /* endif */
  1352.  
  1353.            if ( ldiarr[ulocindx].ulValidityFlags & ADF_BUTTON )
  1354.            {
  1355.              sprintf ( cbuffer, "%#x", apdExtra.usButton );
  1356.              WinSetDlgItemText ( hwndAuxDLG, wrtelc09, cbuffer );
  1357.            } /* endif */
  1358.  
  1359.            if ( ldiarr[ulocindx].ulValidityFlags & ADF_OEM )
  1360.            {
  1361.             /* adf_oem_count_mask is not supported in release 1 */
  1362.             for ( i= 0; i < ldiarr[ulocindx].ulOEMValidityCnt; i++ )
  1363.             {
  1364.                sprintf ( cbuffer, "OEM[%i]= %li", i, apdExtra.OEM[i] );
  1365.                WinSendDlgItemMsg(hwndAuxDLG,
  1366.                                   wrtelc10,
  1367.                                   LM_INSERTITEM,
  1368.                                   MPFROM2SHORT(LIT_END, 0),
  1369.                                   MPFROMP( cbuffer ) );
  1370.  
  1371.             } /* endfor */
  1372.            } /* endif */
  1373.          } /* endif */
  1374.       break;
  1375.     case ID_TEVENT:
  1376.          if ( EVENTTEST == 0 )
  1377.          {
  1378.            hwndEventDLG = WinLoadDlg ( HWND_DESKTOP,
  1379.                            hwnd,
  1380.                            EVNTDTDlgProc,
  1381.                            0L,
  1382.                            IDD_EVDLG,
  1383.                            NULL );
  1384.            EVENTTEST = 1;
  1385.          } else 
  1386.          {
  1387.            sprintf ( cbuffer, "%#x", pedInfo->usKCFlags );
  1388.            WinSetDlgItemText ( hwndEventDLG, wrtelc02, cbuffer );
  1389.  
  1390.            sprintf ( cbuffer, "%#x", pedInfo->usHitTest );
  1391.            WinSetDlgItemText ( hwndEventDLG, wrtelc03, cbuffer );
  1392.  
  1393.            sprintf ( cbuffer, "%#x", pedInfo->flEventStatus );
  1394.            WinSetDlgItemText ( hwndEventDLG, wrtelc04, cbuffer );
  1395.  
  1396.            sprintf ( cbuffer, "%ld", pedInfo->ptlDisplay.x );
  1397.            WinSetDlgItemText ( hwndEventDLG, wrtelc05, cbuffer );
  1398.            sprintf ( cbuffer, "%ld", pedInfo->ptlDisplay.y );
  1399.            WinSetDlgItemText ( hwndEventDLG, wrtelc06, cbuffer );
  1400.  
  1401.            sprintf ( cbuffer, "%ld", pedInfo->ptlSensor.x );
  1402.            WinSetDlgItemText ( hwndEventDLG, wrtelc07, cbuffer );
  1403.            sprintf ( cbuffer, "%ld", pedInfo->ptlSensor.y  );
  1404.            WinSetDlgItemText ( hwndEventDLG, wrtelc08, cbuffer );
  1405.  
  1406.            sprintf ( cbuffer, "%ld", pedInfo->ptlStandard.x );
  1407.            WinSetDlgItemText ( hwndEventDLG, wrtelc09, cbuffer );
  1408.            sprintf ( cbuffer, "%ld", pedInfo->ptlStandard.y  );
  1409.            WinSetDlgItemText ( hwndEventDLG, wrtelc10, cbuffer );
  1410.  
  1411.            sprintf ( cbuffer, "%ld", pedInfo->ulStrokeSeq  );
  1412.            WinSetDlgItemText ( hwndEventDLG, wrtelc11, cbuffer );
  1413.  
  1414.            sprintf ( cbuffer, "%ld", pedInfo->ulStrokeSize );
  1415.            WinSetDlgItemText ( hwndEventDLG, wrtelc12, cbuffer );
  1416.  
  1417.            sprintf ( cbuffer, "%ld", pedInfo->ulLocatorID  );
  1418.            WinSetDlgItemText ( hwndEventDLG, wrtelc13, cbuffer );
  1419.  
  1420.            sprintf ( cbuffer, "%ld", pedInfo->ulLocatorType  );
  1421.            WinSetDlgItemText ( hwndEventDLG, wrtelc14, cbuffer );
  1422.  
  1423.            sprintf ( cbuffer, "%#lx", pedInfo->ulLocatorFlags  );
  1424.            WinSetDlgItemText ( hwndEventDLG, wrtelc15, cbuffer );
  1425.  
  1426.            sprintf ( cbuffer, "%#lx", pedInfo->ulValidityFlags );
  1427.            WinSetDlgItemText ( hwndEventDLG, wrtelc16, cbuffer );
  1428.  
  1429.            sprintf ( cbuffer, "%#lx", pedInfo->ulButtonStatus  );
  1430.            WinSetDlgItemText ( hwndEventDLG, wrtelc17, cbuffer );
  1431.  
  1432.            sprintf ( cbuffer, "%ld", pedInfo->hwndUnderPtr );
  1433.            WinSetDlgItemText ( hwndEventDLG, wrtelc18, cbuffer );
  1434.          } /* endif */
  1435.       break;
  1436.     default:
  1437.     {
  1438.       return( WinDefWindowProc( hwnd, msg, mp1, mp2 ) );
  1439.     }
  1440.   } /* endswitch */
  1441.   return( (MRESULT) FALSE );
  1442. }
  1443.  
  1444. VOID LiftOffThread ( VOID * arg )
  1445. {
  1446.   HMQ   hmqTMain;
  1447.   QMSG  qmsgTMain;
  1448.  
  1449.   /********************************************************************************/
  1450.   /* Initialize PM for this program and create its PM message queue.              */
  1451.   /* The message queue is set to 100 because the thread will be running at        */
  1452.   /* idle item and the main thread will be posting messages for for every stroke. */
  1453.   /********************************************************************************/
  1454.   habT2Main = WinInitialize( (ULONG) NULL );
  1455.   hmqTMain = WinCreateMsgQueue( habT2Main, 100L );
  1456.  
  1457.  
  1458.   /****************************************************************************/
  1459.   /* Register "ThreadLiftOffProc" as the handling procedure for the           */
  1460.   /* "Object Class" class window.                                             */
  1461.   /****************************************************************************/
  1462.   WinRegisterClass( habT2Main,
  1463.                   (PSZ)"Object Class",
  1464.                   (PFNWP)ThreadLiftOffProc,
  1465.                   0L,
  1466.                   0L );
  1467.  
  1468.  
  1469.   hwndT2Frame = WinCreateWindow(HWND_OBJECT,             /* Create an Object Window */
  1470.                                (PSZ)"Object Class",
  1471.                                NULL,
  1472.                                0L,
  1473.                                0,
  1474.                                0,
  1475.                                0,
  1476.                                0,
  1477.                                0L,
  1478.                                HWND_TOP,
  1479.                                OBJECTID2,
  1480.                                NULL,
  1481.                                NULL);
  1482.   /* Set this thread's priority to idle class */
  1483.   DosSetPrty ( PRTYS_THREAD, PRTYC_IDLETIME, 31, 0 );
  1484.  
  1485.   /****************************************************************************/
  1486.   /* This while loop waits for messages from PM.  If not a WM_CLOSE msg,      */
  1487.   /* then we dispatch the message to our client window procedure.             */
  1488.   /****************************************************************************/
  1489.   while( WinGetMsg( habT2Main, &qmsgTMain, (HWND) NULL, 0, 0 ) )
  1490.   {
  1491.     WinDispatchMsg( habT2Main, &qmsgTMain );
  1492.   }
  1493.  
  1494.   /****************************************************************************/
  1495.   /* We will drop out of the while loop if the program receives a WM_CLOSE    */
  1496.   /* message.  We must destroy our PM resources and return to the             */
  1497.   /* invoking procedure.                                                      */
  1498.   /****************************************************************************/
  1499.   WinDestroyWindow( hwndT2Frame );
  1500.   WinDestroyMsgQueue( hmqTMain );
  1501.   WinTerminate( habT2Main );
  1502.  
  1503. }
  1504. MRESULT EXPENTRY ThreadLiftOffProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  1505. {
  1506.   INT          i;
  1507.   HPS          hpsTClient;
  1508.   PSTROKEDATA  psdCurStroke;
  1509.   POINTL       *pxyCurStroke;
  1510.   SHORT        *psCurrP;             /* pointer to get the pressure */
  1511.   CHAR         fButton1Down;
  1512.  
  1513.   switch( msg )
  1514.   {
  1515.     case ID_TLIFTOFF:
  1516.     {
  1517.          psdCurStroke = (PSTROKEDATA)PVOIDFROMMP ( mp1 );
  1518.          fButton1Down = CHAR1FROMMP ( mp2 );
  1519.  
  1520.          hpsTClient = WinGetPS ( hwndClient );
  1521.          pxyCurStroke = psdCurStroke->pXY;
  1522.  
  1523.          /* decrease the number of message waiting */
  1524.          uMsgLeft--;
  1525.          if ( uMsgLeft == 80L )
  1526.          {
  1527.             /* Move the priority of the Lift Off Thread lower because     */
  1528.             /* we we have enough space in the  message queue we  have 100 */
  1529.             DosSetPrty ( PRTYS_THREAD, PRTYC_IDLETIME, 31, 0 );
  1530.          } /* endif */
  1531.          /**************************************************************************/
  1532.          /* if fButton1Down is set to zero it means that fButton2Down is to to one */
  1533.          /* and we are in erase mode. Set the ink to the background to erase       */
  1534.          /**************************************************************************/
  1535.          GpiSetColor( hpsTClient, fButton1Down ? CLR_BLUE : CLR_BACKGROUND );
  1536.  
  1537.          /**************************************************************/
  1538.          /* Move the staring point of the the line to the beging of    */
  1539.          /* the stroke                                                 */
  1540.          /**************************************************************/
  1541.          GpiMove( hpsTClient, &pxyCurStroke[0] );
  1542.  
  1543.          /*******************************************/
  1544.          /* find out if AUXPOINTDATA.sScrZ is valid */
  1545.          /*******************************************/
  1546.          if ( (ldiarr[ulocindx].ulValidityFlags & ADF_SCREENZ) )
  1547.          {
  1548.            /***********************************************************/
  1549.            /* Since I only requested one AUX data                     */
  1550.            /* psdCurStroke->pAuxInfo->cbAuxDesc == 24                 */ /* 4*/
  1551.            /* psdCurStroke->pAuxInfo->ulNumElements == 1              */ /* 8*/
  1552.            /* psdCurStroke->pAuxInfo->ulAuxSize == 2                  */ /*12*/
  1553.            /* psdCurStroke->pAuxInfo->addAuxDesc[0].id == ADT_SCREENZ */ /*16*/
  1554.            /* psdCurStroke->pAuxInfo->addAuxDesc[0].offset == 0L      */ /*20*/
  1555.            /* psdCurStroke->pAuxInfo->addAuxDesc[0].cb == 2L          */ /*24*/
  1556.            /***********************************************************/
  1557.  
  1558.            /* get the first SCREENZ information */
  1559. psCurrP = (SHORT *)&(psdCurStroke->pAuxData->bAuxData[0][psdCurStroke->pAuxInfo->addAuxDesc[0].offset]);
  1560.            sLastP = *psCurrP;    /* this is done becuase bAuxData is unsign CHAR and SCREENZ is SHORT */
  1561.  
  1562.            /* for all the point in the stroke after the first point */
  1563.            for ( i= 1L; i< psdCurStroke->ulNumPoints ; i++ )
  1564.            {
  1565. psCurrP = (SHORT *)&(psdCurStroke->pAuxData->bAuxData[ (i*psdCurStroke->pAuxInfo->ulAuxSize) ][psdCurStroke->pAuxInfo->addAuxDesc[0].offset]);
  1566.              sCurrP = *psCurrP;
  1567.  
  1568.              /***********************************************************************/
  1569.              /*  the smaller AUXPOINTDATA.sScrZ the closer you are to the surface   */
  1570.              /* once you go negative value you are applying pressure to the screen  */
  1571.              /***********************************************************************/
  1572.              lLastWidth += (sLastP > sCurrP) ? (1) : (-1);
  1573.      
  1574.              /***********************************************************************/
  1575.              /* for this example I do not want the width to get bigger than 16 pels */
  1576.              /* and teh width should never be allow to be less than 1 pel.          */
  1577.              /***********************************************************************/
  1578.              lLastWidth = ( lLastWidth <= 16L ) ? lLastWidth : 16L;
  1579.              lLastWidth = ( lLastWidth > 0L ) ? lLastWidth : 1L;
  1580.  
  1581.              sLastP = sCurrP;      /* set the last pressure to the current pressure */
  1582.  
  1583.              /*********************************************/
  1584.              /* Begins a figure that has  geometric width */
  1585.              /*********************************************/
  1586.              GpiBeginPath ( hpsTClient, 1L );
  1587.        
  1588.              /*************************************************/
  1589.              /* Set the current geometric line-width.         */
  1590.              /* This width is only used in the GpiStrokePath  */
  1591.              /*************************************************/
  1592.              GpiSetLineWidthGeom ( hpsTClient, lLastWidth );
  1593.        
  1594.              /************************/
  1595.              /* The figure is a line */
  1596.              /************************/
  1597.              GpiLine ( hpsTClient, &pxyCurStroke[i] );
  1598.        
  1599.              /********************************************/
  1600.              /* Ends the figure that has geometric width */
  1601.              /********************************************/
  1602.              GpiEndPath ( hpsTClient );
  1603.        
  1604.              /***************************************************/
  1605.              /* draws the figures with the geometric line-width */
  1606.              /* and fills it in                                 */
  1607.              /***************************************************/
  1608.              GpiStrokePath ( hpsTClient, 1L, 0L );
  1609.            } /* endfor */
  1610.          } else       /* the Locator does not support SCREENZ */
  1611.          {
  1612.            GpiPolyLine( hpsTClient,
  1613.                           (LONG)(psdCurStroke->ulNumPoints - 1L ),
  1614.                           &pxyCurStroke[1] );
  1615.          } /* endif */
  1616.          WinReleasePS ( hpsTClient );
  1617.          free( psdCurStroke );
  1618.       }
  1619.       break;
  1620.     default:
  1621.     {
  1622.       return( WinDefWindowProc( hwnd, msg, mp1, mp2 ) );
  1623.     }
  1624.   } /* endswitch */
  1625.   return( (MRESULT) FALSE );
  1626. }
  1627.