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

« back to all changes in this revision

Viewing changes to src/glut/beos/glutEvent.cpp

  • 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) 1997, Be Inc.  Copyright (C) 1999, Jake Hamby.
3
 
 *
4
 
 * This program is freely distributable without licensing fees
5
 
 * and is provided without guarantee or warrantee expressed or
6
 
 * implied. This program is -not- in the public domain.
7
 
 *
8
 
 *
9
 
 *  FILE:       glutEvent.cpp
10
 
 *
11
 
 *      DESCRIPTION:    here it is, the BeOS GLUT event loop
12
 
 ***********************************************************/
13
 
 
14
 
/***********************************************************
15
 
 *      Headers
16
 
 ***********************************************************/
17
 
#include <GL/glut.h>
18
 
#include "glutint.h"
19
 
#include "glutState.h"
20
 
#include "glutBlocker.h"
21
 
 
22
 
/***********************************************************
23
 
 *      CLASS:  GLUTtimer
24
 
 *
25
 
 *      DESCRIPTION:    list of timer callbacks
26
 
 ***********************************************************/
27
 
struct GLUTtimer {
28
 
        GLUTtimer *next;        // list of timers
29
 
        bigtime_t timeout;      // time to be called
30
 
        GLUTtimerCB func;       // function to call
31
 
        int value;                      // value
32
 
};
33
 
 
34
 
/***********************************************************
35
 
 *      Private variables
36
 
 ***********************************************************/
37
 
static GLUTtimer *__glutTimerList = 0;                  // list of timer callbacks
38
 
static GLUTtimer *freeTimerList = 0;
39
 
 
40
 
/***********************************************************
41
 
 *      FUNCTION:       glutTimerFunc (7.19)
42
 
 *
43
 
 *      DESCRIPTION:  register a new timer callback
44
 
 ***********************************************************/
45
 
void APIENTRY 
46
 
glutTimerFunc(unsigned int interval, GLUTtimerCB timerFunc, int value)
47
 
{
48
 
  GLUTtimer *timer, *other;
49
 
  GLUTtimer **prevptr;
50
 
 
51
 
  if (!timerFunc)
52
 
    return;
53
 
 
54
 
  if (freeTimerList) {
55
 
    timer = freeTimerList;
56
 
    freeTimerList = timer->next;
57
 
  } else {
58
 
    timer = new GLUTtimer();
59
 
    if (!timer)
60
 
      __glutFatalError("out of memory.");
61
 
  }
62
 
 
63
 
  timer->func = timerFunc;
64
 
  timer->value = value;
65
 
  timer->next = NULL;
66
 
  timer->timeout = system_time() + (interval*1000);     // 1000 ticks in a millisecond
67
 
  prevptr = &__glutTimerList;
68
 
  other = *prevptr;
69
 
  while (other && (other->timeout < timer->timeout)) {
70
 
    prevptr = &other->next;
71
 
    other = *prevptr;
72
 
  }
73
 
  timer->next = other;
74
 
  *prevptr = timer;
75
 
}
76
 
 
77
 
/***********************************************************
78
 
 *      FUNCTION:       handleTimeouts
79
 
 *
80
 
 *      DESCRIPTION:  private function to handle outstanding timeouts
81
 
 ***********************************************************/
82
 
static void
83
 
handleTimeouts(void)
84
 
{
85
 
  bigtime_t now;
86
 
  GLUTtimer *timer;
87
 
 
88
 
  /* Assumption is that __glutTimerList is already determined
89
 
     to be non-NULL. */
90
 
  now = system_time();
91
 
  while (__glutTimerList->timeout <= now) {
92
 
    timer = __glutTimerList;
93
 
    if(gState.currentWindow)
94
 
            gState.currentWindow->LockGL();
95
 
    timer->func(timer->value);
96
 
    if(gState.currentWindow)
97
 
            gState.currentWindow->UnlockGL();
98
 
    __glutTimerList = timer->next;
99
 
    timer->next = freeTimerList;
100
 
    freeTimerList = timer;
101
 
    if (!__glutTimerList)
102
 
      break;
103
 
  }
104
 
}
105
 
 
106
 
 
107
 
