home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 3 / goldfish_volume_3.bin / files / gfx / 3d / irit / grapdrvs / os2drvs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-20  |  52.9 KB  |  1,364 lines

  1. /*****************************************************************************
  2. *   An OS2 2.x driver.                                 *
  3. *                                         *
  4. * Written by:  Gershon Elber                 Ver 0.1, October 1993.  *
  5. *****************************************************************************/
  6.  
  7. #include <stdio.h>
  8.  
  9. #define INCL_WINSTDFILE
  10. #define INCL_WININPUT
  11. #define INCL_WINFRAMEMGR
  12. #define INCL_WINMENUS
  13. #define INCL_DOSPROCESS
  14. #define INCL_PM
  15. #define INCL_BASE
  16. #include <os2.h>
  17.  
  18. #include "irit_sm.h"
  19. #include "genmat.h"
  20. #include "iritprsr.h"
  21. #include "allocate.h"
  22. #include "attribut.h"
  23. #include "ip_cnvrt.h"
  24. #include "cagd_lib.h"
  25. #include "symb_lib.h"
  26. #include "iritgrap.h"
  27. #include "os2drvs.h"
  28. #include "irit_soc.h"
  29.  
  30. #define ID_VIEW        1
  31. #define ID_TRANS    2
  32. #define ID_ANIM        3
  33.  
  34. #define DEFAULT_TRANS_WIDTH    200
  35. #define DEFAULT_TRANS_HEIGHT    500
  36. #define DEFAULT_VIEW_WIDTH    400
  37. #define DEFAULT_VIEW_HEIGHT    400
  38.                                    
  39. #define ARGCV_LINE_LEN    1000
  40. #define ARGCV_MAX_WORDS    100
  41.  
  42. #define RGB_COLOR(R, G, B)    (((R) << 16) + ((G) << 8) + (B))
  43. #define GPI_MOVE(X, Y)    { POINTL Pt; Pt.x = X; Pt.y = Y; GpiMove(hps, &Pt); }
  44. #define GPI_LINE(X, Y)    { POINTL Pt; Pt.x = X; Pt.y = Y; GpiLine(hps, &Pt); }
  45. #define GPI_CHAR_STR_AT(Str, X, Y) { POINTL Pt; int l = strlen(Str); \
  46.                      Pt.x = X - cxChar * (l + 1) / 2; \
  47.                      Pt.y = Y - cyChar / 3; \
  48.                      GpiCharStringAt(hps, &Pt, l, Str); }
  49. #define OS2_MAP_X_COORD(x) ((int) (ViewWidth2 + x * ViewWidth2))
  50. #define OS2_MAP_Y_COORD(y) ((int) (ViewHeight2 + y * ViewWidth2))
  51.  
  52. #define WIN_CHECK_MENU(Item, Val)    WinSendMsg(hwndMenu, MM_SETITEMATTR, \
  53.                            MPFROM2SHORT(Item, TRUE), \
  54.                            MPFROM2SHORT(MIA_CHECKED, \
  55.                                 (Val)));
  56.  
  57. /* Interactive menu setup structure: */
  58. #define INTERACT_NUM_OF_STRINGS        3
  59. #define INTERACT_NUM_OF_SUB_WNDWS    15
  60. #define INTERACT_SUB_WINDOW_WIDTH  0.8         /* Relative to window size. */
  61. #define INTERACT_SUB_WINDOW_HEIGHT 0.04
  62.  
  63. typedef struct InteractString {
  64.     RealType X, Y;
  65.     int Color;
  66.     char *Str;
  67. } InteractString;
  68. typedef struct InteractSubWindow {
  69.     RealType X, Y;                       /* Center points. */
  70.     int Color;
  71.     IGGraphicEventType Event;
  72.     int TextInside; /* If TRUE, Str will be in window, otherwise left to it. */
  73.     char *Str;
  74. } InteractSubWindow;
  75. typedef struct InteractWindowStruct {     /* The interactive menu structures. */
  76.     /* Rotate, Translate, Scale strings: */
  77.     InteractString Strings[INTERACT_NUM_OF_STRINGS];
  78.     InteractSubWindow SubWindows[INTERACT_NUM_OF_SUB_WNDWS];
  79. } InteractWindowStruct;
  80.  
  81. /* Interactive mode menu set up structure is define below: */
  82. static InteractWindowStruct InteractMenu =
  83. {
  84.   {
  85.     { 0.5, 0.76, IG_IRIT_RED,   "Rotate" },
  86.     { 0.5, 0.56, IG_IRIT_GREEN, "Translate" },
  87.     { 0.5, 0.36, IG_IRIT_CYAN,  "Scale" },
  88.   },
  89.   {
  90.     { 0.5, 0.92, IG_IRIT_YELLOW, IG_EVENT_SCR_OBJ_TGL,    TRUE,  "Screen Coords." },
  91.     { 0.5, 0.84, IG_IRIT_BLUE,   IG_EVENT_PERS_ORTHO_TGL, TRUE,  "Perspective" },
  92.     { 0.5, 0.79, IG_IRIT_BLUE,   IG_EVENT_PERS_ORTHO_Z,   FALSE, "Z" },
  93.     { 0.5, 0.69, IG_IRIT_RED,    IG_EVENT_ROTATE_X,       FALSE, "X" },  /* Rot */
  94.     { 0.5, 0.64, IG_IRIT_RED,    IG_EVENT_ROTATE_Y,       FALSE, "Y" },
  95.     { 0.5, 0.59, IG_IRIT_RED,    IG_EVENT_ROTATE_Z,       FALSE, "Z" },
  96.     { 0.5, 0.49, IG_IRIT_GREEN,  IG_EVENT_TRANSLATE_X,    FALSE, "X" },/* Trans */
  97.     { 0.5, 0.44, IG_IRIT_GREEN,  IG_EVENT_TRANSLATE_Y,    FALSE, "Y" },
  98.     { 0.5, 0.39, IG_IRIT_GREEN,  IG_EVENT_TRANSLATE_Z,    FALSE, "Z" },
  99.     { 0.5, 0.29, IG_IRIT_CYAN,   IG_EVENT_SCALE,      FALSE, "" }, /* Scale */
  100.     { 0.5, 0.21, IG_IRIT_YELLOW, IG_EVENT_DEPTH_CUE,      TRUE,  "Depth Cue" },
  101.     { 0.5, 0.16, IG_IRIT_YELLOW, IG_EVENT_SAVE_MATRIX,    TRUE,  "Save Matrix" },
  102.     { 0.5, 0.12, IG_IRIT_YELLOW, IG_EVENT_PUSH_MATRIX,    TRUE,  "Push Matrix" },
  103.     { 0.5, 0.08, IG_IRIT_YELLOW, IG_EVENT_POP_MATRIX,     TRUE,  "Pop Matrix" },
  104.     { 0.5, 0.03, IG_IRIT_WHITE,  IG_EVENT_QUIT,              TRUE,  "Quit" },
  105.   }
  106. };
  107.  
  108. /* Colors to be used for viewed object (see also iritgrap.h):           */
  109. /* This colors are adjusted so as to give OS2 2.x a better chance at       */
  110. /* selecting these colors as solid.                       */
  111. static short Colors[IG_MAX_COLOR + 1][3] =
  112. {
  113.     { 0,   0,   0   },  /* 0. BLACK */
  114.     { 0,   0,   255 },  /* 1. BLUE */
  115.     { 0,   255, 0   },  /* 2. GREEN */
  116.     { 0,   255, 255 },  /* 3. CYAN */
  117.     { 255, 0,   0   },  /* 4. RED */
  118.     { 255, 0,   255 },  /* 5. MAGENTA */
  119.     { 127, 127, 0   },  /* 6. BROWN */
  120.     { 127, 127, 127 },  /* 7. LIGHTGREY */
  121.     { 63,  63,  63  },  /* 8. DARKGRAY */
  122.     { 63,  63,  255 },  /* 9. LIGHTBLUE */
  123.     { 63,  255, 63  },  /* 10. LIGHTGREEN */
  124.     { 63,  255, 255 },  /* 11. LIGHTCYAN */
  125.     { 255, 63,  63  },  /* 12. LIGHTRED */
  126.     { 255, 63,  255 },  /* 13. LIGHTMAGENTA */
  127.     { 255, 255, 63  },  /* 14. YELLOW */
  128.     { 255, 255, 255 }   /* 15. WHITE */
  129. };
  130.  
  131. static int
  132.     GlblSliderIncrements = 0;
  133. static unsigned int
  134.     TransWidth = DEFAULT_TRANS_WIDTH,
  135.     TransHeight = DEFAULT_TRANS_HEIGHT,
  136.     TransWidth2 = DEFAULT_TRANS_WIDTH / 2,
  137.     ViewWidth2 = DEFAULT_VIEW_WIDTH / 2,
  138.     ViewHeight2 = DEFAULT_VIEW_HEIGHT / 2;
  139.  
  140. static LONG CrntColorLowIntensity, CrntColorHighIntensity,
  141.     ColorsLowIntensity[IG_MAX_COLOR + 1],
  142.     ColorsHighIntensity[IG_MAX_COLOR + 1];
  143. static HPS
  144.     CurrentHps = 0;
  145. static HWND
  146.     hwndMenu = 0,
  147.     hwndFrame = 0,
  148.     hwndClient = 0,
  149.     hwndViewFrame = 0,
  150.     hwndTransFrame = 0,
  151.     hwndSlider = 0;
  152. static double
  153.     GlblAnimGetTime = 0.0;
  154.  
  155. static void GetInputFromSocket(void *Data);
  156. static MRESULT TransWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  157. static MRESULT ViewWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  158. static MRESULT ClientWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  159. static MRESULT AnimWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  160. static MRESULT AnimGetTimeWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
  161.  
  162. static void OS2DrvsAnimation(void *Data);
  163. static void HandleGetOneNumber(RealType *t, HWND hwnd);
  164. static IGGraphicEventType GetGraphicEvent(RealType *ChangeFactor,
  165.                       int X,
  166.                       int Y);
  167. static void RedrawViewWindow(HWND hwnd);
  168. static void RedrawTransformationWindow(HWND hwnd);
  169. static void SetColorIndex(int c);
  170. static void SetColorRGB(int Color[3]);
  171.  
  172. /*****************************************************************************
  173. * DESCRIPTION:                                                               M
  174. * Main module of os2drvs - OS2 2.x graphics driver of IRIT.                     M
  175. *                                                                            *
  176. * PARAMETERS:                                                                M
  177. *   argc, argv:  Command line.                                               M
  178. *                                                                            *
  179. * RETURN VALUE:                                                              M
  180. *   int:         Exit code.                                                  M
  181. *                                                                            *
  182. * KEYWORDS:                                                                  M
  183. *   main                                                                     M
  184. *****************************************************************************/
  185. void main(int argc, char **argv)
  186. {
  187.     static ULONG flFrameFlags;
  188.     static char
  189.     *szClientClass = "os2iritdrv.Client",
  190.     *szViewClass = "os2iritdrv.View",
  191.     *szTransClass = "os2iritdrv.Trans";
  192.     int i, x1, x2, y1, y2,
  193.     Xmin = 190,
  194.     Ymin = 190,
  195.     Width = 600,
  196.     Height = 400;
  197.     QMSG qMsg;
  198.     HPS hps;
  199.     HAB hab;
  200.     HMQ hmq;
  201.     RECTL rcl, DeskTopRcl;
  202.  
  203.     IGConfigureGlobals("os2drvs", argc, argv);
  204.     if (getenv("IRIT_DISPLAY_S") != NULL)
  205.     IGGlblStandAlone = FALSE;
  206.  
  207.     if (IGGlblViewPrefPos &&
  208.     sscanf(IGGlblViewPrefPos, "%d,%d,%d,%d", &x1, &x2, &y1, &y2) == 4) {
  209.     Xmin = x1;
  210.     Ymin = y1;
  211.     Width = x2 - x1;
  212.     Height = y2 - y1;
  213.     }
  214.  
  215.     hab = WinInitialize(0);
  216.     hmq = WinCreateMsgQueue(hab, 0);
  217.  
  218.     WinRegisterClass(hab, szClientClass, ClientWndProc, CS_SIZEREDRAW, 0L);
  219.     WinRegisterClass(hab, szViewClass,   ViewWndProc,   CS_SIZEREDRAW, 0L);
  220.     WinRegisterClass(hab, szTransClass,  TransWndProc,  CS_SIZEREDRAW, 0L);
  221.  
  222.     flFrameFlags = FCF_TITLEBAR      | FCF_SYSMENU  |
  223.                    FCF_SIZEBORDER    | FCF_MINMAX   |
  224.                    FCF_SHELLPOSITION | FCF_TASKLIST |
  225.            FCF_MENU;
  226.  
  227.     hwndFrame = WinCreateStdWindow(
  228.                     HWND_DESKTOP,
  229.                     0,
  230.                     &flFrameFlags,
  231.                     szClientClass,
  232.                     NULL,
  233.                     0L,
  234.                     0,
  235.                     ID_OS2DRVS,
  236.                     &hwndClient);
  237.  
  238.     WinQueryWindowRect(HWND_DESKTOP, &DeskTopRcl);
  239.  
  240.     if (DeskTopRcl.yTop < Ymin + Height)   /* Make sure top side is visible. */
  241.     Ymin = DeskTopRcl.yTop - Height;
  242.  
  243.     WinSetWindowPos(hwndFrame, HWND_TOP, Xmin, Ymin, Width, Height,
  244.                 SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ZORDER);
  245.  
  246.     WinQueryWindowRect(hwndClient, &rcl);
  247.     flFrameFlags &= (~FCF_TASKLIST & ~FCF_MENU);
  248.  
  249.     hwndViewFrame = WinCreateWindow(
  250.             hwndClient,
  251.             szViewClass,
  252.             NULL,
  253.             WS_VISIBLE,
  254.             5,
  255.             5,
  256.             (SHORT) ((rcl.xRight * 4) / 5 - 10),
  257.             (SHORT) (rcl.yTop - 10),
  258.             hwndClient,
  259.             HWND_BOTTOM,
  260.             ID_VIEW,
  261.             NULL,
  262.             NULL);
  263.  
  264.     hwndTransFrame = WinCreateWindow(
  265.             hwndClient,
  266.             szTransClass,
  267.             NULL,
  268.             WS_VISIBLE,
  269.             (SHORT) ((rcl.xRight * 4) / 5),
  270.             5,
  271.             (SHORT) (rcl.xRight / 5 - 5),
  272.             (SHORT) (rcl.yTop - 10),
  273.             hwndClient,
  274.             HWND_BOTTOM,
  275.             ID_TRANS,
  276.             NULL,
  277.             NULL);
  278.  
  279.     if (hwndViewFrame == 0 || hwndTransFrame == 0) {
  280.         DosBeep(1000, 100);
  281.         exit(1);
  282.     }
  283.  
  284.     /* Preallocate the colors that will be used frequently. */
  285.     hps = WinBeginPaint(hwndFrame, 0, NULL);
  286.     for (i = 0; i <= IG_MAX_COLOR; i++) {
  287.     ColorsHighIntensity[i] =
  288.         GpiQueryColorIndex(hps, 0L,
  289.         RGB_COLOR(Colors[i][0], Colors[i][1], Colors[i][2]));
  290.     ColorsLowIntensity[i] =
  291.         GpiQueryColorIndex(hps, 0L,
  292.         RGB_COLOR(Colors[i][0] / 2,
  293.               Colors[i][1] / 2,
  294.               Colors[i][2] / 2));
  295.     }
  296.     WinEndPaint(hps);
  297.  
  298.     /* Set up the reading socket as a secondary thread. */
  299.     if (!IGGlblStandAlone) {
  300.     if (_beginthread(GetInputFromSocket, NULL, 128 * 1024, NULL) == -1) {
  301.         WinMessageBox(HWND_DESKTOP, hwndFrame, "Failed to start thread\n",
  302.               NULL, 0, MB_OK);
  303.         exit(1);
  304.     }
  305.     }
  306.  
  307.     while (WinGetMsg(hab, &qMsg, 0L, 0, 0))
  308.     WinDispatchMsg(hab, &qMsg);
  309.  
  310.     WinDestroyWindow(hwndFrame);
  311.     WinDestroyMsgQueue(hmq);
  312.     WinTerminate(hab);
  313. }
  314.  
  315. /*****************************************************************************
  316. * DESCRIPTION:                                                               M
  317. * Optionally construct a state pop up menu for the driver, if has one.       M
  318. *                                                                            *
  319. * PARAMETERS:                                                                M
  320. *   None                                                                     *
  321. *                                                                            *
  322. * RETURN VALUE:                                                              M
  323. *   void                                                                     M
  324. *                                                                            *
  325. * KEYWORDS:                                                                  M
  326. *   IGCreateStateMenu                                                        M
  327. *****************************************************************************/
  328. void IGCreateStateMenu(void)
  329. {
  330.     WIN_CHECK_MENU(IDM_TGLS_SCREEN, 
  331.            IGGlblTransformMode == IG_TRANS_SCREEN ? MIA_CHECKED : 0);
  332.     WIN_CHECK_MENU(IDM_TGLS_PERSP,
  333.            IGGlblViewMode == IG_VIEW_PERSPECTIVE ? MIA_CHECKED : 0);
  334.     WIN_CHECK_MENU(IDM_TGLS_DEPTH_CUE, IGGlblDepthCue ? MIA_CHECKED : 0);
  335.     WIN_CHECK_MENU(IDM_TGLS_BFACE_CULL, IGGlblBackFaceCull ? MIA_CHECKED : 0);
  336.     WIN_CHECK_MENU(IDM_TGLS_INTERNAL, IGGlblDrawInternal ? MIA_CHECKED : 0);
  337.     WIN_CHECK_MENU(IDM_TGLS_VRTX_NRML, IGGlblDrawVNormal ? MIA_CHECKED : 0);
  338.     WIN_CHECK_MENU(IDM_TGLS_POLY_NRML, IGGlblDrawPNormal ? MIA_CHECKED : 0);
  339.     WIN_CHECK_MENU(IDM_TGLS_CTL_MESH, IGGlblDrawSurfaceMesh ? MIA_CHECKED : 0);
  340.     WIN_CHECK_MENU(IDM_TGLS_SRF_POLYS, IGGlblDrawSurfacePoly ? MIA_CHECKED : 0);
  341.     WIN_CHECK_MENU(IDM_TGLS_4_PER_FLAT, IGGlblFourPerFlat ? MIA_CHECKED : 0);
  342. }
  343.  
  344. /*****************************************************************************
  345. * DESCRIPTION:                                                               *
  346. * A secondary thread that waits for input from socket.                 *
  347. *                                                                            *
  348. * PARAMETERS:                                                                *
  349. *   Data:      Not used.                                                     *
  350. *                                                                            *
  351. * RETURN VALUE:                                                              *
  352. *   void                                                                     *
  353. *****************************************************************************/
  354. static void GetInputFromSocket(void *Data)
  355. {
  356.     while (TRUE) {
  357.     if (IGReadObjectsFromSocket(IGGlblViewMode, &IGGlblDisplayList))
  358.         WinInvalidateRect(hwndViewFrame, NULL, FALSE);
  359.     }
  360. }
  361.  
  362. /*****************************************************************************
  363. * DESCRIPTION:                                                               *
  364. * Trans window call back drawing function.                     *
  365. *                                         *
  366. * PARAMETERS:                                                                *
  367. *   hwnd:     A handle on the window.                                        *
  368. *   msg:      Type of event to handle.                                       *
  369. *   mp1, mp2: Parameters of event.                                           *
  370. *                                                                            *
  371. * RETURN VALUE:                                                              *
  372. *   MRESULT:  Event state code.                                              *
  373. *****************************************************************************/
  374. static MRESULT TransWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  375. {
  376.     static IGGraphicEventType
  377.     LastEvent = IG_EVENT_NONE;
  378.     static int
  379.     LastX = 0,
  380.     Button1Down = FALSE;
  381.     RealType ChangeFactor;
  382.     IGGraphicEventType Event;
  383.     int x, y;
  384.     
  385.     switch (msg) {
  386.         case WM_CREATE:
  387.         break;
  388.     case WM_BUTTON1UP:
  389.         Button1Down = FALSE;
  390.         break;
  391.     case WM_BUTTON1DOWN:
  392.         LastEvent = IG_EVENT_NONE;
  393.         x = SHORT1FROMMP(mp1);
  394.         y = SHORT2FROMMP(mp1);
  395.  
  396.         if ((Event = GetGraphicEvent(&ChangeFactor, x, y))
  397.                                != IG_EVENT_NONE) {
  398.         if (Event == IG_EVENT_QUIT) {
  399.             exit(0);           /* Not the nicest ways to quit. */
  400.         }
  401.         else {
  402.             if (IGProcessEvent(Event,
  403.                        ChangeFactor * IGGlblChangeFactor))
  404.                 WinInvalidateRect(hwndViewFrame, NULL, TRUE);
  405.  
  406.             /* Save the event in case drag operation is performed. */
  407.             LastEvent = Event;
  408.             LastX = x;
  409.         }
  410.         }
  411.         Button1Down = TRUE;
  412.         break;
  413.     case WM_MOUSEMOVE:
  414.         if (Button1Down && LastEvent != IG_EVENT_NONE) {
  415.         ChangeFactor = ((x = SHORT1FROMMP(mp1)) - ((RealType) LastX)) /
  416.                                    TransWidth2;
  417.         if (IGProcessEvent(LastEvent,
  418.                    ChangeFactor * IGGlblChangeFactor))
  419.             WinInvalidateRect(hwndViewFrame, NULL, TRUE);
  420.         LastX = x;
  421.         }
  422.         break;
  423.         case WM_PAINT:
  424.         RedrawTransformationWindow(hwnd);
  425.         break;
  426.         case WM_COMMAND:
  427.         break;
  428.     }
  429.     return WinDefWindowProc(hwnd, msg, mp1, mp2);
  430. }
  431.  
  432. /*****************************************************************************
  433. * DESCRIPTION:                                                               *
  434. * View window call back drawing function.                     *
  435. *                                         *
  436. * PARAMETERS:                                                                *
  437. *   hwnd:     A handle on the window.                                        *
  438. *   msg:      Type of event to handle.                                       *
  439. *   mp1, mp2: Parameters of event.                                           *
  440. *                                                                            *
  441. * RETURN VALUE:                                                              *
  442. *   MRESULT:  Event state code.                                              *
  443. *****************************************************************************/
  444. static MRESULT ViewWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  445. {
  446.     switch (msg) {
  447.         case WM_PAINT:
  448.         RedrawViewWindow(hwnd);
  449.         break;
  450.         case WM_COMMAND:
  451.             switch (SHORT1FROMMP(mp1)) {
  452.             }
  453.             break;
  454.     }
  455.     return WinDefWindowProc(hwnd, msg, mp1, mp2);
  456. }
  457.  
  458. /*****************************************************************************
  459. * DESCRIPTION:                                                               *
  460. * Client (Frame) window call back drawing function.                 *
  461. *                                         *
  462. * PARAMETERS:                                                                *
  463. *   hwnd:     A handle on the window.                                        *
  464. *   msg:      Type of event to handle.                                       *
  465. *   mp1, mp2: Parameters of event.                                           *
  466. *                                                                            *
  467. * RETURN VALUE:                                                              *
  468. *   MRESULT:  Event state code.                                              *
  469. *****************************************************************************/
  470. static MRESULT ClientWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  471. {
  472.     POINTL Pt;
  473.     RECTL rcl;
  474.     HPS hps;
  475.     int Refresh;
  476.     FILEDLG fild;
  477.     static int
  478.     Resized = FALSE;
  479.  
  480.     switch (msg) {
  481.     case WM_CREATE:
  482.         hwndMenu = WinWindowFromID(WinQueryWindow(hwnd, QW_PARENT),
  483.                        FID_MENU);
  484.         break;
  485.         case WM_SIZE:
  486.         Resized = TRUE;
  487.         break;
  488.         case WM_PAINT:
  489.         hps = WinBeginPaint(hwnd, 0, NULL);
  490.  
  491.         WinQueryWindowRect(hwnd, &rcl);
  492.         GpiSetColor(hps, CLR_WHITE);
  493.         Pt.x = Pt.y = 0;
  494.         GpiMove(hps, &Pt);
  495.         Pt.x = rcl.xRight;
  496.         Pt.y = rcl.yTop;
  497.         GpiBox(hps, DRO_OUTLINEFILL, &Pt, 0, 0);
  498.  
  499.         WinEndPaint(hps);
  500.  
  501.         if (Resized) {
  502.             Resized = FALSE;
  503.             
  504.             if (hwndViewFrame)
  505.             WinSetWindowPos(hwndViewFrame, HWND_BOTTOM, 5, 5,
  506.                     (SHORT) ((rcl.xRight * 4) / 5 - 10),
  507.                     (SHORT) (rcl.yTop - 10),
  508.                     SWP_SIZE | SWP_MOVE);
  509.         if (hwndTransFrame)
  510.             WinSetWindowPos(hwndTransFrame, HWND_BOTTOM,
  511.                     (SHORT) (rcl.xRight * 4 / 5), 5,
  512.                     (SHORT) (rcl.xRight / 5 - 5),
  513.                     (SHORT) (rcl.yTop - 10),
  514.                     SWP_SIZE | SWP_MOVE);
  515.         }
  516.             break;
  517.         case WM_COMMAND:
  518.         Refresh = FALSE;
  519.             switch (SHORT1FROMMP(mp1)) {
  520.         case IDM_FILE_SAVE:
  521.             IGSaveCurrentMat(IGGlblViewMode, NULL);
  522.             break;
  523.         case IDM_FILE_SAVE_AS:
  524.             memset(&fild, 0, sizeof(FILEDLG));
  525.             fild.cbSize = sizeof(FILEDLG);
  526.             fild.pszTitle = "Save View Matrix";
  527.             fild.pszOKButton = "Save";
  528.             fild.fl = FDS_OPEN_DIALOG | FDS_CENTER ;
  529.             WinFileDlg(HWND_DESKTOP, hwndClient, &fild);
  530.  
  531.             if (strlen(fild.szFullFile) > 0)
  532.             IGSaveCurrentMat(IGGlblViewMode, fild.szFullFile);
  533.             break;
  534.         case IDM_FILE_QUIT:
  535.             exit(0);
  536.             break;
  537.  
  538.         case IDM_MOUSE_MORE:
  539.             IGHandleState(IG_STATE_MORE_SENSITIVE, TRUE);
  540.             break;
  541.         case IDM_MOUSE_LESS:
  542.             IGHandleState(IG_STATE_LESS_SENSITIVE, TRUE);
  543.             break;
  544.  
  545.         case IDM_STATE_MORE_ISO:
  546.             Refresh = IGHandleState(IG_STATE_MORE_ISOLINES, TRUE);
  547.             break;
  548.         case IDM_STATE_LESS_ISO:
  549.             Refresh = IGHandleState(IG_STATE_LESS_ISOLINES, TRUE);
  550.             break;
  551.         case IDM_STATE_FINER_APPROX:
  552.             Refresh = IGHandleState(IG_STATE_FINER_APPROX, TRUE);
  553.             break;
  554.         case IDM_STATE_COARSER_APPROX:
  555.             Refresh = IGHandleState(IG_STATE_COARSER_APPROX, TRUE);
  556.             break;
  557.         case IDM_STATE_SHORTER_VEC:
  558.             Refresh = IGHandleState(IG_STATE_SHORTER_VECTORS, TRUE);
  559.             break;
  560.         case IDM_STATE_LONGER_VEC:
  561.             Refresh = IGHandleState(IG_STATE_LONGER_VECTORS, TRUE);
  562.             break;
  563.         case IDM_STATE_WIDE_LINES:
  564.             Refresh = IGHandleState(IG_STATE_WIDER_LINES, TRUE);
  565.             break;
  566.         case IDM_STATE_THIN_LINES:
  567.             Refresh = IGHandleState(IG_STATE_NARROW_LINES, TRUE);
  568.             break;
  569.  
  570.         case IDM_TGLS_SCREEN:
  571.             IGHandleState(IG_STATE_SCR_OBJ_TGL, TRUE);
  572.             break;
  573.         case IDM_TGLS_PERSP:
  574.             Refresh = IGHandleState(IG_STATE_PERS_ORTHO_TGL, TRUE);
  575.             break;
  576.         case IDM_TGLS_DEPTH_CUE:
  577.             Refresh = IGHandleState(IG_STATE_DEPTH_CUE, TRUE);
  578.             break;
  579.         case IDM_TGLS_BFACE_CULL:
  580.             Refresh = IGHandleState(IG_STATE_BACK_FACE_CULL, TRUE);
  581.             break;
  582.         case IDM_TGLS_INTERNAL:
  583.             Refresh = IGHandleState(IG_STATE_DRAW_INTERNAL, TRUE);
  584.             break;
  585.         case IDM_TGLS_VRTX_NRML:
  586.             Refresh = IGHandleState(IG_STATE_DRAW_VNORMAL, TRUE);
  587.             break;
  588.         case IDM_TGLS_POLY_NRML:
  589.             Refresh = IGHandleState(IG_STATE_DRAW_PNORMAL, TRUE);
  590.             break;
  591.         case IDM_TGLS_CTL_MESH:
  592.             Refresh = IGHandleState(IG_STATE_DRAW_SRF_MESH, TRUE);
  593.             break;
  594.         case IDM_TGLS_SRF_POLYS:
  595.             Refresh = IGHandleState(IG_STATE_DRAW_SRF_POLY, TRUE);
  596.             break;
  597.         case IDM_TGLS_4_PER_FLAT:
  598.             Refresh = IGHandleState(IG_STATE_FOUR_PER_FLAT, TRUE);
  599.             break;
  600.  
  601.         case IDM_VIEW_FRONT:
  602.             Refresh = IGHandleState(IG_STATE_VIEW_FRONT, TRUE);
  603.             break;
  604.         case IDM_VIEW_SIDE:
  605.             Refresh = IGHandleState(IG_STATE_VIEW_SIDE, TRUE);
  606.             break;
  607.         case IDM_VIEW_TOP:
  608.             Refresh = IGHandleState(IG_STATE_VIEW_TOP, TRUE);
  609.             break;
  610.         case IDM_VIEW_ISOMETRY:
  611.             Refresh = IGHandleState(IG_STATE_VIEW_ISOMETRY, TRUE);
  612.             break;
  613.  
  614.         case IDM_ANIM_ACTIVE:
  615.             WinDlgBox(HWND_DESKTOP, HWND_DESKTOP,
  616.                   AnimWndProc, 0, IDM_ANIM, NULL);
  617.             break;
  618.             }
  619.         if (Refresh)
  620.         WinInvalidateRect(hwndViewFrame, NULL, FALSE);
  621.             break;
  622.     }
  623.     return WinDefWindowProc(hwnd, msg, mp1, mp2);
  624. }
  625.  
  626. /*****************************************************************************
  627. * DESCRIPTION:                                                               *
  628. * Animation (Frame) window call back drawing function.                 *
  629. *                                         *
  630. * PARAMETERS:                                                                *
  631. *   hwnd:     A handle on the window.                                        *
  632. *   msg:      Type of event to handle.                                       *
  633. *   mp1, mp2: Parameters of event.                                           *
  634. *                                                                            *
  635. * RETURN VALUE:                                                              *
  636. *   MRESULT:  Event state code.                                              *
  637. *****************************************************************************/
  638. static MRESULT AnimWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  639. {
  640.     static int
  641.     LastSliderVal = -1;
  642.     POINTL Pt;
  643.     RECTL rcl;
  644.     HPS hps;
  645.     WNDPARAMS wprm; 
  646.     SLDCDATA sldcd;
  647.     int i, j, Spacing;
  648.     char Buffer[10];
  649.  
  650.     switch (msg) {
  651.     case WM_CREATE:
  652.         break;
  653.         case WM_INITDLG:
  654.         hwndSlider = WinWindowFromID(hwnd, ID_ANIM_SLIDER);
  655.  
  656.         wprm.fsStatus = WPM_CTLDATA;
  657.         wprm.cbCtlData = sizeof(SLDCDATA);
  658.         wprm.pCtlData = &sldcd;
  659.  
  660.         if (WinSendMsg(hwndSlider, WM_QUERYWINDOWPARAMS,
  661.                MPFROMP(&wprm), 0)) {
  662.         GlblSliderIncrements = sldcd.usScale1Increments;
  663.         Spacing = sldcd.usScale1Spacing;
  664.         }
  665.  
  666.         for (i = 0; i <= GlblSliderIncrements; i++)
  667.         WinSendMsg(hwndSlider, SLM_SETTICKSIZE,
  668.                MPFROM2SHORT(i, 4), NULL);
  669.  
  670.         for (i = 0; i <= GlblSliderIncrements; i += 10)
  671.             WinSendMsg (hwndSlider, SLM_SETTICKSIZE,
  672.                 MPFROM2SHORT(i, 8), NULL);
  673.             WinSetPresParam (hwndSlider, PP_FONTNAMESIZE,
  674.                              strlen(ID_ANIM_SLIDER_FONT) + 1,
  675.                              ID_ANIM_SLIDER_FONT);
  676.  
  677.         AnimFindAnimationTime(&IGAnimation, IGGlblDisplayList);
  678.  
  679.         for (i = j = 0;
  680.          i <= GlblSliderIncrements;
  681.          i += GlblSliderIncrements / 3, j++) {
  682.         RealType
  683.             t = (IGAnimation.StartT * (3 - j) +
  684.                  IGAnimation.FinalT * j) / 3.0;
  685.  
  686.         sprintf(Buffer, "%4.2f", t);
  687.         WinSendMsg(hwndSlider, SLM_SETSCALETEXT,
  688.                MPFROMSHORT(i), MPFROMP(Buffer));
  689.         }
  690.         break;
  691.         case WM_PAINT:
  692.         hps = WinBeginPaint(hwnd, 0, NULL);
  693.  
  694.         WinQueryWindowRect(hwnd, &rcl);
  695.         GpiSetColor(hps, CLR_DARKGRAY);
  696.         Pt.x = Pt.y = 0;
  697.         GpiMove(hps, &Pt);
  698.         Pt.x = rcl.xRight;
  699.         Pt.y = rcl.yTop;
  700.         GpiBox(hps, DRO_OUTLINEFILL, &Pt, 0, 0);
  701.  
  702.         WinEndPaint(hps);
  703.             break;
  704.         case WM_COMMAND:
  705.         case WM_CONTROL:
  706.         switch (COMMANDMSG(&msg) -> cmd) {
  707.         case ID_ANIM_SLIDER:
  708.                     i = SHORT1FROMMR(WinSendDlgItemMsg(hwnd, ID_ANIM_SLIDER,
  709.                 SLM_QUERYSLIDERINFO,
  710.                                 MPFROM2SHORT(SMA_SLIDERARMPOSITION,
  711.                          SMA_INCREMENTVALUE),
  712.                                 0));
  713.             if (LastSliderVal != i) {
  714.             RealType
  715.                 t = i / 100.0;
  716.  
  717.             LastSliderVal = i;
  718.  
  719.             IGAnimation.RunTime =
  720.                 (IGAnimation.FinalT * t +
  721.                  IGAnimation.StartT * (1.0 - t));
  722.  
  723.             AnimDoSingleStep(&IGAnimation, IGGlblDisplayList);
  724.             }
  725.             break;
  726.         case ID_ANIM_SAVE_FILE:
  727.             IGAnimation.SaveAnimation = !IGAnimation.SaveAnimation;
  728.             WinSendDlgItemMsg(hwnd, ID_ANIM_SAVE_FILE, BM_SETCHECK,
  729.                       MPFROM2SHORT(IGAnimation.SaveAnimation,
  730.                            0),
  731.                       NULL);
  732.             break;
  733.         case ID_ANIM_MIN_TIME:
  734.             HandleGetOneNumber(&IGAnimation.StartT, hwnd);
  735.             break;
  736.         case ID_ANIM_MAX_TIME:
  737.             HandleGetOneNumber(&IGAnimation.FinalT, hwnd);
  738.             break;
  739.         case ID_ANIM_TIME_STEP:
  740.             HandleGetOneNumber(&IGAnimation.Dt, hwnd);
  741.             break;
  742.         case ID_ANIM_BEGIN:
  743.             if (_beginthread(OS2DrvsAnimation, NULL,
  744.                      128 * 1024, NULL) == -1)
  745.             WinMessageBox(HWND_DESKTOP, hwndFrame,
  746.                       "Failed to start animation thread\n",
  747.                       NULL, 0, MB_OK);
  748.             break;
  749.         case ID_ANIM_STOP:
  750.             IGAnimation.StopAnim = TRUE;
  751.             break;
  752.         case ID_ANIM_DISMISS:
  753.                     WinDismissDlg(hwnd, FALSE);
  754.             break;
  755.         default:
  756.             break;
  757.         }
  758.             break;
  759.     }
  760.     return WinDefWindowProc(hwnd, msg, mp1, mp2);
  761. }
  762.  
  763. /*****************************************************************************
  764. * DESCRIPTION:                                                               *
  765. *   A secondary thread to execute an animation sequence.                     *
  766. *                                                                            *
  767. * PARAMETERS:                                                                *
  768. *   Data:      Not used.                                                     *
  769. *                                                                            *
  770. * RETURN VALUE:                                                              *
  771. *   void                                                                     *
  772. *****************************************************************************/
  773. static void OS2DrvsAnimation(void *Data)
  774. {
  775.     AnimDoAnimation(&IGAnimation, IGGlblDisplayList);
  776. }
  777.  
  778. /*****************************************************************************
  779. * DESCRIPTION:                                                               *
  780. *   Gets one number from the user, and make sure display is consistent.      *
  781. *                                                                            *
  782. * PARAMETERS:                                                                *
  783. *   t:        Numeric data to modify.                                        *
  784. *   hwnd:     A handle on the window.                                        *
  785. *                                                                            *
  786. * RETURN VALUE:                                                              *
  787. *   void                                                                     *
  788. *****************************************************************************/
  789. static void HandleGetOneNumber(RealType *t, HWND hwnd)
  790. {
  791.     int i, j;
  792.     char Buffer[10];
  793.     RealType
  794.     RunTimeFrac = (IGAnimation.RunTime - IGAnimation.StartT) /
  795.                (IGAnimation.FinalT - IGAnimation.StartT);
  796.  
  797.     GlblAnimGetTime = *t;
  798.     WinDlgBox(HWND_DESKTOP, HWND_DESKTOP, AnimGetTimeWndProc,
  799.           0, ID_ANIM_GET_TIME, NULL);
  800.     *t = GlblAnimGetTime;
  801.  
  802.     IGAnimation.RunTime = (IGAnimation.FinalT * RunTimeFrac +
  803.                IGAnimation.StartT * (1.0 - RunTimeFrac));
  804.  
  805.     for (i = j = 0;
  806.      i <= GlblSliderIncrements;
  807.      i += GlblSliderIncrements / 3, j++) {
  808.     RealType
  809.         t = (IGAnimation.StartT * (3 - j) +
  810.          IGAnimation.FinalT * j) / 3.0;
  811.  
  812.     sprintf(Buffer, "%4.2f", t);
  813.     WinSendMsg(hwndSlider, SLM_SETSCALETEXT,
  814.            MPFROMSHORT(i), MPFROMP(Buffer));
  815.     }
  816. }
  817.  
  818. /*****************************************************************************
  819. * DESCRIPTION:                                                               *
  820. * Animation (Frame) window call back drawing function.                 *
  821. *                                         *
  822. * PARAMETERS:                                                                *
  823. *   hwnd:     A handle on the window.                                        *
  824. *   msg:      Type of event to handle.                                       *
  825. *   mp1, mp2: Parameters of event.                                           *
  826. *                                                                            *
  827. * RETURN VALUE:                                                              *
  828. *   MRESULT:  Event state code.                                              *
  829. *****************************************************************************/
  830. static MRESULT AnimGetTimeWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  831. {
  832.     POINTL Pt;
  833.     RECTL rcl;
  834.     HPS hps;
  835.     char Line[LINE_LEN];
  836.  
  837.     switch (msg) {
  838.     case WM_CREATE:
  839.         break;
  840.         case WM_PAINT:
  841.         hps = WinBeginPaint(hwnd, 0, NULL);
  842.  
  843.         WinQueryWindowRect(hwnd, &rcl);
  844.         GpiSetColor(hps, CLR_PALEGRAY);
  845.         Pt.x = Pt.y = 0;
  846.         GpiMove(hps, &Pt);
  847.         Pt.x = rcl.xRight;
  848.         Pt.y = rcl.yTop;
  849.         GpiBox(hps, DRO_OUTLINEFILL, &Pt, 0, 0);
  850.  
  851.         WinEndPaint(hps);
  852.             break;
  853.         case WM_COMMAND:
  854.         case WM_CONTROL:
  855.         switch (COMMANDMSG(&msg) -> cmd) {
  856.         case ID_ANIM_GET_TIME_ENT:
  857.             WinQueryDlgItemText(hwnd, ID_ANIM_GOT_TIME,
  858.                     LINE_LEN, Line);
  859.             if (sscanf(Line, "%lf", &GlblAnimGetTime) == 1)
  860.                 WinDismissDlg(hwnd, FALSE);
  861.             else
  862.                 DosBeep(300, 200);
  863.             break;
  864.         case ID_ANIM_GET_TIME_CAN:
  865.                     WinDismissDlg(hwnd, FALSE);
  866.             break;
  867.         case ID_ANIM_GOT_TIME:
  868.             break;
  869.         default:
  870.             break;
  871.         }
  872.             break;
  873.     }
  874.     return WinDefWindowProc(hwnd, msg, mp1, mp2);
  875. }
  876.  
  877. /*****************************************************************************
  878. * DESCRIPTION:                                                               *
  879. * Handles input events                                                       *
  880. *                                                                            *
  881. * PARAMETERS:                                                                *
  882. *   ChangeFactor:        A continuous numeric value between -1 and 1. This   *
  883. *             value will be used to set amount of event such as   *
  884. *             rotation or translation.                 *
  885. *   X, Y:         Location of mouse event.                 *
  886. *                                                                            *
  887. * RETURN VALUE:                                                              *
  888. *   IGGraphicEventType:  Type of new event.                                  *
  889. *****************************************************************************/
  890. static IGGraphicEventType GetGraphicEvent(RealType *ChangeFactor, int X, int Y)
  891. {
  892.     int i;
  893.     IGGraphicEventType
  894.     RetVal = IG_EVENT_NONE;
  895.     RealType XPos, YPos;
  896.  
  897.     XPos = ((RealType) X) / TransWidth;
  898.     YPos = ((RealType) Y) / TransHeight;
  899.  
  900.     /* Make sure we are in bound in the X direction. */
  901.     if (XPos < (1.0 - INTERACT_SUB_WINDOW_WIDTH) / 2.0 ||
  902.         XPos > 1.0 - (1.0 - INTERACT_SUB_WINDOW_WIDTH) / 2.0)
  903.     return IG_EVENT_NONE;
  904.  
  905.     /* Now search the sub window the event occured in. */
  906.     for (i = 0; i < INTERACT_NUM_OF_SUB_WNDWS; i++) {
  907.         if (InteractMenu.SubWindows[i].Y <= YPos &&
  908.         InteractMenu.SubWindows[i].Y + INTERACT_SUB_WINDOW_HEIGHT >=
  909.                                       YPos) {
  910.         RetVal = InteractMenu.SubWindows[i].Event;
  911.         break;
  912.     }
  913.     }
  914.  
  915.     /* Take care of special cases in which the window should be updated. */
  916.     switch (RetVal) {
  917.     case IG_EVENT_SCR_OBJ_TGL:
  918.         IGGlblTransformMode = IGGlblTransformMode == IG_TRANS_OBJECT ?
  919.                              IG_TRANS_SCREEN :
  920.                              IG_TRANS_OBJECT;
  921.         WinInvalidateRect(hwndTransFrame, NULL, TRUE);
  922.         IGCreateStateMenu();
  923.         break;
  924.     case IG_EVENT_PERS_ORTHO_TGL:
  925.         IGGlblViewMode = IGGlblViewMode == IG_VIEW_PERSPECTIVE ?
  926.                            IG_VIEW_ORTHOGRAPHIC :
  927.                            IG_VIEW_PERSPECTIVE;
  928.         WinInvalidateRect(hwndTransFrame, NULL, TRUE);
  929.         IGCreateStateMenu();
  930.         break;
  931.     case IG_EVENT_DEPTH_CUE:
  932.         IGGlblDepthCue = !IGGlblDepthCue;
  933.         WinInvalidateRect(hwndTransFrame, NULL, TRUE);
  934.         IGCreateStateMenu();
  935.         break;
  936.     default:
  937.         break;
  938.     }
  939.  
  940.     *ChangeFactor = (((RealType) X) - TransWidth2) / TransWidth2;
  941.  
  942.     return RetVal;
  943. }
  944.  
  945. /*****************************************************************************
  946. * DESCRIPTION:                                                               M
  947. * Redraws the view window.                             M
  948. *                                                                            *
  949. * PARAMETERS:                                                                M
  950. *   None                                                                     M
  951. *                                                                            *
  952. * RETURN VALUE:                                                              M
  953. *   void                                                                     M
  954. *                                                                            *
  955. * KEYWORDS:                                                                  M
  956. *   IGRedrawViewWindow                                                       M
  957. *****************************************************************************/
  958. void IGRedrawViewWindow(void)
  959. {
  960.     WinInvalidateRect(hwndViewFrame, NULL, FALSE);
  961. }
  962.  
  963. /*****************************************************************************
  964. * DESCRIPTION:                                                               *
  965. * Redraws the view window.                                                   *
  966. *                                                                            *
  967. * PARAMETERS:                                                                *
  968. *   hwnd:       A handle on the window.                                      *
  969. *                                                                            *
  970. * RETURN VALUE:                                                              *
  971. *   void                                                                     *
  972. *****************************************************************************/
  973. static void RedrawViewWindow(HWND hwnd)
  974. {
  975.     RECTL rcl;
  976.     IPObjectStruct *PObj, *MatObj;
  977.     MatrixType CrntViewMat;
  978.  
  979.     CurrentHps = WinBeginPaint(hwnd, 0, NULL);
  980.     WinQueryWindowRect(hwnd, &rcl);
  981.     ViewWidth2 = rcl.xRight / 2;
  982.     ViewHeight2 = rcl.yTop / 2;
  983.     WinFillRect(CurrentHps, &rcl, CLR_BLUE);
  984.  
  985.     /* Slim chance that a race will oocur if the following test and set */
  986.     /* is done simultanuously. Should use semaphors probably.            */
  987.     while (IGGlblDisplayListIsUsed) {
  988.     IritSleep(10);
  989.     DosEnterCritSec();
  990.     if (!IGGlblDisplayListIsUsed) {
  991.         IGGlblDisplayListIsUsed = TRUE;
  992.         DosExitCritSec();
  993.         break;
  994.     }
  995.     DosExitCritSec();
  996.     }
  997.  
  998.     switch (IGGlblViewMode) {         /* Update the current view. */
  999.     case IG_VIEW_ORTHOGRAPHIC:
  1000.         GEN_COPY(CrntViewMat, IritPrsrViewMat, sizeof(MatrixType));
  1001.         break;
  1002.     case IG_VIEW_PERSPECTIVE:
  1003.         MatMultTwo4by4(CrntViewMat, IritPrsrViewMat, IritPrsrPrspMat);
  1004.         break;
  1005.     }
  1006.  
  1007.     for (PObj = IGGlblDisplayList, IGGlblAbortKeyPressed = FALSE;
  1008.      PObj != NULL && !IGGlblAbortKeyPressed;
  1009.      PObj = PObj -> Pnext) {
  1010.     int Visible = TRUE;
  1011.  
  1012.     if ((MatObj = AttrGetObjectObjAttrib(PObj, "_animation_mat")) != NULL &&
  1013.         IP_IS_MAT_OBJ(MatObj)) {
  1014.         if (Visible = AttrGetObjectIntAttrib(PObj, "_isvisible")) {
  1015.         MatMultTwo4by4(IGGlblCrntViewMat,
  1016.                    *MatObj -> U.Mat, IritPrsrViewMat);
  1017.             if (IGGlblViewMode == IG_VIEW_PERSPECTIVE) 
  1018.                 MatMultTwo4by4(IGGlblCrntViewMat,
  1019.                        IGGlblCrntViewMat, IritPrsrPrspMat);
  1020.         }
  1021.     }
  1022.     else
  1023.         GEN_COPY(IGGlblCrntViewMat, CrntViewMat, sizeof(MatrixType));
  1024.  
  1025.     if (Visible)
  1026.         IGDrawObject(PObj);
  1027.     }
  1028.  
  1029.     IGGlblDisplayListIsUsed = FALSE;
  1030.  
  1031.     WinEndPaint(CurrentHps);
  1032.     CurrentHps = 0;
  1033. }
  1034.  
  1035. /*****************************************************************************
  1036. * DESCRIPTION:                                                               *
  1037. * Redraws the transformation window.                         *
  1038. *                                                                            *
  1039. * PARAMETERS:                                                                *
  1040. *   hwnd:       A handle on the window.                                      *
  1041. *                                                                            *
  1042. * RETURN VALUE:                                                              *
  1043. *   void                                                                     *
  1044. *****************************************************************************/
  1045. static void RedrawTransformationWindow(HWND hwnd)
  1046. {
  1047.     int i, cxChar, cyChar,
  1048.     SubTransWidth, SubTransHeight, SubTransPosX, SubTransPosY;
  1049.     POINTL Pt;
  1050.     RECTL rcl;
  1051.     FONTMETRICS fm;
  1052.     HPS hps = WinBeginPaint(hwnd, 0, NULL);
  1053.  
  1054.     GpiQueryFontMetrics(WinGetPS(hwnd), (LONG) sizeof(fm), &fm);
  1055.     cxChar = fm.lAveCharWidth;
  1056.     cyChar = fm.lMaxBaselineExt;
  1057.  
  1058.     /* Make sure the menu is consistent with internatal data. */
  1059.     InteractMenu.SubWindows[0].Str =
  1060.     IGGlblTransformMode == IG_TRANS_OBJECT ? "Object Coords."
  1061.                            : "Screen Coords.";
  1062.     InteractMenu.SubWindows[1].Str =
  1063.     IGGlblViewMode == IG_VIEW_PERSPECTIVE ? "Perspective"
  1064.                           : "Orthographic";
  1065.     InteractMenu.SubWindows[10].Str =
  1066.     IGGlblDepthCue ? "Depth cue" : "No depth cue";
  1067.         
  1068.     WinQueryWindowRect(hwnd, &rcl);
  1069.     TransWidth = rcl.xRight;
  1070.     TransWidth2 = rcl.xRight / 2;
  1071.     TransHeight = rcl.yTop;
  1072.  
  1073.     SubTransWidth = (int) (TransWidth * INTERACT_SUB_WINDOW_WIDTH);
  1074.     SubTransHeight = (int) (TransHeight *
  1075.                 INTERACT_SUB_WINDOW_HEIGHT);
  1076.     SubTransPosX = (TransWidth - SubTransWidth) / 2;
  1077.  
  1078.     GpiSetColor(hps, CLR_BLACK);
  1079.     Pt.x = Pt.y = 0;
  1080.     GpiMove(hps, &Pt);
  1081.     Pt.x = TransWidth;
  1082.     Pt.y = TransHeight;
  1083.     GpiBox(hps, DRO_OUTLINEFILL, &Pt, 0, 0);
  1084.  
  1085.     for (i = 0; i < INTERACT_NUM_OF_SUB_WNDWS; i++) {
  1086.     GpiSetColor(hps, InteractMenu.SubWindows[i].Color);
  1087.     SubTransPosY = (int) (TransHeight *
  1088.                   InteractMenu.SubWindows[i].Y);
  1089.     
  1090.     GPI_MOVE(SubTransPosX, SubTransPosY);
  1091.     GPI_LINE(SubTransPosX + SubTransWidth, SubTransPosY);
  1092.     GPI_LINE(SubTransPosX + SubTransWidth,
  1093.          SubTransPosY + SubTransHeight);
  1094.     GPI_LINE(SubTransPosX, SubTransPosY + SubTransHeight);
  1095.     GPI_LINE(SubTransPosX, SubTransPosY);
  1096.     if (InteractMenu.SubWindows[i].TextInside) {
  1097.         GPI_CHAR_STR_AT(InteractMenu.SubWindows[i].Str,
  1098.                 TransWidth / 2,
  1099.                 SubTransPosY + SubTransHeight / 2);
  1100.     }
  1101.     else {
  1102.         GPI_CHAR_STR_AT(InteractMenu.SubWindows[i].Str,
  1103.                 (TransWidth - SubTransWidth) / 3,
  1104.                 SubTransPosY + SubTransHeight / 2);
  1105.         GPI_MOVE(SubTransPosX + SubTransWidth / 2, SubTransPosY);
  1106.         GPI_LINE(SubTransPosX + SubTransWidth / 2,
  1107.              SubTransPosY + SubTransHeight);
  1108.     }
  1109.     }
  1110.  
  1111.     for (i = 0; i < INTERACT_NUM_OF_STRINGS; i++) {
  1112.     GpiSetColor(hps, InteractMenu.Strings[i].Color);
  1113.     GPI_CHAR_STR_AT(InteractMenu.Strings[i].Str,
  1114.             (int) (InteractMenu.Strings[i].X * TransWidth),
  1115.             (int) (InteractMenu.Strings[i].Y * TransHeight));
  1116.     }
  1117.  
  1118.     WinEndPaint(hps);
  1119. }
  1120.  
  1121. /*****************************************************************************
  1122. * DESCRIPTION:                                                               M
  1123. * Low level 2D drawing routine. Coordinates are normalized to -1 to 1 by     M
  1124. * this time.                                                                 M
  1125. *                                                                            *
  1126. * PARAMETERS:                                                                M
  1127. *   X, Y:    Coordinates of 2D location to move to.                          M
  1128. *                                                                            *
  1129. * RETURN VALUE:                                                              M
  1130. *   void                                                                     M
  1131. *                                                                            *
  1132. * KEYWORDS:                                                                  M
  1133. *   IGMoveTo2D                                                               M
  1134. *****************************************************************************/
  1135. void IGMoveTo2D(RealType X, RealType Y)
  1136. {
  1137.     POINTL Pt;
  1138.  
  1139.     Pt.x = OS2_MAP_X_COORD(X);
  1140.     Pt.y = OS2_MAP_Y_COORD(Y);
  1141.     GpiMove(CurrentHps, &Pt);
  1142. }
  1143.  
  1144. /*****************************************************************************
  1145. * DESCRIPTION:                                                               M
  1146. * Low level 2D drawing routine. Coordinates are normalized to -1 to 1 by     M
  1147. * this time.                                                                 M
  1148. *                                                                            *
  1149. * PARAMETERS:                                                                M
  1150. *   X, Y:    Coordinates of 2D location to draw to.                          M
  1151. *                                                                            *
  1152. * RETURN VALUE:                                                              M
  1153. *   void                                                                     M
  1154. *                                                                            *
  1155. * KEYWORDS:                                                                  M
  1156. *   IGLineTo2D                                                               M
  1157. *****************************************************************************/
  1158. void IGLineTo2D(RealType X, RealType Y)
  1159. {
  1160.     POINTL Pt;
  1161.  
  1162.     Pt.x = OS2_MAP_X_COORD(X);
  1163.     Pt.y = OS2_MAP_Y_COORD(Y);
  1164.     GpiLine(CurrentHps, &Pt);
  1165. }
  1166.  
  1167. /*****************************************************************************
  1168. * DESCRIPTION:                                                               M
  1169. * Sets the intensity of a color (high or low).                     M
  1170. *                                                                            *
  1171. * PARAMETERS:                                                                M
  1172. *   High:     TRUE for high, FALSE for low.                                  M
  1173. *                                                                            *
  1174. * RETURN VALUE:                                                              M
  1175. *   void                                                                     M
  1176. *                                                                            *
  1177. * KEYWORDS:                                                                  M
  1178. *   IGSetColorIntensity                                                      M
  1179. *****************************************************************************/
  1180. void IGSetColorIntensity(int High)
  1181. {
  1182.     if (!CurrentHps)
  1183.     return;
  1184.     GpiSetColor(CurrentHps,
  1185.         High ? CrntColorHighIntensity : CrntColorLowIntensity);
  1186.  
  1187.     IGGlblIntensityHighState = High;
  1188. }
  1189.  
  1190. /*****************************************************************************
  1191. * DESCRIPTION:                                                               M
  1192. * Sets the color of an object according to its color/rgb attributes.         M
  1193. *   If object has an RGB attribute it will be used. Otherwise, if the object M
  1194. * has a COLOR attribute it will use. Otherwise, WHITE will be used.         M
  1195. *                                                                            *
  1196. * PARAMETERS:                                                                M
  1197. *   PObj:      To set the drawing color to its color.                        M
  1198. *                                                                            *
  1199. * RETURN VALUE:                                                              M
  1200. *   void                                                                     M
  1201. *                                                                            *
  1202. * KEYWORDS:                                                                  M
  1203. *   IGSetColorObj                                                            M
  1204. *****************************************************************************/
  1205. void IGSetColorObj(IPObjectStruct *PObj)
  1206. {
  1207.     int c, Color[3];
  1208.  
  1209.     if (AttrGetObjectRGBColor(PObj, &Color[0], &Color[1], &Color[2])) {
  1210.     SetColorRGB(Color);
  1211.     }
  1212.     else if ((c = AttrGetObjectColor(PObj)) != IP_ATTR_NO_COLOR) {
  1213.     SetColorIndex(c);
  1214.     }
  1215.     else {
  1216.     /* Use white as default color: */
  1217.     SetColorIndex(IG_IRIT_WHITE);
  1218.     }
  1219. }
  1220.  
  1221. /*****************************************************************************
  1222. * DESCRIPTION:                                                               M
  1223. * Sets the line width to draw the given object, in pixels.             M
  1224. *                                                                            *
  1225. * PARAMETERS:                                                                M
  1226. *   Width:    In pixels of lines to draw with.                               M
  1227. *                                                                            *
  1228. * RETURN VALUE:                                                              M
  1229. *   void                                                                     M
  1230. *                                                                            *
  1231. * KEYWORDS:                                                                  M
  1232. *   IGSetWidthObj                                                            M
  1233. *****************************************************************************/
  1234. void IGSetWidthObj(int Width)
  1235. {
  1236.     GpiSetLineWidthGeom(CurrentHps, Width);
  1237. }
  1238.  
  1239. /*****************************************************************************
  1240. * DESCRIPTION:                                                               *
  1241. * Sets the color according to the given color index.                     *
  1242. *                                                                            *
  1243. * PARAMETERS:                                                                *
  1244. *   color:     Index of color to use. Must be between 0 and IG_MAX_COLOR.    *
  1245. *                                                                            *
  1246. * RETURN VALUE:                                                              *
  1247. *   void                                                                     *
  1248. *****************************************************************************/
  1249. static void SetColorIndex(int color)
  1250. {
  1251.     if (color > IG_MAX_COLOR)
  1252.     color = IG_IRIT_WHITE;
  1253.  
  1254.     CrntColorHighIntensity = ColorsHighIntensity[color];
  1255.     CrntColorLowIntensity = ColorsLowIntensity[color];
  1256.  
  1257.     if (CurrentHps) {
  1258.     GpiSetColor(CurrentHps, CrntColorHighIntensity);
  1259. }
  1260.  
  1261.     IGGlblIntensityHighState = TRUE;
  1262. }
  1263.  
  1264. /*****************************************************************************
  1265. * DESCRIPTION:                                                               *
  1266. * Sets the color according to the given RGB values.                 *
  1267. *                                                                            *
  1268. * PARAMETERS:                                                                *
  1269. *   Color:      An RGB vector of integer values between 0 and 255.           *
  1270. *                                                                            *
  1271. * RETURN VALUE:                                                              *
  1272. *   void                                                                     *
  1273. *****************************************************************************/
  1274. static void SetColorRGB(int Color[3])
  1275. {
  1276.     if (!CurrentHps)
  1277.     return;
  1278.  
  1279.     CrntColorHighIntensity =
  1280.     GpiQueryColorIndex(CurrentHps, 0L,
  1281.                RGB_COLOR(Color[0], Color[1], Color[2]));
  1282.     CrntColorLowIntensity =
  1283.     GpiQueryColorIndex(CurrentHps, 0L,
  1284.                RGB_COLOR(Color[0] / 2, Color[1] / 2, Color[2] / 2));
  1285.  
  1286.     GpiSetColor(CurrentHps, CrntColorHighIntensity);
  1287.  
  1288.     IGGlblIntensityHighState = TRUE;
  1289. }
  1290.  
  1291. /*****************************************************************************
  1292. * DESCRIPTION:                                                               M
  1293. * Handles the events of the pop up window.                                   M
  1294. *                                                                            *
  1295. * PARAMETERS:                                                                M
  1296. *   State:      Event to handle.                                             M
  1297. *   Refresh:    Do we need to refresh the screen according to what we know   M
  1298. *        on entry.                             M
  1299. *                                                                            *
  1300. * RETURN VALUE:                                                              M
  1301. *   int:        TRUE, if we need to refresh the screen.                      M
  1302. *                                                                            *
  1303. * KEYWORDS:                                                                  M
  1304. *   IGHandleState                                                            M
  1305. *****************************************************************************/
  1306. int IGHandleState(int State, int Refresh)
  1307. {
  1308.     int UpdateView = TRUE;
  1309.  
  1310.     switch (State) {
  1311.         case IG_STATE_SCR_OBJ_TGL:
  1312.     case IG_STATE_PERS_ORTHO_TGL:
  1313.     case IG_STATE_DEPTH_CUE:
  1314.         WinInvalidateRect(hwndTransFrame, NULL, TRUE);
  1315.     default:
  1316.         UpdateView = IGDefaultStateHandler(State, Refresh);
  1317.         break;
  1318.     }
  1319.  
  1320.     WinInvalidateRect(hwndTransFrame, NULL, TRUE);
  1321.     IGCreateStateMenu();
  1322.  
  1323.     return UpdateView;
  1324. }
  1325.  
  1326. /*****************************************************************************
  1327. * DESCRIPTION:                                                               M
  1328. * Make some sound.                                                           M
  1329. *                                                                            *
  1330. * PARAMETERS:                                                                M
  1331. *   None                                                                     M
  1332. *                                                                            *
  1333. * RETURN VALUE:                                                              M
  1334. *   void                                                                     M
  1335. *                                                                            *
  1336. * KEYWORDS:                                                                  M
  1337. *   IGIritBeep                                                               M
  1338. *****************************************************************************/
  1339. void IGIritBeep(void)
  1340. {
  1341.     DosBeep(1000, 100);
  1342. }
  1343.  
  1344. /*****************************************************************************
  1345. * DESCRIPTION:                                                               M
  1346. *   Should we stop this animation?                         M
  1347. *                                                                            *
  1348. * PARAMETERS:                                                                M
  1349. *   Anim:     The animation to abort.                                        M
  1350. *                                                                            *
  1351. * RETURN VALUE:                                                              M
  1352. *   int:      TRUE if we need to abort, FALSE otherwise.                     M
  1353. *                                                                            *
  1354. * KEYWORDS:                                                                  M
  1355. *   AnimCheckInterrupt                                                       M
  1356. *****************************************************************************/
  1357. int AnimCheckInterrupt(AnimationStruct *Anim)
  1358. {
  1359.     if (Anim ->StopAnim)
  1360.     fprintf(stderr, "\nAnimation was interrupted by the user.\n");
  1361.  
  1362.     return Anim -> StopAnim;
  1363. }
  1364.