示例#1
0
/* generate_mouse_event: [bgman thread]
 *  Helper to generate a mouse event.
 */
static void generate_mouse_event(unsigned int type,
                                 int x, int y, int z, int w, float pressure,
                                 int dx, int dy, int dz, int dw,
                                 unsigned int button,
                                 ALLEGRO_DISPLAY *display)
{
   ALLEGRO_EVENT event;

   if (!_al_event_source_needs_to_generate_event(&the_mouse.parent.es))
      return;

   event.mouse.type = type;
   event.mouse.timestamp = al_get_time();
   event.mouse.display = display;
   event.mouse.x = x;
   event.mouse.y = y;
   event.mouse.z = z;
   event.mouse.w = w;
   event.mouse.dx = dx;
   event.mouse.dy = dy;
   event.mouse.dz = dz;
   event.mouse.dw = dw;
   event.mouse.button = button;
   event.mouse.pressure = pressure;
   _al_event_source_emit_event(&the_mouse.parent.es, &event);
}
示例#2
0
/* handle_key_release: [fdwatch thread]
 *  Helper: stuff to do when a key is released.
 */
static void handle_key_release(int mycode)
{
   ALLEGRO_EVENT event;

   /* This can happen, e.g. when we are switching back into a VT with
    * ALT+Fn, we only get the release event of the function key.
    */
   if (!_AL_KEYBOARD_STATE_KEY_DOWN(the_keyboard.state, mycode))
      return;

   /* Maintain the key_down array. */
   _AL_KEYBOARD_STATE_CLEAR_KEY_DOWN(the_keyboard.state, mycode);

   /* Generate key release events if necessary. */
   if (!_al_event_source_needs_to_generate_event(&the_keyboard.parent.es))
      return;

   event.keyboard.type = ALLEGRO_EVENT_KEY_UP;
   event.keyboard.timestamp = al_get_time();
   event.keyboard.display = NULL;
   event.keyboard.keycode = mycode;
   event.keyboard.unichar = 0;
   event.keyboard.modifiers = 0;

   _al_event_source_emit_event(&the_keyboard.parent.es, &event);
}
示例#3
0
static void android_keyboard_handle_event(ALLEGRO_DISPLAY *display,
   int scancode, int unichar, ALLEGRO_EVENT_TYPE event_type)
{
   ALLEGRO_EVENT event;

   ASSERT(display != NULL);
   ASSERT(scancode > 0);

   if (event_type == ALLEGRO_EVENT_KEY_UP) {
      _AL_KEYBOARD_STATE_CLEAR_KEY_DOWN(the_state, scancode);
   }
   else {
      _AL_KEYBOARD_STATE_SET_KEY_DOWN(the_state, scancode);
   }

   _al_event_source_lock(&the_keyboard.es);
   
   if (_al_event_source_needs_to_generate_event(&the_keyboard.es)) {
      
      event.keyboard.type = event_type;
      event.keyboard.timestamp = al_get_time();
      event.keyboard.display = display;
      event.keyboard.keycode = scancode;
      event.keyboard.unichar = unichar;
      event.keyboard.modifiers = 0;
      event.keyboard.repeat = event_type == ALLEGRO_EVENT_KEY_CHAR;
      
      _al_event_source_emit_event(&the_keyboard.es, &event);
   }
   
   _al_event_source_unlock(&the_keyboard.es);
}
示例#4
0
/* handle_key_press: [fdwatch thread]
 *  Helper: stuff to do when a key is pressed.
 */
static void handle_key_press(int mycode, unsigned int ascii)
{
   ALLEGRO_EVENT_TYPE event_type;
   ALLEGRO_EVENT event;

   event_type = (_AL_KEYBOARD_STATE_KEY_DOWN(the_keyboard.state, mycode)
                 ? ALLEGRO_EVENT_KEY_CHAR
                 : ALLEGRO_EVENT_KEY_DOWN);

   /* Maintain the key_down array. */
   _AL_KEYBOARD_STATE_SET_KEY_DOWN(the_keyboard.state, mycode);

   /* Generate key press/repeat events if necessary. */
   if (!_al_event_source_needs_to_generate_event(&the_keyboard.parent.es))
      return;

   event.keyboard.type = event_type;
   event.keyboard.timestamp = al_get_time();
   event.keyboard.display = NULL;
   event.keyboard.keycode = mycode;
   event.keyboard.unichar = ascii;
   event.keyboard.modifiers = the_keyboard.modifiers;

   _al_event_source_emit_event(&the_keyboard.parent.es, &event);

   /* The first press should generate a KEY_CHAR also */
   if (event_type == ALLEGRO_EVENT_KEY_DOWN) {
      event.keyboard.type = ALLEGRO_EVENT_KEY_CHAR;
      event.keyboard.timestamp = al_get_time();
      _al_event_source_emit_event(&the_keyboard.parent.es, &event);
   }
}
示例#5
0
/* Handle X11 switch event. [X11 thread]
 */
void _al_xwin_display_switch_handler_inner(ALLEGRO_DISPLAY *display, bool focus_in)
{
   ALLEGRO_EVENT_SOURCE *es = &display->es;
   _al_event_source_lock(es);
   if (_al_event_source_needs_to_generate_event(es)) {
      ALLEGRO_EVENT event;
      if (focus_in)
         event.display.type = ALLEGRO_EVENT_DISPLAY_SWITCH_IN;
      else
         event.display.type = ALLEGRO_EVENT_DISPLAY_SWITCH_OUT;
      event.display.timestamp = al_get_time();
      _al_event_source_emit_event(es, &event);
   }
   _al_event_source_unlock(es);
}
示例#6
0
/* ljoy_generate_button_event: [fdwatch thread]
 *
 *  Helper to generate an event after a button is pressed or released.
 *  The joystick must be locked BEFORE entering this function.
 */
static void ljoy_generate_button_event(ALLEGRO_JOYSTICK_LINUX *joy, int button, ALLEGRO_EVENT_TYPE event_type)
{
   ALLEGRO_EVENT event;

   if (!_al_event_source_needs_to_generate_event(&joy->parent.es))
      return;

   event.joystick.type = event_type;
   event.joystick.timestamp = al_current_time();
   event.joystick.stick = 0;
   event.joystick.axis = 0;
   event.joystick.pos = 0.0;
   event.joystick.button = button;

   _al_event_source_emit_event(&joy->parent.es, &event);
}
示例#7
0
/* ljoy_generate_axis_event: [fdwatch thread]
 *
 *  Helper to generate an event after an axis is moved.
 *  The joystick must be locked BEFORE entering this function.
 */
static void ljoy_generate_axis_event(ALLEGRO_JOYSTICK_LINUX *joy, int stick, int axis, float pos)
{
   ALLEGRO_EVENT event;

   if (!_al_event_source_needs_to_generate_event(&joy->parent.es))
      return;

   event.joystick.type = ALLEGRO_EVENT_JOYSTICK_AXIS;
   event.joystick.timestamp = al_current_time();
   event.joystick.stick = stick;
   event.joystick.axis = axis;
   event.joystick.pos = pos;
   event.joystick.button = 0;

   _al_event_source_emit_event(&joy->parent.es, &event);
}
示例#8
0
void _al_xwin_display_expose(ALLEGRO_DISPLAY *display,
   XExposeEvent *xevent)
{
   ALLEGRO_EVENT_SOURCE *es = &display->es;
   _al_event_source_lock(es);
   if (_al_event_source_needs_to_generate_event(es)) {
      ALLEGRO_EVENT event;
      event.display.type = ALLEGRO_EVENT_DISPLAY_EXPOSE;
      event.display.timestamp = al_get_time();
      event.display.x = xevent->x;
      event.display.y = xevent->y;
      event.display.width = xevent->width;
      event.display.height = xevent->height;
      _al_event_source_emit_event(es, &event);
   }
   _al_event_source_unlock(es);
}
示例#9
0
/* ljoy_generate_button_event: [fdwatch thread]
 *
 *  Helper to generate an event after a button is pressed or released.
 *  The joystick must be locked BEFORE entering this function.
 */