/***********************************************************
108
 
 *      FUNCTION:       processEventsAndTimeouts
109
 
 *
110
 
 *      DESCRIPTION:  clear gBlock, then check all windows for events
111
 
 ***********************************************************/
112
 
static void
113
 
processEventsAndTimeouts(void)
114
 
{
115
 
        gBlock.WaitEvent();             // if there is already an event, returns
116
 
                                                        // immediately, otherwise wait forever
117
 
        gBlock.ClearEvents();
118
 
        
119
 
        if(gState.quitAll)
120
 
                exit(0);                // exit handler cleans up windows and quits nicely
121
 
        
122
 
        if (gState.currentWindow)
123
 
                gState.currentWindow->LockGL();
124
 
        for(int i=0; i<gState.windowListSize; i++) {
125
 
                if (gState.windowList[i]) {
126
 
                        GlutWindow *win = gState.windowList[i];
127
 
                        // NOTE: we can use win as a shortcut for gState.windowList[i]
128
 
                        // in callbacks, EXCEPT we need to check the original variable
129
 
                        // after each callback to make sure the window hasn't been destroyed
130
 
                        if (win->anyevents) {
131
 
                                win->anyevents = false;
132
 
                                if (win->reshapeEvent) {
133
 
                                        win->reshapeEvent = false;
134
 
                                        __glutSetWindow(win);
135
 
                                        win->reshape(win->m_width, win->m_height);
136
 
                                }
137
 
                                if (!gState.windowList[i])
138
 
                                        continue;       // window was destroyed by callback!
139
 
 
140
 
                                if (win->displayEvent) {
141
 
                                        win->displayEvent = false;
142
 
                                        __glutSetWindow(win);
143
 
                                        win->display();
144
 
                                }
145
 
                                if (!gState.windowList[i])
146
 
                                        continue;       // window was destroyed by callback!
147
 
 
148
 
                                if (win->mouseEvent) {
149
 
                                        win->mouseEvent = false;
150
 
                                        __glutSetWindow(win);
151
 
                                        if (win->mouse) {
152
 
                                                gState.modifierKeys = win->modifierKeys;
153
 
                                                win->mouse(win->button, win->mouseState, win->mouseX, win->mouseY);
154
 
                                                gState.modifierKeys = ~0;
155
 
                                        }
156
 
                                }
157
 
                                if (!gState.windowList[i])
158
 
                                        continue;       // window was destroyed by callback!
159
 
 
160
 
                                if (win->menuEvent) {
161
 
                                        win->menuEvent = false;
162
 
                                        __glutSetWindow(win);
163
 
                                        GlutMenu *menu = __glutGetMenuByNum(win->menuNumber);
164
 
                                        if (menu) {
165
 
                                                gState.currentMenu = menu;
166
 
                                                menu->select(win->menuValue);
167
 
                                        }
168
 
                                }
169
 
                                if (!gState.windowList[i])
170
 
                                        continue;       // window was destroyed by callback!
171
 
 
172
 
                                if (win->statusEvent) {
173
 
                                        win->statusEvent = false;
174
 
                                        __glutSetWindow(win);
175
 
                                        if (gState.menuStatus) {
176
 
                                                gState.currentMenu = __glutGetMenuByNum(win->menuNumber);
177
 
                                                gState.menuStatus(win->menuStatus, win->statusX, win->statusY);
178
 
                                        }
179
 
                                }
180
 
                                if (!gState.windowList[i])
181
 
                                        continue;       // window was destroyed by callback!
182
 
 
183
 
                                if (win->motionEvent) {
184
 
                                        win->motionEvent = false;
185
 
                                        __glutSetWindow(win);
186
 
                                        if (win->motion)
187
 
                                                win->motion(win->motionX, win->motionY);
188
 
                                }
189
 
                                if (!gState.windowList[i])
190
 
                                        continue;       // window was destroyed by callback!
191
 
 
192
 
                                if (win->passiveEvent) {
193
 
                                        win->passiveEvent = false;
194
 
                                        __glutSetWindow(win);
195
 
                                        if (win->passive)
196
 
                                                win->passive(win->passiveX, win->passiveY);
197
 
                                }
198
 
                                if (!gState.windowList[i])
199
 
                                        continue;       // window was destroyed by callback!
200
 
 
201
 
                                if (win->keybEvent) {
202
 
                                        win->keybEvent = false;
203
 
                                        __glutSetWindow(win);
204
 
                                        if (win->keyboard) {
205
 
                                                gState.modifierKeys = win->modifierKeys;
206
 
                                                win->keyboard(win->key, win->keyX, win->keyY);
207
 
                                                gState.modifierKeys = ~0;
208
 
                                        }
209
 
                                }
210
 
                                if (!gState.windowList[i])
211
 
                                        continue;       // window was destroyed by callback!
212
 
 
213
 
                                if (win->specialEvent) {
214
 
                                        win->specialEvent = false;
215
 
                                        __glutSetWindow(win);
216
 
                                        if (win->special) {
217
 
                                                gState.modifierKeys = win->modifierKeys;
218
 
                                                win->special(win->specialKey, win->specialX, win->specialY);
219
 
                                                gState.modifierKeys = ~0;
220
 
                                        }
221
 
                                }
222
 
                                if (!gState.windowList[i])
223
 
                                        continue;       // window was destroyed by callback!
224
 
 
225
 
                                if (win->entryEvent) {
226
 
                                        win->entryEvent = false;
227
 
                                        __glutSetWindow(win);
228
 
                                        if (win->entry)
229
 
                                                win->entry(win->entryState);
230
 
                                }
231
 
                                if (!gState.windowList[i])
232
 
                                        continue;       // window was destroyed by callback!
233
 
 
234
 
                                if (win->windowStatusEvent) {
235
 
                                        win->windowStatusEvent = false;
236
 
                                        __glutSetWindow(win);
237
 
                                        if (win->windowStatus)
238
 
                                                win->windowStatus(win->visState);
239
 
                                }
240
 
                                if (!gState.windowList[i])
241
 
                                        continue;       // window was destroyed by callback!
242
 
                        }
243
 
                }
244
 
        }
245
 
        if (gState.currentWindow)
246
 
                gState.currentWindow->UnlockGL();
247
 
 
248
 
        // This code isn't necessary since BGLView automatically traps errors
249
 
#if 0
250
 
        if(gState.debug) {
251
 
                for(int i=0; i<gState.windowListSize; i++) {
252
 
                        if (gState.windowList[i]) {
253
 
                                gState.windowList[i]->LockGL();
254
 
                                glutReportErrors();
255
 
                                gState.windowList[i]->UnlockGL();
256
 
                        }
257
 
                }
258
 
        }
259
 
#endif
260
 
        if (__glutTimerList) {
261
 
      handleTimeouts();
262
 
    }
263
 
}
264
 
 
265
 
