summaryrefslogtreecommitdiffstats
path: root/src/glut/os2/os2_winproc.cpp
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2003-06-13 21:49:46 +0000
committerBrian Paul <[email protected]>2003-06-13 21:49:46 +0000
commit225517aff0afc3270fab277d1c9ac2864053820c (patch)
treefa00e2b162788b4fe2ebb9254baf6526997c9903 /src/glut/os2/os2_winproc.cpp
parent8fa507592b7bdb087c9eb32ed2322cb805b724ec (diff)
GLUT for OS/2 (Evgeny Kotsuba)
Diffstat (limited to 'src/glut/os2/os2_winproc.cpp')
-rw-r--r--src/glut/os2/os2_winproc.cpp1297
1 files changed, 1297 insertions, 0 deletions
diff --git a/src/glut/os2/os2_winproc.cpp b/src/glut/os2/os2_winproc.cpp
new file mode 100644
index 00000000000..e2d4ba9d550
--- /dev/null
+++ b/src/glut/os2/os2_winproc.cpp
@@ -0,0 +1,1297 @@
+/* os2_winproc.c */
+
+
+#define INCL_DEV
+#include "WarpGL.h"
+#include "GL/os2mesa.h"
+
+
+#define _MEERROR_H_
+#include <mmioos2.h> /* It is from MMPM toolkit */
+#include <dive.h>
+#include <fourcc.h>
+
+
+#include "os2mesadef.h"
+#include "glutint.h"
+
+
+#define POKA 0
+
+#if POKA
+
+extern unsigned __glutMenuButton;
+extern GLUTidleCB __glutIdleFunc;
+extern GLUTtimer *__glutTimerList;
+extern void handleTimeouts(void);
+extern GLUTmenuItem *__glutGetUniqueMenuItem(GLUTmenu * menu, int unique);
+static HMENU __glutHMenu;
+
+#endif
+
+extern void _mesa_ResizeBuffersMESA( void );
+
+
+MRESULT EXPENTRY GlutWindowProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 );
+MRESULT EXPENTRY GlutWindowChildProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 );
+void updateWindowState(GLUTwindow *window, int visState);
+
+volatile extern HAB hab; /* PM anchor block handle */
+volatile extern HPS hpsCurrent;
+
+RECTL rCtls[52];
+ULONG ulNumRcls;
+
+MRESULT EXPENTRY GlutWindowChildProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
+{ MRESULT rc;
+ rc = GlutWindowProc(hwnd, msg, mp1, mp2 );
+ return rc;
+}
+
+MRESULT EXPENTRY GlutWindowProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
+{
+ HPS hps = NULLHANDLE; /* presentation space handle */
+ GLUTwindow* window; /* GLUT window associated with message. */
+ GLUTmenu* menu; /* GLUT menu associated with message. */
+ RECTL rclClient;
+ POINTL point;
+ int button = -1,rc,key;
+
+
+/* Process the message. */
+
+ switch( msg )
+ {
+ case WM_CREATE:
+ {
+ SIZEL sizl = { 0L, 0L };
+ LONG *alCaps;
+ HDC hdc;
+
+ /*+-----------------------------------------------------------------+*/
+ /*| The client window is being created. Create the semaphore to |*/
+ /*| control access to the presentation space. Then create the |*/
+ /*| thread that will draw the lines. |*/
+ /*+-----------------------------------------------------------------+*/
+ // DosCreateMutexSem( (PSZ)NULL, &hmtxPS, 0UL, FALSE );
+
+ hdc = WinOpenWindowDC(hwnd);
+
+ /*+-----------------------------------------------------------------+*/
+ /*| Create a non-cached presentation space. We will not release |*/
+ /*| this PS, as we will be Selecting a Palette to this PS and then |*/
+ /*| animating the palette. Upon releasing a PS the palette is no |*/
+ /*| longer selected for obvious reasons. |*/
+ /*+-----------------------------------------------------------------+*/
+ hpsCurrent = GpiCreatePS( hab,
+ hdc,
+ &sizl,
+ PU_PELS | GPIF_DEFAULT |
+ GPIT_MICRO | GPIA_ASSOC );
+// DevQueryCaps( hdc, lStart, lCount, alCaps );
+// fPaletteCaps = alCaps[CAPS_ADDITIONAL_GRAPHICS] & CAPS_PALETTE_MANAGER;
+// PaletteInit(3);
+ /* ��p���� hpsBuffer � p���� RGB color table */
+
+ GpiCreateLogColorTable(hpsCurrent,0 ,LCOLF_RGB,0,0,NULL);
+ GpiSetPattern(hpsCurrent,PATSYM_SOLID);
+ GpiSetPatternSet(hpsCurrent,LCID_DEFAULT);
+
+ }
+ break;
+
+ return 0;
+ case WM_CLOSE:
+ WinPostMsg( hwnd, WM_QUIT, NULL, NULL );
+
+ return 0;
+
+ case WM_PAINT:
+ window = __glutGetWindow(hwnd);
+ if (window)
+ {
+ PWMC ctx;
+// hps = WinBeginPaint(hwnd,NULLHANDLE,&rclClient);
+ hps = WinBeginPaint(hwnd,NULLHANDLE,&rclClient);
+ // blit Dive buffer to screen.
+
+ {
+ SWP swp; // Window position
+ POINTL pointl; // Point to offset from Desktop
+
+ // Convert the point to offset from desktop lower left.
+ pointl.x = 0;
+ pointl.y = 0;
+ WinMapWindowPoints ( hwnd, HWND_DESKTOP, &pointl, 1 );
+
+
+// ctx = window->ctx;
+// ctx->xDiveScr = pointl.x;
+// ctx->yDiveScr = pointl.y;
+ }
+// rc = DiveBlitImage (ctx->hDive,
+// ctx->ulDiveBufferNumber,
+// DIVE_BUFFER_SCREEN );
+//
+
+ if (window->win == hwnd) {
+ __glutPostRedisplay(window, GLUT_REPAIR_WORK);
+ } else if (window->overlay && window->overlay->win == hwnd) {
+ __glutPostRedisplay(window, GLUT_OVERLAY_REPAIR_WORK);
+ }
+ WinEndPaint(hps);
+ } else {
+
+ hps = WinBeginPaint(hwnd,NULLHANDLE,&rclClient);
+ WinFillRect(hps, &rclClient, CLR_WHITE);
+ WinEndPaint(hps);
+ }
+ break;
+
+ case WM_VRNDISABLED:
+
+// pwinData->fDataInProcess = TRUE;
+// DiveSetupBlitter ( pwinData->hDive, 0 );
+// pwinData->fVrnDisabled = TRUE;
+ break;
+
+ case WM_VRNENABLED:
+ { HRGN hrgn; /* Region handle */
+ RGNRECT rgnCtl; /* Processing control structure */
+// RECTL rCtls[52];
+// ULONG ulNumRcls;
+
+// pwinData->fDataInProcess = TRUE;
+ hps = WinGetPS ( hwnd );
+ if ( !hps )
+ break;
+ hrgn = GpiCreateRegion ( hps, 0L, NULL );
+ if ( hrgn )
+ { /* NOTE: If mp1 is zero, then this was just a move message.
+ ** Illustrate the visible region on a WM_VRNENABLE.
+ */
+ WinQueryVisibleRegion ( hwnd, hrgn );
+ rgnCtl.ircStart = 0;
+ rgnCtl.crc = 50;
+ rgnCtl.ulDirection = 1;
+
+ /* Get the all ORed rectangles */
+ if ( GpiQueryRegionRects ( hps, hrgn, NULL,
+ &rgnCtl, rCtls) )
+ {
+ ulNumRcls = rgnCtl.crcReturned;
+
+ /* Now find the window position and size, relative to parent.
+ */
+// WinQueryWindowPos ( pwinData->hwndClient, &pwinData->swp );
+
+// rcl.xLeft = 0;
+// rcl.yBottom = 0;
+
+ /* Convert the point to offset from desktop lower left.
+ */
+// pointl.x = pwinData->swp.x;
+// pointl.y = pwinData->swp.y;
+
+// WinMapWindowPoints ( pwinData->hwndFrame,
+// HWND_DESKTOP, &pointl, 1 );
+
+// pwinData->cxWindowPos = pointl.x;
+// pwinData->cyWindowPos = pointl.y;
+
+ }
+ GpiDestroyRegion( hps, hrgn );
+ }
+ WinReleasePS( hps );
+
+ }
+ break;
+
+ case WM_SIZE:
+ window = __glutGetWindow(hwnd);
+ if (window)
+ { int width,height;
+ width = SHORT1FROMMP(mp2);
+ height = SHORT2FROMMP(mp2);
+ if (width != window->width || height != window->height) {
+#if 0 /* Win32 GLUT does not support overlays for now. */
+ if (window->overlay) {
+ XResizeWindow(__glutDisplay, window->overlay->win, width, height);
+ }
+#endif
+ window->width = width;
+ window->height = height;
+ __glutSetWindow(window);
+ if(width <= 0 || height <= 0)
+ break;
+ _mesa_ResizeBuffersMESA();
+
+ /* Do not execute OpenGL out of sequence with respect
+ to the SetWindowPos request! */
+ window->reshape(width, height);
+ window->forceReshape = FALSE;
+ /* A reshape should be considered like posting a
+ repair request. */
+ __glutPostRedisplay(window, GLUT_REPAIR_WORK);
+ }
+ }
+ return 0;
+ case WM_SHOW:
+ window = __glutGetWindow(hwnd);
+ if (window) {
+ int visState;
+ visState = SHORT1FROMMP( mp1 );
+ updateWindowState(window, visState);
+ }
+ return 0;
+
+ case WM_ACTIVATE:
+ window = __glutGetWindow(hwnd);
+// /* Make sure we re-select the correct palette if needed. */
+// if (LOWORD(wParam)) {
+// PostMessage(hwnd, WM_PALETTECHANGED, 0, 0);
+// }
+ if (window) {
+ int visState;
+ visState = SHORT1FROMMP( mp1 );
+ updateWindowState(window, visState);
+ }
+ return 0;
+
+ case WM_CHAR:
+ { USHORT fsflags;
+ window = __glutGetWindow(hwnd);
+ if (!window) {
+ break;
+ }
+ fsflags = SHORT1FROMMP(mp1);
+/* ?? */
+ if((fsflags & KC_KEYUP) ) /* ����p�p㥬 �⦠⨥ ������, p����p㥬 ⮫쪮 �� ����⨥ */
+ break;
+///////////////////////////////////////////////////
+ if(!(fsflags & KC_CHAR) )
+ {
+ if (!(fsflags & KC_VIRTUALKEY))
+ break;
+ key = 0;
+ /* Get the virtual key from mp2. */
+ switch (SHORT2FROMMP(mp2))
+ {
+/* directional keys */
+ case VK_LEFT: key = GLUT_KEY_LEFT; break;
+ case VK_UP: key = GLUT_KEY_UP; break;
+ case VK_RIGHT: key = GLUT_KEY_RIGHT; break;
+ case VK_DOWN: key = GLUT_KEY_DOWN; break;
+
+ case VK_PAGEUP: key = GLUT_KEY_PAGE_UP; break;
+ case VK_PAGEDOWN:key = GLUT_KEY_PAGE_DOWN; break;
+ case VK_HOME: key = GLUT_KEY_HOME;break;
+ case VK_END: key = GLUT_KEY_END; break;
+ case VK_INSERT: key = GLUT_KEY_INSERT; break;
+
+/* function keys */
+ case VK_F1 : key = GLUT_KEY_F1; break;
+ case VK_F2 : key = GLUT_KEY_F2; break;
+ case VK_F3 : key = GLUT_KEY_F3; break;
+ case VK_F4 : key = GLUT_KEY_F4; break;
+ case VK_F5 : key = GLUT_KEY_F5; break;
+ case VK_F6 : key = GLUT_KEY_F6; break;
+ case VK_F7 : key = GLUT_KEY_F7; break;
+ case VK_F8 : key = GLUT_KEY_F8; break;
+ case VK_F9 : key = GLUT_KEY_F9; break;
+ case VK_F10: key = GLUT_KEY_F10;break;
+ case VK_F11: key = GLUT_KEY_F11; break;
+ case VK_F12: key = GLUT_KEY_F12; break;
+ case VK_ESC: key = -1; break; /* Character codes */
+ case VK_SPACE: key = -1; break;
+ case VK_TAB: key = -1; break;
+ }
+ if(!key)
+ { break; /* Key Not implemented */
+ }
+ if(key > 0)
+ { if (!window->special) /* �� ��⠭������ ��ࠡ��稪� */
+ break;
+
+ WinQueryPointerPos(HWND_DESKTOP,&point);
+ ScreenToClient(window->win, &point);
+ __glutSetWindow(window);
+ __glutModifierMask = 0;
+ if(WinGetKeyState(HWND_DESKTOP,VK_SHIFT) & 0x8000) /* high order bit is on */
+ __glutModifierMask |= ShiftMask;
+ if(WinGetKeyState(HWND_DESKTOP,VK_CTRL) & 0x8000)
+ __glutModifierMask |= ControlMask;
+ if(WinGetKeyState(HWND_DESKTOP,VK_MENU) & 0x8000)
+ __glutModifierMask |= Mod1Mask;
+ window->special(key, point.x, point.y);
+ __glutModifierMask = (unsigned int) ~0;
+ return 0;
+ }
+
+ }
+/////////////////////////////////////////////////////
+ /* If we are ignoring auto repeated key strokes for the window, bail. */
+ if (window->ignoreKeyRepeat && (CHAR3FROMMP(mp1)) )
+ break;
+ if(!((unsigned char)SHORT1FROMMP(mp2)) ) /* ����p�p㥬 ��ᨬ����� ���� */
+ break;
+ if (window->keyboard) {
+ WinQueryPointerPos(HWND_DESKTOP,&point);
+
+ ScreenToClient(window->win, &point);
+ __glutSetWindow(window);
+ __glutModifierMask = 0;
+ if(WinGetKeyState(HWND_DESKTOP,VK_SHIFT) & 0x8000) /* high order bit is on */
+ __glutModifierMask |= ShiftMask;
+ if(WinGetKeyState(HWND_DESKTOP,VK_CTRL) & 0x8000)
+ __glutModifierMask |= ControlMask;
+ if(WinGetKeyState(HWND_DESKTOP,VK_MENU) & 0x8000)
+ __glutModifierMask |= Mod1Mask;
+ window->keyboard((unsigned char)SHORT1FROMMP(mp2), point.x, point.y);
+ __glutModifierMask = (unsigned int) ~0;
+ }
+ return 0;
+ } /* endof case WM_CHAR: */
+////////////////////////////////////////////////
+ case WM_BUTTON1DOWN:
+ button = GLUT_LEFT_BUTTON;
+ case WM_BUTTON3DOWN:
+ if (button < 0)
+ button = GLUT_MIDDLE_BUTTON;
+ case WM_BUTTON2DOWN:
+ if (button < 0)
+ button = GLUT_RIGHT_BUTTON;
+ { POINTS psh;
+ psh = *((POINTS *)&mp1);
+ point.x = psh.x;
+ point.y = psh.y;
+ }
+ /* finish the menu if we get a button down message (user must have
+ cancelled the menu). */
+ if (__glutMappedMenu) {
+ /* TODO: take this out once the menu on middle mouse stuff works
+ properly. */
+ if (button == GLUT_MIDDLE_BUTTON)
+ return 0;
+ /* get current mouse pointer position */
+// WinQueryPointerPos(HWND_DESKTOP,&point);
+ /* map from desktop to client window */
+// WinMapWindowPoints(HWND_DESKTOP, hwnd, &point, 1);
+ __glutItemSelected = NULL;
+ __glutFinishMenu(hwnd, point.x, point.y);
+ return 0;
+ }
+ window = __glutGetWindow(hwnd);
+ if (window) {
+ window->buttonDownState = button+1;
+ menu = __glutGetMenuByNum(window->menu[button]);
+ if (menu) {
+//todo
+// __glutMenuButton = button == GLUT_RIGHT_BUTTON ? TPM_RIGHTBUTTON :
+// button == GLUT_LEFT_BUTTON ? TPM_LEFTBUTTON :
+// 0x0001;
+// __glutStartMenu(menu, window, point.x, point.y, x, y);
+ } else if (window->mouse) {
+
+ __glutSetWindow(window);
+ __glutModifierMask = 0;
+ if (WinGetKeyState(HWND_DESKTOP,VK_SHIFT) & 0x8000) /* < 0 = high order bit is on. */
+ __glutModifierMask |= ShiftMask;
+ if (WinGetKeyState(HWND_DESKTOP,VK_CTRL) & 0x8000)
+ __glutModifierMask |= ControlMask;
+ if (WinGetKeyState(HWND_DESKTOP,VK_MENU) & 0x8000)
+ __glutModifierMask |= Mod1Mask;
+ window->mouse(button, GLUT_DOWN, point.x, point.y);
+ __glutModifierMask = (unsigned int)~0;
+ } else {
+ /* Stray mouse events. Ignore. */
+ }
+ }
+ return 0;
+
+ break;
+/********************************************/
+ case WM_BUTTON1UP:
+ button = GLUT_LEFT_BUTTON;
+ case WM_BUTTON3UP:
+ if (button < 0)
+ button = GLUT_MIDDLE_BUTTON;
+ case WM_BUTTON2UP:
+ if (button < 0)
+ button = GLUT_RIGHT_BUTTON;
+ { POINTS psh;
+ psh = *((POINTS *)&mp1);
+ point.x = psh.x;
+ point.y = psh.y;
+ }
+ /* Bail out if we're processing a menu. */
+ /* Bail out = �������� � �����⮬ */
+ if (__glutMappedMenu) {
+ WinQueryPointerPos(HWND_DESKTOP,&point);
+ WinMapWindowPoints(HWND_DESKTOP, hwnd, &point, 1);
+ /* if we're getting the middle button up signal, then something
+ on the menu was selected. */
+ if (button == GLUT_MIDDLE_BUTTON) {
+ return 0;
+ /* For some reason, the code below always returns -1 even
+ though the point IS IN THE ITEM! Therefore, just bail out if
+ we get a middle mouse up. The user must select using the
+ left mouse button. Stupid Win32. */
+#if 0
+ int item = MenuItemFromPoint(hwnd, __glutHMenu, point);
+ if (item != -1)
+ __glutItemSelected = (GLUTmenuItem*)GetMenuItemID(__glutHMenu, item);
+ else
+ __glutItemSelected = NULL;
+ __glutFinishMenu(hwnd, point.x, point.y);
+#endif
+ } else {
+ __glutItemSelected = NULL;
+ __glutFinishMenu(hwnd, point.x, point.y);
+ }
+ return 0;
+ }
+
+ window = __glutGetWindow(hwnd);
+ if(window)
+ window->buttonDownState = 0;
+
+ if (window && window->mouse) {
+ __glutSetWindow(window);
+ __glutModifierMask = 0;
+ if (WinGetKeyState(HWND_DESKTOP,VK_SHIFT) & 0x8000) /* < 0 = high order bit is on */
+ __glutModifierMask |= ShiftMask;
+ if (WinGetKeyState(HWND_DESKTOP,VK_CTRL) & 0x8000)
+ __glutModifierMask |= ControlMask;
+ if (WinGetKeyState(HWND_DESKTOP,VK_MENU) & 0x8000)
+ __glutModifierMask |= Mod1Mask;
+ window->mouse(button, GLUT_UP, point.x, point.y);
+
+ __glutModifierMask = (unsigned int)~0;
+ } else {
+ /* Window might have been destroyed and all the
+ events for the window may not yet be received. */
+ }
+ return 0;
+
+
+ break;
+//////////////////////////////////////////////////
+ case WM_COMMAND:
+ window = __glutGetWindow(hwnd);
+ if (window)
+ { if (window->wm_command)
+ window->wm_command(hwnd,mp1,mp2);
+ }
+ break;
+
+ case WM_MOUSEMOVE:
+ if (!__glutMappedMenu) {
+ window = __glutGetWindow(hwnd);
+ if (window) {
+ /* If motion function registered _and_ buttons held *
+ down, call motion function... */
+ { POINTS psh;
+ psh = *((POINTS *)&mp1);
+ point.x = psh.x;
+ point.y = psh.y;
+ }
+
+ if (window->motion && window->buttonDownState) {
+ __glutSetWindow(window);
+ window->motion(point.x, point.y);
+ }
+ /* If passive motion function registered _and_
+ buttons not held down, call passive motion
+ function... */
+ else if (window->passive && !window->buttonDownState) {
+ __glutSetWindow(window);
+ window->passive(point.x, point.y);
+ }
+ }
+ } else {
+ /* Motion events are thrown away when a pop up menu is
+ active. */
+ }
+ return 0;
+
+
+ default:
+ /* For all other messages, let the default window procedure process them. */
+ return ( WinDefWindowProc( hwnd, msg, mp1, mp2 ) );
+
+ } //endof switch( msg )
+ return ( WinDefWindowProc( hwnd, msg, mp1, mp2 ) );
+// return NULL;
+}
+
+void APIENTRY glutCommandFunc(GLUTcommandCB Func)
+{
+extern GLUTwindow *__glutCurrentWindow;
+ __glutCurrentWindow->wm_command = Func;
+}
+
+
+
+
+void
+updateWindowState(GLUTwindow *window, int visState)
+{
+ GLUTwindow* child;
+
+ /* XXX shownState and visState are the same in Win32. */
+ window->shownState = visState;
+ if (visState != window->visState) {
+ if (window->windowStatus) {
+ window->visState = visState;
+ __glutSetWindow(window);
+ window->windowStatus(visState);
+ }
+ }
+ /* Since Win32 only sends an activate for the toplevel window,
+ update the visibility for all the child windows. */
+ child = window->children;
+ while (child) {
+ updateWindowState(child, visState);
+ child = child->siblings;
+ }
+}
+
+#if POKA
+
+LONG WINAPI
+__glutWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ POINT point; /* Point structure. */
+ PAINTSTRUCT ps; /* Paint structure. */
+ LPMINMAXINFO minmax; /* Minimum/maximum info structure. */
+ GLUTwindow* window; /* GLUT window associated with message. */
+ GLUTmenu* menu; /* GLUT menu associated with message. */
+ int x, y, width, height, key;
+ int button = -1;
+
+ switch(msg) {
+ case WM_CREATE:
+ return 0;
+ case WM_CLOSE:
+ PostQuitMessage(0);
+ return 0;
+#if 0
+ case WM_DESTROY:
+ /* XXX NVidia's NT OpenGL can have problems closing down
+ its OpenGL internal data structures if we just allow
+ the process to terminate without unbinding and deleting
+ the windows context. Apparently, DirectDraw unloads
+ before OPENGL32.DLL in the close down sequence, but
+ NVidia's NT OpenGL needs DirectDraw to close down its
+ data structures. */
+ window = __glutGetWindow(hwnd);
+ if (window) {
+ if (window->ctx) {
+ wglMakeCurrent(NULL, NULL);
+ wglDeleteContext(window->ctx);
+ }
+ }
+ return 0;
+#endif
+
+ case WM_SYSKEYUP:
+ case WM_KEYUP:
+ window = __glutGetWindow(hwnd);
+ if (!window) {
+ break;
+ }
+ /* Win32 is dumb and sends these messages only to the parent
+ window. Therefore, find out if we're in a child window and
+ call the child windows keyboard callback if we are. */
+ if (window->parent) {
+ GetCursorPos(&point);
+ ScreenToClient(hwnd, &point);
+ hwnd = ChildWindowFromPoint(hwnd, point);
+ window = __glutGetWindow(hwnd);
+ }
+ if (window->specialUp || window->keyboardUp) {
+ GetCursorPos(&point);
+ ScreenToClient(window->win, &point);
+ __glutSetWindow(window);
+ __glutModifierMask = 0;
+ if (GetKeyState(VK_SHIFT) < 0) /* < 0 = high order bit is on */
+ __glutModifierMask |= ShiftMask;
+ if (GetKeyState(VK_SHIFT) < 0) /* < 0 = high order bit is on */
+ __glutModifierMask |= ControlMask;
+ if (GetKeyState(VK_MENU) < 0)
+ __glutModifierMask |= Mod1Mask;
+ switch (wParam) {
+ /* *INDENT-OFF* */
+ case VK_F1: key = GLUT_KEY_F1; break;
+ case VK_F2: key = GLUT_KEY_F2; break;
+ case VK_F3: key = GLUT_KEY_F3; break;
+ case VK_F4: key = GLUT_KEY_F4; break;
+ case VK_F5: key = GLUT_KEY_F5; break;
+ case VK_F6: key = GLUT_KEY_F6; break;
+ case VK_F7: key = GLUT_KEY_F7; break;
+ case VK_F8: key = GLUT_KEY_F8; break;
+ case VK_F9: key = GLUT_KEY_F9; break;
+ case VK_F10: key = GLUT_KEY_F10; break;
+ case VK_F11: key = GLUT_KEY_F11; break;
+ case VK_F12: key = GLUT_KEY_F12; break;
+ case VK_LEFT: key = GLUT_KEY_LEFT; break;
+ case VK_UP: key = GLUT_KEY_UP; break;
+ case VK_RIGHT: key = GLUT_KEY_RIGHT; break;
+ case VK_DOWN: key = GLUT_KEY_DOWN; break;
+ case VK_PRIOR: key = GLUT_KEY_PAGE_UP; break;
+ case VK_NEXT: key = GLUT_KEY_PAGE_DOWN; break;
+ case VK_HOME: key = GLUT_KEY_HOME; break;
+ case VK_END: key = GLUT_KEY_END; break;
+ case VK_INSERT: key = GLUT_KEY_INSERT; break;
+ case VK_DELETE:
+ /* Delete is an ASCII character. */
+ if (window->keyboardUp) {
+ window->keyboardUp((unsigned char) 127, point.x, point.y);
+ }
+ return 0;
+ /* *INDENT-ON* */
+ default:
+ if (window->keyboardUp) {
+ key = MapVirtualKey(wParam, 2); /* Map to ASCII. */
+ if (isascii(key) && (key != 0)) {
+
+ /* XXX Attempt to determine modified ASCII character
+ is quite incomplete. Digits, symbols, CapsLock,
+ Ctrl, and numeric keypad are all ignored. Fix this. */
+
+ if (!(__glutModifierMask & ShiftMask))
+ key = tolower(key);
+ window->keyboardUp((unsigned char) key, point.x, point.y);
+ }
+ }
+ __glutModifierMask = (unsigned int) ~0;
+ return 0;
+ }
+ if (window->specialUp) {
+ window->specialUp(key, point.x, point.y);
+ }
+ __glutModifierMask = (unsigned int) ~0;
+ }
+ return 0;
+
+ case WM_SYSCHAR:
+ case WM_CHAR:
+ window = __glutGetWindow(hwnd);
+ if (!window) {
+ break;
+ }
+
+ /* Bit 30 of lParam is set if key already held down. If
+ we are ignoring auto repeated key strokes for the window, bail. */
+ if (window->ignoreKeyRepeat && (lParam & (1 << 30)) ) {
+ break;
+ }
+
+ /* Win32 is dumb and sends these messages only to the parent
+ window. Therefore, find out if we're in a child window and
+ call the child windows keyboard callback if we are. */
+ if (window->parent) {
+ GetCursorPos(&point);
+ ScreenToClient(hwnd, &point);
+ hwnd = ChildWindowFromPoint(hwnd, point);
+ window = __glutGetWindow(hwnd);
+ }
+ if (window->keyboard) {
+ GetCursorPos(&point);
+ ScreenToClient(window->win, &point);
+ __glutSetWindow(window);
+ __glutModifierMask = 0;
+ if (GetKeyState(VK_SHIFT) < 0) /* < 0 = high order bit is on */
+ __glutModifierMask |= ShiftMask;
+ if (GetKeyState(VK_CONTROL) < 0)
+ __glutModifierMask |= ControlMask;
+ if (GetKeyState(VK_MENU) < 0)
+ __glutModifierMask |= Mod1Mask;
+ window->keyboard((unsigned char)wParam, point.x, point.y);
+ __glutModifierMask = (unsigned int) ~0;
+ }
+ return 0;
+
+ case WM_SYSKEYDOWN:
+ case WM_KEYDOWN:
+ window = __glutGetWindow(hwnd);
+ if (!window) {
+ break;
+ }
+
+ /* Bit 30 of lParam is set if key already held down. If
+ we are ignoring auto repeated key strokes for the window, bail. */
+ if (window->ignoreKeyRepeat && (lParam & (1 << 30)) ) {
+ break;
+ }
+
+ /* Win32 is dumb and sends these messages only to the parent
+ window. Therefore, find out if we're in a child window and
+ call the child windows keyboard callback if we are. */
+ if (window->parent) {
+ GetCursorPos(&point);
+ ScreenToClient(hwnd, &point);
+ hwnd = ChildWindowFromPoint(hwnd, point);
+ window = __glutGetWindow(hwnd);
+ }
+ if (window->special) {
+ switch (wParam) {
+ /* *INDENT-OFF* */
+ /* function keys */
+ case VK_F1: key = GLUT_KEY_F1; break;
+ case VK_F2: key = GLUT_KEY_F2; break;
+ case VK_F3: key = GLUT_KEY_F3; break;
+ case VK_F4: key = GLUT_KEY_F4; break;
+ case VK_F5: key = GLUT_KEY_F5; break;
+ case VK_F6: key = GLUT_KEY_F6; break;
+ case VK_F7: key = GLUT_KEY_F7; break;
+ case VK_F8: key = GLUT_KEY_F8; break;
+ case VK_F9: key = GLUT_KEY_F9; break;
+ case VK_F10: key = GLUT_KEY_F10; break;
+ case VK_F11: key = GLUT_KEY_F11; break;
+ case VK_F12: key = GLUT_KEY_F12; break;
+ /* directional keys */
+ case VK_LEFT: key = GLUT_KEY_LEFT; break;
+ case VK_UP: key = GLUT_KEY_UP; break;
+ case VK_RIGHT: key = GLUT_KEY_RIGHT; break;
+ case VK_DOWN: key = GLUT_KEY_DOWN; break;
+ /* *INDENT-ON* */
+
+ case VK_PRIOR:
+ /* VK_PRIOR is Win32's Page Up */
+ key = GLUT_KEY_PAGE_UP;
+ break;
+ case VK_NEXT:
+ /* VK_NEXT is Win32's Page Down */
+ key = GLUT_KEY_PAGE_DOWN;
+ break;
+ case VK_HOME:
+ key = GLUT_KEY_HOME;
+ break;
+ case VK_END:
+ key = GLUT_KEY_END;
+ break;
+ case VK_INSERT:
+ key = GLUT_KEY_INSERT;
+ break;
+ case VK_DELETE:
+ goto handleDelete;
+ default:
+ goto defproc;
+ }
+ GetCursorPos(&point);
+ ScreenToClient(window->win, &point);
+ __glutSetWindow(window);
+ __glutModifierMask = 0;
+ if (GetKeyState(VK_SHIFT) < 0) /* < 0 = high order bit is on */
+ __glutModifierMask |= ShiftMask;
+ if (GetKeyState(VK_CONTROL) < 0)
+ __glutModifierMask |= ControlMask;
+ if (GetKeyState(VK_MENU) < 0)
+ __glutModifierMask |= Mod1Mask;
+ window->special(key, point.x, point.y);
+ __glutModifierMask = (unsigned int) ~0;
+ } else if (window->keyboard) {
+ /* Specially handle any keys that match ASCII values but
+ do not generate Windows WM_SYSCHAR or WM_CHAR messages. */
+ switch (wParam) {
+ case VK_DELETE:
+ handleDelete:
+ /* Delete is an ASCII character. */
+ GetCursorPos(&point);
+ ScreenToClient(window->win, &point);
+ __glutSetWindow(window);
+ __glutModifierMask = 0;
+ if (GetKeyState(VK_SHIFT) < 0) /* < 0 = high order bit is on */
+ __glutModifierMask |= ShiftMask;
+ if (GetKeyState(VK_CONTROL) < 0)
+ __glutModifierMask |= ControlMask;
+ if (GetKeyState(VK_MENU) < 0)
+ __glutModifierMask |= Mod1Mask;
+ window->keyboard((unsigned char) 127, point.x, point.y);
+ __glutModifierMask = (unsigned int) ~0;
+ return 0;
+ default:
+ /* Let the following WM_SYSCHAR or WM_CHAR message generate
+ the keyboard callback. */
+ break;
+ }
+ }
+ return 0;
+
+ case WM_LBUTTONDOWN:
+ button = GLUT_LEFT_BUTTON;
+ case WM_MBUTTONDOWN:
+ if (button < 0)
+ button = GLUT_MIDDLE_BUTTON;
+ case WM_RBUTTONDOWN:
+ if (button < 0)
+ button = GLUT_RIGHT_BUTTON;
+
+ /* finish the menu if we get a button down message (user must have
+ cancelled the menu). */
+ if (__glutMappedMenu) {
+ /* TODO: take this out once the menu on middle mouse stuff works
+ properly. */
+ if (button == GLUT_MIDDLE_BUTTON)
+ return 0;
+ GetCursorPos(&point);
+ ScreenToClient(hwnd, &point);
+ __glutItemSelected = NULL;
+ __glutFinishMenu(hwnd, point.x, point.y);
+ return 0;
+ }
+
+ /* set the capture so we can get mouse events outside the window */
+ SetCapture(hwnd);
+
+ /* Win32 doesn't return the same numbers as X does when the mouse
+ goes beyond the upper or left side of the window. roll the
+ Win32's 0..2^16 pointer co-ord range to 0 +/- 2^15. */
+ x = LOWORD(lParam);
+ y = HIWORD(lParam);
+ if(x & 1 << 15) x -= (1 << 16);
+ if(y & 1 << 15) y -= (1 << 16);
+
+ window = __glutGetWindow(hwnd);
+ if (window) {
+ menu = __glutGetMenuByNum(window->menu[button]);
+ if (menu) {
+ point.x = LOWORD(lParam); point.y = HIWORD(lParam);
+ ClientToScreen(window->win, &point);
+ __glutMenuButton = button == GLUT_RIGHT_BUTTON ? TPM_RIGHTBUTTON :
+ button == GLUT_LEFT_BUTTON ? TPM_LEFTBUTTON :
+ 0x0001;
+ __glutStartMenu(menu, window, point.x, point.y, x, y);
+ } else if (window->mouse) {
+
+ __glutSetWindow(window);
+ __glutModifierMask = 0;
+ if (GetKeyState(VK_SHIFT) < 0) /* < 0 = high order bit is on. */
+ __glutModifierMask |= ShiftMask;
+ if (GetKeyState(VK_CONTROL) < 0)
+ __glutModifierMask |= ControlMask;
+ if (GetKeyState(VK_MENU) < 0)
+ __glutModifierMask |= Mod1Mask;
+ window->mouse(button, GLUT_DOWN, x, y);
+ __glutModifierMask = (unsigned int)~0;
+ } else {
+ /* Stray mouse events. Ignore. */
+ }
+ }
+ return 0;
+
+ case WM_LBUTTONUP:
+ button = GLUT_LEFT_BUTTON;
+ case WM_MBUTTONUP:
+ if (button < 0)
+ button = GLUT_MIDDLE_BUTTON;
+ case WM_RBUTTONUP:
+ if (button < 0)
+ button = GLUT_RIGHT_BUTTON;
+
+ /* Bail out if we're processing a menu. */
+ if (__glutMappedMenu) {
+ GetCursorPos(&point);
+ ScreenToClient(hwnd, &point);
+ /* if we're getting the middle button up signal, then something
+ on the menu was selected. */
+ if (button == GLUT_MIDDLE_BUTTON) {
+ return 0;
+ /* For some reason, the code below always returns -1 even
+ though the point IS IN THE ITEM! Therefore, just bail out if
+ we get a middle mouse up. The user must select using the
+ left mouse button. Stupid Win32. */
+#if 0
+ int item = MenuItemFromPoint(hwnd, __glutHMenu, point);
+ if (item != -1)
+ __glutItemSelected = (GLUTmenuItem*)GetMenuItemID(__glutHMenu, item);
+ else
+ __glutItemSelected = NULL;
+ __glutFinishMenu(hwnd, point.x, point.y);
+#endif
+ } else {
+ __glutItemSelected = NULL;
+ __glutFinishMenu(hwnd, point.x, point.y);
+ }
+ return 0;
+ }
+
+ /* Release the mouse capture. */
+ ReleaseCapture();
+
+ window = __glutGetWindow(hwnd);
+ if (window && window->mouse) {
+ /* Win32 doesn't return the same numbers as X does when the
+ mouse goes beyond the upper or left side of the window. roll
+ the Win32's 0..2^16 pointer co-ord range to 0 +/- 2^15. */
+ x = LOWORD(lParam);
+ y = HIWORD(lParam);
+ if(x & 1 << 15) x -= (1 << 16);
+ if(y & 1 << 15) y -= (1 << 16);
+
+ __glutSetWindow(window);
+ __glutModifierMask = 0;
+ if (GetKeyState(VK_SHIFT) < 0) /* < 0 = high order bit is on */
+ __glutModifierMask |= ShiftMask;
+ if (GetKeyState(VK_CONTROL) < 0)
+ __glutModifierMask |= ControlMask;
+ if (GetKeyState(VK_MENU) < 0)
+ __glutModifierMask |= Mod1Mask;
+ window->mouse(button, GLUT_UP, x, y);
+ __glutModifierMask = (unsigned int)~0;
+ } else {
+ /* Window might have been destroyed and all the
+ events for the window may not yet be received. */
+ }
+ return 0;
+
+ case WM_ENTERMENULOOP:
+ /* KLUDGE: create a timer that fires every 100 ms when we start a
+ menu so that we can still process the idle & timer events (that
+ way, the timers will fire during a menu pick and so will the
+ idle func. */
+ SetTimer(hwnd, 1, 1, NULL);
+ return 0;
+
+ case WM_TIMER:
+#if 0
+ /* If the timer id is 2, then this is the timer that is set up in
+ the main glut message processing loop, and we don't want to do
+ anything but acknowledge that we got it. It is used to prevent
+ CPU spiking when an idle function is installed. */
+ if (wParam == 2)
+ return 0;
+#endif
+
+ /* only worry about the idle function and the timeouts, since
+ these are the only events we expect to process during
+ processing of a menu. */
+ /* we no longer process the idle functions (as outlined in the
+ README), since drawing can't be done until the menu has
+ finished...it's pretty lame when the animation goes on, but
+ doesn't update, so you get this weird jerkiness. */
+#if 0
+ if (__glutIdleFunc)
+ __glutIdleFunc();
+#endif
+ if (__glutTimerList)
+ handleTimeouts();
+ return 0;
+
+ case WM_EXITMENULOOP:
+ /* nuke the above created timer...we don't need it anymore, since
+ the menu is gone now. */
+ KillTimer(hwnd, 1);
+ return 0;
+
+ case WM_MENUSELECT:
+ if (lParam != 0)
+ __glutHMenu = (HMENU)lParam;
+ return 0;
+
+ case WM_COMMAND:
+ if (__glutMappedMenu) {
+ if (GetSubMenu(__glutHMenu, LOWORD(wParam)))
+ __glutItemSelected = NULL;
+ else
+ __glutItemSelected =
+ __glutGetUniqueMenuItem(__glutMappedMenu, LOWORD(wParam));
+ GetCursorPos(&point);
+ ScreenToClient(hwnd, &point);
+ __glutFinishMenu(hwnd, point.x, point.y);
+ }
+ return 0;
+
+ case WM_MOUSEMOVE:
+ if (!__glutMappedMenu) {
+ window = __glutGetWindow(hwnd);
+ if (window) {
+ /* If motion function registered _and_ buttons held *
+ down, call motion function... */
+ x = LOWORD(lParam);
+ y = HIWORD(lParam);
+
+ /* Win32 doesn't return the same numbers as X does when the
+ mouse goes beyond the upper or left side of the window.
+ roll the Win32's 0..2^16 pointer co-ord range to 0..+/-2^15. */
+ if(x & 1 << 15) x -= (1 << 16);
+ if(y & 1 << 15) y -= (1 << 16);
+
+ if (window->motion && wParam &
+ (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) {
+ __glutSetWindow(window);
+ window->motion(x, y);
+ }
+ /* If passive motion function registered _and_
+ buttons not held down, call passive motion
+ function... */
+ else if (window->passive &&
+ ((wParam &
+ (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) ==
+ 0)) {
+ __glutSetWindow(window);
+ window->passive(x, y);
+ }
+ }
+ } else {
+ /* Motion events are thrown away when a pop up menu is
+ active. */
+ }
+ return 0;
+
+ case WM_GETMINMAXINFO:
+ /* this voodoo is brought to you by Win32 (again). It allows the
+ window to be bigger than the screen, and smaller than 100x100
+ (although it doesn't seem to help the y minimum). */
+ minmax = (LPMINMAXINFO)lParam;
+ minmax->ptMaxSize.x = __glutScreenWidth;
+ minmax->ptMaxSize.y = __glutScreenHeight;
+ minmax->ptMinTrackSize.x = 0;
+ minmax->ptMinTrackSize.y = 0;
+ minmax->ptMaxTrackSize.x = __glutScreenWidth +
+ GetSystemMetrics(SM_CXSIZE) * 2;
+ minmax->ptMaxTrackSize.y = __glutScreenHeight +
+ GetSystemMetrics(SM_CXSIZE) * 2 + GetSystemMetrics(SM_CYCAPTION);
+ return 0;
+
+ case WM_SIZE:
+ window = __glutGetWindow(hwnd);
+ if (window) {
+ width = LOWORD(lParam);
+ height = HIWORD(lParam);
+ if (width != window->width || height != window->height) {
+#if 0 /* Win32 GLUT does not support overlays for now. */
+ if (window->overlay) {
+ XResizeWindow(__glutDisplay, window->overlay->win, width, height);
+ }
+#endif
+ window->width = width;
+ window->height = height;
+ __glutSetWindow(window);
+ /* Do not execute OpenGL out of sequence with respect
+ to the SetWindowPos request! */
+ GdiFlush();
+ window->reshape(width, height);
+ window->forceReshape = FALSE;
+ /* A reshape should be considered like posting a
+ repair request. */
+ __glutPostRedisplay(window, GLUT_REPAIR_WORK);
+ }
+ }
+ return 0;
+
+ case WM_SETCURSOR:
+ /* If the cursor is not in the client area, then we want to send
+ this message to the default window procedure ('cause its
+ probably in the border or title, and we don't handle that
+ cursor. otherwise, set our cursor. Win32 makes us set the
+ cursor every time the mouse moves (DUMB!). */
+ if(LOWORD(lParam) != HTCLIENT) {
+ goto defproc;
+ }
+ window = __glutGetWindow(hwnd);
+ if (window) {
+ __glutSetCursor(window);
+ }
+ /* TODO: check out the info in DevStudio on WM_SETCURSOR in the
+ DefaultAction section. */
+ return 1;
+
+ case WM_SETFOCUS:
+ window = __glutGetWindow(hwnd);
+ if (window) {
+ window->entryState = WM_SETFOCUS;
+ if (window->entry) {
+ __glutSetWindow(window);
+ window->entry(GLUT_ENTERED);
+ /* XXX Generation of fake passive notify? See how much
+ work the X11 code does to support fake passive notify
+ callbacks. */
+ }
+ if (window->joystick && __glutCurrentWindow) {
+ if (__glutCurrentWindow->joyPollInterval > 0) {
+ MMRESULT result;
+
+ /* Because Win32 will only let one window capture the
+ joystick at a time, we must capture it when we get the
+ focus and release it when we lose the focus. */
+ result = joySetCapture(__glutCurrentWindow->win,
+ JOYSTICKID1, 0, TRUE);
+ if (result != JOYERR_NOERROR) {
+ return 0;
+ }
+ (void) joySetThreshold(JOYSTICKID1,
+ __glutCurrentWindow->joyPollInterval);
+ }
+ }
+ }
+ return 0;
+
+ case WM_KILLFOCUS:
+ window = __glutGetWindow(hwnd);
+ if (window) {
+ window->entryState = WM_KILLFOCUS;
+ if (window->entry) {
+ __glutSetWindow(window);
+ window->entry(GLUT_LEFT);
+ }
+ if (window->joystick && __glutCurrentWindow) {
+ if (__glutCurrentWindow->joyPollInterval > 0) {
+ /* Because Win32 will only let one window capture the
+ joystick at a time, we must capture it when we get the
+ focus and release it when we lose the focus. */
+ (void) joyReleaseCapture(JOYSTICKID1);
+ }
+ }
+ }
+ return 0;
+ case WM_ACTIVATE:
+ window = __glutGetWindow(hwnd);
+ /* Make sure we re-select the correct palette if needed. */
+ if (LOWORD(wParam)) {
+ PostMessage(hwnd, WM_PALETTECHANGED, 0, 0);
+ }
+ if (window) {
+ int visState;
+
+ /* HIWORD(wParam) is the minimized flag. */
+ visState = !HIWORD(wParam);
+ updateWindowState(window, visState);
+ }
+ return 0;
+
+ /* Colour Palette Management */
+ case WM_PALETTECHANGED:
+ if (hwnd == (HWND)wParam) {
+ /* Don't respond to the message that we sent! */
+ break;
+ }
+ /* fall through to WM_QUERYNEWPALETTE */
+
+ case WM_QUERYNEWPALETTE:
+ window = __glutGetWindow(hwnd);
+ if (window && window->colormap) {
+ UnrealizeObject(window->colormap->cmap);
+ SelectPalette(window->hdc, window->colormap->cmap, FALSE);
+ RealizePalette(window->hdc);
+ return TRUE;
+ }
+ return FALSE;
+
+ case MM_JOY1MOVE:
+ case MM_JOY1ZMOVE:
+ window = __glutGetWindow(hwnd);
+ if (window->joystick) {
+ JOYINFOEX jix;
+ int x, y, z;
+
+ /* Because WIN32 only supports messages for X, Y, and Z
+ translations, we must poll for the rest */
+ jix.dwSize = sizeof(jix);
+ jix.dwFlags = JOY_RETURNALL;
+ joyGetPosEx(JOYSTICKID1,&jix);
+
+#define SCALE(v) ((int) ((v - 32767)/32.768))
+
+ /* Convert to integer for scaling. */
+ x = jix.dwXpos;
+ y = jix.dwYpos;
+ z = jix.dwZpos;
+ window->joystick(jix.dwButtons, SCALE(x), SCALE(y), SCALE(z));
+
+ return TRUE;
+ }
+ return FALSE;
+ case MM_JOY1BUTTONDOWN:
+ case MM_JOY1BUTTONUP:
+ window = __glutGetWindow(hwnd);
+ if (window->joystick) {
+ JOYINFOEX jix;
+
+ /* Because WIN32 only supports messages for X, Y, and Z
+ translations, we must poll for the rest */
+ jix.dwSize = sizeof(jix);
+ jix.dwFlags = JOY_RETURNALL;
+ joyGetPosEx(JOYSTICKID1,&jix);
+
+ return TRUE;
+ }
+ return FALSE;
+
+#if 0
+ /* Miscellaneous messages (don't really need to enumerate them,
+ but it's good to know what you're not getting sometimes). */
+ case WM_DISPLAYCHANGE:
+ break;
+ case WM_NCHITTEST:
+ /* This event is generated by every mouse move event. */
+ goto defproc;
+ case WM_NCMOUSEMOVE:
+ goto defproc;
+ case WM_NCACTIVATE:
+ goto defproc;
+ case WM_NCPAINT:
+ goto defproc;
+ case WM_NCCALCSIZE:
+ goto defproc;
+ case WM_NCCREATE:
+ goto defproc;
+ case WM_NCDESTROY:
+ goto defproc;
+ case WM_NCLBUTTONDOWN:
+ goto defproc;
+ case WM_SETTEXT:
+ goto defproc;
+ case WM_GETTEXT:
+ goto defproc;
+ case WM_ACTIVATEAPP:
+ goto defproc;
+ case WM_GETICON:
+ goto defproc;
+ case WM_ERASEBKGND:
+ goto defproc;
+ case WM_WINDOWPOSCHANGING:
+ goto defproc;
+ case WM_WINDOWPOSCHANGED:
+ goto defproc;
+ case WM_MOUSEACTIVATE:
+ goto defproc;
+ case WM_SHOWWINDOW:
+ goto defproc;
+ case WM_MOVING:
+ goto defproc;
+ case WM_MOVE:
+ goto defproc;
+ case WM_KEYUP:
+ goto defproc;
+ case WM_CAPTURECHANGED:
+ goto defproc;
+ case WM_SYSCOMMAND:
+ goto defproc;
+ case WM_ENTERSIZEMOVE:
+ goto defproc;
+ case WM_ENTERIDLE:
+ goto defproc;
+#endif
+
+ default:
+ goto defproc;
+ }
+
+defproc:
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+}
+
+#endif
+
+#if defined(__OS2PM__)
+Bool __glutSetWindowText(Window window, char *text)
+{
+ return WinSetWindowText(window, (PCSZ)text);
+
+}
+
+#endif
+ \ No newline at end of file