home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 5 / MA_Cover_5.iso / ppc / mesa / src-tk / tkwndws.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-01-31  |  30.2 KB  |  1,190 lines

  1. /* $Id */
  2.  
  3. /*
  4.  * $Log: tkwndws.c,v $
  5.  * Revision 1.4  1997/08/01 20:00:00  brianp
  6.  * applied more Cynus-Win32 changes from Stephane Rehel
  7.  *
  8.  * Revision 1.3  1997/05/03 03:05:07  brianp
  9.  * added & to tkhpalette parameter to WMesaCreateContext()
  10.  *
  11.  * Revision 1.2  1997/04/14 21:58:35  brianp
  12.  * fixed C++ style comments
  13.  * added Cygnus-Win32 changes from Stephane
  14.  *
  15.  */
  16.  
  17.  
  18. /*
  19.  * This is the MS Window version of tk.
  20.  * Based on SGI code.  See copyright below.
  21.  */
  22.  
  23.  
  24. /*
  25.  * (c) Copyright 1993, Silicon Graphics, Inc.
  26.  * ALL RIGHTS RESERVED
  27.  * Permission to use, copy, modify, and distribute this software for
  28.  * any purpose and without fee is hereby granted, provided that the above
  29.  * copyright notice appear in all copies and that both the copyright notice
  30.  * and this permission notice appear in supporting documentation, and that
  31.  * the name of Silicon Graphics, Inc. not be used in advertising
  32.  * or publicity pertaining to distribution of the software without specific,
  33.  * written prior permission.
  34.  *
  35.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  36.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  37.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  38.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  39.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  40.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  41.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  42.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  43.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  44.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  45.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  46.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  47.  *
  48.  * US Government Users Restricted Rights
  49.  * Use, duplication, or disclosure by the Government is subject to
  50.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  51.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  52.  * clause at DFARS 252.227-7013 and/or in similar or successor
  53.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  54.  * Unpublished-- rights reserved under the copyright laws of the
  55.  * United States.  Contractor/manufacturer is Silicon Graphics,
  56.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  57.  *
  58.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  59.  */
  60.  
  61. /* Mesa Tweaking by: Mark E. Peterson (markp@ic.mankato.mn.us) */
  62.  
  63. #include <windows.h>
  64. #include <stdio.h>
  65. #include <stdlib.h>
  66. #include <string.h>
  67. #include "gltk.h"
  68. #include "gl\wmesa.h"
  69.  
  70. #define static
  71.  
  72. #if defined(__cplusplus) || defined(c_plusplus)
  73. #define class c_class
  74. #endif
  75.  
  76. #if DBG
  77. #define TKASSERT(x)                                     \
  78. if ( !(x) ) {                                           \
  79.     PrintMessage("%s(%d) Assertion failed %s\n",        \
  80.         __FILE__, __LINE__, #x);                        \
  81. }
  82. #else
  83. #define TKASSERT(x)
  84. #endif  /* DBG */
  85.  
  86. /******************************************************************************/
  87.  
  88. #ifdef __CYGWIN32__
  89. #define WNDCLASSW WNDCLASS
  90. #endif
  91.  
  92. static struct _WINDOWINFO {
  93.     int x, y;
  94.     int width, height;
  95.     GLenum type;
  96.     GLenum dmPolicy;
  97.     int ipfd;
  98.     BOOL bDefPos;
  99. } windInfo = {
  100.     0, 0, 100, 100, TK_INDEX | TK_SINGLE, TK_MINIMUM_CRITERIA, 0, TRUE
  101. };
  102.  
  103.  
  104. static HWND     tkhwnd     = NULL;
  105. static HDC      tkhdc      = NULL;
  106. static HPALETTE tkhpalette = NULL;
  107. GLboolean tkPopupEnable = TRUE;
  108.  
  109. /* Fixed palette support.*/
  110.  
  111. #define BLACK   PALETTERGB(0,0,0)
  112. #define WHITE   PALETTERGB(255,255,255)
  113. #define NUM_STATIC_COLORS   (COLOR_BTNHIGHLIGHT - COLOR_SCROLLBAR + 1)
  114.  
  115. static void (*ExposeFunc)(int, int)              = NULL;
  116. static void (*ReshapeFunc)(GLsizei, GLsizei)     = NULL;
  117. static void (*DisplayFunc)(void)                 = NULL;
  118. static GLenum (*KeyDownFunc)(int, GLenum)        = NULL;
  119. static GLenum (*MouseDownFunc)(int, int, GLenum) = NULL;
  120. static GLenum (*MouseUpFunc)(int, int, GLenum)   = NULL;
  121. static GLenum (*MouseMoveFunc)(int, int, GLenum) = NULL;
  122. static void (*IdleFunc)(void)                    = NULL;
  123.  
  124. static char     *lpszClassName = "tkLibWClass";
  125. static WCHAR    *lpszClassNameW = L"tkLibWClass";
  126.  
  127. long FAR PASCAL _export tkWndProc(HWND hWnd, UINT message, DWORD wParam, LONG lParam);
  128. static unsigned char ComponentFromIndex(int i, int nbits, int shift );
  129. static void PrintMessage( const char *Format, ... );
  130. /*static PALETTEENTRY *FillRgbPaletteEntries( PIXELFORMATDESCRIPTOR *Pfd, PALETTEENTRY *Entries, UINT Count );*/
  131. static HPALETTE CreateCIPalette( HDC Dc );
  132. static HPALETTE CreateRGBPalette( HDC hdc );
  133. static void DestroyThisWindow( HWND Window );
  134. static void CleanUp( void );
  135. static void DelayPaletteRealization( void );
  136. static long RealizePaletteNow( HDC Dc, HPALETTE Palette);
  137. static void ForceRedraw( HWND Window );
  138. static void *AllocateMemory( size_t Size );
  139. static void *AllocateZeroedMemory( size_t Size );
  140. static void FreeMemory( void *Chunk );
  141.  
  142. /*
  143.  *  Prototypes for the debugging functions go here
  144.  */
  145.  
  146. #define DBGFUNC 0
  147. #if DBGFUNC
  148.  
  149. static void DbgPrintf( const char *Format, ... );
  150. static void pwi( void );
  151. static void pwr(RECT *pr);
  152. /*static void ShowPixelFormat(HDC hdc);*/
  153.  
  154. #endif
  155. #define NCOLORS 17
  156. float tkRGBMap[NCOLORS][3] = {
  157.     {0,0,0},
  158.     {0,0,0},
  159.     {0,0,0},
  160.     {0,0,0},
  161.     {0,0,0},
  162.     {0,0,0},
  163.     {0,0,0},
  164.     {0,0,0},
  165.     {0,0,0},
  166.     {0,0,0},
  167.     {1,0,0},
  168.     {0,1,0},
  169.     {1,1,0},
  170.     {0,0,1},
  171.     {1,0,1},
  172.     {0,1,1},
  173.     {1,1,1}
  174. };
  175.  
  176.  
  177. /***************************************************************
  178.  *                                                             *
  179.  *  Exported Functions go here                                 *
  180.  *                                                             *
  181.  ***************************************************************/
  182.  
  183. void tkErrorPopups(GLboolean bEnable)
  184. {
  185.     tkPopupEnable = bEnable;
  186. }
  187.  
  188. void tkCloseWindow(void)
  189. {
  190.     DestroyThisWindow(tkhwnd);
  191.     /*
  192.     if (w.cMain) {
  193.        XMesaDestroyContext(w.cMain);
  194.     }
  195.     */
  196. #ifdef FX
  197.     fxMesaDestroyContext(NULL);
  198. #else
  199.     WMesaDestroyContext();
  200. #endif
  201. }
  202.  
  203.  
  204. void tkExec(void)
  205. {
  206.     MSG Message;
  207.  
  208.     /*
  209.      *  WM_SIZE gets delivered before we get here!
  210.      */
  211.  
  212.     if (ReshapeFunc)
  213.     {
  214.         RECT ClientRect;
  215.  
  216.         GetClientRect(tkhwnd, &ClientRect);
  217.         (*ReshapeFunc)(ClientRect.right, ClientRect.bottom);
  218.     }
  219.  
  220.     while (GL_TRUE)
  221.     {
  222.         /*
  223.          *  Process all pending messages
  224.          */
  225.  
  226.         while (PeekMessage(&Message, NULL, 0, 0, PM_NOREMOVE) == TRUE)
  227.         {
  228.             if (GetMessage(&Message, NULL, 0, 0) )
  229.             {
  230.                 TranslateMessage(&Message);
  231.                 DispatchMessage(&Message);
  232.             }
  233.             else
  234.             {
  235.                 /*
  236.                  *  Nothing else to do here, just return
  237.                  */
  238.  
  239.                 return;
  240.             }
  241.         }
  242.  
  243.         /*
  244.          *  If an idle function was defined, call it
  245.          */
  246.  
  247.         if (IdleFunc)
  248.         {
  249.             (*IdleFunc)();
  250. /* Code added by Li Wei    (liwei@aiar.xjtu.edu.cn)*/
  251.             ForceRedraw(tkhwnd);
  252. /* End modification by Li Wei    */
  253.         }
  254.     }
  255. }
  256.  
  257. void tkExposeFunc(void (*Func)(int, int))
  258. {
  259.     ExposeFunc = Func;
  260. }
  261.  
  262. void tkReshapeFunc(void (*Func)(GLsizei, GLsizei))
  263. {
  264.     ReshapeFunc = Func;
  265. }
  266.  
  267. void tkDisplayFunc(void (*Func)(void))
  268. {
  269.     DisplayFunc = Func;
  270. }
  271.  
  272. void tkKeyDownFunc(GLenum (*Func)(int, GLenum))
  273. {
  274.     KeyDownFunc = Func;
  275. }
  276.  
  277. void tkMouseDownFunc(GLenum (*Func)(int, int, GLenum))
  278. {
  279.     MouseDownFunc = Func;
  280. }
  281.  
  282. void tkMouseUpFunc(GLenum (*Func)(int, int, GLenum))
  283. {
  284.     MouseUpFunc = Func;
  285. }
  286.  
  287. void tkMouseMoveFunc(GLenum (*Func)(int, int, GLenum))
  288. {
  289.     MouseMoveFunc = Func;
  290. }
  291.  
  292. void tkIdleFunc(void (*Func)(void))
  293. {
  294.     IdleFunc = Func;
  295. }
  296.  
  297. void tkInitPosition(int x, int y, int width, int height)
  298. {
  299.     if (x == CW_USEDEFAULT)
  300.     {
  301.         x = 0;
  302.         y = 0;
  303.         windInfo.bDefPos = TRUE;
  304.     }
  305.     else
  306.         windInfo.bDefPos = FALSE;
  307.  
  308.     windInfo.x = x + GetSystemMetrics(SM_CXFRAME);
  309.     windInfo.y = y + GetSystemMetrics(SM_CYCAPTION)
  310.                  - GetSystemMetrics(SM_CYBORDER)
  311.                  + GetSystemMetrics(SM_CYFRAME);
  312.     windInfo.width = width;
  313.     windInfo.height = height;
  314. }
  315.  
  316. void tkInitDisplayMode(GLenum type)
  317. {
  318.     windInfo.type = type;
  319. }
  320.  
  321. void tkInitDisplayModePolicy(GLenum type)
  322. {
  323.     windInfo.dmPolicy = type;
  324. }
  325.  
  326. GLenum tkInitDisplayModeID(GLint ipfd)
  327. {
  328.     windInfo.ipfd = ipfd;
  329.     return GL_TRUE;
  330. }
  331.  
  332. GLenum tkInitWindowAW(char *title, BOOL bUnicode)
  333. {
  334. #ifdef FX
  335.     fxMesaContext Cur;
  336. #else
  337.     WMesaContext Cur;
  338. #endif
  339.     WNDCLASS wndclass;
  340.     RECT     WinRect;
  341.     HANDLE   hInstance;
  342.     ATOM     aRegister;
  343.     GLenum   Result = GL_FALSE,RGB_Flag=GL_TRUE,DB_Flag=GL_FALSE;
  344.    GLint attribs[100];
  345.    int i;
  346.  
  347. #ifdef FX
  348.    /* Build fxMesa attribute list */
  349.    i = 0;
  350.    if (TK_IS_DOUBLE(windInfo.type)) {
  351.       attribs[i] = FXMESA_DOUBLEBUFFER;
  352.       i++;
  353.    }
  354.    if (TK_HAS_DEPTH(windInfo.type)) {
  355.       attribs[i] = FXMESA_DEPTH_SIZE;
  356.       i++;
  357.       attribs[i] = 1;
  358.       i++;
  359.    }
  360.    if (TK_HAS_ALPHA(windInfo.type)) {
  361.       attribs[i] = FXMESA_ALPHA_SIZE;
  362.       i++;
  363.       attribs[i] = 1;
  364.       i++;
  365.    }
  366.    if (TK_HAS_ACCUM(windInfo.type)) {
  367.       attribs[i] = FXMESA_ACCUM_SIZE;
  368.       i++;
  369.       attribs[i] = 1;
  370.       i++;
  371.    }
  372.    if (TK_HAS_STENCIL(windInfo.type)) {
  373.       attribs[i] = FXMESA_STENCIL_SIZE;
  374.       i++;
  375.       attribs[i] = 1;
  376.       i++;
  377.    }
  378.    attribs[i] = FXMESA_NONE;  /* end of list */
  379. #endif
  380.  
  381.     hInstance = GetModuleHandle(NULL);
  382.  
  383.     /* Must not define CS_CS_PARENTDC style.*/
  384.     wndclass.style         = CS_HREDRAW | CS_VREDRAW;
  385.     wndclass.lpfnWndProc   = (WNDPROC)tkWndProc;
  386.     wndclass.cbClsExtra    = 0;
  387.     wndclass.cbWndExtra    = 0;
  388.     wndclass.hInstance     = hInstance;
  389.     wndclass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
  390.     wndclass.hCursor       = LoadCursor(NULL, IDC_ARROW);
  391.     wndclass.hbrBackground = GetStockObject(BLACK_BRUSH);
  392.     wndclass.lpszMenuName  = NULL;
  393.  
  394.     if (bUnicode)
  395.         wndclass.lpszClassName = (LPCSTR)lpszClassNameW;
  396.     else
  397.         wndclass.lpszClassName = (LPCSTR)lpszClassName;
  398.  
  399.     if (bUnicode)
  400.     {
  401.         aRegister = RegisterClassW((CONST WNDCLASSW *)&wndclass);
  402.     }
  403.     else
  404.     {
  405.         aRegister = RegisterClass(&wndclass);
  406.     }
  407.  
  408.  
  409.     /*
  410.      *  If the window failed to register, then there's no
  411.      *  need to continue further.
  412.      */
  413.  
  414.     if(0 == aRegister)
  415.     {
  416.         PrintMessage("Failed to register window class\n");
  417.         return(Result);
  418.     }
  419.  
  420.  
  421.     /*
  422.      *  Make window large enough to hold a client area as large as windInfo
  423.      */
  424.  
  425.     WinRect.left   = windInfo.x;
  426.     WinRect.right  = windInfo.x + windInfo.width;
  427.     WinRect.top    = windInfo.y;
  428.     WinRect.bottom = windInfo.y + windInfo.height;
  429.  
  430.     AdjustWindowRect(&WinRect, WS_OVERLAPPEDWINDOW, FALSE);
  431.  
  432.     /*
  433.      *  Must use WS_CLIPCHILDREN and WS_CLIPSIBLINGS styles.
  434.      */
  435.  
  436.     if (bUnicode)
  437.     {
  438.         tkhwnd = CreateWindowW(
  439.                     (LPCWSTR)lpszClassNameW,
  440.                     (LPCWSTR)title,
  441.                     WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
  442.                     (windInfo.bDefPos) ? CW_USEDEFAULT : WinRect.left,
  443.                     (windInfo.bDefPos) ? CW_USEDEFAULT : WinRect.top,
  444.                     WinRect.right - WinRect.left,
  445.                     WinRect.bottom - WinRect.top,
  446.                     NULL,
  447.                     NULL,
  448.                     hInstance,
  449.                     NULL);
  450.     }
  451.     else
  452.     {
  453.         tkhwnd = CreateWindow(
  454.                     lpszClassName,
  455.                     title,
  456.                     WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
  457.                     (windInfo.bDefPos) ? CW_USEDEFAULT : WinRect.left,
  458.                     (windInfo.bDefPos) ? CW_USEDEFAULT : WinRect.top,
  459.                     WinRect.right - WinRect.left,
  460.                     WinRect.bottom - WinRect.top,
  461.                     NULL,
  462.                     NULL,
  463.                     hInstance,
  464.                     NULL);
  465.     }
  466.  
  467.     if ( NULL != tkhwnd )
  468.     {
  469.        /* If default window positioning used, find out window position and fix
  470.         * up the windInfo position info.
  471.         */
  472.         if (windInfo.bDefPos)
  473.         {
  474.             GetWindowRect(tkhwnd, &WinRect);
  475.             windInfo.x = WinRect.left + GetSystemMetrics(SM_CXFRAME);
  476.             windInfo.y = WinRect.top  + GetSystemMetrics(SM_CYCAPTION)
  477.                          - GetSystemMetrics(SM_CYBORDER)
  478.                          + GetSystemMetrics(SM_CYFRAME);
  479.         }
  480.  
  481.         tkhdc = GetDC(tkhwnd);
  482.  
  483.         if ( NULL != tkhdc )
  484.             ShowWindow(tkhwnd, SW_SHOWDEFAULT);
  485.         else
  486.             PrintMessage("Could not get an HDC for window 0x%08lX\n", tkhwnd );
  487.     }
  488.     else
  489.         PrintMessage("create window failed\n");
  490.     if (windInfo.type & TK_INDEX)
  491.     {
  492.       RGB_Flag=GL_FALSE;
  493.       tkSetRGBMap(NCOLORS,(float *) tkRGBMap);
  494.     }
  495.     if (windInfo.type & TK_DOUBLE)
  496.       DB_Flag=GL_TRUE;
  497. #ifdef FX
  498.     /* XXX something's wrong here! */
  499.     Cur=fxMesaCreateContext(tkhwnd,tkhpalette,RGB_Flag,DB_Flag, attribs);
  500.     fxMesaMakeCurrent(Cur);
  501. #else
  502.     Cur=WMesaCreateContext(tkhwnd,&tkhpalette,RGB_Flag,DB_Flag);
  503.     WMesaMakeCurrent(Cur);
  504. #endif
  505.     return GL_TRUE;
  506. }
  507.  
  508. /* Initialize a window, create a rendering context for that window*/
  509. GLenum tkInitWindow(char *title)
  510. {
  511.     TKASSERT( NULL==tkhwnd      );
  512.     TKASSERT( NULL==tkhdc       );
  513.     TKASSERT( NULL==tkhrc       );
  514.     TKASSERT( NULL==tkhpalette  );
  515.  
  516.     return tkInitWindowAW(title, FALSE);
  517. }
  518.  
  519.  
  520. /******************************************************************************/
  521.  
  522. /*
  523.  * You cannot just call DestroyWindow() here.  The programs do not expect
  524.  * tkQuit() to return;  DestroyWindow() just sends a WM_DESTROY message
  525.  */
  526.  
  527. void tkQuit(void)
  528. {
  529.     DestroyThisWindow(tkhwnd);
  530.     ExitProcess(0);
  531. }
  532.  
  533. /******************************************************************************/
  534.  
  535. void tkSetOneColor(int index, float r, float g, float b)
  536. {
  537.     PALETTEENTRY PalEntry;
  538.     HPALETTE Palette;
  539.     if ( NULL != (Palette = CreateCIPalette( tkhdc )) )
  540.     {
  541.         PalEntry.peRed   = (BYTE)(r*(float)255.0 + (float)0.5);
  542.         PalEntry.peGreen = (BYTE)(g*(float)255.0 + (float)0.5);
  543.         PalEntry.peBlue  = (BYTE)(b*(float)255.0 + (float)0.5);
  544.         PalEntry.peFlags = 0;
  545.         SetPaletteEntries( Palette, index, 1, &PalEntry);
  546.         DelayPaletteRealization();
  547.     }
  548. }
  549.  
  550. void tkSetFogRamp(int density, int startIndex)
  551. {
  552.     HPALETTE CurrentPal;
  553.     PALETTEENTRY *pPalEntry;
  554.     UINT n, i, j, k, intensity, fogValues, colorValues;
  555.  
  556.     if ( NULL != (CurrentPal = CreateCIPalette(tkhdc)) )
  557.     {
  558.         n = GetPaletteEntries( CurrentPal, 0, 0, NULL );
  559.  
  560.         pPalEntry = AllocateMemory( n * sizeof(PALETTEENTRY) );
  561.  
  562.         if ( NULL != pPalEntry)
  563.         {
  564.             fogValues = 1 << density;
  565.             colorValues = 1 << startIndex;
  566.             for (i = 0; i < colorValues; i++) {
  567.                 for (j = 0; j < fogValues; j++) {
  568.                     k = i * fogValues + j;
  569.  
  570.                     intensity = i * fogValues + j * colorValues;
  571.                     /*mf: not sure what they're trying to do here*/
  572.                     /*intensity = (intensity << 8) | intensity; ???*/
  573.  
  574.                     /*
  575.                       This is a workaround for a GDI palette "feature".  If any of
  576.                       the static colors are repeated in the palette, those colors
  577.                       will map to the first occurance.  So, for our case where there
  578.                       are only two static colors (black and white), if a white
  579.                       color appears anywhere in the palette other than in the last
  580.                       entry, the static white will remap to the first white.  This
  581.                       destroys the nice one-to-one mapping we are trying to achieve.
  582.                       
  583.                       There are two ways to workaround this.  The first is to
  584.                       simply not allow a pure white anywhere but in the last entry.
  585.                       Such requests are replaced with an attenuated white of
  586.                       (0xFE, 0xFE, 0xFE).
  587.                       
  588.                       The other way is to mark these extra whites with PC_RESERVED
  589.                       which will cause GDI to skip these entries when mapping colors.
  590.                       This way the app gets the actual colors requested, but can
  591.                       have side effects on other apps.
  592.                       
  593.                       Both solutions are included below.  The PC_RESERVED solution is
  594.                       the one currently enabled.  It may have side effects, but taking
  595.                       over the static colors as we are is a really big side effect that
  596.                       should swamp out the effects of using PC_RESERVED.
  597.                     */
  598.                 if (intensity > 0xFF)
  599.                   intensity = 0xFF;
  600.                 pPalEntry[k].peRed =pPalEntry[k].peGreen = pPalEntry[k].peBlue = (BYTE) intensity;
  601.                 pPalEntry[k].peFlags = 0;
  602.  
  603.                 }
  604.             }
  605.  
  606.             SetPaletteEntries(CurrentPal, 0, n, pPalEntry);
  607.             FreeMemory( pPalEntry );
  608.  
  609.             DelayPaletteRealization();
  610.         }
  611.     }
  612. }
  613.  
  614. void tkSetGreyRamp(void)
  615. {
  616.     HPALETTE CurrentPal;
  617.     PALETTEENTRY *Entries;
  618.     UINT Count, i;
  619.     float intensity;
  620.  
  621.     if ( NULL != (CurrentPal = CreateCIPalette( tkhdc )) )
  622.     {
  623.         Count   = GetPaletteEntries( CurrentPal, 0, 0, NULL );
  624.         Entries = AllocateMemory( Count * sizeof(PALETTEENTRY) );
  625.  
  626.         if ( NULL != Entries )
  627.         {
  628.             for (i = 0; i < Count; i++)
  629.             {
  630.                 intensity = (float)(((double)i / (double)(Count-1)) * (double)255.0 + (double)0.5);
  631.                 Entries[i].peRed =
  632.                 Entries[i].peGreen =
  633.                 Entries[i].peBlue = (BYTE) intensity;
  634.                 Entries[i].peFlags = 0;
  635.             }
  636.             SetPaletteEntries( CurrentPal, 0, Count, Entries );
  637.             FreeMemory( Entries );
  638.  
  639.             DelayPaletteRealization();
  640.         }
  641.     }
  642. }
  643.  
  644. void tkSetRGBMap( int Size, float *Values )
  645. {
  646.     HPALETTE CurrentPal;
  647.     int i;
  648.     if ( NULL != (CurrentPal = CreateCIPalette( tkhdc )) )
  649.     {
  650.       for (i=0; i<Size; i++)
  651.         tkSetOneColor(i,Values[i*3],Values[i*3+1],Values[i*3+2]);
  652.     }
  653. }
  654.  
  655. /******************************************************************************/
  656.  
  657. void tkSwapBuffers(void)
  658. {
  659. #ifdef FX
  660.   fxMesaSwapBuffers();
  661. #else
  662.   WMesaSwapBuffers();
  663. #endif
  664. }
  665.  
  666. /******************************************************************************/
  667.  
  668. GLint tkGetColorMapSize(void)
  669. {
  670.     CreateCIPalette( tkhdc );
  671.  
  672.     if ( NULL == tkhpalette )
  673.         return( 0 );
  674.  
  675.     return( GetPaletteEntries( tkhpalette, 0, 0, NULL ) );
  676. }
  677.  
  678. void tkGetMouseLoc(int *x, int *y)
  679. {
  680.     POINT Point;
  681.  
  682.     *x = 0;
  683.     *y = 0;
  684.  
  685.     GetCursorPos(&Point);
  686.  
  687.     /*
  688.      *  GetCursorPos returns screen coordinates,
  689.      *  we want window coordinates
  690.      */
  691.  
  692.     *x = Point.x - windInfo.x;
  693.     *y = Point.y - windInfo.y;
  694. }
  695.  
  696. HWND tkGetHWND(void)
  697. {
  698.     return tkhwnd;
  699. }
  700.  
  701. HDC tkGetHDC(void)
  702. {
  703.     return tkhdc;
  704. }
  705. GLenum tkGetDisplayModePolicy(void)
  706. {
  707.     return windInfo.dmPolicy;
  708. }
  709.  
  710. GLint tkGetDisplayModeID(void)
  711. {
  712.     return windInfo.ipfd;
  713. }
  714.  
  715. GLenum tkGetDisplayMode(void)
  716. {
  717.     return windInfo.type;
  718. }
  719.  
  720.  
  721. /***********************************************************************
  722.  *                                                                     *
  723.  *  The Following functions are for our own use only. (ie static)      *
  724.  *                                                                     *
  725.  ***********************************************************************/
  726.  
  727. long FAR PASCAL _export
  728. tkWndProc(HWND hWnd, UINT message, DWORD wParam, LONG lParam)
  729. {
  730.     int key;
  731.     PAINTSTRUCT paint;
  732.     HDC hdc;
  733.  
  734.     switch (message)
  735.     {
  736.  
  737.     case WM_USER:
  738.  
  739.         if ( RealizePaletteNow( tkhdc, tkhpalette) > 0 )
  740.             ForceRedraw( hWnd );
  741.         return(0);
  742.  
  743.     case WM_SIZE:
  744.         windInfo.width  = LOWORD(lParam);
  745.         windInfo.height = HIWORD(lParam);
  746.  
  747.         if (ReshapeFunc)
  748.         {
  749.             (*ReshapeFunc)(windInfo.width, windInfo.height);
  750.  
  751.             ForceRedraw( hWnd );
  752.         }
  753.         return (0);
  754.  
  755.     case WM_MOVE:
  756.         windInfo.x = LOWORD(lParam);
  757.         windInfo.y = HIWORD(lParam);
  758.         return (0);
  759.  
  760.     case WM_PAINT:
  761.  
  762.         /*
  763.          *  Validate the region even if there are no DisplayFunc.
  764.          *  Otherwise, USER will not stop sending WM_PAINT messages.
  765.          */
  766.  
  767.         hdc = BeginPaint(tkhwnd, &paint);
  768.  
  769.         if (DisplayFunc)
  770.         {
  771.             (*DisplayFunc)();
  772.         }
  773.  
  774.         EndPaint(tkhwnd, &paint);
  775.         return (0);
  776.  
  777.     case WM_PALETTECHANGED:
  778.         if ( hWnd != (HWND) wParam )
  779.           RealizePaletteNow(tkhdc,tkhpalette);
  780.         return (0);
  781.     case WM_QUERYNEWPALETTE:
  782.  
  783.        /* In the foreground!  Let RealizePaletteNow do the work--*/
  784.        /* if management of the static system color usage is needed,*/
  785.        /* RealizePaletteNow will take care of it.*/
  786.  
  787.         if ( NULL != tkhpalette )
  788.         {
  789.             if ( RealizePaletteNow(tkhdc, tkhpalette) > 0 )
  790.                 ForceRedraw( hWnd );
  791.  
  792.             return (1);
  793.         }
  794.  
  795.         return (0);
  796.  
  797.     case WM_ACTIVATE:
  798.  
  799.        /*
  800.          If the window is going inactive, the palette must be realized to
  801.          the background.  Cannot depend on WM_PALETTECHANGED to be sent since
  802.          the window that comes to the foreground may or may not be palette
  803.          managed.
  804.          */
  805.  
  806.         if ( LOWORD(wParam) == WA_INACTIVE )
  807.         {
  808.             if ( NULL != tkhpalette )
  809.             {
  810.                /*
  811.                  Realize as a background palette.  Need to call
  812.                  RealizePaletteNow rather than RealizePalette directly to
  813.                  because it may be necessary to release usage of the static
  814.                  system colors.
  815.                  */
  816.  
  817.                 if ( RealizePaletteNow( tkhdc, tkhpalette) > 0 )
  818.                     ForceRedraw( hWnd );
  819.             }
  820.         }
  821.  
  822.         /* Allow DefWindowProc() to finish the default processing (which includes*/
  823.         /* changing the keyboard focus).*/
  824.  
  825.         break;
  826.  
  827.     case WM_MOUSEMOVE:
  828.  
  829.         if (MouseMoveFunc)
  830.         {
  831.             GLenum mask;
  832.  
  833.             mask = 0;
  834.             if (wParam & MK_LBUTTON) {
  835.                 mask |= TK_LEFTBUTTON;
  836.             }
  837.             if (wParam & MK_MBUTTON) {
  838.                 mask |= TK_MIDDLEBUTTON;
  839.             }
  840.             if (wParam & MK_RBUTTON) {
  841.                 mask |= TK_RIGHTBUTTON;
  842.             }
  843.  
  844.             if ((*MouseMoveFunc)( LOWORD(lParam), HIWORD(lParam), mask ))
  845.             {
  846.                 ForceRedraw( hWnd );
  847.             }
  848.         }
  849.         return (0);
  850.  
  851.     case WM_LBUTTONDOWN:
  852.  
  853.         SetCapture(hWnd);
  854.  
  855.         if (MouseDownFunc)
  856.         {
  857.             if ( (*MouseDownFunc)(LOWORD(lParam), HIWORD(lParam),
  858.                  TK_LEFTBUTTON) )
  859.             {
  860.                 ForceRedraw( hWnd );
  861.             }
  862.         }
  863.         return (0);
  864.  
  865.     case WM_LBUTTONUP:
  866.  
  867.         ReleaseCapture();
  868.  
  869.         if (MouseUpFunc)
  870.         {
  871.             if ((*MouseUpFunc)(LOWORD(lParam), HIWORD(lParam), TK_LEFTBUTTON))
  872.             {
  873.                 ForceRedraw( hWnd );
  874.             }
  875.         }
  876.         return (0);
  877.  
  878.     case WM_MBUTTONDOWN:
  879.  
  880.         SetCapture(hWnd);
  881.  
  882.         if (MouseDownFunc)
  883.         {
  884.             if ((*MouseDownFunc)(LOWORD(lParam), HIWORD(lParam),
  885.                     TK_MIDDLEBUTTON))
  886.             {
  887.                 ForceRedraw( hWnd );
  888.             }
  889.         }
  890.         return (0);
  891.  
  892.     case WM_MBUTTONUP:
  893.  
  894.         ReleaseCapture();
  895.  
  896.         if (MouseUpFunc)
  897.         {
  898.             if ((*MouseUpFunc)(LOWORD(lParam), HIWORD(lParam),
  899.                 TK_MIDDLEBUTTON))
  900.             {
  901.                 ForceRedraw( hWnd );
  902.             }
  903.         }
  904.         return (0);
  905.  
  906.     case WM_RBUTTONDOWN:
  907.  
  908.         SetCapture(hWnd);
  909.  
  910.         if (MouseDownFunc)
  911.         {
  912.             if ((*MouseDownFunc)(LOWORD(lParam), HIWORD(lParam),
  913.                 TK_RIGHTBUTTON))
  914.             {
  915.                 ForceRedraw( hWnd );
  916.             }
  917.         }
  918.         return (0);
  919.  
  920.     case WM_RBUTTONUP:
  921.  
  922.         ReleaseCapture();
  923.  
  924.         if (MouseUpFunc)
  925.         {
  926.             if ((*MouseUpFunc)(LOWORD(lParam), HIWORD(lParam),
  927.                 TK_RIGHTBUTTON))
  928.             {
  929.                 ForceRedraw( hWnd );
  930.             }
  931.         }
  932.         return (0);
  933.  
  934.     case WM_KEYDOWN:
  935.         switch (wParam) {
  936.         case VK_SPACE:          key = TK_SPACE;         break;
  937.         case VK_RETURN:         key = TK_RETURN;        break;
  938.         case VK_ESCAPE:         key = TK_ESCAPE;        break;
  939.         case VK_LEFT:           key = TK_LEFT;          break;
  940.         case VK_UP:             key = TK_UP;            break;
  941.         case VK_RIGHT:          key = TK_RIGHT;         break;
  942.         case VK_DOWN:           key = TK_DOWN;          break;
  943.         default:                key = GL_FALSE;         break;
  944.         }
  945.  
  946.         if (key && KeyDownFunc)
  947.         {
  948.             GLenum mask;
  949.  
  950.             mask = 0;
  951.             if (GetKeyState(VK_CONTROL)) {
  952.                 mask |= TK_CONTROL;
  953.             }
  954.  
  955.             if (GetKeyState(VK_SHIFT)) {
  956.  
  957.                 mask |= TK_SHIFT;
  958.             }
  959.  
  960.             if ( (*KeyDownFunc)(key, mask) )
  961.             {
  962.                 ForceRedraw( hWnd );
  963.             }
  964.         }
  965.         return (0);
  966.  
  967.     case WM_CHAR:
  968.         if (('0' <= wParam && wParam <= '9') ||
  969.             ('a' <= wParam && wParam <= 'z') ||
  970.             ('A' <= wParam && wParam <= 'Z')) {
  971.  
  972.             key = wParam;
  973.         } else {
  974.             key = GL_FALSE;
  975.         }
  976.  
  977.         if (key && KeyDownFunc) {
  978.             GLenum mask;
  979.  
  980.             mask = 0;
  981.  
  982.             if (GetKeyState(VK_CONTROL)) {
  983.                 mask |= TK_CONTROL;
  984.             }
  985.  
  986.             if (GetKeyState(VK_SHIFT)) {
  987.                 mask |= TK_SHIFT;
  988.             }
  989.  
  990.             if ( (*KeyDownFunc)(key, mask) )
  991.             {
  992.                 ForceRedraw( hWnd );
  993.             }
  994.         }
  995.         return (0);
  996.  
  997.     case WM_CLOSE:
  998.         DestroyWindow(tkhwnd);
  999.         return(0);
  1000.  
  1001.     case WM_DESTROY:
  1002.         CleanUp();
  1003.         PostQuitMessage(TRUE);
  1004.         return 0;
  1005.     }
  1006.     return(DefWindowProc( hWnd, message, wParam, lParam));
  1007. }
  1008. static HPALETTE CreateCIPalette( HDC Dc )
  1009. {
  1010.     LOGPALETTE *LogicalPalette;
  1011.     HPALETTE StockPalette;
  1012.     UINT PaletteSize, StockPaletteSize, EntriesToCopy;
  1013.  
  1014.     if ( (Dc != NULL) && (NULL == tkhpalette) )
  1015.     {
  1016.                 PaletteSize = 256; /*(Pfd.cColorBits >= 8) ? 256 : (1 << Pfd.cColorBits);*/
  1017.  
  1018.                 LogicalPalette = AllocateZeroedMemory( sizeof(LOGPALETTE) +
  1019.                                         (PaletteSize * sizeof(PALETTEENTRY)) );
  1020.  
  1021.                 if ( NULL != LogicalPalette )
  1022.                 {
  1023.                     LogicalPalette->palVersion    = 0x300;
  1024.                     LogicalPalette->palNumEntries = PaletteSize;
  1025.  
  1026.                     StockPalette     = GetStockObject(DEFAULT_PALETTE);
  1027.                     StockPaletteSize = GetPaletteEntries( StockPalette, 0, 0, NULL );
  1028.  
  1029.                     /*
  1030.                      *  start by copying default palette into new one
  1031.                      */
  1032.  
  1033.                     EntriesToCopy = StockPaletteSize < PaletteSize ?
  1034.                                         StockPaletteSize : PaletteSize;
  1035.  
  1036.                     GetPaletteEntries( StockPalette, 0, EntriesToCopy,
  1037.                                         LogicalPalette->palPalEntry );
  1038.  
  1039.                     /*
  1040.                      *  If we are taking possession of the system colors,
  1041.                      *  must guarantee that 0 and 255 are black and white
  1042.                      *  (respectively).
  1043.                      */
  1044.  
  1045.                     tkhpalette = CreatePalette(LogicalPalette);
  1046.  
  1047.                     FreeMemory(LogicalPalette);
  1048.  
  1049.                     RealizePaletteNow( Dc, tkhpalette);
  1050.                 }
  1051.             }
  1052.     return( tkhpalette );
  1053. }
  1054. static void
  1055. PrintMessage( const char *Format, ... )
  1056. {
  1057.     va_list ArgList;
  1058.     char Buffer[256];
  1059.  
  1060.     va_start(ArgList, Format);
  1061.     vsprintf(Buffer, Format, ArgList);
  1062.     va_end(ArgList);
  1063.  
  1064.     MessageBox(GetFocus(), Buffer, "Error", MB_OK);
  1065. }
  1066.  
  1067. static void
  1068. DelayPaletteRealization( void )
  1069. {
  1070.     MSG Message;
  1071.  
  1072.     TKASSERT(NULL!=tkhwnd);
  1073.  
  1074.     /*
  1075.      *  Add a WM_USER message to the queue, if there isn't one there already.
  1076.      */
  1077.  
  1078.     if (!PeekMessage(&Message, tkhwnd, WM_USER, WM_USER, PM_NOREMOVE) )
  1079.     {
  1080.         PostMessage( tkhwnd, WM_USER, 0, 0);
  1081.     }
  1082. }
  1083.  
  1084. /******************************Public*Routine******************************\
  1085. * RealizePaletteNow
  1086. *
  1087. * Select the given palette in background or foreground mode (as specified
  1088. * by the bForceBackground flag), and realize the palette.
  1089. *
  1090. * If static system color usage is set, the system colors are replaced.
  1091. *
  1092. * History:
  1093. *  26-Apr-1994 -by- Gilman Wong [gilmanw]
  1094. * Wrote it.
  1095. \**************************************************************************/
  1096.  
  1097. static long RealizePaletteNow( HDC Dc, HPALETTE Palette)
  1098. {
  1099.     long Result = -1;
  1100.     TKASSERT( NULL!=Dc      );
  1101.     TKASSERT( NULL!=Palette );
  1102.     if ( NULL != SelectPalette( Dc, Palette, FALSE ) )
  1103.     {
  1104.       Result = RealizePalette( Dc );
  1105. #ifndef FX
  1106.       WMesaPaletteChange(Palette);
  1107. #endif
  1108.     }
  1109.     return( Result );
  1110. }
  1111.  
  1112. static void
  1113. ForceRedraw( HWND Window )
  1114. {
  1115.     MSG Message;
  1116.  
  1117.     if (!PeekMessage(&Message, Window, WM_PAINT, WM_PAINT, PM_NOREMOVE) )
  1118.     {
  1119.         InvalidateRect( Window, NULL, FALSE );
  1120.     }
  1121. }
  1122. static void
  1123. DestroyThisWindow( HWND Window )
  1124. {
  1125.     if ( NULL != Window )
  1126.     {
  1127.         DestroyWindow( Window );
  1128.     }
  1129. }
  1130.  
  1131. /*
  1132.  *  This Should be called in response to a WM_DESTROY message
  1133.  */
  1134.  
  1135. static void
  1136. CleanUp( void )
  1137. {
  1138.     HPALETTE hStock;
  1139.  
  1140.     /*Cleanup the palette.*/
  1141.  
  1142.     if ( NULL != tkhpalette )
  1143.     {
  1144.        /* If static system color usage is set, restore the system colors.*/
  1145.  
  1146.         if ((hStock = GetStockObject( DEFAULT_PALETTE ))!=NULL)
  1147.           SelectPalette( tkhdc, hStock, FALSE );
  1148.         DeleteObject( tkhpalette );
  1149.     }
  1150.  
  1151.     /* Cleanup the DC.*/
  1152.  
  1153.     if ( NULL != tkhdc )
  1154.         ReleaseDC( tkhwnd, tkhdc );
  1155.     /* Be really nice and reset global values.*/
  1156.     tkhwnd        = NULL;
  1157.     tkhdc         = NULL;
  1158.     tkhpalette    = NULL;
  1159.  
  1160.     ExposeFunc    = NULL;
  1161.     ReshapeFunc   = NULL;
  1162.     IdleFunc      = NULL;
  1163.     DisplayFunc   = NULL;
  1164.     KeyDownFunc   = NULL;
  1165.     MouseDownFunc = NULL;
  1166.     MouseUpFunc   = NULL;
  1167.     MouseMoveFunc = NULL;
  1168. }
  1169.  
  1170. static void *
  1171. AllocateMemory( size_t Size )
  1172. {
  1173.     return( LocalAlloc( LMEM_FIXED, Size ) );
  1174. }
  1175.  
  1176. static void *
  1177. AllocateZeroedMemory( size_t Size )
  1178. {
  1179.     return( LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT, Size ) );
  1180. }
  1181.  
  1182.  
  1183. static void
  1184. FreeMemory( void *Chunk )
  1185. {
  1186.     TKASSERT( NULL!=Chunk );
  1187.  
  1188.     LocalFree( Chunk );
  1189. }
  1190.