/***********************************************************
266
 
 *      FUNCTION:       waitForSomething
267
 
 *
268
 
 *      DESCRIPTION:  use gBlock to wait for a new event or timeout
269
 
 ***********************************************************/
270
 
static void
271
 
waitForSomething(void)
272
 
{
273
 
        bigtime_t timeout = __glutTimerList->timeout;
274
 
        bigtime_t now = system_time();
275
 
        
276
 
        if (gBlock.PendingEvent())
277
 
                goto immediatelyHandleEvent;
278
 
        
279
 
        if(timeout>now)
280
 
                gBlock.WaitEvent(timeout-now);
281
 
        if (gBlock.PendingEvent()) {
282
 
        immediatelyHandleEvent:
283
 
                processEventsAndTimeouts();
284
 
        } else {
285
 
                if (__glutTimerList)
286
 
                        handleTimeouts();
287
 
        }
288
 
}
289
 
 
290
 
/***********************************************************
291
 
 *      FUNCTION:       idleWait
292
 
 *
293
 
 *      DESCRIPTION:  check for events, then call idle function
294
 
 ***********************************************************/
295
 
static void
296
 
idleWait(void)
297
 
{
298
 
  if (gBlock.PendingEvent()) {
299
 
    processEventsAndTimeouts();
300
 
  } else {
301
 
    if (__glutTimerList)
302
 
      handleTimeouts();
303
 
  }
304
 
  /* Make sure idle func still exists! */
305
 
  if(gState.currentWindow)
306
 
          gState.currentWindow->LockGL();
307
 
  if (gState.idle) {
308
 
    gState.idle();
309
 
  }
310
 
  if(gState.currentWindow)
311
 
          gState.currentWindow->UnlockGL();
312
 
}
313
 
 
314
 