static void ljoy_generate_button_event(ALLEGRO_JOYSTICK_LINUX *joy, int button, ALLEGRO_EVENT_TYPE event_type)
{
    ALLEGRO_EVENT event;
    ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source();

    if (!_al_event_source_needs_to_generate_event(es))
        return;

    event.joystick.type = event_type;
    event.joystick.timestamp = al_get_time();
    event.joystick.id = (ALLEGRO_JOYSTICK *)joy;
    event.joystick.stick = 0;
    event.joystick.axis = 0;
    event.joystick.pos = 0.0;
    event.joystick.button = button;

    _al_event_source_emit_event(es, &event);
}
/* generate_axis_event: [joystick thread]
 *  Helper to generate an event after an axis is moved.
 *  The joystick must be locked BEFORE entering this function.
 */
static void generate_axis_event(ALLEGRO_JOYSTICK_DIRECTX *joy, int stick, int axis, float pos)
{
   ALLEGRO_EVENT event;
   ALLEGRO_EVENT_SOURCE *es = al_get_joystick_event_source();

   if (!_al_event_source_needs_to_generate_event(es))
      return;

   event.joystick.type = ALLEGRO_EVENT_JOYSTICK_AXIS;
   event.joystick.timestamp = al_get_time();
   event.joystick.id = (ALLEGRO_JOYSTICK *)joy;
   event.joystick.stick = stick;
   event.joystick.axis = axis;
   event.joystick.pos = pos;
   event.joystick.button = 0;

   _al_event_source_emit_event(es, &event);
}
/* _al_win_kbd_handle_key_release:
 *  Does stuff when a key is released.
 */
void _al_win_kbd_handle_key_release(int scode, int vcode, bool extended, ALLEGRO_DISPLAY_WIN *win_disp)
{
   ALLEGRO_EVENT event;
   int my_code;

   if (!installed)
     return;

   my_code = 0;
   if (extended)
      my_code = extkey_to_keycode(vcode);

   if (my_code == 0) {
      if (vcode == VK_SHIFT)
         vcode = MapVirtualKey(scode, MAPVK_VSC_TO_VK_EX);
      my_code = hw_to_mycode[vcode];
   }
   update_modifiers(my_code, false);

   _AL_KEYBOARD_STATE_CLEAR_KEY_DOWN(the_state, my_code);
      
   /* Windows only sends a WM_KEYUP message for the Shift keys when
      both have been released. If one of the Shift keys is still reported
      as down, we need to release it as well. */
   if (my_code == ALLEGRO_KEY_LSHIFT && _AL_KEYBOARD_STATE_KEY_DOWN(the_state, ALLEGRO_KEY_RSHIFT))
      _al_win_kbd_handle_key_release(scode, VK_RSHIFT, extended, win_disp);
   else if (my_code == ALLEGRO_KEY_RSHIFT && _AL_KEYBOARD_STATE_KEY_DOWN(the_state, ALLEGRO_KEY_LSHIFT))
      _al_win_kbd_handle_key_release(scode, VK_LSHIFT, extended, win_disp);
   
   if (!_al_event_source_needs_to_generate_event(&the_keyboard.es))
      return;

   event.keyboard.type = ALLEGRO_EVENT_KEY_UP;
   event.keyboard.timestamp = al_get_time();
   event.keyboard.display = (void*)win_disp;
   event.keyboard.keycode = my_code;
   event.keyboard.unichar = 0;
   event.keyboard.modifiers = 0;

   _al_event_source_lock(&the_keyboard.es);
   _al_event_source_emit_event(&the_keyboard.es, &event);
   _al_event_source_unlock(&the_keyboard.es);
}
示例#12
0
/* Generate a resize event if the size has changed. We cannot asynchronously
 * change the display size here yet, since the user will only know about a
 * changed size after receiving the resize event. Here we merely add the
 * event to the queue.
 */
static void win_generate_resize_event(ALLEGRO_DISPLAY_WIN *win_display)
{
   ALLEGRO_DISPLAY *display = (ALLEGRO_DISPLAY *)win_display;
   ALLEGRO_EVENT_SOURCE *es = &display->es;
   WINDOWINFO wi;
   int x, y, w, h;

   wi.cbSize = sizeof(WINDOWINFO);
   GetWindowInfo(win_display->window, &wi);
   x = wi.rcClient.left;
   y = wi.rcClient.top;
   w = wi.rcClient.right - wi.rcClient.left;
   h = wi.rcClient.bottom - wi.rcClient.top;

   /* Don't generate events when restoring after minimise. */
   if (w == 0 && h == 0 && x == -32000 && y == -32000)
      return;

   if (display->w != w || display->h != h) {
      _al_event_source_lock(es);
      if (_al_event_source_needs_to_generate_event(es)) {
         ALLEGRO_EVENT event;
         event.display.type = ALLEGRO_EVENT_DISPLAY_RESIZE;
         event.display.timestamp = al_get_time();
         event.display.x = x;
         event.display.y = y;
         event.display.width = w;
         event.display.height = h;
         event.display.source = display;
         _al_event_source_emit_event(es, &event);

         /* Generate an expose event. */
         /* This seems a bit redundant after a resize. */
         if (win_display->display.flags & ALLEGRO_GENERATE_EXPOSE_EVENTS) {
            event.display.type = ALLEGRO_EVENT_DISPLAY_EXPOSE;
            _al_event_source_emit_event(es, &event);
         }
      }
      _al_event_source_unlock(es);
   }
}
示例#13
0
/* Handle X11 switch event. [X11 thread]
 */
void _al_xwin_display_switch_handler(ALLEGRO_DISPLAY *display,
   XFocusChangeEvent *xevent)
{
   /* Anything but NotifyNormal seem to indicate the switch is not "real".
    * TODO: Find out details?
    */
   if (xevent->mode != NotifyNormal)
      return;

   ALLEGRO_EVENT_SOURCE *es = &display->es;
   _al_event_source_lock(es);
   if (_al_event_source_needs_to_generate_event(es)) {
      ALLEGRO_EVENT event;
      if (xevent->type == FocusOut)
         event.display.type = ALLEGRO_EVENT_DISPLAY_SWITCH_OUT;
      else
         event.display.type = ALLEGRO_EVENT_DISPLAY_SWITCH_IN;
      event.display.timestamp = al_get_time();
      _al_event_source_emit_event(es, &event);
   }
   _al_event_source_unlock(es);
}
示例#14
0
/* handle_key_release: [bgman thread]
 *  Hook for the X event dispatcher to handle key releases.
 *  The caller must lock the X-display.
 */
