~ubuntu-branches/ubuntu/precise/mesa/precise-updates

« back to all changes in this revision

Viewing changes to src/glut/glx/win32_winproc.c

  • Committer: Bazaar Package Importer
  • Author(s): Christopher James Halse Rogers
  • Date: 2011-08-04 16:25:08 UTC
  • mfrom: (1.2.37 upstream)
  • Revision ID: james.westby@ubuntu.com-20110804162508-kujg82moxerjg1kk
Tags: 7.11-0ubuntu1
* Fake merge from Debian experimental, updating previous changelog entries.
  New upstream release fixes infrequent X crash (LP: #800778).
  Remaining Ubuntu changes:
 - debian/control
    + Drop lesstif-dev from Build-Depends; it's in Universe.
    + Comment out GLw libs since it depends on lesstif-dev.
    + Drop i686 swx11 libgl package.
    + Add libdrm-dev to mesa-common-dev Depends.
    + Drop libwayland-dev from Build-Depends; it's in Universe.
    + Update Breaks for Ubuntu versions
    + Enable llvm on armel as well as i386 and amd64
  - debian/rules
    + Use --disable-glw for swx11 targets too.
    + Don't enable motif for swx11 targets.
    + Use lzma compression for binary debs to save CD space.
    + Drop unloved mach64 driver.
    + Use --enable-shared-dricore to claw back CD space.
    + Enable llvmpipe software rasteriser.
    + Enable llvm on armel as well as i386 and amd64
  - debian/patches
    + 100_no_abi_tag.patch
    + 101_ubuntu_hidden_glname.patch
    + 103_savage-expose_fbmodes_with_nonzero_alpha.patch
  - rules, libgl1-mesa-{glx,dev,swx11,swx11-dev}.install.in,
    libgl1-mesa-{glx,swx11}.{postinst,prerm}.in, libgl1-mesa-dev.links.in:
    Install libGL.so* in /usr/lib/mesa to allow things to work with
    alternatives.
  - debian/not-installed:
    + Drop i686 files; we don't build 686-optimised packages in the first
      place.
  - debian/gbp.conf
    + Point at Ubuntu branch to make git-buildpackage less narky.
  - 113_fix_tls.diff: Fix crashes in unrelated code due to TLS usage.
  - debian/patches/111_export_searchdirs_in_dripc.diff:
    + Add drisearchdirs variable to dri.pc so the Xserver can pick up the
      alternate DRI driver dirs.
  - debian/patches/115_llvm_dynamic_linking.diff
    + Dynamically link DRI drivers to libllvm.  Saves ~6MiB per DRI driver.
  - debian/patches/116_use_shared_galliumcore.diff:
  - debian/libgl1-mesa-dri.install.in:
    + Link gallium DRI drivers against shared gallium routines to save CD
      space.
* debian/rules:
* debian/libgl1-mesa-dri-experimental.install.{i386,amd64}.in
  - Explicitly install i915g only when it has been built, matching what is
    done with r300g.
* debian/rules:
* debian/control:
* debian/libegl1-mesa{,-dev}.install.in:
* debian/libegl1-mesa.symbols:
  - Enable the Wayland EGL backend.
* debian/rules:
* debian/libegl1-mesa.{postinst,prerm,install}.in:
* debian/libegl1-mesa-dev.{install,links}.in:
* debian/libgles{1,2}-mesa.install.in:
* debian/libgles{1,2}-mesa-dev.links.in:
* debian/libopenvg1-mesa{,-dev}.install.in:
* debian/libopenvg1-mesa-dev.links.in:
  - Use alternatives for libEGL to match the handling of libGL.
    libEGL (and associated GL|ES and OpenVG libraries) now live in
    /usr/lib/$MULTIARCH/mesa-egl.  (LP: #812639)
* debian/patches/118_fix_24bpp_software_rendering.diff:
  - Cherry pick upstream patch from master fixing graphical corruption when
    using a 24bpp framebuffer and software rendering. (LP: #810339)
* debian/rules:
* debian/clean:
  - Generate xmlpool pot file and clean up other po files for
    pkgbinarymangler's benefit (LP: #410264).
* debian/patches/119_r600g_gnome_shell_rendering_fix.diff:
  - Cherry pick upstream commit fixing rendering corruption in gnome-shell
    (and therefore likely Unity as well).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 
2
 
/* Copyright (c) Nate Robins, 1997. */
3
 
/* portions Copyright (c) Mark Kilgard, 1997, 1998. */
4
 
 
5
 
/* This program is freely distributable without licensing fees 
6
 
   and is provided without guarantee or warrantee expressed or 
7
 
   implied. This program is -not- in the public domain. */
8
 
 
9
 
 
10
 
#include "glutint.h"
11
 
#include <sys/timeb.h>
12
 
#ifdef __MINGW32__
13
 
#include <ctype.h>
14
 
#endif
15
 
 
16
 
#if defined(_WIN32) && !defined(__CYGWIN32__)
17
 
#include <mmsystem.h>  /* Win32 Multimedia API header. */
18
 
#endif
19
 
 
20
 
extern unsigned __glutMenuButton;
21
 
extern GLUTidleCB __glutIdleFunc;
22
 
extern GLUTtimer *__glutTimerList;
23
 
extern GLUTmenuItem *__glutGetUniqueMenuItem(GLUTmenu * menu, UINT unique);
24
 
static HMENU __glutHMenu;
25
 
 
26
 
static void
27
 
updateWindowState(GLUTwindow *window, int visState)
28
 
{
29
 
  GLUTwindow* child;
30
 
 
31
 
  /* XXX shownState and visState are the same in Win32. */
32
 
  window->shownState = visState;
33
 
  if (visState != window->visState) {
34
 
    if (window->windowStatus) {
35
 
      window->visState = visState;
36
 
      __glutSetWindow(window);
37
 
      window->windowStatus(visState);
38
 
    }
39
 
  }
40
 
  /* Since Win32 only sends an activate for the toplevel window,
41
 
     update the visibility for all the child windows. */
42
 
  child = window->children;
43
 
  while (child) {
44
 
    updateWindowState(child, visState);
45
 
    child = child->siblings;
46
 
  }
47
 
}
48
 
 
49
 
LONG WINAPI
50
 
__glutWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
51
 
52
 
  POINT         point;                  /* Point structure. */
53
 
  PAINTSTRUCT   ps;                     /* Paint structure. */
54
 
  LPMINMAXINFO  minmax;                 /* Minimum/maximum info structure. */
55
 
  GLUTwindow*   window;                 /* GLUT window associated with message. */
56
 
  GLUTmenu*     menu;                   /* GLUT menu associated with message. */
57
 
  int x, y, width, height, key;
58
 
  int button = -1;
59
 
 
60
 
  switch(msg) {
61
 
  case WM_CREATE:
62
 
    return 0;
63
 
  case WM_CLOSE:
64
 
    if (__glutExitFunc) {
65
 
      __glutExitFunc(0);
66
 
    }
67
 
    exit(0);
68
 
    break;
69
 
#if 0
70
 
  case WM_DESTROY:
71
 
    /* XXX NVidia's NT OpenGL can have problems closing down
72
 
       its OpenGL internal data structures if we just allow
73
 
       the process to terminate without unbinding and deleting
74
 
       the windows context.  Apparently, DirectDraw unloads
75
 
       before OPENGL32.DLL in the close down sequence, but
76
 
       NVidia's NT OpenGL needs DirectDraw to close down its
77
 
       data structures. */
78
 
    window = __glutGetWindow(hwnd);
79
 
    if (window) {
80
 
      if (window->ctx) {
81
 
        wglMakeCurrent(NULL, NULL);
82
 
        wglDeleteContext(window->ctx);
83
 
      }
84
 
    }
85
 
    return 0;
86
 
#endif
87
 
  case WM_PAINT:
88
 
    window = __glutGetWindow(hwnd);
89
 
    if (window) {
90
 
      BeginPaint(hwnd, &ps);            /* Must have this for some Win32 reason. */
91
 
      EndPaint(hwnd, &ps);
92
 
      if (window->win == hwnd) {
93
 
        __glutPostRedisplay(window, GLUT_REPAIR_WORK);
94
 
      } else if (window->overlay && window->overlay->win == hwnd) {
95
 
        __glutPostRedisplay(window, GLUT_OVERLAY_REPAIR_WORK);
96
 
      }
97
 
    }
98
 
    return 0;
99
 
 
100
 
  case WM_SYSKEYUP:
101
 
  case WM_KEYUP:
102
 
    window = __glutGetWindow(hwnd);
103
 
    if (!window) {
104
 
      break;
105
 
    }
106
 
    /* Win32 is dumb and sends these messages only to the parent
107
 
       window.  Therefore, find out if we're in a child window and
108
 
       call the child windows keyboard callback if we are. */
109
 
    if (window->parent) {
110
 
      GetCursorPos(&point);
111
 
      ScreenToClient(hwnd, &point);
112
 
      hwnd = ChildWindowFromPoint(hwnd, point);
113
 
      window = __glutGetWindow(hwnd);
114
 
    }
115
 
    if (window->specialUp || window->keyboardUp) {
116
 
      GetCursorPos(&point);
117
 
      ScreenToClient(window->win, &point);
118
 
      __glutSetWindow(window);
119
 
      __glutModifierMask = 0;
120
 
      if (GetKeyState(VK_SHIFT) < 0)  /* < 0 = high order bit is on */
121
 
        __glutModifierMask |= ShiftMask;
122
 
      if (GetKeyState(VK_SHIFT) < 0)  /* < 0 = high order bit is on */
123
 
        __glutModifierMask |= ControlMask;
124
 
      if (GetKeyState(VK_MENU) < 0)
125
 
        __glutModifierMask |= Mod1Mask;
126
 
      switch (wParam) {
127
 
      /* *INDENT-OFF* */
128
 
      case VK_F1:     key = GLUT_KEY_F1; break;
129
 
      case VK_F2:     key = GLUT_KEY_F2; break;
130
 
      case VK_F3:     key = GLUT_KEY_F3; break;
131
 
      case VK_F4:     key = GLUT_KEY_F4; break;
132
 
      case VK_F5:     key = GLUT_KEY_F5; break;
133
 
      case VK_F6:     key = GLUT_KEY_F6; break;
134
 
      case VK_F7:     key = GLUT_KEY_F7; break;
135
 
      case VK_F8:     key = GLUT_KEY_F8; break;
136
 
      case VK_F9:     key = GLUT_KEY_F9; break;
137
 
      case VK_F10:    key = GLUT_KEY_F10; break;
138
 
      case VK_F11:    key = GLUT_KEY_F11; break;
139
 
      case VK_F12:    key = GLUT_KEY_F12; break;
140
 
      case VK_LEFT:   key = GLUT_KEY_LEFT; break;
141
 
      case VK_UP:     key = GLUT_KEY_UP; break;
142
 
      case VK_RIGHT:  key = GLUT_KEY_RIGHT; break;
143
 
      case VK_DOWN:   key = GLUT_KEY_DOWN; break;
144
 
      case VK_PRIOR:  key = GLUT_KEY_PAGE_UP; break;
145
 
      case VK_NEXT:   key = GLUT_KEY_PAGE_DOWN; break;
146
 
      case VK_HOME:   key = GLUT_KEY_HOME; break;
147
 
      case VK_END:    key = GLUT_KEY_END; break;
148
 
      case VK_INSERT: key = GLUT_KEY_INSERT; break;
149
 
      case VK_DELETE:
150
 
        /* Delete is an ASCII character. */
151
 
        if (window->keyboardUp) {
152
 
          window->keyboardUp((unsigned char) 127, point.x, point.y);
153
 
        }
154
 
        return 0;
155
 
      /* *INDENT-ON* */
156
 
      default:
157
 
        if (window->keyboardUp) {
158
 
          key = MapVirtualKey(wParam, 2);  /* Map to ASCII. */
159
 
          if (isascii(key) && (key != 0)) {
160
 
 
161
 
            /* XXX Attempt to determine modified ASCII character
162
 
               is quite incomplete.  Digits, symbols, CapsLock,
163
 
               Ctrl, and numeric keypad are all ignored.  Fix this. */
164
 
 
165
 
            if (!(__glutModifierMask & ShiftMask))
166
 
              key = tolower(key);
167
 
            window->keyboardUp((unsigned char) key, point.x, point.y);
168
 
          }
169
 
        }
170
 
        __glutModifierMask = (unsigned int) ~0;
171
 
        return 0;
172
 
      }
173
 
      if (window->specialUp) {
174
 
        window->specialUp(key, point.x, point.y);
175
 
      }
176
 
      __glutModifierMask = (unsigned int) ~0;
177
 
    }
178
 
    return 0;
179
 
 
180
 
  case WM_SYSCHAR:
181
 
  case WM_CHAR:
182
 
    window = __glutGetWindow(hwnd);
183
 
    if (!window) {
184
 
      break;
185
 
    }
186
 
 
187
 
    /* Bit 30 of lParam is set if key already held down.  If
188
 
       we are ignoring auto repeated key strokes for the window, bail. */
189
 
    if (window->ignoreKeyRepeat && (lParam & (1 << 30)) ) {
190
 
      break;
191
 
    }
192
 
 
193
 
    /* Win32 is dumb and sends these messages only to the parent
194
 
       window.  Therefore, find out if we're in a child window and
195
 
       call the child windows keyboard callback if we are. */
196
 
    if (window->parent) {
197
 
        GetCursorPos(&point);
198
 
        ScreenToClient(hwnd, &point);
199
 
        hwnd = ChildWindowFromPoint(hwnd, point);
200
 
        window = __glutGetWindow(hwnd);
201
 
    }
202
 
    if (window->keyboard) {
203
 
      GetCursorPos(&point);
204
 
      ScreenToClient(window->win, &point);
205
 
      __glutSetWindow(window);
206
 
      __glutModifierMask = 0;
207
 
      if (GetKeyState(VK_SHIFT) < 0)    /* < 0 = high order bit is on */
208
 
        __glutModifierMask |= ShiftMask;
209
 
      if (GetKeyState(VK_CONTROL) < 0)
210
 
        __glutModifierMask |= ControlMask;
211
 
      if (GetKeyState(VK_MENU) < 0)
212
 
        __glutModifierMask |= Mod1Mask;
213
 
      window->keyboard((unsigned char)wParam, point.x, point.y);
214
 
      __glutModifierMask = (unsigned int) ~0;
215
 
    }
216
 
    return 0;
217
 
 
218
 
  case WM_SYSKEYDOWN:
219
 
  case WM_KEYDOWN:
220
 
    window = __glutGetWindow(hwnd);
221
 
    if (!window) {
222
 
      break;
223
 
    }
224
 
 
225
 
    /* Bit 30 of lParam is set if key already held down.  If
226
 
       we are ignoring auto repeated key strokes for the window, bail. */
227
 
    if (window->ignoreKeyRepeat && (lParam & (1 << 30)) ) {
228
 
      break;
229
 
    }
230
 
 
231
 
    /* Win32 is dumb and sends these messages only to the parent
232
 
       window.  Therefore, find out if we're in a child window and
233
 
       call the child windows keyboard callback if we are. */
234
 
    if (window->parent) {
235
 
        GetCursorPos(&point);
236
 
        ScreenToClient(hwnd, &point);
237
 
        hwnd = ChildWindowFromPoint(hwnd, point);
238
 
        window = __glutGetWindow(hwnd);
239
 
    }
240
 
    if (window->special) {
241
 
      switch (wParam) {
242
 
        /* *INDENT-OFF* */
243
 
        /* function keys */
244
 
        case VK_F1:     key = GLUT_KEY_F1; break;
245
 
        case VK_F2:     key = GLUT_KEY_F2; break;
246
 
        case VK_F3:     key = GLUT_KEY_F3; break;
247
 
        case VK_F4:     key = GLUT_KEY_F4; break;
248
 
        case VK_F5:     key = GLUT_KEY_F5; break;
249
 
        case VK_F6:     key = GLUT_KEY_F6; break;
250
 
        case VK_F7:     key = GLUT_KEY_F7; break;
251
 
        case VK_F8:     key = GLUT_KEY_F8; break;
252
 
        case VK_F9:     key = GLUT_KEY_F9; break;
253
 
        case VK_F10:    key = GLUT_KEY_F10; break;
254
 
        case VK_F11:    key = GLUT_KEY_F11; break;
255
 
        case VK_F12:    key = GLUT_KEY_F12; break;
256
 
        /* directional keys */
257
 
        case VK_LEFT:   key = GLUT_KEY_LEFT; break;
258
 
        case VK_UP:     key = GLUT_KEY_UP; break;
259
 
        case VK_RIGHT:  key = GLUT_KEY_RIGHT; break;
260
 
        case VK_DOWN:   key = GLUT_KEY_DOWN; break;
261
 
        /* *INDENT-ON* */
262
 
 
263
 
        case VK_PRIOR:
264
 
          /* VK_PRIOR is Win32's Page Up */
265
 
          key = GLUT_KEY_PAGE_UP;
266
 
          break;
267
 
        case VK_NEXT:
268
 
          /* VK_NEXT is Win32's Page Down */
269
 
          key = GLUT_KEY_PAGE_DOWN;
270
 
          break;
271
 
        case VK_HOME:
272
 
          key = GLUT_KEY_HOME;
273
 
          break;
274
 
        case VK_END:
275
 
          key = GLUT_KEY_END;
276
 
          break;
277
 
        case VK_INSERT:
278
 
          key = GLUT_KEY_INSERT;
279
 
          break;
280
 
        case VK_DELETE:
281
 
          goto handleDelete;
282
 
        default:
283
 
          goto defproc;
284
 
      }
285
 
      GetCursorPos(&point);
286
 
      ScreenToClient(window->win, &point);
287
 
      __glutSetWindow(window);
288
 
      __glutModifierMask = 0;
289
 
      if (GetKeyState(VK_SHIFT) < 0)    /* < 0 = high order bit is on */
290
 
        __glutModifierMask |= ShiftMask;
291
 
      if (GetKeyState(VK_CONTROL) < 0)
292
 
        __glutModifierMask |= ControlMask;
293
 
      if (GetKeyState(VK_MENU) < 0)
294
 
        __glutModifierMask |= Mod1Mask;
295
 
      window->special(key, point.x, point.y);
296
 
      __glutModifierMask = (unsigned int) ~0;
297
 
    } else if (window->keyboard) {
298
 
      /* Specially handle any keys that match ASCII values but
299
 
         do not generate Windows WM_SYSCHAR or WM_CHAR messages. */
300
 
      switch (wParam) {
301
 
      case VK_DELETE:
302
 
      handleDelete:
303
 
        /* Delete is an ASCII character. */
304
 
        GetCursorPos(&point);
305
 
        ScreenToClient(window->win, &point);
306
 
        __glutSetWindow(window);
307
 
        __glutModifierMask = 0;
308
 
        if (GetKeyState(VK_SHIFT) < 0)  /* < 0 = high order bit is on */
309
 
          __glutModifierMask |= ShiftMask;
310
 
        if (GetKeyState(VK_CONTROL) < 0)
311
 
          __glutModifierMask |= ControlMask;
312
 
        if (GetKeyState(VK_MENU) < 0)
313
 
          __glutModifierMask |= Mod1Mask;
314
 
        window->keyboard((unsigned char) 127, point.x, point.y);
315
 
        __glutModifierMask = (unsigned int) ~0;
316
 
        return 0;
317
 
      default:
318
 
        /* Let the following WM_SYSCHAR or WM_CHAR message generate
319
 
           the keyboard callback. */
320
 
        break;
321
 
      }
322
 
    }
323
 
    return 0;
324
 
 
325
 
  case WM_LBUTTONDOWN:
326
 
    button = GLUT_LEFT_BUTTON;
327
 
  case WM_MBUTTONDOWN:
328
 
    if (button < 0)
329
 
      button = GLUT_MIDDLE_BUTTON;
330
 
  case WM_RBUTTONDOWN:
331
 
    if (button < 0)
332
 
      button = GLUT_RIGHT_BUTTON;
333
 
    
334
 
    /* finish the menu if we get a button down message (user must have
335
 
       cancelled the menu). */
336
 
    if (__glutMappedMenu) {
337
 
      /* TODO: take this out once the menu on middle mouse stuff works
338
 
         properly. */
339
 
      if (button == GLUT_MIDDLE_BUTTON)
340
 
        return 0;
341
 
      GetCursorPos(&point);
342
 
      ScreenToClient(hwnd, &point);
343
 
      __glutItemSelected = NULL;
344
 
      __glutFinishMenu(hwnd, point.x, point.y);
345
 
      return 0;
346
 
    }
347
 
 
348
 
    /* set the capture so we can get mouse events outside the window */
349
 
    SetCapture(hwnd);
350
 
 
351
 
    /* Win32 doesn't return the same numbers as X does when the mouse
352
 
       goes beyond the upper or left side of the window.  roll the
353
 
       Win32's 0..2^16 pointer co-ord range to 0 +/- 2^15. */
354
 
    x = LOWORD(lParam);
355
 
    y = HIWORD(lParam);
356
 
    if(x & 1 << 15) x -= (1 << 16);
357
 
    if(y & 1 << 15) y -= (1 << 16);
358
 
        
359
 
    window = __glutGetWindow(hwnd);
360
 
    if (window) {
361
 
      menu = __glutGetMenuByNum(window->menu[button]);
362
 
      if (menu) {
363
 
        point.x = LOWORD(lParam); point.y = HIWORD(lParam);
364
 
        ClientToScreen(window->win, &point);
365
 
        __glutMenuButton = button == GLUT_RIGHT_BUTTON ? TPM_RIGHTBUTTON :
366
 
                           button == GLUT_LEFT_BUTTON  ? TPM_LEFTBUTTON :
367
 
                           0x0001;
368
 
        __glutStartMenu(menu, window, point.x, point.y, x, y);
369
 
      } else if (window->mouse) {
370
 
        
371
 
        __glutSetWindow(window);
372
 
        __glutModifierMask = 0;
373
 
        if (GetKeyState(VK_SHIFT) < 0)  /* < 0 = high order bit is on. */
374
 
          __glutModifierMask |= ShiftMask;
375
 
        if (GetKeyState(VK_CONTROL) < 0)
376
 
          __glutModifierMask |= ControlMask;
377
 
        if (GetKeyState(VK_MENU) < 0)
378
 
          __glutModifierMask |= Mod1Mask;
379
 
        window->mouse(button, GLUT_DOWN, x, y);
380
 
        __glutModifierMask = (unsigned int)~0;
381
 
      } else {
382
 
        /* Stray mouse events.  Ignore. */
383
 
      }
384
 
    }
385
 
    return 0;
386
 
 
387
 
  case WM_LBUTTONUP:
388
 
    button = GLUT_LEFT_BUTTON;
389
 
  case WM_MBUTTONUP:
390
 
    if (button < 0)
391
 
      button = GLUT_MIDDLE_BUTTON;
392
 
  case WM_RBUTTONUP:
393
 
    if (button < 0)
394
 
      button = GLUT_RIGHT_BUTTON;
395
 
 
396
 
    /* Bail out if we're processing a menu. */
397
 
    if (__glutMappedMenu) {
398
 
      GetCursorPos(&point);
399
 
      ScreenToClient(hwnd, &point);
400
 
      /* if we're getting the middle button up signal, then something
401
 
         on the menu was selected. */
402
 
      if (button == GLUT_MIDDLE_BUTTON) {
403
 
        return 0;
404
 
        /* For some reason, the code below always returns -1 even
405
 
           though the point IS IN THE ITEM!  Therefore, just bail out if
406
 
           we get a middle mouse up.  The user must select using the
407
 
           left mouse button.  Stupid Win32. */
408
 
#if 0
409
 
        int item = MenuItemFromPoint(hwnd, __glutHMenu, point);
410
 
        if (item != -1)
411
 
          __glutItemSelected = (GLUTmenuItem*)GetMenuItemID(__glutHMenu, item);
412
 
        else
413
 
          __glutItemSelected = NULL;
414
 
        __glutFinishMenu(hwnd, point.x, point.y);
415
 
#endif
416
 
      } else {
417
 
        __glutItemSelected = NULL;
418
 
        __glutFinishMenu(hwnd, point.x, point.y);
419
 
      }
420
 
      return 0;
421
 
    }
422
 
 
423
 
    /* Release the mouse capture. */
424
 
    ReleaseCapture();
425
 
 
426
 
    window = __glutGetWindow(hwnd);
427
 
    if (window && window->mouse) {
428
 
      /* Win32 doesn't return the same numbers as X does when the
429
 
         mouse goes beyond the upper or left side of the window.  roll
430
 
         the Win32's 0..2^16 pointer co-ord range to 0 +/- 2^15. */
431
 
      x = LOWORD(lParam);
432
 
      y = HIWORD(lParam);
433
 
      if(x & 1 << 15) x -= (1 << 16);
434
 
      if(y & 1 << 15) y -= (1 << 16);
435
 
      
436
 
      __glutSetWindow(window);
437
 
      __glutModifierMask = 0;
438
 
      if (GetKeyState(VK_SHIFT) < 0)    /* < 0 = high order bit is on */
439
 
        __glutModifierMask |= ShiftMask;
440
 
      if (GetKeyState(VK_CONTROL) < 0)
441
 
        __glutModifierMask |= ControlMask;
442
 
      if (GetKeyState(VK_MENU) < 0)
443
 
        __glutModifierMask |= Mod1Mask;
444
 
      window->mouse(button, GLUT_UP, x, y);
445
 
      __glutModifierMask = (unsigned int)~0;
446
 
    } else {
447
 
      /* Window might have been destroyed and all the 
448
 
         events for the window may not yet be received. */
449
 
    }
450
 
    return 0;
451
 
 
452
 
  case WM_ENTERMENULOOP:
453
 
    /* KLUDGE: create a timer that fires every 100 ms when we start a
454
 
       menu so that we can still process the idle & timer events (that
455
 
       way, the timers will fire during a menu pick and so will the
456
 
       idle func. */
457
 
    SetTimer(hwnd, 1, 1, NULL);
458
 
    return 0;
459
 
 
460
 
  case WM_TIMER:
461
 
#if 0
462
 
    /* If the timer id is 2, then this is the timer that is set up in
463
 
       the main glut message processing loop, and we don't want to do
464
 
       anything but acknowledge that we got it.  It is used to prevent
465
 
       CPU spiking when an idle function is installed. */
466
 
    if (wParam == 2)
467
 
      return 0;
468
 
#endif
469
 
 
470
 
    /* only worry about the idle function and the timeouts, since
471
 
       these are the only events we expect to process during
472
 
       processing of a menu. */
473
 
    /* we no longer process the idle functions (as outlined in the
474
 
       README), since drawing can't be done until the menu has
475
 
       finished...it's pretty lame when the animation goes on, but
476
 
       doesn't update, so you get this weird jerkiness. */
477
 
#if 0    
478
 
     if (__glutIdleFunc)
479
 
       __glutIdleFunc();
480
 
#endif
481
 
    if (__glutTimerList)
482
 
      handleTimeouts();
483
 
    return 0;
484
 
 
485
 
  case WM_EXITMENULOOP:
486
 
    /* nuke the above created timer...we don't need it anymore, since
487
 
       the menu is gone now. */
488
 
    KillTimer(hwnd, 1);
489
 
    return 0;
490
 
 
491
 
  case WM_MENUSELECT:
492
 
    if (lParam != 0)
493
 
      __glutHMenu = (HMENU)lParam;
494
 
    return 0;
495
 
 
496
 
  case WM_COMMAND:
497
 
    if (__glutMappedMenu) {
498
 
      if (GetSubMenu(__glutHMenu, LOWORD(wParam)))
499
 
        __glutItemSelected = NULL;
500
 
      else
501
 
        __glutItemSelected = 
502
 
          __glutGetUniqueMenuItem(__glutMappedMenu, LOWORD(wParam));
503
 
      GetCursorPos(&point);
504
 
      ScreenToClient(hwnd, &point);
505
 
      __glutFinishMenu(hwnd, point.x, point.y);
506
 
    } 
507
 
    return 0;
508
 
 
509
 
  case WM_MOUSEMOVE:
510
 
    if (!__glutMappedMenu) {
511
 
      window = __glutGetWindow(hwnd);
512
 
      if (window) {
513
 
          /* If motion function registered _and_ buttons held *
514
 
             down, call motion function...  */
515
 
        x = LOWORD(lParam);
516
 
        y = HIWORD(lParam);
517
 
 
518
 
        /* Win32 doesn't return the same numbers as X does when the
519
 
           mouse goes beyond the upper or left side of the window.
520
 
           roll the Win32's 0..2^16 pointer co-ord range to 0..+/-2^15. */
521
 
        if(x & 1 << 15) x -= (1 << 16);
522
 
        if(y & 1 << 15) y -= (1 << 16);
523
 
 
524
 
        if (window->motion && wParam &
525
 
            (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) {
526
 
          __glutSetWindow(window);
527
 
          window->motion(x, y);
528
 
        }
529
 
        /* If passive motion function registered _and_
530
 
           buttons not held down, call passive motion
531
 
           function...  */
532
 
        else if (window->passive &&
533
 
                 ((wParam &
534
 
                   (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) ==
535
 
                  0)) {
536
 
          __glutSetWindow(window);
537
 
          window->passive(x, y);
538
 
        }
539
 
      }
540
 
    } else {
541
 
      /* Motion events are thrown away when a pop up menu is
542
 
         active. */
543
 
    }
544
 
    return 0;
545
 
 
546
 
  case WM_GETMINMAXINFO:
547
 
    /* this voodoo is brought to you by Win32 (again).  It allows the
548
 
       window to be bigger than the screen, and smaller than 100x100
549
 
       (although it doesn't seem to help the y minimum). */
550
 
    minmax = (LPMINMAXINFO)lParam;
551
 
#if 0
552
 
    /* These two lines are disabled to fix incorrect handling of
553
 
     * window maximization on Vista.  See bug 23182.
554
 
     */
555
 
    minmax->ptMaxSize.x = __glutScreenWidth;
556
 
    minmax->ptMaxSize.y = __glutScreenHeight;
557
 
#endif
558
 
    minmax->ptMinTrackSize.x = 0;
559
 
    minmax->ptMinTrackSize.y = 0;
560
 
    minmax->ptMaxTrackSize.x = __glutScreenWidth + 
561
 
      GetSystemMetrics(SM_CXSIZE) * 2;
562
 
    minmax->ptMaxTrackSize.y = __glutScreenHeight + 
563
 
      GetSystemMetrics(SM_CXSIZE) * 2 + GetSystemMetrics(SM_CYCAPTION);
564
 
    return 0;
565
 
 
566
 
  case WM_SIZE:
567
 
    window = __glutGetWindow(hwnd);
568
 
    if (window) {
569
 
      width = LOWORD(lParam);
570
 
      height = HIWORD(lParam);
571
 
      if (width != window->width || height != window->height) {
572
 
#if 0  /* Win32 GLUT does not support overlays for now. */
573
 
        if (window->overlay) {
574
 
          XResizeWindow(__glutDisplay, window->overlay->win, width, height);
575
 
        }
576
 
#endif
577
 
        window->width = width;
578
 
        window->height = height;
579
 
        __glutSetWindow(window);
580
 
        /* Do not execute OpenGL out of sequence with respect
581
 
           to the SetWindowPos request! */
582
 
        GdiFlush();
583
 
        window->reshape(width, height);
584
 
        window->forceReshape = FALSE;
585
 
        /* A reshape should be considered like posting a
586
 
           repair request. */
587
 
        __glutPostRedisplay(window, GLUT_REPAIR_WORK);
588
 
      }
589
 
    }
590
 
    return 0;
591
 
 
592
 
  case WM_SETCURSOR:
593
 
    /* If the cursor is not in the client area, then we want to send
594
 
       this message to the default window procedure ('cause its
595
 
       probably in the border or title, and we don't handle that
596
 
       cursor.  otherwise, set our cursor.  Win32 makes us set the
597
 
       cursor every time the mouse moves (DUMB!). */
598
 
    if(LOWORD(lParam) != HTCLIENT) {
599
 
      goto defproc;
600
 
    }
601
 
    window = __glutGetWindow(hwnd);
602
 
    if (window) {
603
 
      __glutSetCursor(window);
604
 
    }
605
 
    /* TODO: check out the info in DevStudio on WM_SETCURSOR in the
606
 
       DefaultAction section. */
607
 
    return 1;
608
 
 
609
 
  case WM_SETFOCUS:
610
 
    window = __glutGetWindow(hwnd);
611
 
    if (window) {
612
 
      window->entryState = WM_SETFOCUS;
613
 
      if (window->entry) {
614
 
        __glutSetWindow(window);
615
 
        window->entry(GLUT_ENTERED);
616
 
        /* XXX Generation of fake passive notify?  See how much
617
 
           work the X11 code does to support fake passive notify
618
 
           callbacks. */
619
 
      }
620
 
      if (window->joystick && __glutCurrentWindow) {
621
 
        if (__glutCurrentWindow->joyPollInterval > 0) {
622
 
          MMRESULT result;
623
 
 
624
 
          /* Because Win32 will only let one window capture the
625
 
             joystick at a time, we must capture it when we get the
626
 
             focus and release it when we lose the focus. */
627
 
          result = joySetCapture(__glutCurrentWindow->win,
628
 
            JOYSTICKID1, 0, TRUE);
629
 
          if (result != JOYERR_NOERROR) {
630
 
            return 0;
631
 
          }
632
 
          (void) joySetThreshold(JOYSTICKID1,
633
 
            __glutCurrentWindow->joyPollInterval);
634
 
        }
635
 
      }
636
 
    }
637
 
    return 0;
638
 
 
639
 
  case WM_KILLFOCUS:
640
 
    window = __glutGetWindow(hwnd);
641
 
    if (window) {
642
 
      window->entryState = WM_KILLFOCUS;
643
 
      if (window->entry) {
644
 
        __glutSetWindow(window);
645
 
        window->entry(GLUT_LEFT);
646
 
      }
647
 
      if (window->joystick && __glutCurrentWindow) {
648
 
        if (__glutCurrentWindow->joyPollInterval > 0) {
649
 
          /* Because Win32 will only let one window capture the
650
 
             joystick at a time, we must capture it when we get the
651
 
             focus and release it when we lose the focus. */
652
 
            (void) joyReleaseCapture(JOYSTICKID1);
653
 
        }
654
 
      }
655
 
    }
656
 
    return 0;
657
 
  case WM_ACTIVATE:
658
 
    window = __glutGetWindow(hwnd);
659
 
    /* Make sure we re-select the correct palette if needed. */
660
 
    if (LOWORD(wParam)) {
661
 
      PostMessage(hwnd, WM_PALETTECHANGED, 0, 0);
662
 
    }
663
 
    if (window) {
664
 
      int visState;
665
 
 
666
 
      /* HIWORD(wParam) is the minimized flag. */
667
 
      visState = !HIWORD(wParam);
668
 
      updateWindowState(window, visState);
669
 
    }
670
 
    return 0;
671
 
 
672
 
  /* Colour Palette Management */
673
 
  case WM_PALETTECHANGED:
674
 
    if (hwnd == (HWND)wParam) {
675
 
      /* Don't respond to the message that we sent! */
676
 
      break;
677
 
    }
678
 
    /* fall through to WM_QUERYNEWPALETTE */
679
 
 
680
 
  case WM_QUERYNEWPALETTE:
681
 
    window = __glutGetWindow(hwnd);
682
 
    if (window && window->colormap) {
683
 
      UnrealizeObject(window->colormap->cmap);
684
 
      SelectPalette(window->hdc, window->colormap->cmap, FALSE);
685
 
      RealizePalette(window->hdc);
686
 
      return TRUE;
687
 
    }
688
 
    return FALSE;
689
 
 
690
 
  case MM_JOY1MOVE:
691
 
  case MM_JOY1ZMOVE:
692
 
    window = __glutGetWindow(hwnd);
693
 
    if (window->joystick) {
694
 
      JOYINFOEX jix;
695
 
      int x, y, z;
696
 
 
697
 
      /* Because WIN32 only supports messages for X, Y, and Z
698
 
         translations, we must poll for the rest */
699
 
      jix.dwSize = sizeof(jix);
700
 
      jix.dwFlags = JOY_RETURNALL;
701
 
      joyGetPosEx(JOYSTICKID1,&jix);
702
 
 
703
 
#define SCALE(v)  ((int) ((v - 32767)/32.768))
704
 
 
705
 
      /* Convert to integer for scaling. */
706
 
      x = jix.dwXpos;
707
 
      y = jix.dwYpos;
708
 
      z = jix.dwZpos;
709
 
      window->joystick(jix.dwButtons, SCALE(x), SCALE(y), SCALE(z));
710
 
 
711
 
      return TRUE;
712
 
    }
713
 
    return FALSE;
714
 
  case MM_JOY1BUTTONDOWN:
715
 
  case MM_JOY1BUTTONUP:
716
 
    window = __glutGetWindow(hwnd);
717
 
    if (window->joystick) {
718
 
      JOYINFOEX jix;
719
 
 
720
 
      /* Because WIN32 only supports messages for X, Y, and Z
721
 
         translations, we must poll for the rest */
722
 
      jix.dwSize = sizeof(jix);
723
 
      jix.dwFlags = JOY_RETURNALL;
724
 
      joyGetPosEx(JOYSTICKID1,&jix);
725
 
 
726
 
      return TRUE;
727
 
    }
728
 
    return FALSE;
729
 
 
730
 
#if 0
731
 
  /* Miscellaneous messages (don't really need to enumerate them,
732
 
     but it's good to know what you're not getting sometimes). */
733
 
  case WM_DISPLAYCHANGE:
734
 
    break;
735
 
  case WM_NCHITTEST:
736
 
    /* This event is generated by every mouse move event. */
737
 
    goto defproc;
738
 
  case WM_NCMOUSEMOVE:
739
 
    goto defproc;
740
 
  case WM_NCACTIVATE:
741
 
    goto defproc;
742
 
  case WM_NCPAINT:
743
 
    goto defproc;
744
 
  case WM_NCCALCSIZE:
745
 
    goto defproc;
746
 
  case WM_NCCREATE:
747
 
    goto defproc;
748
 
  case WM_NCDESTROY:
749
 
    goto defproc;
750
 
  case WM_NCLBUTTONDOWN:
751
 
    goto defproc;
752
 
  case WM_SETTEXT:
753
 
    goto defproc;
754
 
  case WM_GETTEXT:
755
 
    goto defproc;
756
 
  case WM_ACTIVATEAPP:
757
 
    goto defproc;
758
 
  case WM_GETICON:
759
 
    goto defproc;
760
 
  case WM_ERASEBKGND:
761
 
    goto defproc;
762
 
  case WM_WINDOWPOSCHANGING:
763
 
    goto defproc;
764
 
  case WM_WINDOWPOSCHANGED:
765
 
    goto defproc;
766
 
  case WM_MOUSEACTIVATE:
767
 
    goto defproc;
768
 
  case WM_SHOWWINDOW:
769
 
    goto defproc;
770
 
  case WM_MOVING:
771
 
    goto defproc;
772
 
  case WM_MOVE:
773
 
    goto defproc;
774
 
  case WM_KEYUP:
775
 
    goto defproc;
776
 
  case WM_CAPTURECHANGED:
777
 
    goto defproc;
778
 
  case WM_SYSCOMMAND:
779
 
    goto defproc;
780
 
  case WM_ENTERSIZEMOVE:
781
 
    goto defproc;
782
 
  case WM_ENTERIDLE:
783
 
    goto defproc;
784
 
#endif
785
 
 
786
 
  default: 
787
 
    goto defproc;
788
 
  }
789
 
 
790
 
defproc:    
791
 
  return DefWindowProc(hwnd, msg, wParam, lParam); 
792