/***********************************************************
315
 
 *      FUNCTION:       glutMainLoop (3.1)
316
 
 *
317
 
 *      DESCRIPTION:  enter the event processing loop
318
 
 ***********************************************************/
319
 
void glutMainLoop()
320
 
{
321
 
  if (!gState.windowListSize)
322
 
    __glutFatalUsage("main loop entered with no windows created.");
323
 
 
324
 
  if(gState.currentWindow)
325
 
          gState.currentWindow->UnlockGL();
326
 
 
327
 
  for (;;) {
328
 
    if (gState.idle) {
329
 
      idleWait();
330
 
    } else {
331
 
      if (__glutTimerList) {
332
 
        waitForSomething();
333
 
      } else {
334
 
        processEventsAndTimeouts();
335
 
      }
336
 
    }
337
 
  }
338
 
}
339
 
 
340
 
/***********************************************************
341
 
 *      CLASS:          GlutWindow
342
 
 *
343
 
 *      FUNCTION:       KeyDown
344
 
 *
345
 
 *      DESCRIPTION:  handles keyboard and special events
346
 
 ***********************************************************/
347
 
void GlutWindow::KeyDown(const char *s, int32 slen)
348
 
{
349
 
  ulong aChar = s[0];
350
 
  BGLView::KeyDown(s,slen);
351
 
  
352
 
  BPoint p;
353
 
        
354
 
        switch (aChar) {
355
 
                case B_FUNCTION_KEY:
356
 
                switch(Window()->CurrentMessage()->FindInt32("key")) {
357
 
                        case B_F1_KEY:
358
 
                                aChar = GLUT_KEY_F1;
359
 
                                goto specialLabel;
360
 
                        case B_F2_KEY:
361
 
                                aChar = GLUT_KEY_F2;
362
 
                                goto specialLabel;
363
 
                        case B_F3_KEY:
364
 
                                aChar = GLUT_KEY_F3;
365
 
                                goto specialLabel;
366
 
                        case B_F4_KEY:
367
 
                                aChar = GLUT_KEY_F4;
368
 
                                goto specialLabel;
369
 
                        case B_F5_KEY:
370
 
                                aChar = GLUT_KEY_F5;
371
 
                                goto specialLabel;
372
 
                        case B_F6_KEY:
373
 
                                aChar = GLUT_KEY_F6;
374
 
                                goto specialLabel;
375
 
                        case B_F7_KEY:
376
 
                                aChar = GLUT_KEY_F7;
377
 
                                goto specialLabel;
378
 
                        case B_F8_KEY:
379
 
                                aChar = GLUT_KEY_F8;
380
 
                                goto specialLabel;
381
 
                        case B_F9_KEY:
382
 
                                aChar = GLUT_KEY_F9;
383
 
                                goto specialLabel;
384
 
                        case B_F10_KEY:
385
 
                                aChar = GLUT_KEY_F10;
386
 
                                goto specialLabel;
387
 
                        case B_F11_KEY:
388
 
                                aChar = GLUT_KEY_F11;
389
 
                                goto specialLabel;
390
 
                        case B_F12_KEY:
391
 
                                aChar = GLUT_KEY_F12;
392
 
                                goto specialLabel;
393
 
                        default:
394
 
                                return;
395
 
                }
396
 
                case B_LEFT_ARROW:
397
 
                        aChar = GLUT_KEY_LEFT;
398
 
                        goto specialLabel;
399
 
                case B_UP_ARROW:
400
 
                        aChar = GLUT_KEY_UP;
401
 
                        goto specialLabel;
402
 
                case B_RIGHT_ARROW:
403
 
                        aChar = GLUT_KEY_RIGHT;
404
 
                        goto specialLabel;
405
 
                case B_DOWN_ARROW:
406
 
                        aChar = GLUT_KEY_DOWN;
407
 
                        goto specialLabel;
408
 
                case B_PAGE_UP:
409
 
                        aChar = GLUT_KEY_PAGE_UP;
410
 
                        goto specialLabel;
411
 
                case B_PAGE_DOWN:
412
 
                        aChar = GLUT_KEY_PAGE_DOWN;
413
 
                        goto specialLabel;
414
 
                case B_HOME:
415
 
                        aChar = GLUT_KEY_HOME;
416
 
                        goto specialLabel;
417
 
                case B_END:
418
 
                        aChar = GLUT_KEY_END;
419
 
                        goto specialLabel;
420
 
                case B_INSERT:
421
 
            aChar = GLUT_KEY_INSERT;
422
 
specialLabel:   
423
 
                        if (special) {
424
 
                                anyevents = specialEvent = true;
425
 
                                GetMouse(&p,&m_buttons);
426
 
                                specialKey = aChar;
427
 
                                specialX = (int)p.x;
428
 
                                specialY = (int)p.y;
429
 
                                goto setModifiers;      // set the modifier variable
430
 
                        }
431
 
                        return;
432
 
 
433
 
                default:
434
 
                        break;
435
 
        }
436
 
                
437
 
        if (keyboard) {
438
 
                anyevents = keybEvent = true;
439
 
                GetMouse(&p,&m_buttons);
440
 
                key = aChar;
441
 
                keyX = (int)p.x;
442
 
                keyY = (int)p.y;
443
 
setModifiers:
444
 
                modifierKeys = 0;
445
 
                uint32 beMod = Window()->CurrentMessage()->FindInt32("modifiers");
446
 
                if(beMod & B_SHIFT_KEY)
447
 
                        modifierKeys |= GLUT_ACTIVE_SHIFT;
448
 
                if(beMod & B_CONTROL_KEY)
449
 
                        modifierKeys |= GLUT_ACTIVE_CTRL;
450
 
                if(beMod & B_OPTION_KEY) {
451
 
                        // since the window traps B_COMMAND_KEY, we'll have to settle
452
 
                        // for the option key.. but we need to get the raw character,
453
 
                        // not the Unicode-enhanced version
454
 
                        key = Window()->CurrentMessage()->FindInt32("raw_char");
455
 
                        modifierKeys |= GLUT_ACTIVE_ALT;
456
 
                }
457
 
                gBlock.NewEvent();
458
 
        }
459
 
}
460
 
 
461
 