static void handle_key_release(int mycode, ALLEGRO_DISPLAY *display)
{
    if (last_press_code == mycode)
        last_press_code = -1;

    _al_event_source_lock(&the_keyboard.parent.es);
    {
        /* Update the key_down array.  */
        _AL_KEYBOARD_STATE_CLEAR_KEY_DOWN(the_keyboard.state, mycode);

        /* Generate the release event if necessary. */
        if (_al_event_source_needs_to_generate_event(&the_keyboard.parent.es)) {
            ALLEGRO_EVENT event;
            event.keyboard.type = ALLEGRO_EVENT_KEY_UP;
            event.keyboard.timestamp = al_get_time();
            event.keyboard.display = display;
            event.keyboard.keycode = mycode;
            event.keyboard.unichar = 0;
            event.keyboard.modifiers = 0;
            _al_event_source_emit_event(&the_keyboard.parent.es, &event);
        }
    }
    _al_event_source_unlock(&the_keyboard.parent.es);
}
示例#15
0
static LRESULT CALLBACK window_callback(HWND hWnd, UINT message, 
    WPARAM wParam, LPARAM lParam)
{
   ALLEGRO_DISPLAY *d = NULL;
   ALLEGRO_DISPLAY_WIN *win_display = NULL;
   WINDOWINFO wi;
   int w;
   int h;
   int x;
   int y;
   unsigned int i;
   ALLEGRO_EVENT_SOURCE *es = NULL;
   ALLEGRO_SYSTEM *system = al_get_system_driver();

   wi.cbSize = sizeof(WINDOWINFO);

   if (message == _al_win_msg_call_proc) {
      ((void (*)(void*))wParam) ((void*)lParam);
      return 0;
   }

   if (!system) {
      return DefWindowProc(hWnd,message,wParam,lParam); 
   }

   if (message == _al_win_msg_suicide && wParam) {
      win_display = (ALLEGRO_DISPLAY_WIN*)wParam;
      win_display->end_thread = true;
      DestroyWindow(hWnd);
      return 0;
   }

   for (i = 0; i < system->displays._size; i++) {
      ALLEGRO_DISPLAY **dptr = _al_vector_ref(&system->displays, i);
      d = *dptr;
      win_display = (void*)d;
      if (win_display->window == hWnd) {
         es = &d->es;
         break;
      }
   }

   if (i == system->displays._size)
      return DefWindowProc(hWnd,message,wParam,lParam); 

   if (message == _al_win_msg_suicide) {
      win_display->end_thread = true;
      DestroyWindow(hWnd);
      return 0;
   }

   switch (message) {
      case WM_INPUT: 
      {
          UINT dwSize;
          LPBYTE lpb;
          RAWINPUT* raw;

          /* We can't uninstall WM_INPUT mesages. */
          if (!al_is_mouse_installed())
             break;

          GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, 
                          sizeof(RAWINPUTHEADER));
          lpb = malloc(sizeof(BYTE)*dwSize);
          if (lpb == NULL) 
              break;

          GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER));
          raw = (RAWINPUT*)lpb;

          if (raw->header.dwType != RIM_TYPEMOUSE) {
             free(lpb); 
             break;
          }

       {
          RAWMOUSE *rm = &raw->data.mouse;
          int x = raw->data.mouse.lLastX;
          int y = raw->data.mouse.lLastY;
          bool abs = rm->usFlags & (MOUSE_MOVE_ABSOLUTE
                                 || MOUSE_VIRTUAL_DESKTOP);
          if (abs || x || y)
             _al_win_mouse_handle_move(x, y, abs, win_display);

          if (rm->usButtonFlags & RI_MOUSE_BUTTON_1_DOWN)
             _al_win_mouse_handle_button(1, true, x, y, abs, win_display);
          if (rm->usButtonFlags & RI_MOUSE_BUTTON_1_UP)
             _al_win_mouse_handle_button(1, false, x, y, abs, win_display);
          if (rm->usButtonFlags & RI_MOUSE_BUTTON_2_DOWN)
             _al_win_mouse_handle_button(2, true, x, y, abs, win_display);
          if (rm->usButtonFlags & RI_MOUSE_BUTTON_2_UP)
             _al_win_mouse_handle_button(2, false, x, y, abs, win_display);
          if (rm->usButtonFlags & RI_MOUSE_BUTTON_3_DOWN)
             _al_win_mouse_handle_button(3, true, x, y, abs, win_display);
          if (rm->usButtonFlags & RI_MOUSE_BUTTON_3_UP)
             _al_win_mouse_handle_button(3, false, x, y, abs, win_display);
          if (rm->usButtonFlags & RI_MOUSE_BUTTON_4_DOWN)
             _al_win_mouse_handle_button(4, true, x, y, abs, win_display);
          if (rm->usButtonFlags & RI_MOUSE_BUTTON_4_UP)
             _al_win_mouse_handle_button(4, false, x, y, abs, win_display);
          if (rm->usButtonFlags & RI_MOUSE_BUTTON_5_DOWN)
             _al_win_mouse_handle_button(5, true, x, y, abs, win_display);
          if (rm->usButtonFlags & RI_MOUSE_BUTTON_5_UP)
             _al_win_mouse_handle_button(5, false, x, y, abs, win_display);

          if (rm->usButtonFlags & RI_MOUSE_WHEEL) {
             SHORT z = (SHORT)rm->usButtonData;
             _al_win_mouse_handle_wheel(z / WHEEL_DELTA, false, win_display);
          }
       }

          free(lpb); 
          break;
      }
      case WM_LBUTTONDOWN:
      case WM_LBUTTONUP: {
         int mx = GET_X_LPARAM(lParam);
         int my = GET_Y_LPARAM(lParam);
         bool down = (message == WM_LBUTTONDOWN);
         _al_win_mouse_handle_button(1, down, mx, my, true, win_display);
         handle_mouse_capture(down, hWnd);
         break;
      }
      case WM_MBUTTONDOWN:
      case WM_MBUTTONUP: {
         int mx = GET_X_LPARAM(lParam);
         int my = GET_Y_LPARAM(lParam);
         bool down = (message == WM_MBUTTONDOWN);
         _al_win_mouse_handle_button(3, down, mx, my, true, win_display);
         handle_mouse_capture(down, hWnd);
         break;
      }
      case WM_RBUTTONDOWN:
      case WM_RBUTTONUP: {
         int mx = GET_X_LPARAM(lParam);
         int my = GET_Y_LPARAM(lParam);
         bool down = (message == WM_RBUTTONDOWN);
         _al_win_mouse_handle_button(2, down, mx, my, true, win_display);
         handle_mouse_capture(down, hWnd);
         break;
      }
      case WM_XBUTTONDOWN:
      case WM_XBUTTONUP: {
         int mx = GET_X_LPARAM(lParam);
         int my = GET_Y_LPARAM(lParam);
         int button = HIWORD(wParam);
         bool down = (message == WM_XBUTTONDOWN);
         if (button == XBUTTON1)
            _al_win_mouse_handle_button(4, down, mx, my, true, win_display);
         else if (button == XBUTTON2)
            _al_win_mouse_handle_button(5, down, mx, my, true, win_display);
         handle_mouse_capture(down, hWnd);
         return TRUE;
      }
      case WM_MOUSEWHEEL: {
         int d = GET_WHEEL_DELTA_WPARAM(wParam);
         _al_win_mouse_handle_wheel(d / WHEEL_DELTA, false, win_display);
         return TRUE;
      }
      case WM_MOUSEMOVE: {
         TRACKMOUSEEVENT tme;
         int mx = GET_X_LPARAM(lParam);
         int my = GET_Y_LPARAM(lParam);

         if (win_display->mouse_cursor_shown && we_hid_the_mouse) {
            we_hid_the_mouse = false;
            win_display->display.vt->hide_mouse_cursor((void*)win_display);
         }

         _al_win_mouse_handle_move(mx, my, true, win_display);
         if (mx >= 0 && my >= 0 && mx < d->w && my < d->h) {
            tme.cbSize = sizeof(tme);
            tme.dwFlags = TME_QUERY;
            if (TrackMouseEvent(&tme) && !tme.hwndTrack) {
               tme.dwFlags = TME_LEAVE;
               tme.hwndTrack = hWnd;
               tme.dwHoverTime = 0;
               TrackMouseEvent(&tme);
               _al_win_mouse_handle_enter(win_display);
            }
         }

         break;
      }
      case WM_MOUSELEAVE: {
          _al_win_mouse_handle_leave(win_display);
          break;
      }
      case WM_CAPTURECHANGED: if (al_is_mouse_installed()) {
         int i;
         ALLEGRO_MOUSE_STATE state;
         if (!lParam || (HWND)lParam == hWnd)
            break;
         al_get_mouse_state(&state);
         for (i = 1; i <= 5; i++) {
            if (al_mouse_button_down(&state, i))
               _al_win_mouse_handle_button(i, 0, 0, 0, true, win_display);
         }
         break;
      }
      case WM_NCMOUSEMOVE: {
         if (!win_display->mouse_cursor_shown) {
            we_hid_the_mouse = true;
            win_display->display.vt->show_mouse_cursor((void*)win_display);
         }
         break;
      }
      case WM_SYSKEYDOWN: {
         int vcode = wParam; 
         bool repeated  = (lParam >> 30) & 0x1;
         _al_win_kbd_handle_key_press(0, vcode, repeated, win_display);
         break;
      }
      case WM_KEYDOWN: {
         int vcode = wParam; 
         int scode = (lParam >> 16) & 0xff;
         bool repeated  = (lParam >> 30) & 0x1;
         /* We can't use TranslateMessage() because we don't know if it will
            produce a WM_CHAR or not. */
         _al_win_kbd_handle_key_press(scode, vcode, repeated, win_display);
         break;
      }
      case WM_SYSKEYUP:
      case WM_KEYUP: {
         int vcode = wParam;
         _al_win_kbd_handle_key_release(vcode, win_display);
         break;
      }
      case WM_SYSCOMMAND: {
         if (_al_win_disable_screensaver &&
               ((wParam & 0xfff0) == SC_MONITORPOWER || (wParam & 0xfff0) == SC_SCREENSAVE)) {
            return 0;
         }
         else if ((wParam & 0xfff0) == SC_KEYMENU) {
            /* Prevent Windows from intercepting the ALT key.
               (Disables opening menus via the ALT key.) */
            return 0;
         }
         break;
      }
      case WM_PAINT: {
         if ((win_display->display.flags & ALLEGRO_GENERATE_EXPOSE_EVENTS) &&
                  _al_event_source_needs_to_generate_event(es)) {
            RECT r;
            HRGN hrgn;
            GetWindowRect(win_display->window, &r);
            hrgn = CreateRectRgn(r.left, r.top, r.right, r.bottom);
            if (GetUpdateRgn(win_display->window, hrgn, false) != ERROR) {
               PAINTSTRUCT ps;
               DWORD size;
               LPRGNDATA rgndata;
               int n;
               int i;
               RECT *rects;
               BeginPaint(win_display->window, &ps);
               size = GetRegionData(hrgn, 0, NULL);
               rgndata = _AL_MALLOC(size);
               GetRegionData(hrgn, size, rgndata);
               n = rgndata->rdh.nCount;
               rects = (RECT *)rgndata->Buffer;
               //GetWindowInfo(win_display->window, &wi);
               _al_event_source_lock(es);
               for (i = 0; i < n; i++) {
                  ALLEGRO_EVENT event;
                  event.display.type = ALLEGRO_EVENT_DISPLAY_EXPOSE;
                  event.display.timestamp = al_current_time();
                  event.display.x = rects[i].left;
                  event.display.y = rects[i].top;
                  event.display.width = rects[i].right - rects[i].left;
                  event.display.height = rects[i].bottom - rects[i].top;
                  _al_event_source_emit_event(es, &event);
               }
               _al_event_source_unlock(es);
               _AL_FREE(rgndata);
               EndPaint(win_display->window, &ps);
               DeleteObject(hrgn);
            }
            return 0;
         }
         break;
      }

      case WM_SETCURSOR:
         switch (LOWORD(lParam)) {
            case HTLEFT:
            case HTRIGHT:
               SetCursor(LoadCursor(NULL, IDC_SIZEWE));
               break;
            case HTBOTTOM:
            case HTTOP:
               SetCursor(LoadCursor(NULL, IDC_SIZENS));
               break;
            case HTBOTTOMLEFT:
            case HTTOPRIGHT:
               SetCursor(LoadCursor(NULL, IDC_SIZENESW));
               break;
            case HTBOTTOMRIGHT:
            case HTTOPLEFT:
               SetCursor(LoadCursor(NULL, IDC_SIZENWSE));
               break;
            default:
               if (win_display->mouse_cursor_shown) {
                  SetCursor(win_display->mouse_selected_hcursor);
               }
               else {
                  SetCursor(NULL);
               }
               break;
         }
         return 1;
      case WM_ACTIVATE:
         if (LOWORD(wParam) != WA_INACTIVE) {
            /* This SetWindowPos is for faux-fullscreen windows that lost focus
             * so they can get placed back on top
             */
             // FIXME: this doesn't seem to work
            //SetWindowPos(win_display->window, HWND_TOP, 0, 0, 0, 0,
            //   SWP_NOMOVE | SWP_NOSIZE);
            if (d->vt->switch_in)
            	  d->vt->switch_in(d);
            _al_event_source_lock(es);
            if (_al_event_source_needs_to_generate_event(es)) {
               ALLEGRO_EVENT event;
               event.display.type = ALLEGRO_EVENT_DISPLAY_SWITCH_IN;
               event.display.timestamp = al_current_time();
               _al_event_source_emit_event(es, &event);
            }
            _al_event_source_unlock(es);
            _al_win_grab_input(win_display);
            return 0;
         }
         else {
            if (d->flags & ALLEGRO_FULLSCREEN) {
               d->vt->switch_out(d);
            }
            _al_event_source_lock(es);
            if (_al_event_source_needs_to_generate_event(es)) {
               ALLEGRO_EVENT event;
               event.display.type = ALLEGRO_EVENT_DISPLAY_SWITCH_OUT;
               event.display.timestamp = al_current_time();
               _al_event_source_emit_event(es, &event);
            }
            _al_event_source_unlock(es);
            return 0;
         }
         break;
      case WM_MENUCHAR :
         return (MNC_CLOSE << 16) | (wParam & 0xffff);
      case WM_CLOSE:
         _al_event_source_lock(es);
         if (_al_event_source_needs_to_generate_event(es)) {
            ALLEGRO_EVENT event;
            event.display.type = ALLEGRO_EVENT_DISPLAY_CLOSE;
            event.display.timestamp = al_current_time();
            _al_event_source_emit_event(es, &event);
         }
         _al_event_source_unlock(es);
         return 0;
      case WM_SIZE:
         if (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED || wParam == SIZE_MINIMIZED) {
            /*
             * Delay the resize event so we don't get bogged down with them
             */
            if (!resize_postponed) {
               resize_postponed = true;
               postpone_resize(win_display->window);
            }
         }
         return 0;
      case WM_USER+0:
         /* Generate a resize event if the size has changed. We cannot asynchronously
          * change the display size here yet, since the user will only know about a
          * changed size after receiving the resize event. Here we merely add the
          * event to the queue.
          */
         GetWindowInfo(win_display->window, &wi);
         x = wi.rcClient.left;
         y = wi.rcClient.top;
         w = wi.rcClient.right - wi.rcClient.left;
         h = wi.rcClient.bottom - wi.rcClient.top;
         if (d->w != w || d->h != h) {
            _al_event_source_lock(es);
            if (_al_event_source_needs_to_generate_event(es)) {
               ALLEGRO_EVENT event;
               event.display.type = ALLEGRO_EVENT_DISPLAY_RESIZE;
               event.display.timestamp = al_current_time();
               event.display.x = x;
               event.display.y = y;
               event.display.width = w;
               event.display.height = h;
               _al_event_source_emit_event(es, &event);
            }

            /* Generate an expose event. */
            if (_al_event_source_needs_to_generate_event(es)) {
               ALLEGRO_EVENT event;
               event.display.type = ALLEGRO_EVENT_DISPLAY_EXPOSE;
               event.display.timestamp = al_current_time();
               event.display.x = x;
               event.display.y = y;
               event.display.width = w;
               event.display.height = h;
               _al_event_source_emit_event(es, &event);
            }
            _al_event_source_unlock(es);
         }
         resize_postponed = false;
         win_display->can_acknowledge = true;
         return 0;
   } 

   return DefWindowProc(hWnd,message,wParam,lParam); 
}
示例#16
0
static void handle_key_press(int mycode, int unichar, int filtered,
                             unsigned int modifiers, ALLEGRO_DISPLAY *display)
{
    bool is_repeat;

    is_repeat = (last_press_code == mycode);
    if (mycode > 0)
        last_press_code = mycode;

    _al_event_source_lock(&the_keyboard.parent.es);
    {
        /* Update the key_down array.  */
        _AL_KEYBOARD_STATE_SET_KEY_DOWN(the_keyboard.state, mycode);

        /* Generate the events if necessary. */
        if (_al_event_source_needs_to_generate_event(&the_keyboard.parent.es)) {
            ALLEGRO_EVENT event;

            event.keyboard.type = ALLEGRO_EVENT_KEY_DOWN;
            event.keyboard.timestamp = al_get_time();
            event.keyboard.display = display;
            event.keyboard.keycode = last_press_code;
            event.keyboard.unichar = 0;
            event.keyboard.modifiers = 0;
            event.keyboard.repeat = false;

            /* Don't send KEY_DOWN for non-physical key events. */
            if (mycode > 0 && !is_repeat) {
                _al_event_source_emit_event(&the_keyboard.parent.es, &event);
            }

            /* Don't send KEY_CHAR for events filtered by an input method,
             * nor modifier keys.
             */
            if (!filtered && mycode < ALLEGRO_KEY_MODIFIERS) {
                event.keyboard.type = ALLEGRO_EVENT_KEY_CHAR;
                event.keyboard.unichar = unichar;
                event.keyboard.modifiers = modifiers;
                event.keyboard.repeat = is_repeat;
                _al_event_source_emit_event(&the_keyboard.parent.es, &event);
            }
        }
    }
    _al_event_source_unlock(&the_keyboard.parent.es);

// FIXME?
#ifndef ALLEGRO_RASPBERRYPI
    /* Toggle mouse grab key.  The system driver should not be locked here. */
    if (last_press_code && !is_repeat) {
        ALLEGRO_SYSTEM_XGLX *system = (void *)al_get_system_driver();
        if (system->toggle_mouse_grab_keycode == mycode &&
                (modifiers & system->toggle_mouse_grab_modifiers)
                == system->toggle_mouse_grab_modifiers)
        {
            if (system->mouse_grab_display == display)
                al_ungrab_mouse();
            else
                al_grab_mouse(display);
        }
    }
#endif

    /* Exit by Ctrl-Alt-End.  */
    if ((_al_three_finger_flag)
            && ((mycode == ALLEGRO_KEY_DELETE) || (mycode == ALLEGRO_KEY_END))
            && (modifiers & ALLEGRO_KEYMOD_CTRL)
            && (modifiers & (ALLEGRO_KEYMOD_ALT | ALLEGRO_KEYMOD_ALTGR)))
    {
        ALLEGRO_WARN("Three finger combo detected. SIGTERMing "
                     "pid %d\n", main_pid);
        kill(main_pid, SIGTERM);
    }
}
示例#17
0
static LRESULT CALLBACK window_callback(HWND hWnd, UINT message, 
    WPARAM wParam, LPARAM lParam)
{
   ALLEGRO_DISPLAY *d = NULL;
   ALLEGRO_DISPLAY_WIN *win_display = NULL;
   unsigned int i;
   ALLEGRO_EVENT_SOURCE *es = NULL;
   ALLEGRO_SYSTEM *system = al_get_system_driver();

   if (message == _al_win_msg_call_proc) {
      ((void (*)(void*))wParam) ((void*)lParam);
      return 0;
   }

   if (!system) {
      return DefWindowProc(hWnd,message,wParam,lParam); 
   }

   if (message == _al_win_msg_suicide && wParam) {
      win_display = (ALLEGRO_DISPLAY_WIN*)wParam;
      break_window_message_pump(win_display, hWnd);
      DestroyWindow(hWnd);
      return 0;
   }

   for (i = 0; i < system->displays._size; i++) {
      ALLEGRO_DISPLAY **dptr = _al_vector_ref(&system->displays, i);
      d = *dptr;
      win_display = (void*)d;
      if (win_display->window == hWnd) {
         es = &d->es;
         break;
      }
   }

   if (i == system->displays._size)
      return DefWindowProc(hWnd,message,wParam,lParam); 

   if (message == _al_win_msg_suicide) {
      break_window_message_pump(win_display, hWnd);
      DestroyWindow(hWnd);
      return 0;
   }

   switch (message) {
      case WM_INPUT: 
      {
         /* RAW Input is currently unused. */
          UINT dwSize;
          LPBYTE lpb;
          RAWINPUT* raw;

          /* We can't uninstall WM_INPUT mesages. */
          if (!al_is_mouse_installed())
             break;

          GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, 
                          sizeof(RAWINPUTHEADER));
          lpb = al_malloc(sizeof(BYTE)*dwSize);
          if (lpb == NULL) 
              break;

          GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER));
          raw = (RAWINPUT*)lpb;

          if (raw->header.dwType != RIM_TYPEMOUSE) {
             al_free(lpb); 
             break;
          }

       {
          RAWMOUSE *rm = &raw->data.mouse;
          int x = raw->data.mouse.lLastX;
          int y = raw->data.mouse.lLastY;
          bool abs = (rm->usFlags & (MOUSE_MOVE_ABSOLUTE
                                    | MOUSE_VIRTUAL_DESKTOP)) != 0;
          if (abs || x || y)
             _al_win_mouse_handle_move(x, y, abs, win_display);

          if (rm->usButtonFlags & RI_MOUSE_BUTTON_1_DOWN)
             _al_win_mouse_handle_button(1, true, x, y, abs, win_display);
          if (rm->usButtonFlags & RI_MOUSE_BUTTON_1_UP)
             _al_win_mouse_handle_button(1, false, x, y, abs, win_display);
          if (rm->usButtonFlags & RI_MOUSE_BUTTON_2_DOWN)
             _al_win_mouse_handle_button(2, true, x, y, abs, win_display);
          if (rm->usButtonFlags & RI_MOUSE_BUTTON_2_UP)
             _al_win_mouse_handle_button(2, false, x, y, abs, win_display);
          if (rm->usButtonFlags & RI_MOUSE_BUTTON_3_DOWN)
             _al_win_mouse_handle_button(3, true, x, y, abs, win_display);
          if (rm->usButtonFlags & RI_MOUSE_BUTTON_3_UP)
             _al_win_mouse_handle_button(3, false, x, y, abs, win_display);
          if (rm->usButtonFlags & RI_MOUSE_BUTTON_4_DOWN)
             _al_win_mouse_handle_button(4, true, x, y, abs, win_display);
          if (rm->usButtonFlags & RI_MOUSE_BUTTON_4_UP)
             _al_win_mouse_handle_button(4, false, x, y, abs, win_display);
          if (rm->usButtonFlags & RI_MOUSE_BUTTON_5_DOWN)
             _al_win_mouse_handle_button(5, true, x, y, abs, win_display);
          if (rm->usButtonFlags & RI_MOUSE_BUTTON_5_UP)
             _al_win_mouse_handle_button(5, false, x, y, abs, win_display);

          if (rm->usButtonFlags & RI_MOUSE_WHEEL) {
             SHORT z = (SHORT)rm->usButtonData;
             _al_win_mouse_handle_wheel(z / WHEEL_DELTA, false, win_display);
          }
       }

          al_free(lpb); 
          break;
      }
      case WM_LBUTTONDOWN:
      case WM_LBUTTONUP: {
         int mx = GET_X_LPARAM(lParam);
         int my = GET_Y_LPARAM(lParam);
         bool down = (message == WM_LBUTTONDOWN);
         _al_win_mouse_handle_button(1, down, mx, my, true, win_display);
         handle_mouse_capture(down, hWnd);
         break;
      }
      case WM_MBUTTONDOWN:
      case WM_MBUTTONUP: {
         int mx = GET_X_LPARAM(lParam);
         int my = GET_Y_LPARAM(lParam);
         bool down = (message == WM_MBUTTONDOWN);
         _al_win_mouse_handle_button(3, down, mx, my, true, win_display);
         handle_mouse_capture(down, hWnd);
         break;
      }
      case WM_RBUTTONDOWN:
      case WM_RBUTTONUP: {
         int mx = GET_X_LPARAM(lParam);
         int my = GET_Y_LPARAM(lParam);
         bool down = (message == WM_RBUTTONDOWN);
         _al_win_mouse_handle_button(2, down, mx, my, true, win_display);
         handle_mouse_capture(down, hWnd);
         break;
      }
      case WM_XBUTTONDOWN:
      case WM_XBUTTONUP: {
         int mx = GET_X_LPARAM(lParam);
         int my = GET_Y_LPARAM(lParam);
         int button = HIWORD(wParam);
         bool down = (message == WM_XBUTTONDOWN);
         if (button == XBUTTON1)
            _al_win_mouse_handle_button(4, down, mx, my, true, win_display);
         else if (button == XBUTTON2)
            _al_win_mouse_handle_button(5, down, mx, my, true, win_display);
         handle_mouse_capture(down, hWnd);
         return TRUE;
      }
      case WM_MOUSEWHEEL: {
         int d = GET_WHEEL_DELTA_WPARAM(wParam);
         _al_win_mouse_handle_wheel(d / WHEEL_DELTA, false, win_display);
         return TRUE;
      }
      case WM_MOUSEHWHEEL: {
         int d = GET_WHEEL_DELTA_WPARAM(wParam);
         _al_win_mouse_handle_hwheel(d / WHEEL_DELTA, false, win_display);
         return TRUE;
      }
      case WM_MOUSEMOVE: {
         TRACKMOUSEEVENT tme;
         int mx = GET_X_LPARAM(lParam);
         int my = GET_Y_LPARAM(lParam);

         if (win_display->mouse_cursor_shown && we_hid_the_mouse) {
            we_hid_the_mouse = false;
            win_display->display.vt->hide_mouse_cursor((void*)win_display);
         }

         _al_win_mouse_handle_move(mx, my, true, win_display);
         if (mx >= 0 && my >= 0 && mx < d->w && my < d->h) {
            tme.cbSize = sizeof(tme);
            tme.dwFlags = TME_QUERY;
            if (TrackMouseEvent(&tme) && !tme.hwndTrack) {
               tme.dwFlags = TME_LEAVE;
               tme.hwndTrack = hWnd;
               tme.dwHoverTime = 0;
               TrackMouseEvent(&tme);
               _al_win_mouse_handle_enter(win_display);
            }
         }

         /* WM_SETCURSOR messages are not received while the mouse is
          * captured.  We call SetCursor here so that changing the mouse
          * cursor has an effect while the user is holding down the mouse
          * button.
          */
         if (GetCapture() == hWnd && win_display->mouse_cursor_shown) {
            SetCursor(win_display->mouse_selected_hcursor);
         }

         break;
      }
      case WM_MOUSELEAVE: {
         _al_win_mouse_handle_leave(win_display);
         break;
      }
      case WM_CAPTURECHANGED: {
         if (al_is_mouse_installed()) {
            int i;
            ALLEGRO_MOUSE_STATE state;
            if (!lParam || (HWND)lParam == hWnd)
               break;
            al_get_mouse_state(&state);
            for (i = 1; i <= 5; i++) {
               if (al_mouse_button_down(&state, i))
                  _al_win_mouse_handle_button(i, 0, 0, 0, true, win_display);
            }
         }
         break;
      }
      case WM_NCMOUSEMOVE: {
         if (!win_display->mouse_cursor_shown) {
            we_hid_the_mouse = true;
            win_display->display.vt->show_mouse_cursor((void*)win_display);
         }
         break;
      }
      case WM_SYSKEYDOWN: {
         int vcode = wParam;
         bool extended = (lParam >> 24) & 0x1;
         bool repeated  = (lParam >> 30) & 0x1;
         _al_win_kbd_handle_key_press(0, vcode, extended, repeated, win_display);
         break;
      }
      case WM_KEYDOWN: {
         int vcode = wParam; 
         int scode = (lParam >> 16) & 0xff;
         bool extended = (lParam >> 24) & 0x1;
         bool repeated = (lParam >> 30) & 0x1;
         /* We can't use TranslateMessage() because we don't know if it will
            produce a WM_CHAR or not. */
         _al_win_kbd_handle_key_press(scode, vcode, extended, repeated, win_display);
         break;
      }
      case WM_SYSKEYUP:
      case WM_KEYUP: {
         int vcode = wParam;
         int scode = (lParam >> 16) & 0xff;
         bool extended = (lParam >> 24) & 0x1;
         _al_win_kbd_handle_key_release(scode, vcode, extended, win_display);
         break;
      }
      case WM_SYSCOMMAND: {
         if (_al_win_disable_screensaver &&
               ((wParam & 0xfff0) == SC_MONITORPOWER || (wParam & 0xfff0) == SC_SCREENSAVE)) {
            return 0;
         }
         else if ((wParam & 0xfff0) == SC_KEYMENU) {
            /* Prevent Windows from intercepting the ALT key.
               (Disables opening menus via the ALT key.) */
            return 0;
         }
         break;
      }
      case WM_PAINT: {
         if (win_display->display.flags & ALLEGRO_GENERATE_EXPOSE_EVENTS) {
            RECT r;
            HRGN hrgn;
            GetWindowRect(win_display->window, &r);
            hrgn = CreateRectRgn(r.left, r.top, r.right, r.bottom);
            if (GetUpdateRgn(win_display->window, hrgn, false) != ERROR) {
               PAINTSTRUCT ps;
               DWORD size;
               LPRGNDATA rgndata;
               int n;
               int i;
               RECT *rects;
               BeginPaint(win_display->window, &ps);
               size = GetRegionData(hrgn, 0, NULL);
               rgndata = al_malloc(size);
               GetRegionData(hrgn, size, rgndata);
               n = rgndata->rdh.nCount;
               rects = (RECT *)rgndata->Buffer;
               _al_event_source_lock(es);
               if (_al_event_source_needs_to_generate_event(es)) {
                  ALLEGRO_EVENT event;
                  event.display.type = ALLEGRO_EVENT_DISPLAY_EXPOSE;
                  event.display.timestamp = al_get_time();
                  for (i = 0; i < n; i++) {
                     event.display.x = rects[i].left;
                     event.display.y = rects[i].top;
                     event.display.width = rects[i].right - rects[i].left;
                     event.display.height = rects[i].bottom - rects[i].top;
                     _al_event_source_emit_event(es, &event);
                  }
               }
               _al_event_source_unlock(es);
               al_free(rgndata);
               EndPaint(win_display->window, &ps);
               DeleteObject(hrgn);
            }
            return 0;
         }
         break;
      }

      case WM_SETCURSOR:
         switch (LOWORD(lParam)) {
            case HTLEFT:
            case HTRIGHT:
               SetCursor(LoadCursor(NULL, IDC_SIZEWE));
               break;
            case HTBOTTOM:
            case HTTOP:
               SetCursor(LoadCursor(NULL, IDC_SIZENS));
               break;
            case HTBOTTOMLEFT:
            case HTTOPRIGHT:
               SetCursor(LoadCursor(NULL, IDC_SIZENESW));
               break;
            case HTBOTTOMRIGHT:
            case HTTOPLEFT:
               SetCursor(LoadCursor(NULL, IDC_SIZENWSE));
               break;
            default:
               if (win_display->mouse_cursor_shown) {
                  SetCursor(win_display->mouse_selected_hcursor);
               }
               else {
                  SetCursor(NULL);
               }
               break;
         }
         return 1;
      case WM_ACTIVATE:
         if (HIWORD(wParam) && LOWORD(wParam) != WA_INACTIVE)
            break;

         if (HIWORD(wParam))
            d->flags |= ALLEGRO_MINIMIZED;
         else
            d->flags &= ~ALLEGRO_MINIMIZED;

         if (LOWORD(wParam) != WA_INACTIVE) {
            // Make fullscreen windows TOPMOST again
            if (d->flags & ALLEGRO_FULLSCREEN_WINDOW) {
               SetWindowPos(win_display->window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
            }
            if (d->vt->switch_in)
               d->vt->switch_in(d);
            _al_win_fix_modifiers();
            _al_event_source_lock(es);
            if (_al_event_source_needs_to_generate_event(es)) {
               ALLEGRO_EVENT event;
               memset(&event, 0, sizeof(event));
               event.display.type = ALLEGRO_EVENT_DISPLAY_SWITCH_IN;
               event.display.timestamp = al_get_time();
               _al_event_source_emit_event(es, &event);
            }
            _al_event_source_unlock(es);
            _al_win_grab_input(win_display);
            return 0;
         }
         else {
            // Remove TOPMOST flag from fullscreen windows so we can alt-tab. Also must raise the new activated window
            if (d->flags & ALLEGRO_FULLSCREEN_WINDOW) {
               SetWindowPos(win_display->window, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
               SetWindowPos(GetForegroundWindow(), HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
            }
            // Show the taskbar in case we hid it
            SetWindowPos(FindWindow("Shell_traywnd", ""), 0, 0, 0, 0, 0, SWP_SHOWWINDOW);
            if (d->flags & ALLEGRO_FULLSCREEN) {
               d->vt->switch_out(d);
            }
            _al_event_source_lock(es);
            if (_al_event_source_needs_to_generate_event(es)) {
               ALLEGRO_EVENT event;
               memset(&event, 0, sizeof(event));
               event.display.type = ALLEGRO_EVENT_DISPLAY_SWITCH_OUT;
               event.display.timestamp = al_get_time();
               _al_event_source_emit_event(es, &event);
            }
            _al_event_source_unlock(es);
            return 0;
         }
         break;
      case WM_MENUCHAR :
         return (MNC_CLOSE << 16) | (wParam & 0xffff);
      case WM_CLOSE:
         _al_event_source_lock(es);
         if (_al_event_source_needs_to_generate_event(es)) {
            ALLEGRO_EVENT event;
            memset(&event, 0, sizeof(event));
            event.display.type = ALLEGRO_EVENT_DISPLAY_CLOSE;
            event.display.timestamp = al_get_time();
            _al_event_source_emit_event(es, &event);
         }
         _al_event_source_unlock(es);
         return 0;
      case WM_SIZE:
         if (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED || wParam == SIZE_MINIMIZED) {
            /*
             * Delay the resize event so we don't get bogged down with them
             */
            if (!resize_postponed) {
               resize_postponed = true;
               _beginthread(postpone_thread_proc, 0, (void *)d);
            }
         }
         return 0;
      case WM_ENTERSIZEMOVE:
         /* DefWindowProc for WM_ENTERSIZEMOVE enters a modal loop, which also
          * ends up blocking the loop in d3d_display_thread_proc (which is
          * where we are called from, if using D3D).  Rather than batching up
          * intermediate resize events which the user cannot acknowledge in the
          * meantime anyway, make it so only a single resize event is generated
          * at WM_EXITSIZEMOVE.
          */
         if (d->flags & ALLEGRO_DIRECT3D) {
            resize_postponed = true;
         }
         break;
      case WM_EXITSIZEMOVE:
         if (resize_postponed) {
            win_generate_resize_event(win_display);
            win_display->ignore_resize = false;
            resize_postponed = false;
            win_display->can_acknowledge = true;
         }
         break;
   } 

   return DefWindowProc(hWnd,message,wParam,lParam); 
}
示例#18
0
static void generate_touch_input_event(int type, double timestamp, int id, float x, float y, float dx, float dy, bool primary, ALLEGRO_DISPLAY_WIN *win_disp)
{
   ALLEGRO_EVENT event;

   bool want_touch_event           = _al_event_source_needs_to_generate_event(&touch_input.es);
   bool want_mouse_emulation_event = _al_event_source_needs_to_generate_event(&touch_input.mouse_emulation_es) && primary && al_is_mouse_installed();

   if (touch_input.mouse_emulation_mode == ALLEGRO_MOUSE_EMULATION_NONE)
      want_mouse_emulation_event = false;
   else if (touch_input.mouse_emulation_mode == ALLEGRO_MOUSE_EMULATION_INCLUSIVE)
      want_touch_event = want_mouse_emulation_event ? (want_touch_event && !primary) : want_touch_event;
   else if (touch_input.mouse_emulation_mode == ALLEGRO_MOUSE_EMULATION_EXCLUSIVE)
      want_touch_event = want_mouse_emulation_event ? false : want_touch_event;

   if (!want_touch_event && !want_mouse_emulation_event)
      return;

   if (want_touch_event) {

      event.touch.type      = type;
      event.touch.display   = (ALLEGRO_DISPLAY*)win_disp;
      event.touch.timestamp = timestamp;
      event.touch.id        = id;
      event.touch.x         = x;
      event.touch.y         = y;
      event.touch.dx        = dx;
      event.touch.dy        = dy;
      event.touch.primary   = primary;

      _al_event_source_lock(&touch_input.es);
      _al_event_source_emit_event(&touch_input.es, &event);
      _al_event_source_unlock(&touch_input.es);
   }

   if (want_mouse_emulation_event) {

      ALLEGRO_MOUSE_STATE state;

      switch (type) {
         case ALLEGRO_EVENT_TOUCH_BEGIN: type = ALLEGRO_EVENT_MOUSE_BUTTON_DOWN; break;
         case ALLEGRO_EVENT_TOUCH_CANCEL:
         case ALLEGRO_EVENT_TOUCH_END:   type = ALLEGRO_EVENT_MOUSE_BUTTON_UP;   break;
         case ALLEGRO_EVENT_TOUCH_MOVE:  type = ALLEGRO_EVENT_MOUSE_AXES;        break;
      }

      al_get_mouse_state(&state);

      event.mouse.type      = type;
      event.mouse.timestamp = timestamp;
      event.mouse.display   = (ALLEGRO_DISPLAY*)win_disp;
      event.mouse.x         = (int)x;
      event.mouse.y         = (int)y;
      event.mouse.z         = state.z;
      event.mouse.w         = state.w;
      event.mouse.dx        = (int)dx;
      event.mouse.dy        = (int)dy;
      event.mouse.dz        = 0;
      event.mouse.dw        = 0;
      event.mouse.button    = 1;
      event.mouse.pressure  = state.pressure;

      al_set_mouse_xy(event.mouse.display, event.mouse.x, event.mouse.y);

      _al_event_source_lock(&touch_input.mouse_emulation_es);
      _al_event_source_emit_event(&touch_input.mouse_emulation_es, &event);
      _al_event_source_unlock(&touch_input.mouse_emulation_es);
   }
}
示例#19
0
void _al_xglx_display_configure(ALLEGRO_DISPLAY *d, int x, int y,
   int width, int height, bool setglxy)
{
   ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)d;

   ALLEGRO_EVENT_SOURCE *es = &glx->display.es;
   _al_event_source_lock(es);

   /* Generate a resize event if the size has changed non-programmtically.
    * We cannot asynchronously change the display size here yet, since the user
    * will only know about a changed size after receiving the resize event.
    * Here we merely add the event to the queue.
    */
   if (!glx->programmatic_resize &&
         (d->w != width ||
          d->h != height)) {
      if (_al_event_source_needs_to_generate_event(es)) {
         ALLEGRO_EVENT event;
         event.display.type = ALLEGRO_EVENT_DISPLAY_RESIZE;
         event.display.timestamp = al_get_time();
         event.display.x = x;
         event.display.y = y;
         event.display.width = width;
         event.display.height = height;
         _al_event_source_emit_event(es, &event);
      }
   }

   /* We receive two configure events when toggling the window frame.
    * We ignore the first one as it has bogus coordinates.
    * The only way to tell them apart seems to be the send_event field.
    * Unfortunately, we also end up ignoring the only event we receive in
    * response to a XMoveWindow request so we have to compensate for that.
    */
   if (setglxy) {
      glx->x = x;
      glx->y = y;
   }
   

   ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX*)al_get_system_driver();
   ALLEGRO_MONITOR_INFO mi;
   int center_x = (glx->x + (glx->x + width)) / 2;
   int center_y = (glx->y + (glx->y + height)) / 2;
         
   _al_xglx_get_monitor_info(system, glx->adapter, &mi);
   
   ALLEGRO_DEBUG("xconfigure event! %ix%i\n", x, y);
   
   /* check if we're no longer inside the stored adapter */
   if ((center_x < mi.x1 && center_x > mi.x2) ||
      (center_y < mi.y1 && center_y > mi.x2))
   {
      
      int new_adapter = _al_xglx_get_adapter(system, glx, true);
      if (new_adapter != glx->adapter) {
         ALLEGRO_DEBUG("xdpy: adapter change!\n");
         _al_xglx_unuse_adapter(system, glx->adapter);
         if (d->flags & ALLEGRO_FULLSCREEN)
            _al_xglx_restore_video_mode(system, glx->adapter);
         glx->adapter = new_adapter;
         _al_xglx_use_adapter(system, glx->adapter);
      }
      
   }
   
   _al_event_source_unlock(es);
}
/* _al_win_kbd_handle_key_press:
 *  Does stuff when a key is pressed.
 */