/***********************************************************
462
 
 *      CLASS:          GlutWindow
463
 
 *
464
 
 *      FUNCTION:       MouseDown
465
 
 *
466
 
 *      DESCRIPTION:  handles mouse and menustatus events
467
 
 ***********************************************************/
468
 
void GlutWindow::MouseDown(BPoint point)
469
 
{
470
 
        BGLView::MouseDown(point);
471
 
        MouseCheck();
472
 
}
473
 
 
474
 
/***********************************************************
475
 
 *      CLASS:          GlutWindow
476
 
 *
477
 
 *      FUNCTION:       MouseCheck
478
 
 *
479
 
 *      DESCRIPTION:  checks for button state changes
480
 
 ***********************************************************/
481
 
void GlutWindow::MouseCheck()
482
 
{
483
 
        if (mouseEvent)
484
 
                return;         // we already have an outstanding mouse event
485
 
 
486
 
        BPoint point;
487
 
        uint32 newButtons;
488
 
        GetMouse(&point, &newButtons);
489
 
        if (m_buttons != newButtons) {
490
 
                if (newButtons&B_PRIMARY_MOUSE_BUTTON && !(m_buttons&B_PRIMARY_MOUSE_BUTTON)) {
491
 
                        button = GLUT_LEFT_BUTTON;
492
 
                        mouseState = GLUT_DOWN;
493
 
                } else if (m_buttons&B_PRIMARY_MOUSE_BUTTON && !(newButtons&B_PRIMARY_MOUSE_BUTTON)) {
494
 
                        button = GLUT_LEFT_BUTTON;
495
 
                        mouseState = GLUT_UP;
496
 
                } else if (newButtons&B_SECONDARY_MOUSE_BUTTON && !(m_buttons&B_SECONDARY_MOUSE_BUTTON)) {
497
 
                        button = GLUT_RIGHT_BUTTON;
498
 
                        mouseState = GLUT_DOWN;
499
 
                } else if (m_buttons&B_SECONDARY_MOUSE_BUTTON && !(newButtons&B_SECONDARY_MOUSE_BUTTON)) {
500
 
                        button = GLUT_RIGHT_BUTTON;
501
 
                        mouseState = GLUT_UP;
502
 
                } else if (newButtons&B_TERTIARY_MOUSE_BUTTON && !(m_buttons&B_TERTIARY_MOUSE_BUTTON)) {
503
 
                        button = GLUT_MIDDLE_BUTTON;
504
 
                        mouseState = GLUT_DOWN;
505
 
                } else if (m_buttons&B_TERTIARY_MOUSE_BUTTON && !(newButtons&B_TERTIARY_MOUSE_BUTTON)) {
506
 
                        button = GLUT_MIDDLE_BUTTON;
507
 
                        mouseState = GLUT_UP;
508
 
                }
509
 
        } else {
510
 
                return;         // no change, return
511
 
        }
512
 
        m_buttons = newButtons;
513
 
 
514
 
        if (mouseState == GLUT_DOWN) {
515
 
                BWindow *w = Window();
516
 
                GlutMenu *m = __glutGetMenuByNum(menu[button]);
517
 
                if (m) {
518
 
                        if (gState.menuStatus) {
519
 
                                anyevents = statusEvent = true;
520
 
                                menuNumber = menu[button];
521
 
                                menuStatus = GLUT_MENU_IN_USE;
522
 
                                statusX = (int)point.x;
523
 
                                statusY = (int)point.y;
524
 
                                gBlock.NewEvent();
525
 
                        }               
526
 
                        BRect bounds = w->Frame();
527
 
                        point.x += bounds.left;
528
 
                        point.y += bounds.top;
529
 
                        GlutPopUp *bmenu = static_cast<GlutPopUp*>(m->CreateBMenu());   // start menu
530
 
                        bmenu->point = point;
531
 
                        bmenu->win = this;
532
 
                        thread_id menu_thread = spawn_thread(MenuThread, "menu thread", B_NORMAL_PRIORITY, bmenu);
533
 
                        resume_thread(menu_thread);
534
 
                        return;
535
 
                }
536
 
        }
537
 
 
538
 
        if (mouse) {
539
 
                anyevents = mouseEvent = true;
540
 
                mouseX = (int)point.x;
541
 
                mouseY = (int)point.y;
542
 
                modifierKeys = 0;
543
 
                uint32 beMod = modifiers();
544
 
                if(beMod & B_SHIFT_KEY)
545
 
                        modifierKeys |= GLUT_ACTIVE_SHIFT;
546
 
                if(beMod & B_CONTROL_KEY)
547
 
                        modifierKeys |= GLUT_ACTIVE_CTRL;
548
 
                if(beMod & B_OPTION_KEY) {
549
 
                        modifierKeys |= GLUT_ACTIVE_ALT;
550
 
                }
551
 
                gBlock.NewEvent();
552
 
        }
553
 
}
554
 
 
555
 
/***********************************************************
556
 
 *      CLASS:          GlutWindow
557
 
 *
558
 
 *      FUNCTION:       MouseMoved
559
 
 *
560
 
 *      DESCRIPTION:  handles entry, motion, and passive events
561
 
 ***********************************************************/
562
 
void GlutWindow::MouseMoved(BPoint point,
563
 
                                                ulong transit, const BMessage *msg)
564
 
{
565
 
        BGLView::MouseMoved(point,transit,msg);
566
 
        
567
 
        if(transit != B_INSIDE_VIEW) {
568
 
                if (entry) {
569
 
                        anyevents = entryEvent = true;
570
 
                        gBlock.NewEvent();
571
 
                }
572
 
                if (transit == B_ENTERED_VIEW) {
573
 
                        entryState = GLUT_ENTERED;
574
 
                        MakeFocus();    // make me the current focus
575
 
                        __glutSetCursor(cursor);
576
 
                } else
577
 
                        entryState = GLUT_LEFT;
578
 
        }
579
 
        
580
 
        MouseCheck();
581
 
        if(m_buttons) {
582
 
                if(motion) {
583
 
                        anyevents = motionEvent = true;
584
 
                        motionX = (int)point.x;
585
 
                        motionY = (int)point.y;
586
 
                        gBlock.NewEvent();
587
 
                }
588
 
        } else {
589
 
                if(passive) {
590
 
                        anyevents = passiveEvent = true;
591
 
                        passiveX = (int)point.x;
592
 
                        passiveY = (int)point.y;
593
 
                        gBlock.NewEvent();
594
 
                }
595
 
        }
596
 
}
597
 
 
598
 