void _al_win_kbd_handle_key_press(int scode, int vcode, bool extended,
                           bool repeated, ALLEGRO_DISPLAY_WIN *win_disp)
{
   ALLEGRO_DISPLAY *display = (ALLEGRO_DISPLAY *)win_disp;
   ALLEGRO_EVENT event;
   int my_code;
   bool actual_repeat;
   int char_count;
   int event_count;
   int i;
   BYTE ks[256];
   WCHAR buf[8] = { 0 };

   if (!installed)
      return;

   /* Check for an extended key first. */
   my_code = 0;
   if (extended)
      my_code = extkey_to_keycode(vcode);

   /* Map a non-extended key.  This also works as a fallback in case
      the key was extended, but no extended mapping was found. */
   if (my_code == 0) {
      if (vcode == VK_SHIFT) /* Left or right Shift key? */
         vcode = MapVirtualKey(scode, MAPVK_VSC_TO_VK_EX);
      my_code = hw_to_mycode[vcode];
   }
   update_modifiers(my_code, true);   

   actual_repeat = repeated && _AL_KEYBOARD_STATE_KEY_DOWN(the_state, my_code);
   _AL_KEYBOARD_STATE_SET_KEY_DOWN(the_state, my_code);

   if (!_al_event_source_needs_to_generate_event(&the_keyboard.es))
      return;

   event.keyboard.type = ALLEGRO_EVENT_KEY_DOWN;
   event.keyboard.timestamp = al_get_time();
   event.keyboard.display = display;
   event.keyboard.keycode = my_code;
   event.keyboard.unichar = 0;
   event.keyboard.modifiers = 0;
   event.keyboard.repeat = false;

   _al_event_source_lock(&the_keyboard.es);

   if (my_code > 0 && !actual_repeat) {
      _al_event_source_emit_event(&the_keyboard.es, &event);
   }

   /* Send char events, but not for modifier keys or dead keys. */
   if (my_code < ALLEGRO_KEY_MODIFIERS) {
      char_count = ToUnicode(vcode, scode, GetKeyboardState(ks) ? ks : NULL, buf, 8, 0);
      /* Send ASCII code 127 for both Del keys. */
      if (char_count == 0 && vcode == VK_DELETE) {
         char_count = 1;
         buf[0] = 127;
      }
      if (char_count != -1) { /* -1 means it was a dead key. */
         event_count = char_count ? char_count : 1;
         event.keyboard.type = ALLEGRO_EVENT_KEY_CHAR;
         update_toggle_modifiers();
         event.keyboard.modifiers = modifiers;
         event.keyboard.repeat = actual_repeat;
         for (i = 0; i < event_count; i++) {
            event.keyboard.unichar = buf[i];
            _al_event_source_emit_event(&the_keyboard.es, &event);
         }
      }
   }
   _al_event_source_unlock(&the_keyboard.es);

   /* Toggle mouse grab key. */
   if (my_code && !repeated) {
      ALLEGRO_SYSTEM_WIN *system = (void *)al_get_system_driver();
      if (my_code == system->toggle_mouse_grab_keycode &&
         (modifiers & system->toggle_mouse_grab_modifiers) == system->toggle_mouse_grab_modifiers)
      {
         if (system->mouse_grab_display == display) {
            al_ungrab_mouse();
         }
         else {
            al_grab_mouse(display);
         }
      }
   }
}
示例#21
0
void _al_xglx_display_configure(ALLEGRO_DISPLAY *d, int x, int y,
   int width, int height, bool setglxy)
{
   ALLEGRO_DISPLAY_XGLX *glx = (ALLEGRO_DISPLAY_XGLX *)d;

   ALLEGRO_EVENT_SOURCE *es = &glx->display.es;
   _al_event_source_lock(es);

   /* Generate a resize event if the size has changed non-programmatically.
    * We cannot asynchronously change the display size here yet, since the user
    * will only know about a changed size after receiving the resize event.
    * Here we merely add the event to the queue.
    */
   if (!glx->programmatic_resize &&
         (d->w != width ||
          d->h != height)) {
      if (_al_event_source_needs_to_generate_event(es)) {
         ALLEGRO_EVENT event;
         event.display.type = ALLEGRO_EVENT_DISPLAY_RESIZE;
         event.display.timestamp = al_get_time();
         event.display.x = x;
         event.display.y = y;
         event.display.width = width;
         event.display.height = height;
         _al_event_source_emit_event(es, &event);
      }
   }

   if (setglxy) {
      glx->x = x;
      glx->y = y;
   }

   ALLEGRO_SYSTEM_XGLX *system = (ALLEGRO_SYSTEM_XGLX*)al_get_system_driver();
   ALLEGRO_MONITOR_INFO mi;
   int center_x = (glx->x + (glx->x + width)) / 2;
   int center_y = (glx->y + (glx->y + height)) / 2;

   _al_xglx_get_monitor_info(system, glx->adapter, &mi);

   ALLEGRO_DEBUG("xconfigure event! %ix%i\n", x, y);

   /* check if we're no longer inside the stored adapter */
   if ((center_x < mi.x1 && center_x > mi.x2) ||
      (center_y < mi.y1 && center_y > mi.x2))
   {
      int new_adapter = _al_xglx_get_adapter(system, glx, true);
      if (new_adapter != glx->adapter) {
         ALLEGRO_DEBUG("xdpy: adapter change!\n");
         _al_xglx_unuse_adapter(system, glx->adapter);
         if (d->flags & ALLEGRO_FULLSCREEN)
            _al_xglx_restore_video_mode(system, glx->adapter);
         glx->adapter = new_adapter;
         _al_xglx_use_adapter(system, glx->adapter);
      }

   }

   _al_xwin_check_maximized(d);

   _al_event_source_unlock(es);
}