/***********************************************************
599
 
 *      CLASS:          GlutWindow
600
 
 *
601
 
 *      FUNCTION:       FrameResized
602
 
 *
603
 
 *      DESCRIPTION:  handles reshape event
604
 
 ***********************************************************/
605
 
void GlutWindow::FrameResized(float width, float height)
606
 
{
607
 
        BGLView::FrameResized(width, height);
608
 
        if (visible) {
609
 
                anyevents = reshapeEvent = true;
610
 
                m_width = (int)(width)+1;
611
 
                m_height = (int)(height)+1;
612
 
                gBlock.NewEvent();
613
 
        }
614
 
}
615
 
 
616
 
/***********************************************************
617
 
 *      CLASS:          GlutWindow
618
 
 *
619
 
 *      FUNCTION:       Draw
620
 
 *
621
 
 *      DESCRIPTION:  handles reshape and display events
622
 
 ***********************************************************/
623
 
void GlutWindow::Draw(BRect updateRect)
624
 
{
625
 
        BGLView::Draw(updateRect);
626
 
        BRect frame = Frame();
627
 
        if (m_width != (frame.Width()+1) || m_height != (frame.Height()+1)) {
628
 
                FrameResized(frame.Width(), frame.Height());
629
 
        }
630
 
        Window()->Lock();
631
 
        if (visible) {
632
 
                anyevents = displayEvent = true;
633
 
                gBlock.NewEvent();
634
 
        }
635
 
        Window()->Unlock();
636
 
}
637
 
 
638
 
/***********************************************************
639
 
 *      CLASS:          GlutWindow
640
 
 *
641
 
 *      FUNCTION:       Pulse
642
 
 *
643
 
 *      DESCRIPTION:  handles mouse up event (MouseUp is broken)
644
 
 ***********************************************************/
645
 
void GlutWindow::Pulse()
646
 
{
647
 
        BGLView::Pulse();
648
 
        if (m_buttons) {        // if there are buttons pressed
649
 
                MouseCheck();
650
 
        }
651
 
}
652
 
 
653
 
/***********************************************************
654
 
 *      CLASS:          GlutWindow
655
 
 *
656
 
 *      FUNCTION:       ErrorCallback
657
 
 *
658
 
 *      DESCRIPTION:  handles GL error messages
659
 
 ***********************************************************/
660
 
void GlutWindow::ErrorCallback(GLenum errorCode) {
661
 
        __glutWarning("GL error: %s", gluErrorString(errorCode));
662
 
}
663
 
 
664
 
/***********************************************************
665
 
 *      CLASS:          GlutWindow
666
 
 *
667
 
 *      FUNCTION:       MenuThread
668
 
 *
669
 
 *      DESCRIPTION:  a new thread to launch popup menu, wait
670
 
 *                      wait for response, then clean up afterwards and
671
 
 *                      send appropriate messages
672
 
 ***********************************************************/
673
 
long GlutWindow::MenuThread(void *m) {
674
 
        GlutPopUp *bmenu = static_cast<GlutPopUp*>(m);
675
 
        GlutWindow *win = bmenu->win;   // my window
676
 
        GlutBMenuItem *result = (GlutBMenuItem*)bmenu->Go(bmenu->point);
677
 
        win->Window()->Lock();
678
 
        win->anyevents = win->statusEvent = true;
679
 
        win->menuStatus = GLUT_MENU_NOT_IN_USE;
680
 
        win->menuNumber = bmenu->menu;
681
 
        BPoint cursor;
682
 
        uint32 buttons;
683
 
        win->GetMouse(&cursor, &buttons);
684
 
        win->statusX = (int)cursor.x;
685
 
        win->statusY = (int)cursor.y;
686
 
        if(result && result->menu) {
687
 
                win->menuEvent = true;
688
 
                win->menuNumber = result->menu;  // in case it was a submenu
689
 
                win->menuValue = result->value;
690
 
        }
691
 
        win->Window()->Unlock();
692
 
        gBlock.NewEvent();
693
 
        delete bmenu;
694
 
        return 0;
695
 
}