示例#1
0
static int l_get_key_modifiers(lua_State *L)
{
    l_push_modifiers_table(L, SDL_GetModState());
    return 1;
}
示例#2
0
/**
 * \brief Returns whether the caps lock key is currently active.
 * \return \c true if the caps lock key is currently active.
 */
bool InputEvent::is_caps_lock_on() {

  SDL_Keymod mod = SDL_GetModState();
  return mod & KMOD_CAPS;
}
示例#3
0
static void sdl_refresh(DisplayState *ds)
{
    SDL_Event ev1, *ev = &ev1;
    int mod_state;
    int buttonstate = SDL_GetMouseState(NULL, NULL);

    if (last_vm_running != vm_running) {
        last_vm_running = vm_running;
        sdl_update_caption();
    }

    vga_hw_update();
    SDL_EnableUNICODE(!is_graphic_console());

    while (SDL_PollEvent(ev)) {
        switch (ev->type) {
        case SDL_VIDEOEXPOSE:
            sdl_update(ds, 0, 0, real_screen->w, real_screen->h);
            break;
        case SDL_KEYDOWN:
        case SDL_KEYUP:
            if (ev->type == SDL_KEYDOWN) {
                if (!alt_grab) {
                    mod_state = (SDL_GetModState() & gui_grab_code) ==
                                gui_grab_code;
                } else {
                    mod_state = (SDL_GetModState() & (gui_grab_code | KMOD_LSHIFT)) ==
                                (gui_grab_code | KMOD_LSHIFT);
                }
                gui_key_modifier_pressed = mod_state;
                if (gui_key_modifier_pressed) {
                    int keycode;
                    keycode = sdl_keyevent_to_keycode(&ev->key);
                    switch(keycode) {
                    case 0x21: /* 'f' key on US keyboard */
                        toggle_full_screen(ds);
                        gui_keysym = 1;
                        break;
                    case 0x02 ... 0x0a: /* '1' to '9' keys */
                        /* Reset the modifiers sent to the current console */
                        reset_keys();
                        console_select(keycode - 0x02);
                        if (!is_graphic_console()) {
                            /* display grab if going to a text console */
                            if (gui_grab)
                                sdl_grab_end();
                        }
                        gui_keysym = 1;
                        break;
                    default:
                        break;
                    }
                } else if (!is_graphic_console()) {
                    int keysym;
                    keysym = 0;
                    if (ev->key.keysym.mod & (KMOD_LCTRL | KMOD_RCTRL)) {
                        switch(ev->key.keysym.sym) {
                        case SDLK_UP: keysym = QEMU_KEY_CTRL_UP; break;
                        case SDLK_DOWN: keysym = QEMU_KEY_CTRL_DOWN; break;
                        case SDLK_LEFT: keysym = QEMU_KEY_CTRL_LEFT; break;
                        case SDLK_RIGHT: keysym = QEMU_KEY_CTRL_RIGHT; break;
                        case SDLK_HOME: keysym = QEMU_KEY_CTRL_HOME; break;
                        case SDLK_END: keysym = QEMU_KEY_CTRL_END; break;
                        case SDLK_PAGEUP: keysym = QEMU_KEY_CTRL_PAGEUP; break;
                        case SDLK_PAGEDOWN: keysym = QEMU_KEY_CTRL_PAGEDOWN; break;
                        default: break;
                        }
                    } else {
                        switch(ev->key.keysym.sym) {
                        case SDLK_UP: keysym = QEMU_KEY_UP; break;
                        case SDLK_DOWN: keysym = QEMU_KEY_DOWN; break;
                        case SDLK_LEFT: keysym = QEMU_KEY_LEFT; break;
                        case SDLK_RIGHT: keysym = QEMU_KEY_RIGHT; break;
                        case SDLK_HOME: keysym = QEMU_KEY_HOME; break;
                        case SDLK_END: keysym = QEMU_KEY_END; break;
                        case SDLK_PAGEUP: keysym = QEMU_KEY_PAGEUP; break;
                        case SDLK_PAGEDOWN: keysym = QEMU_KEY_PAGEDOWN; break;
                        case SDLK_BACKSPACE: keysym = QEMU_KEY_BACKSPACE; break;
                        case SDLK_DELETE: keysym = QEMU_KEY_DELETE; break;
                        default: break;
                        }
                    }
                    if (keysym) {
                        kbd_put_keysym(keysym);
                    } else if (ev->key.keysym.unicode != 0) {
                        kbd_put_keysym(ev->key.keysym.unicode);
                    }
                }
            } else if (ev->type == SDL_KEYUP) {
                if (!alt_grab) {
                    mod_state = (ev->key.keysym.mod & gui_grab_code);
                } else {
                    mod_state = (ev->key.keysym.mod &
                                 (gui_grab_code | KMOD_LSHIFT));
                }
                if (!mod_state) {
                    if (gui_key_modifier_pressed) {
                        gui_key_modifier_pressed = 0;
                        if (gui_keysym == 0) {
                            /* exit/enter grab if pressing Ctrl-Alt */
                            if (!gui_grab) {
                                /* if the application is not active,
                                   do not try to enter grab state. It
                                   prevents
                                   'SDL_WM_GrabInput(SDL_GRAB_ON)'
                                   from blocking all the application
                                   (SDL bug). */
                                if (SDL_GetAppState() & SDL_APPACTIVE)
                                    sdl_grab_start();
                            } else {
                                sdl_grab_end();
                            }
                            /* SDL does not send back all the
                               modifiers key, so we must correct it */
                            reset_keys();
                            break;
                        }
                        gui_keysym = 0;
                    }
                }
            }
            if (is_graphic_console() && !gui_keysym)
                sdl_process_key(&ev->key);
            break;
        case SDL_QUIT:
            if (!no_quit)
                qemu_system_shutdown_request();
            break;
        case SDL_MOUSEMOTION:
            if (gui_grab || kbd_mouse_is_absolute() ||
                absolute_enabled) {
                sdl_send_mouse_event(ev->motion.xrel, ev->motion.yrel, 0,
                       ev->motion.x, ev->motion.y, ev->motion.state);
            }
            break;
        case SDL_MOUSEBUTTONDOWN:
        case SDL_MOUSEBUTTONUP:
            {
                SDL_MouseButtonEvent *bev = &ev->button;
                if (!gui_grab && !kbd_mouse_is_absolute()) {
                    if (ev->type == SDL_MOUSEBUTTONDOWN &&
                        (bev->button == SDL_BUTTON_LEFT)) {
                        /* start grabbing all events */
                        sdl_grab_start();
                    }
                } else {
                    int dz;
                    dz = 0;
                    if (ev->type == SDL_MOUSEBUTTONDOWN) {
                        buttonstate |= SDL_BUTTON(bev->button);
                    } else {
                        buttonstate &= ~SDL_BUTTON(bev->button);
                    }
#ifdef SDL_BUTTON_WHEELUP
                    if (bev->button == SDL_BUTTON_WHEELUP && ev->type == SDL_MOUSEBUTTONDOWN) {
                        dz = -1;
                    } else if (bev->button == SDL_BUTTON_WHEELDOWN && ev->type == SDL_MOUSEBUTTONDOWN) {
                        dz = 1;
                    }
#endif
                    sdl_send_mouse_event(0, 0, dz, bev->x, bev->y, buttonstate);
                }
            }
            break;
        case SDL_ACTIVEEVENT:
            if (gui_grab && ev->active.state == SDL_APPINPUTFOCUS &&
                !ev->active.gain && !gui_fullscreen_initial_grab) {
                sdl_grab_end();
            }
            if (ev->active.state & SDL_APPACTIVE) {
                if (ev->active.gain) {
                    /* Back to default interval */
                    dcl->gui_timer_interval = 0;
                    dcl->idle = 0;
                } else {
                    /* Sleeping interval */
                    dcl->gui_timer_interval = 500;
                    dcl->idle = 1;
                }
            }
            break;
        default:
            break;
        }
示例#4
0
bool select_difficulty( void )
{
	JE_loadPic(VGAScreen, 2, false);
	JE_dString(VGAScreen, JE_fontCenter(difficulty_name[0], FONT_SHAPES), 20, difficulty_name[0], FONT_SHAPES);

	difficultyLevel = 2;
	int difficulty_max = 3;

	bool fade_in = true;
	for (; ; )
	{
		for (int i = 1; i <= difficulty_max; i++)
		{
			JE_outTextAdjust(VGAScreen, JE_fontCenter(difficulty_name[i], SMALL_FONT_SHAPES), i * 24 + 30, difficulty_name[i], 15, -4 + (i == difficultyLevel ? 2 : 0), SMALL_FONT_SHAPES, true);
		}
		JE_showVGA();

		if (fade_in)
		{
			fade_palette(colors, 10, 0, 255);
			fade_in = false;
		}

		JE_word temp = 0;
		JE_textMenuWait(&temp, false);

		if (SDL_GetModState() & KMOD_SHIFT)
		{
			if ((difficulty_max < 4 && keysactive[SDLK_g]) ||
			    (difficulty_max == 4 && keysactive[SDLK_RIGHTBRACKET]))
			{
				difficulty_max++;
			}
		} else if (difficulty_max == 5 && keysactive[SDLK_l] && keysactive[SDLK_o] && keysactive[SDLK_r] && keysactive[SDLK_d]) {
			difficulty_max++;
		}

		if (newkey)
		{
			switch (lastkey_sym)
			{
			case SDLK_UP:
				difficultyLevel--;
				if (difficultyLevel < 1)
				{
					difficultyLevel = difficulty_max;
				}
				JE_playSampleNum(S_CURSOR);
				break;
			case SDLK_DOWN:
				difficultyLevel++;
				if (difficultyLevel > difficulty_max)
				{
					difficultyLevel = 1;
				}
				JE_playSampleNum(S_CURSOR);
				break;

			case SDLK_RETURN:
				JE_playSampleNum(S_SELECT);
				/* fading handled elsewhere
				fade_black(10); */

				if (difficultyLevel == 6)
				{
					difficultyLevel = 8;
				} else if (difficultyLevel == 5) {
					difficultyLevel = 6;
				}
				return true;

			case SDLK_ESCAPE:
				JE_playSampleNum(S_SPRING);
				/* fading handled elsewhere
				fade_black(10); */

				return false;

			default:
				break;
			}
		}
	}
}
示例#5
0
/**
 * \brief Returns whether the CTRL key is currently down.
 *
 * There is no distinction between the right and left CTRL keys in this function.
 *
 * \return true if the CTRL key is currently down
 */
bool InputEvent::is_control_down() {

  SDL_Keymod mod = SDL_GetModState();
  return mod & KMOD_CTRL;
}
示例#6
0
void Runtime::pollEvents(bool blocking) {
  if (isActive() && !isRestart()) {
    SDL_Event ev;
    SDL_Keymod mod;
    if (blocking ? SDL_WaitEvent(&ev) : SDL_PollEvent(&ev)) {
      MAEvent *maEvent = NULL;
      switch (ev.type) {
      case SDL_TEXTINPUT:
        // pre-transformed/composted text
        mod = SDL_GetModState();
        if (!mod || (mod & (KMOD_SHIFT|KMOD_CAPS))) {
          // ALT + CTRL keys handled in SDL_KEYDOWN
          for (int i = 0; ev.text.text[i] != 0; i++) {
            MAEvent *keyEvent = new MAEvent();
            keyEvent->type = EVENT_TYPE_KEY_PRESSED;
            keyEvent->key = ev.text.text[i];
            keyEvent->nativeKey = 0;
            pushEvent(keyEvent);
          }
        }
        break;
      case SDL_QUIT:
        setExit(true);
        break;
      case SDL_KEYDOWN:
        if (!isEditing() && ev.key.keysym.sym == SDLK_c
            && (ev.key.keysym.mod & KMOD_CTRL)) {
          setExit(true);
        } else if (ev.key.keysym.sym == SDLK_m && (ev.key.keysym.mod & KMOD_CTRL)) {
          showMenu();
        } else if (ev.key.keysym.sym == SDLK_b && (ev.key.keysym.mod & KMOD_CTRL)) {
          setBack();
        } else if (ev.key.keysym.sym == SDLK_BACKSPACE &&
                   get_focus_edit() == NULL &&
                   ((ev.key.keysym.mod & KMOD_CTRL) || !isRunning())) {
          setBack();
        } else if (!isEditing() && ev.key.keysym.sym == SDLK_PAGEUP &&
                   (ev.key.keysym.mod & KMOD_CTRL)) {
          _output->scroll(true, true);
        } else if (!isEditing() && ev.key.keysym.sym == SDLK_PAGEDOWN &&
                   (ev.key.keysym.mod & KMOD_CTRL)) {
          _output->scroll(false, true);
        } else if (!isEditing() && ev.key.keysym.sym == SDLK_UP &&
                   (ev.key.keysym.mod & KMOD_CTRL)) {
          _output->scroll(true, false);
        } else if (!isEditing() && ev.key.keysym.sym == SDLK_DOWN &&
                   (ev.key.keysym.mod & KMOD_CTRL)) {
          _output->scroll(false, false);
        } else if (ev.key.keysym.sym == SDLK_p && (ev.key.keysym.mod & KMOD_CTRL)) {
          ::screen_dump();
        } else {
          int lenMap = sizeof(keymap) / sizeof(keymap[0]);
          for (int i = 0; i < lenMap; i++) {
            if (ev.key.keysym.sym == keymap[i][0]) {
              maEvent = new MAEvent();
              maEvent->type = EVENT_TYPE_KEY_PRESSED;
              maEvent->key = keymap[i][1];
              maEvent->nativeKey = ev.key.keysym.mod;
              break;
            }
          }
          if (maEvent == NULL &&
              ((ev.key.keysym.sym >= SDLK_KP_1 && ev.key.keysym.sym <= SDLK_KP_9) ||
               ((ev.key.keysym.mod & KMOD_CTRL) &&
                ev.key.keysym.sym != SDLK_LSHIFT &&
                ev.key.keysym.sym != SDLK_RSHIFT &&
                ev.key.keysym.sym != SDLK_LCTRL &&
                ev.key.keysym.sym != SDLK_RCTRL) ||
               (ev.key.keysym.mod & KMOD_ALT))) {
            maEvent = new MAEvent();
            maEvent->type = EVENT_TYPE_KEY_PRESSED;
            maEvent->key = ev.key.keysym.sym;
            maEvent->nativeKey = ev.key.keysym.mod;
          }
        }
        break;
      case SDL_MOUSEBUTTONDOWN:
        if (ev.button.button == SDL_BUTTON_RIGHT) {
          _menuX = ev.motion.x;
          _menuY = ev.motion.y;
          showMenu();
        } else if (ev.motion.x != 0 && ev.motion.y != 0) {
          // avoid phantom down message when launching in windows
          maEvent = getMotionEvent(EVENT_TYPE_POINTER_PRESSED, &ev);
        }
        break;
      case SDL_MOUSEMOTION:
        maEvent = getMotionEvent(EVENT_TYPE_POINTER_DRAGGED, &ev);
        break;
      case SDL_MOUSEBUTTONUP:
        SDL_SetCursor(_cursorArrow);
        maEvent = getMotionEvent(EVENT_TYPE_POINTER_RELEASED, &ev);
        break;
      case SDL_WINDOWEVENT:
        switch (ev.window.event) {
        case SDL_WINDOWEVENT_FOCUS_GAINED:
          SDL_SetModState(KMOD_NONE);
          break;
        case SDL_WINDOWEVENT_RESIZED:
          onResize(ev.window.data1, ev.window.data2);
          break;
        case SDL_WINDOWEVENT_EXPOSED:
          _graphics->redraw();
          break;
        case SDL_WINDOWEVENT_LEAVE:
          _output->removeHover();
          break;
        }
        break;
      case SDL_DROPFILE:
        setLoadPath(ev.drop.file);
        setExit(false);
        SDL_free(ev.drop.file);
        break;
      case SDL_MOUSEWHEEL:
        if (!_output->scroll(ev.wheel.y == 1, false)) {
          maEvent = new MAEvent();
          maEvent->type = EVENT_TYPE_KEY_PRESSED;
          maEvent->key = ev.wheel.y == 1 ? SB_KEY_UP : SB_KEY_DN;
          maEvent->nativeKey = KMOD_CTRL;
        }
        break;
      }
      if (maEvent != NULL) {
        pushEvent(maEvent);
      }
    }
  }
}
示例#7
0
// Get the equivalent ASCII (Unicode?) character for a keypress.
static int GetTypedChar(SDL_Keysym *sym)
{
    // We only return typed characters when entering text, after
    // I_StartTextInput() has been called. Otherwise we return nothing.
    if (!text_input_enabled)
    {
        return 0;
    }

    // If we're strictly emulating Vanilla, we should always act like
    // we're using a US layout keyboard (in ev_keydown, data1=data2).
    // Otherwise we should use the native key mapping.
    if (vanilla_keyboard_mapping)
    {
        int result = TranslateKey(sym);

        // If shift is held down, apply the original uppercase
        // translation table used under DOS.
        if ((SDL_GetModState() & KMOD_SHIFT) != 0
         && result >= 0 && result < arrlen(shiftxform))
        {
            result = shiftxform[result];
        }

        return result;
    }
    else
    {
        SDL_Event next_event;

        // Special cases, where we always return a fixed value.
        switch (sym->sym)
        {
            case SDLK_BACKSPACE: return KEY_BACKSPACE;
            case SDLK_RETURN:    return KEY_ENTER;
            default:
                break;
        }

        // The following is a gross hack, but I don't see an easier way
        // of doing this within the SDL2 API (in SDL1 it was easier).
        // We want to get the fully transformed input character associated
        // with this keypress - correct keyboard layout, appropriately
        // transformed by any modifier keys, etc. So peek ahead in the SDL
        // event queue and see if the key press is immediately followed by
        // an SDL_TEXTINPUT event. If it is, it's reasonable to assume the
        // key press and the text input are connected. Technically the SDL
        // API does not guarantee anything of the sort, but in practice this
        // is what happens and I've verified it through manual inspect of
        // the SDL source code.
        //
        // In an ideal world we'd split out ev_keydown into a separate
        // ev_textinput event, as SDL2 has done. But this doesn't work
        // (I experimented with the idea), because lots of Doom's code is
        // based around different responders "eating" events to stop them
        // being passed on to another responder. If code is listening for
        // a text input, it cannot block the corresponding keydown events
        // which can affect other responders.
        //
        // So we're stuck with this as a rather fragile alternative.

        if (SDL_PeepEvents(&next_event, 1, SDL_PEEKEVENT,
                           SDL_FIRSTEVENT, SDL_LASTEVENT) == 1
         && next_event.type == SDL_TEXTINPUT)
        {
            // If an SDL_TEXTINPUT event is found, we always assume it
            // matches the key press. The input text must be a single
            // ASCII character - if it isn't, it's possible the input
            // char is a Unicode value instead; better to send a null
            // character than the unshifted key.
            if (strlen(next_event.text.text) == 1
             && (next_event.text.text[0] & 0x80) == 0)
            {
                return next_event.text.text[0];
            }
        }

        // Failed to find anything :/
        return 0;
    }
}
示例#8
0
Sdl2Application::InputEvent::Modifiers Sdl2Application::MouseMoveEvent::modifiers() {
    if(modifiersLoaded) return _modifiers;
    modifiersLoaded = true;
    return _modifiers = fixedModifiers(Uint16(SDL_GetModState()));
}
示例#9
0
int main(int argc, char *argv[])
{
  SDL_Init(SDL_INIT_VIDEO);
  SDL_WM_SetCaption("La grue !", NULL);
  SDL_SetVideoMode(LARGEUR_ECRAN, HAUTEUR_ECRAN, 32, SDL_OPENGL);
  SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluOrtho2D(0, LARGEUR_ECRAN, 0, HAUTEUR_ECRAN);
  

  bool continuer = true;
  SDL_Event event;
  SDLMod mod = KMOD_NONE;

  int angle_grand_bras = 45;
  int angle_petit_bras = -10;
  int longueur_fils = 50;

  while (continuer)
    {
      SDL_WaitEvent(&event);
      mod = SDL_GetModState();
      switch(event.type)
        {
	case SDL_QUIT:
	  continuer = false;
	  break;
	case SDL_KEYDOWN:
	  switch (event.key.keysym.sym)
            {
	    case SDLK_ESCAPE: /* Appui sur la touche Echap, on arrête le programme */
	      continuer = false;
	      break;
	    case SDLK_UP:
	      if (longueur_fils > LONGUEUR_FILS_MIN)
		longueur_fils -= 1;
	      break;
	    case SDLK_DOWN:
	      if (longueur_fils < LONGUEUR_FILS_MAX)
		longueur_fils += 1;
	      break;
	    case SDLK_LEFT:
	      if (mod & KMOD_SHIFT) {
		if (angle_grand_bras < ANGLE_GD_BRAS_MAX)
		  angle_grand_bras += 5;
	      } else {
		if (angle_petit_bras < ANGLE_PT_BRAS_MAX)
		  angle_petit_bras += 5;
	      }
	      break;
	    case SDLK_RIGHT:
	      if (mod & KMOD_SHIFT) {
		if (angle_grand_bras > ANGLE_GD_BRAS_MIN)
		  angle_grand_bras -= 5;
	      } else {
		if (angle_petit_bras > ANGLE_PT_BRAS_MIN)
		  angle_petit_bras -= 5;
	      }
	      break;
	    case SDLK_h:
	      /* dessinerRepere(50); */
	      break;
	    default:
	      break;
            }
	  break;
	default:
	  break;
        }

      /* efface le tampon d'affichage */
      glClear(GL_COLOR_BUFFER_BIT);

      /* dessine */

      /* base */
      glPushMatrix();
      glTranslated(20, 20, 0);
      glBegin(GL_QUADS);
      glColor3ub(255, 150, 0);
      glVertex2d(0, 0);
      glVertex2d(0, 40);
      glVertex2d(100, 40);
      glVertex2d(100, 0);
      glEnd();
      glPopMatrix();

      /* grand bras */
      glPushMatrix();
      glTranslated(70, 60, 0);
      glRotated(angle_grand_bras, 0, 0, 1);
      glBegin(GL_QUADS);
      glColor3ub(255, 250, 0);
      glVertex2d(0, -15);
      glVertex2d(0, 15);
      glVertex2d(LONGUEUR_GD_BRAS, 15);
      glVertex2d(LONGUEUR_GD_BRAS, -15);
      glEnd();

      /* petit bras */
      glTranslated(LONGUEUR_GD_BRAS, 0, 0);
      glRotated(angle_petit_bras, 0, 0, 1);
      glBegin(GL_QUADS);
      glColor3ub(50, 250, 50);
      glVertex2d(0, -10);
      glVertex2d(0, 10);
      glVertex2d(LONGUEUR_PT_BRAS, 10);
      glVertex2d(LONGUEUR_PT_BRAS, -10);
      glEnd();
      
      /* fils */
      glTranslated(LONGUEUR_PT_BRAS, 0, 0);
      glRotated(-90 + (angle_petit_bras * -1) + (angle_grand_bras * -1), 0, 0, 1);
      glBegin(GL_LINES);
      glColor3ub(255, 255, 255);
      glVertex2d(0, 0);
      glVertex2d(longueur_fils, 0);
      glEnd();

      /* caisse */
      glTranslated(longueur_fils, 0, 0);
      glBegin(GL_QUADS);
      glColor3ub(255, 0, 0);
      glVertex2d(0, (TAILLE_CAISSE / 2));
      glVertex2d(TAILLE_CAISSE, (TAILLE_CAISSE / 2));
      glVertex2d(TAILLE_CAISSE, -(TAILLE_CAISSE / 2));
      glVertex2d(0, -(TAILLE_CAISSE / 2));
      glEnd();

      /* Restore la matrice de base pour que les modifications
	 qui viennent d'être effectuées ne s'ajoutent pas
	 à chaque fois que les éléments se redessine */
      glPopMatrix();

      /* s'assure que toutes les cmd opengl ont été exécutées */
      glFlush();

      /* échange des buffers back et front */
      SDL_GL_SwapBuffers();
    }

  SDL_Quit();

  return 0;
}
示例#10
0
static void handle_keydown(DisplayState *ds, SDL_Event *ev)
{
    int mod_state;
    int keycode;

    if (alt_grab) {
//    	LOGV("Found alt grab\n");
        mod_state = (SDL_GetModState() & (gui_grab_code | KMOD_LSHIFT)) ==
                    (gui_grab_code | KMOD_LSHIFT);
    } else if (ctrl_grab) {
//    	LOGV("Found ctrl grab\n");
        mod_state = (SDL_GetModState() & KMOD_RCTRL) == KMOD_RCTRL;
    } else {
//    	LOGV("Default grab\n");
        mod_state = (SDL_GetModState() & gui_grab_code) == gui_grab_code;
    }
    gui_key_modifier_pressed = mod_state;

    if (gui_key_modifier_pressed) {
        keycode = sdl_keyevent_to_keycode(&ev->key);
//        LOGV("Found modifier pressed for key/keycode = %d/%d\n", ev->key.keysym.sym, keycode);
        switch (keycode) {
        case 1: /* 'f' key on US keyboard */
        	LOGV("Keycode Pressed 'f' Fullscreen\n");
            toggle_full_screen(ds);
            gui_keysym = 1;
            break;
        case 16: /* 'u' key on US keyboard */
        	LOGV("Keycode Pressed 'u' unset Scale\n");
            if (scaling_active) {
            	LOGV("Found scaling active Unsetting...\n");
                scaling_active = 0;
                sdl_resize(ds);
                vga_hw_invalidate();
                vga_hw_update();
                reset_keys();
            }
            gui_keysym = 1;
            break;

        case 22 ... 23: /* '1' to '9' keys */ //MK hack
            /* Reset the modifiers sent to the current console */
        	LOGV("Keycode Pressed '1-9' console\n");
            reset_keys();
            console_select(keycode - 22);
            gui_keysym = 1;
//            if (gui_fullscreen) {
//            	LOGV("Found fullscreen breaking...\n");
//                break;
//            }
            if (!is_graphic_console()) {
                /* release grab if going to a text console */
            	LOGV("Found text console releasing grab...\n");
                if (gui_grab) {
                	LOGV("Found grab, grab ending...\n");
                    sdl_grab_end();
                } else if (absolute_enabled) {
                	LOGV("Found absolute_enabled, show cursor...\n");
                    sdl_show_cursor();
                }
            } else if (absolute_enabled) {
            	LOGV("Found absolute_enabled, hiding cursor and grabing mouse...\n");
                sdl_hide_cursor();
                absolute_mouse_grab();
            }
            break;
        case 24: /* '4' Zoom In */
        case 25: /* '3' Zoom Out*/
        	LOGV("Keycode Pressed '3/4' Zoom\n");
//            if (!gui_fullscreen) {
        	{

                int width = MAX(real_screen->w + (keycode == 25 ? 50 : -50),
                                160);
                int height = (ds_get_height(ds) * width) / ds_get_width(ds);
                LOGV("Found no fullscreen, scaling to: %dx%d \n", width, height);
                sdl_scale(ds, width, height);
                vga_hw_invalidate();
                vga_hw_update();
                reset_keys();
                gui_keysym = 1;
        	}
//            }
            break;
        case 26: /* Fit to Screen */
        	LOGV("Keycode Pressed '5' Fit to Screen\n");
//            if (!gui_fullscreen) {
        	{
            	int width;
            	int height;
            	AndroidGetWindowSize(&width, &height);
            	LOGV("Got Android window size=%dx%d", width, height);
            	LOGV("Got VM  resolution=%dx%d", ds_get_width(ds), ds_get_height(ds));
            	float aspectRatio = (float) ds_get_height(ds) / (float) ds_get_width(ds);
            	LOGV("Got aspectRatio=%f", aspectRatio);
            	int new_width = (int) (height / aspectRatio);
            	if(new_width > width){
            		LOGV("Width is overrun, modifying height");
            		new_width = width;
            		height = width * aspectRatio;
            	}
                LOGV("Found no fullscreen, Fit To Screen: %dx%d \n", new_width, height);
                sdl_scale(ds, new_width, height);
                vga_hw_invalidate();
                vga_hw_update();
                reset_keys();
                gui_keysym = 1;
        	}
//            }
            break;
        case 27: /* Stretch to Screen */
        	LOGV("Keycode Pressed '6' Fit to Screen\n");
//        	            if (!gui_fullscreen) {
        	            	{
        	            	int width;
        	            	int height;
        	            	AndroidGetWindowSize(&width, &height);
        	                LOGV("Found no fullscreen, Fit To Screen: %dx%d \n", width, height);
        	                sdl_scale(ds, width, height);
        	                vga_hw_invalidate();
        	                vga_hw_update();
        	                reset_keys();
        	                gui_keysym = 1;
        	            	}
//        	            }
        	            break;
        default:
        	LOGV("Default\n");
            break;
        }
    } else if (!is_graphic_console()) {
示例#11
0
文件: events.cpp 项目: Debug-/dhewm3
/*
================
Sys_GetEvent
================
*/
sysEvent_t Sys_GetEvent() {
	SDL_Event ev;
	sysEvent_t res = { };
	byte key;

	static const sysEvent_t res_none = { SE_NONE, 0, 0, 0, NULL };

#if SDL_VERSION_ATLEAST(2, 0, 0)
	static char *s = NULL;
	static size_t s_pos = 0;

	if (s) {
		res.evType = SE_CHAR;
		res.evValue = s[s_pos];

		s_pos++;
		if (!s[s_pos]) {
			free(s);
			s = NULL;
			s_pos = 0;
		}

		return res;
	}
#endif

	static byte c = 0;

	if (c) {
		res.evType = SE_CHAR;
		res.evValue = c;

		c = 0;

		return res;
	}

	if (SDL_PollEvent(&ev)) {
		switch (ev.type) {
#if SDL_VERSION_ATLEAST(2, 0, 0)
		case SDL_WINDOWEVENT:
			switch (ev.window.event) {
				case SDL_WINDOWEVENT_FOCUS_GAINED: {
						// unset modifier, in case alt-tab was used to leave window and ALT is still set
						// as that can cause fullscreen-toggling when pressing enter...
						SDL_Keymod currentmod = SDL_GetModState();
					
						int newmod = KMOD_NONE;
						if (currentmod & KMOD_CAPS) // preserve capslock
							newmod |= KMOD_CAPS;

						SDL_SetModState((SDL_Keymod)newmod);
					} // new context because visual studio complains about newmod and currentmod not initialized because of the case SDL_WINDOWEVENT_FOCUS_LOST

					GLimp_GrabInput(GRAB_ENABLE | GRAB_REENABLE | GRAB_HIDECURSOR);
					break;
				case SDL_WINDOWEVENT_FOCUS_LOST:
					GLimp_GrabInput(0);
					break;
			}

			return res_none;
#else
		case SDL_ACTIVEEVENT:
			{
				int flags = 0;

				if (ev.active.gain) {
					flags = GRAB_ENABLE | GRAB_REENABLE | GRAB_HIDECURSOR;

					// unset modifier, in case alt-tab was used to leave window and ALT is still set
					// as that can cause fullscreen-toggling when pressing enter...
					SDLMod currentmod = SDL_GetModState();
					int newmod = KMOD_NONE;
					if (currentmod & KMOD_CAPS) // preserve capslock
						newmod |= KMOD_CAPS;

					SDL_SetModState((SDLMod)newmod);
				}

				GLimp_GrabInput(flags);
			}

			return res_none;

		case SDL_VIDEOEXPOSE:
			return res_none;
#endif

		case SDL_KEYDOWN:
			if (ev.key.keysym.sym == SDLK_RETURN && (ev.key.keysym.mod & KMOD_ALT) > 0) {
				cvarSystem->SetCVarBool("r_fullscreen", !renderSystem->IsFullScreen());
				PushConsoleEvent("vid_restart");
				return res_none;
			}

			// fall through
		case SDL_KEYUP:
			key = mapkey(ev.key.keysym.sym);
#if !SDL_VERSION_ATLEAST(2, 0, 0)
			if (!key) {
				unsigned char c;
				// check if its an unmapped console key
				if (ev.key.keysym.unicode == (c = Sys_GetConsoleKey(false))) {
					key = c;
				} else if (ev.key.keysym.unicode == (c = Sys_GetConsoleKey(true))) {
					key = c;
				} else {
					if (ev.type == SDL_KEYDOWN)
						common->Warning("unmapped SDL key %d (0x%x)", ev.key.keysym.sym, ev.key.keysym.unicode);
					return res_none;
				}
			}
#else
			if(!key) {
				if (ev.key.keysym.scancode == SDL_SCANCODE_GRAVE) {
					key = Sys_GetConsoleKey(true);
				} else {
					if (ev.type == SDL_KEYDOWN) {
						common->Warning("unmapped SDL key %d", ev.key.keysym.sym);
					return res_none;
					}

				}
			}

#endif

			res.evType = SE_KEY;
			res.evValue = key;
			res.evValue2 = ev.key.state == SDL_PRESSED ? 1 : 0;

			kbd_polls.Append(kbd_poll_t(key, ev.key.state == SDL_PRESSED));

#if SDL_VERSION_ATLEAST(2, 0, 0)
			if (key == K_BACKSPACE && ev.key.state == SDL_PRESSED)
				c = key;
#else
			if (ev.key.state == SDL_PRESSED && (ev.key.keysym.unicode & 0xff00) == 0)
				c = ev.key.keysym.unicode & 0xff;
#endif

			return res;

#if SDL_VERSION_ATLEAST(2, 0, 0)
		case SDL_TEXTINPUT:
			if (ev.text.text && *ev.text.text) {
				if (!ev.text.text[1])
					c = *ev.text.text;
				else
					s = strdup(ev.text.text);
			}

			return res_none;
#endif

		case SDL_MOUSEMOTION:
			res.evType = SE_MOUSE;
			res.evValue = ev.motion.xrel;
			res.evValue2 = ev.motion.yrel;

			mouse_polls.Append(mouse_poll_t(M_DELTAX, ev.motion.xrel));
			mouse_polls.Append(mouse_poll_t(M_DELTAY, ev.motion.yrel));

			return res;

#if SDL_VERSION_ATLEAST(2, 0, 0)
		case SDL_MOUSEWHEEL:
			res.evType = SE_KEY;

			if (ev.wheel.y > 0) {
				res.evValue = K_MWHEELUP;
				mouse_polls.Append(mouse_poll_t(M_DELTAZ, 1));
			} else {
				res.evValue = K_MWHEELDOWN;
				mouse_polls.Append(mouse_poll_t(M_DELTAZ, -1));
			}

			res.evValue2 = 1;

			return res;
#endif

		case SDL_MOUSEBUTTONDOWN:
		case SDL_MOUSEBUTTONUP:
			res.evType = SE_KEY;

			switch (ev.button.button) {
			case SDL_BUTTON_LEFT:
				res.evValue = K_MOUSE1;
				mouse_polls.Append(mouse_poll_t(M_ACTION1, ev.button.state == SDL_PRESSED ? 1 : 0));
				break;
			case SDL_BUTTON_MIDDLE:
				res.evValue = K_MOUSE3;
				mouse_polls.Append(mouse_poll_t(M_ACTION3, ev.button.state == SDL_PRESSED ? 1 : 0));
				break;
			case SDL_BUTTON_RIGHT:
				res.evValue = K_MOUSE2;
				mouse_polls.Append(mouse_poll_t(M_ACTION2, ev.button.state == SDL_PRESSED ? 1 : 0));
				break;

#if !SDL_VERSION_ATLEAST(2, 0, 0)
			case SDL_BUTTON_WHEELUP:
				res.evValue = K_MWHEELUP;
				if (ev.button.state == SDL_PRESSED)
					mouse_polls.Append(mouse_poll_t(M_DELTAZ, 1));
				break;
			case SDL_BUTTON_WHEELDOWN:
				res.evValue = K_MWHEELDOWN;
				if (ev.button.state == SDL_PRESSED)
					mouse_polls.Append(mouse_poll_t(M_DELTAZ, -1));
				break;
#endif
			}

			res.evValue2 = ev.button.state == SDL_PRESSED ? 1 : 0;

			return res;

		case SDL_QUIT:
			PushConsoleEvent("quit");
			return res_none;

		case SDL_USEREVENT:
			switch (ev.user.code) {
			case SE_CONSOLE:
				res.evType = SE_CONSOLE;
				res.evPtrLength = (intptr_t)ev.user.data1;
				res.evPtr = ev.user.data2;
				return res;
			default:
				common->Warning("unknown user event %u", ev.user.code);
				return res_none;
			}
		default:
			common->Warning("unknown event %u", ev.type);
			return res_none;
		}
	}

	return res_none;
}
示例#12
0
static int _process_mouse_event(void)
{
    SDLMod keymods;
    short shift_flags = 0;

    memset(&pdc_mouse_status, 0, sizeof(MOUSE_STATUS));

    keymods = SDL_GetModState();

    if (keymods & KMOD_SHIFT)
        shift_flags |= BUTTON_SHIFT;

    if (keymods & KMOD_CTRL)
        shift_flags |= BUTTON_CONTROL;

    if (keymods & KMOD_ALT)
        shift_flags |= BUTTON_ALT;

    if (event.type == SDL_MOUSEMOTION)
    {
        int i;

        pdc_mouse_status.x = event.motion.x / pdc_fwidth;
        pdc_mouse_status.y = event.motion.y / pdc_fheight;

        if (!event.motion.state ||
           (pdc_mouse_status.x == old_mouse_status.x &&
            pdc_mouse_status.y == old_mouse_status.y))
            return -1;

        pdc_mouse_status.changes = PDC_MOUSE_MOVED;

        for (i = 0; i < 3; i++)
        {
            if (event.motion.state & SDL_BUTTON(i + 1))
            {
                pdc_mouse_status.button[i] = BUTTON_MOVED | shift_flags;
                pdc_mouse_status.changes |= (1 << i);
            }
        }
    }
    else
    {
        short action = (event.button.state == SDL_PRESSED) ?
                       BUTTON_PRESSED : BUTTON_RELEASED;
        Uint8 btn = event.button.button;

        /* handle scroll wheel */

        if ((btn == 4 || btn == 5) && action == BUTTON_RELEASED)
        {
            pdc_mouse_status.x = pdc_mouse_status.y = -1;

            pdc_mouse_status.changes = (btn == 5) ?
                PDC_MOUSE_WHEEL_DOWN : PDC_MOUSE_WHEEL_UP;

            return KEY_MOUSE;
        }

        if (btn < 1 || btn > 3)
            return -1;

        /* check for a click -- a press followed immediately by a release */

        if (action == BUTTON_PRESSED && SP->mouse_wait)
        {
            SDL_Event rel;

            napms(SP->mouse_wait);

            if (SDL_PollEvent(&rel))
            {
                if (rel.type == SDL_MOUSEBUTTONUP && rel.button.button == btn)
                    action = BUTTON_CLICKED;
                else
                    SDL_PushEvent(&rel);
            }
        }

        pdc_mouse_status.x = event.button.x / pdc_fwidth;
        pdc_mouse_status.y = event.button.y / pdc_fheight;

        btn--;

        pdc_mouse_status.button[btn] = action | shift_flags;
        pdc_mouse_status.changes = (1 << btn);
    }

    old_mouse_status = pdc_mouse_status;

    return KEY_MOUSE;
}
示例#13
0
/**
 * Handles screen key shortcuts.
 * @param action Pointer to an action.
 */
void Screen::handle(Action *action)
{
	if (Options::debug)
	{
		if (action->getDetails()->type == SDL_KEYDOWN && action->getDetails()->key.keysym.sym == SDLK_F8)
		{
			switch(Timer::gameSlowSpeed)
			{
				case 1: Timer::gameSlowSpeed = 5; break;
				case 5: Timer::gameSlowSpeed = 15; break;
				default: Timer::gameSlowSpeed = 1; break;
			}
		}
	}
	
	if (action->getDetails()->type == SDL_KEYDOWN && action->getDetails()->key.keysym.sym == SDLK_RETURN && (SDL_GetModState() & KMOD_ALT) != 0)
	{
		Options::fullscreen = !Options::fullscreen;
		resetDisplay();
	}
	else if (action->getDetails()->type == SDL_KEYDOWN && action->getDetails()->key.keysym.sym == Options::keyScreenshot)
	{
		std::ostringstream ss;
		int i = 0;
		do
		{
			ss.str("");
			ss << Options::getMasterUserFolder() << "screen" << std::setfill('0') << std::setw(3) << i << ".png";
			i++;
		}
		while (CrossPlatform::fileExists(ss.str()));
		screenshot(ss.str());
		return;
	}
}
示例#14
0
void textbox::handle_event(const SDL_Event& event, bool was_forwarded)
{
	if(!enabled())
		return;

	scrollarea::handle_event(event);
	if(hidden())
		return;

	bool changed = false;

	const int old_selstart = selstart_;
	const int old_selend = selend_;

	//Sanity check: verify that selection start and end are within text
	//boundaries
	if(is_selection() && !(size_t(selstart_) <= text_.size() && size_t(selend_) <= text_.size())) {
		WRN_DP << "out-of-boundary selection\n";
		selstart_ = selend_ = -1;
	}

	int mousex, mousey;
	const Uint8 mousebuttons = SDL_GetMouseState(&mousex,&mousey);
	if(!(mousebuttons & SDL_BUTTON(1))) {
		grabmouse_ = false;
	}

	SDL_Rect const &loc = inner_location();
	bool clicked_inside = !mouse_locked() && (event.type == SDL_MOUSEBUTTONDOWN
					   && (mousebuttons & SDL_BUTTON(1))
					   && point_in_rect(mousex, mousey, loc));
	if(clicked_inside) {
		set_focus(true);
	}
	if ((grabmouse_ && (!mouse_locked() && event.type == SDL_MOUSEMOTION)) || clicked_inside) {
		const int x = mousex - loc.x + text_pos_;
		const int y = mousey - loc.y;
		int pos = 0;
		int distance = x;

		for(unsigned int i = 1; i < char_x_.size(); ++i) {
			if(static_cast<int>(yscroll_) + y < char_y_[i]) {
				break;
			}

			// Check individually each distance (if, one day, we support
			// RTL languages, char_x_[c] may not be monotonous.)
			if(abs(x - char_x_[i]) < distance && yscroll_ + y < char_y_[i] + line_height_) {
				pos = i;
				distance = abs(x - char_x_[i]);
			}
		}

		cursor_ = pos;

		if(grabmouse_)
			selend_ = cursor_;

		update_text_cache(false);

		if(!grabmouse_ && mousebuttons & SDL_BUTTON(1)) {
			grabmouse_ = true;
			selstart_ = selend_ = cursor_;
		} else if (! (mousebuttons & SDL_BUTTON(1))) {
			grabmouse_ = false;
		}

		set_dirty();
	}

	//if we don't have the focus, then see if we gain the focus,
	//otherwise return
	if(!was_forwarded && focus(&event) == false) {
		if (!mouse_locked() && event.type == SDL_MOUSEMOTION && point_in_rect(mousex, mousey, loc))
			events::focus_handler(this);

		return;
	}

	if(event.type != SDL_KEYDOWN || (!was_forwarded && focus(&event) != true)) {
		draw();
		return;
	}

	const SDL_keysym& key = reinterpret_cast<const SDL_KeyboardEvent&>(event).keysym;
	const SDLMod modifiers = SDL_GetModState();

	const int c = key.sym;
	const int old_cursor = cursor_;

	if(editable_) {
		if(c == SDLK_LEFT && cursor_ > 0)
			--cursor_;

		if(c == SDLK_RIGHT && cursor_ < static_cast<int>(text_.size()))
			++cursor_;

		// ctrl-a, ctrl-e and ctrl-u are readline style shortcuts, even on Macs
		if(c == SDLK_END || (c == SDLK_e && (modifiers & KMOD_CTRL)))
			cursor_ = text_.size();

		if(c == SDLK_HOME || (c == SDLK_a && (modifiers & KMOD_CTRL)))
			cursor_ = 0;

		if((old_cursor != cursor_) && (modifiers & KMOD_SHIFT)) {
			if(selstart_ == -1)
				selstart_ = old_cursor;
			selend_ = cursor_;
		}
	} else if(c == SDLK_LEFT || c == SDLK_RIGHT || c == SDLK_END || c == SDLK_HOME) {
		pass_event_to_target(event);
	}

	if(editable_) {
		if(c == SDLK_BACKSPACE) {
			changed = true;
			if(is_selection()) {
				erase_selection();
			} else if(cursor_ > 0) {
				--cursor_;
				text_.erase(text_.begin()+cursor_);
			}
		}

		if(c == SDLK_u && (modifiers & KMOD_CTRL)) { // clear line
			changed = true;
			cursor_ = 0;
			text_.resize(0);
		}

		if(c == SDLK_DELETE && !text_.empty()) {
			changed = true;
			if(is_selection()) {
				erase_selection();
			} else {
				if(cursor_ < static_cast<int>(text_.size())) {
					text_.erase(text_.begin()+cursor_);
				}
			}
		}
	} else if(c == SDLK_BACKSPACE || c == SDLK_DELETE || (c == SDLK_u && (modifiers & KMOD_CTRL))) {
		pass_event_to_target(event);
	}

#if SDL_VERSION_ATLEAST(2, 0, 0)
	ucs4::char_t character = key.scancode;
#else
	ucs4::char_t character = key.unicode;
#endif

	//movement characters may have a "Unicode" field on some platforms, so ignore it.
	if(!(c == SDLK_UP || c == SDLK_DOWN || c == SDLK_LEFT || c == SDLK_RIGHT ||
	   c == SDLK_DELETE || c == SDLK_BACKSPACE || c == SDLK_END || c == SDLK_HOME ||
	   c == SDLK_PAGEUP || c == SDLK_PAGEDOWN)) {
		if(character != 0) {
			DBG_G << "Char: " << character << ", c = " << c << "\n";
		}
		if((event.key.keysym.mod & copypaste_modifier)
//on windows SDL fires for AltGr lctrl+ralt (needed to access @ etc on certain keyboards)
#ifdef _WIN32
			&& !(event.key.keysym.mod & KMOD_ALT)
#endif
		) {
			switch(c) {
			case SDLK_v: // paste
				{
				if(!editable()) {
					pass_event_to_target(event);
					break;
				}

				changed = true;
				if(is_selection())
					erase_selection();

				std::string str = copy_from_clipboard(false);

				//cut off anything after the first newline
				str.erase(std::find_if(str.begin(),str.end(),utils::isnewline),str.end());

				ucs4::string s = utils::string_to_ucs4string(str);

				if(text_.size() < max_size_) {
					if(s.size() + text_.size() > max_size_) {
						s.resize(max_size_ - text_.size());
					}
					text_.insert(text_.begin()+cursor_, s.begin(), s.end());
					cursor_ += s.size();
				}

				}

				break;

			case SDLK_c: // copy
				{
					if(is_selection())
					{
						const size_t beg = std::min<size_t>(size_t(selstart_),size_t(selend_));
						const size_t end = std::max<size_t>(size_t(selstart_),size_t(selend_));

						ucs4::string ws(text_.begin() + beg, text_.begin() + end);
						std::string s = utils::ucs4string_to_string(ws);
						copy_to_clipboard(s, false);
					}
				}
				break;
			}
		} else if(editable_) {
			if(character >= 32 && character != 127) {
				changed = true;
				if(is_selection())
					erase_selection();

				if(text_.size() + 1 <= max_size_) {
					text_.insert(text_.begin()+cursor_,character);
					++cursor_;
				}
			}
		} else {
			pass_event_to_target(event);
		}
	}

	if(is_selection() && (selend_ != cursor_))
		selstart_ = selend_ = -1;

	//since there has been cursor activity, make the cursor appear for
	//at least the next 500ms.
	show_cursor_ = true;
	show_cursor_at_ = SDL_GetTicks();

	if(changed || old_cursor != cursor_ || old_selstart != selstart_ || old_selend != selend_) {
		text_image_ = NULL;
		handle_text_changed(text_);
	}

	set_dirty(true);
}
示例#15
0
void SDLViewer::execute()
{
  bool redisplay = true;
  MouseButton button = NoButton;
  unsigned char key;
  int x, y;
  SDL_Event event;
  int modifiers = 0;
  static unsigned int stimer;

  //Ensure window visible for interaction
  show();

  // Enter event loop processing
  while ( !quitProgram )
  {
    // Check for events
    // Delay redisplay & resize until event queue empty
    if (SDL_PollEvent(&event) == 0)
    {
      // Resize window
      if (resized)
      {
        if (stimer < SDL_GetTicks())
        {
          // Create in new dimensions
          resized = false;
          open(width, height);
          redisplay = true;
        }
        else
          continue;   //Cycle until timer runs out
      }

      if (redisplay)
      {
        // Redraw Viewer (Call virtual to display)
        display();
        redisplay = false;
      }

      // Wait for next event
      SDL_WaitEvent( &event );
    }

    //Save shift states
    modifiers = SDL_GetModState();
    keyState.shift = (modifiers & KMOD_SHIFT);
    keyState.ctrl = (modifiers & KMOD_CTRL);
    keyState.alt = (modifiers & KMOD_ALT);

    // Process event
    switch (event.type)
    {
    case SDL_QUIT:
      quitProgram = true;
      break;
    case SDL_VIDEORESIZE:
      //Adjust viewport metrics etc...
      resize(event.resize.w, event.resize.h);
      resized = true;
      //Start timer to wait for sizing events to cease before calling actual context resize
      stimer = SDL_GetTicks() + 200;
      break;
    case SDL_KEYDOWN:
      //Pass keystrokes on KEYDOWN only, char info not provided by SDL on KEYUP
      key = event.key.keysym.unicode;
      if (!key)
      {
        int code = (int)event.key.keysym.sym;
        if (code == SDLK_KP8 || code == SDLK_UP) key = KEY_UP;
        if (code == SDLK_KP2 || code == SDLK_DOWN) key = KEY_DOWN;
        if (code == SDLK_KP4 || code == SDLK_LEFT) key = KEY_LEFT;
        if (code == SDLK_KP6 || code == SDLK_RIGHT) key = KEY_RIGHT;
        if (code == SDLK_KP9 || code == SDLK_PAGEUP) key = KEY_PAGEUP;
        if (code == SDLK_KP3 || code == SDLK_PAGEDOWN) key = KEY_PAGEDOWN;
        if (code == SDLK_KP7 || code == SDLK_HOME) key = KEY_HOME;
        if (code == SDLK_KP1 || code == SDLK_END) key = KEY_END;
        //key = (unsigned char)code;
        if (!key) continue;
      }
      SDL_GetMouseState(&x, &y);
      if (keyPress(key, x, y)) redisplay = true;
      break;
    case SDL_MOUSEMOTION:
      if (mouseState)
      {
        mouseMove(event.motion.x, event.motion.y);
        redisplay = true;
      }
      break;
    case SDL_MOUSEBUTTONDOWN:
      button = (MouseButton)event.button.button;
      // XOR state of three mouse buttons to the mouseState variable
      if (button <= RightButton) mouseState ^= (int)pow(2.0,button);
      mousePress( button, true, event.button.x, event.button.y);
      break;
    case SDL_MOUSEBUTTONUP:
      mouseState = 0;
      button = (MouseButton)event.button.button;
      mousePress( button, false, event.button.x, event.button.y);
      redisplay = true;
      break;
    case SDL_USEREVENT:
      // Timer event
      redisplay = true;
      break;
    case SDL_ACTIVEEVENT:
      if (event.active.state == SDL_APPACTIVE && event.active.gain == 1)   // Restored from icon
        redisplay = true;
      break;
    case SDL_VIDEOEXPOSE:
      redisplay = true;   // Repaint
      break;
    }
  }
}
示例#16
0
文件: main.cpp 项目: ptitSeb/f1spirit
int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    LPSTR lpCmdLine, int nCmdShow)
{
#else
int main(int argc, char** argv) {
#endif

	SDL_Surface *screen_sfc;
	F1SpiritApp *game;
	KEYBOARDSTATE *k;

	int time, act_time;
	SDL_Event event;
	bool quit = false;
	bool need_to_redraw = true;

#ifdef F1SPIRIT_DEBUG_MESSAGES

	output_debug_message("Application started\n");
#endif
#ifdef HAVE_GLES
	fullscreen = true;
#endif
	screen_sfc = initialization((fullscreen ? SDL_FULLSCREEN : 0));

	if (screen_sfc == 0)
		return 0;

	k = new KEYBOARDSTATE();

	game = new F1SpiritApp();

	#if 0//ndef HAVE_GLES
	// why recreating the context ???
	if (fullscreen) {
	#ifdef HAVE_GLES
		EGL_Close();
		screen_sfc = SDL_SetVideoMode((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y, COLOUR_DEPTH, (fullscreen ? SDL_FULLSCREEN : 0));
		EGL_Open((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y);
	#else
		screen_sfc = SDL_SetVideoMode((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y, COLOUR_DEPTH, SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : 0));
	#endif
		SDL_WM_SetCaption(application_name, 0);
		SDL_ShowCursor(SDL_DISABLE);
		reload_textures++;

	#ifndef HAVE_GLES
		SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
		SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
		SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
		SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
	#endif
	} 
	#endif

	time = init_time = SDL_GetTicks();
	
	IMG_Init(IMG_INIT_JPG|IMG_INIT_PNG);

	while (!quit) {
		while ( SDL_PollEvent( &event ) ) {
			switch ( event.type ) {
					/* Keyboard event */

				case SDL_KEYDOWN:
#ifdef __APPLE__

					if (event.key.keysym.sym == SDLK_q) {
						SDLMod modifiers;
						modifiers = SDL_GetModState();

						if ((modifiers &KMOD_META) != 0) {
							quit = true;
						}
					}

#else
					if (event.key.keysym.sym == SDLK_F12) {
						quit = true;
					} 

#endif
					if (event.key.keysym.sym == SDLK_F10) {
						game->save_configuration("f1spirit.cfg");
						game->load_configuration("f1spirit.cfg");
					} 

#ifdef _WIN32
					if (event.key.keysym.sym == SDLK_F4) {
						SDLMod modifiers;

						modifiers = SDL_GetModState();

						if ((modifiers&KMOD_ALT) != 0)
							quit = true;
					} 

#endif
#ifdef __APPLE__
					if (event.key.keysym.sym == SDLK_f) {
						SDLMod modifiers;

						modifiers = SDL_GetModState();

						if ((modifiers&KMOD_META) != 0) {
							/* Toggle FULLSCREEN mode: */
							if (fullscreen)
								fullscreen = false;
							else
								fullscreen = true;

							screen_sfc = SDL_SetVideoMode((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y, COLOUR_DEPTH, SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : 0));

							calcMinMax((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y);

							SDL_WM_SetCaption(application_name, 0);

							SDL_ShowCursor(SDL_DISABLE);

							reload_textures++;

							SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);

							SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);

							SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);

							SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
						}
					}

#else
					if (event.key.keysym.sym == SDLK_RETURN) {
						SDLMod modifiers;

						modifiers = SDL_GetModState();

						if ((modifiers&KMOD_ALT) != 0) {
							/* Toggle FULLSCREEN mode: */
							if (fullscreen)
								fullscreen = false;
							else
								fullscreen = true;
							#ifndef HAVE_GLES

							#ifdef HAVE_GLES
							EGL_Close();
							screen_sfc = SDL_SetVideoMode((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y, COLOUR_DEPTH, SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : 0));
							EGL_Open((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y);
							#else
							screen_sfc = SDL_SetVideoMode((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y, COLOUR_DEPTH, SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : 0));
							#endif

							calcMinMax((fullscreen)?desktopW:SCREEN_X, (fullscreen)?desktopH:SCREEN_Y);
							
							SDL_WM_SetCaption(application_name, 0);

							SDL_ShowCursor(SDL_DISABLE);

							reload_textures++;

							#ifndef HAVE_GLES
							SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
							SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
							SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
							SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
							SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
							SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
							#endif
							#endif
						}
					}

#endif

					if (event.key.keysym.sym == SDLK_f) {
						SDLMod modifiers;

						modifiers = SDL_GetModState();

						if ((modifiers&KMOD_ALT) != 0) {
							/* toggle FPS mode: */
							if (show_fps)
								show_fps = false;
							else
								show_fps = true;
						} 
					} 

					/* Keyboard event */
					SDL_keysym *ks;

					ks = new SDL_keysym();

					*ks = event.key.keysym;

					k->keyevents.Add(ks);

					break;

					/* SDL_QUIT event (window close) */

				case SDL_QUIT:
					quit = true;

					break;
			} 
		} 

		act_time = SDL_GetTicks();

		if (act_time - time >= REDRAWING_PERIOD) 
		{
			int max_frame_step = 10;
			/*
			   frames_per_sec_tmp+=1;
			   if ((act_time-init_time)>=1000) {
			    frames_per_sec=frames_per_sec_tmp;
			    frames_per_sec_tmp=0;
			    init_time=act_time;
			   } // if
			*/
			// On PANDORA, let's target 25 fps...
			int min_frame=1;
			#ifdef PANDORA
			min_frame=2;
			#endif

			do {
				time += REDRAWING_PERIOD;

				if ((act_time - time) > 10*REDRAWING_PERIOD)
					time = act_time;

				/* cycle */
				k->cycle();

				if (!game->cycle(k))
					quit = true;

				need_to_redraw = true;

				k->keyevents.Delete();

				act_time = SDL_GetTicks();

				max_frame_step--;
				min_frame--;
			} while (((act_time - time >= REDRAWING_PERIOD) && (max_frame_step > 0)) || (min_frame > 0));

		} 

		/* Redraw */
		if (need_to_redraw) {
			game->draw();
			need_to_redraw = false;
			frames_per_sec_tmp += 1;
		} 

		if ((act_time - init_time) >= 1000) {
			frames_per_sec = frames_per_sec_tmp;
			frames_per_sec_tmp = 0;
			init_time = act_time;
		} 

		#ifndef PANDORA
		SDL_Delay(1);
		#endif

	} 


	delete k;

	k = 0;

	delete game;

	game = 0;

	Stop_playback();

	finalization();

#ifdef F1SPIRIT_DEBUG_MESSAGES

	output_debug_message("Application finished\n");

	close_debug_messages();

#endif

	return 0;
} /* main */
示例#17
0
bool IN_IsNumLockDown() {
    return SDL_GetModState() & KMOD_NUM;
}
示例#18
0
文件: main.cpp 项目: andyfriesen/ika
void Engine::CheckMessages() {
    CDEBUG("checkmessages");

    SDL_Event event;

    while (SDL_PollEvent(&event)) {
        switch (event.type) {
            case SDL_KEYDOWN: {
                the<Input>()->KeyDown(event.key.keysym.sym);
                // bottom line screenshot if F11 is pressed
                //if (event.key.keysym.sym == SDLK_F11 && event.key.state == SDL_PRESSED)
                //    ScreenShot();

                // Alt-F4: Quit.  Now.
                if (event.key.keysym.sym == SDLK_F4 &&
                    (SDL_GetModState() & (KMOD_LALT | KMOD_RALT))) {
                    Shutdown();
                    exit(0);
                }
                break;
            }

            case SDL_KEYUP: {
                the<Input>()->KeyUp(event.key.keysym.sym);
                break;
            }

            case SDL_JOYAXISMOTION: {
                the<Input>()->JoyAxisMove(event.jaxis.which, event.jaxis.axis, event.jaxis.value);
                break;
            }

            case SDL_JOYBUTTONDOWN:
            case SDL_JOYBUTTONUP: {
                the<Input>()->JoyButtonChange(event.jbutton.which, event.jbutton.button, event.jbutton.state == SDL_PRESSED);
                break;
            }

            case SDL_MOUSEBUTTONDOWN: {
                the<Input>()->MouseButtonChange(event.button.button, true);
                break;
            }

            case SDL_MOUSEBUTTONUP: {
                the<Input>()->MouseButtonChange(event.button.button, false);
                break;
            }

            case SDL_MOUSEMOTION: {
                the<Input>()->MouseMoved(event.motion.x, event.motion.y);
                break;
            }

            case SDL_QUIT: {
                Shutdown();
                exit(0);
                break;
            }

            default: {
                break;
            }
        }
    }
}
示例#19
0
//
// I_GetEvent
//
void I_GetEvent (void)
{
   event_t event;
   event_t mouseevent = {ev_mouse, 0, 0, 0};
   static int mbuttons = 0;
   int sendmouseevent = 0;

   SDL_Event ev;
   
   if (!(SDL_GetAppState()&SDL_APPINPUTFOCUS) && havefocus)
   {
      havefocus = false;
      UngrabMouse();
      SetCursorState(true);
   }
   else if((SDL_GetAppState()&SDL_APPINPUTFOCUS) && !havefocus)
   {
      havefocus = true;
      if(!mousepaused)
         I_ResumeMouse();
   }

   while(SDL_PollEvent(&ev))
   {
      event.data1 = event.data2 = event.data3 = 0;
      switch(ev.type)
      {
         case SDL_QUIT:
            AddCommandString("quit");
            break;
         case SDL_KEYDOWN:
            event.type = ev_keydown;
            event.data1 = ev.key.keysym.sym;
            if(event.data1 >= SDLK_KP0 && event.data1 <= SDLK_KP9)
               event.data2 = event.data3 = '0' + (event.data1 - SDLK_KP0);
            else if(event.data1 == SDLK_KP_PERIOD)
               event.data2 = event.data3 = '.';
            else if(event.data1 == SDLK_KP_DIVIDE)
               event.data2 = event.data3 = '/';
            else if(event.data1 == SDLK_KP_ENTER)
               event.data2 = event.data3 = '\r';
            else if ( (ev.key.keysym.unicode & 0xFF80) == 0 ) 
               event.data2 = event.data3 = ev.key.keysym.unicode;
            else
               event.data2 = event.data3 = 0;

#ifdef WIN32
            // SoM: Ignore the tab portion of alt-tab presses
            if(event.data1 == SDLK_TAB && SDL_GetModState() & (KMOD_LALT | KMOD_RALT))
               event.data1 = event.data2 = event.data3 = 0;
            else
#endif
            D_PostEvent(&event);
            break;
         case SDL_KEYUP:
            event.type = ev_keyup;
            event.data1 = ev.key.keysym.sym;
            if ( (ev.key.keysym.unicode & 0xFF80) == 0 ) 
               event.data2 = event.data3 = ev.key.keysym.unicode;
            else
               event.data2 = event.data3 = 0;
            D_PostEvent(&event);
            break;
         case SDL_MOUSEMOTION:
            if(flushmouse)
            {
               flushmouse = false;
               break;
            }
			// denis - ignore artificially inserted events (see SDL_WarpMouse below)
			if(ev.motion.x == screen->width/2 &&
			   ev.motion.y == screen->height/2)
			{
				break;
			}
            mouseevent.data2 += AccelerateMouse(ev.motion.xrel);
            mouseevent.data3 -= AccelerateMouse(ev.motion.yrel);
            sendmouseevent = 1;
            break;
         case SDL_MOUSEBUTTONDOWN:
            if(nomouse)
		break;
            event.type = ev_keydown;
            if(ev.button.button == SDL_BUTTON_LEFT)
            {
               event.data1 = KEY_MOUSE1;
               mbuttons |= 1;
            }
            else if(ev.button.button == SDL_BUTTON_RIGHT)
            {
               event.data1 = KEY_MOUSE2;
               mbuttons |= 2;
            }
            else if(ev.button.button == SDL_BUTTON_MIDDLE)
            {
               event.data1 = KEY_MOUSE3;
               mbuttons |= 4;
            }
            else if(ev.button.button == SDL_BUTTON_WHEELUP)
               event.data1 = KEY_MWHEELUP;
            else if(ev.button.button == SDL_BUTTON_WHEELDOWN)
               event.data1 = KEY_MWHEELDOWN;

			D_PostEvent(&event);
            break; 
         case SDL_MOUSEBUTTONUP:
            if(nomouse)
		break;
            event.type = ev_keyup;
            if(ev.button.button == SDL_BUTTON_LEFT)
            {
               event.data1 = KEY_MOUSE1;
               mbuttons &= ~1;
            }
            else if(ev.button.button == SDL_BUTTON_RIGHT)
            {
               event.data1 = KEY_MOUSE2;
               mbuttons &= ~2;
            }
            else if(ev.button.button == SDL_BUTTON_MIDDLE)
            {
               event.data1 = KEY_MOUSE3;
               mbuttons &= ~4;
            }
            else if(ev.button.button == SDL_BUTTON_WHEELUP)
               event.data1 = KEY_MWHEELUP;
            else if(ev.button.button == SDL_BUTTON_WHEELDOWN)
               event.data1 = KEY_MWHEELDOWN;

			D_PostEvent(&event);
            break;
      };
   }

   if(!nomouse)
   {
       if(sendmouseevent)
       {
          mouseevent.data1 = mbuttons;
          D_PostEvent(&mouseevent);
       }
       
       if(mousegrabbed && screen)
       {
          SDL_WarpMouse(screen->width/ 2, screen->height / 2);
       }
   }
}
示例#20
0
 bool InputWrapper::isModifierHeld(SDL_Keymod mod)
 {
     return SDL_GetModState() & mod;
 }
示例#21
0
// Handle a released key
void ManMachineInterface::HandleKeyReleased(const Key_t &key)
{
  PressedKeys[key] = false;
  // Here we manage only actions which are activated on KEY_RELEASED event.

  { // Managing keys related to interface (no game interaction)
    // Always available
    switch(key){
      // Managing interface
    case KEY_HELP:
      Game::GetInstance()->UserAsksForHelpMenu();
      return;
    case KEY_QUIT:
    case KEY_PAUSE:
      Game::GetInstance()->UserAsksForMenu();
      return;
    case KEY_FULLSCREEN:
      AppWarmux::GetInstance()->video->ToggleFullscreen();
      return;
    case KEY_CHAT:
      if(Network::IsConnected())
        Game::GetInstance()->chatsession.ShowInput();
      return;
    case KEY_CENTER:
      Camera::GetInstance()->CenterOnActiveCharacter();
      return;
    case KEY_TOGGLE_INTERFACE:
      Interface::GetInstance()->EnableDisplay(!Interface::GetInstance()->IsDisplayed());
      return;
    case KEY_MINIMAP_FROM_GAME:
      Interface::GetInstance()->ToggleMinimap();
      return;
    case KEY_MENU_OPTIONS_FROM_GAME: {
      OptionMenu options_menu;
      options_menu.Run();
      return;
    }
    case KEY_MOVE_CAMERA_RIGHT:
      Camera::GetInstance()->RemoveLRMoveIntention(INTENTION_MOVE_RIGHT);
      return;
    case KEY_MOVE_CAMERA_LEFT:
      Camera::GetInstance()->RemoveLRMoveIntention(INTENTION_MOVE_LEFT);
      return;
    case KEY_MOVE_CAMERA_UP:
      Camera::GetInstance()->RemoveUDMoveIntention(INTENTION_MOVE_UP);
      return;
    case KEY_MOVE_CAMERA_DOWN:
      Camera::GetInstance()->RemoveUDMoveIntention(INTENTION_MOVE_DOWN);
      return;
    case KEY_DECREASE_MINIMAP:
      Interface::GetInstance()->MinimapSizeDelta(1);
      return;
    case KEY_INCREASE_MINIMAP:
      Interface::GetInstance()->MinimapSizeDelta(-1);
      return;
    case KEY_DECREASE_VOLUME:
      {
        Config *cfg = Config::GetInstance();
        int volume = cfg->GetVolumeMusic() - 5;
        if (volume > 0) {
          cfg->SetVolumeMusic(volume);
        } else {
          cfg->SetVolumeMusic(0);
          JukeBox::GetInstance()->ActiveMusic(false);
        }
        volume = cfg->GetVolumeEffects() - 5;
        if (volume > 0) {
          cfg->SetVolumeEffects(volume);
        } else {
          cfg->SetVolumeEffects(0);
          JukeBox::GetInstance()->ActiveEffects(false);
        }
        return;
      }
    case KEY_INCREASE_VOLUME:
      {
        Config *cfg = Config::GetInstance();
        int max_volume = cfg->GetMaxVolume();
        int volume = cfg->GetVolumeMusic() + 5;
        if (volume < max_volume) {
          cfg->SetVolumeMusic(volume);
        } else {
          cfg->SetVolumeMusic(max_volume);
        }
        JukeBox::GetInstance()->ActiveMusic(true);

        volume = cfg->GetVolumeEffects() + 5;
        if (volume < max_volume) {
          cfg->SetVolumeEffects(volume);
        } else {
          cfg->SetVolumeEffects(max_volume);
        }
        JukeBox::GetInstance()->ActiveEffects(true);
        return;
      }
    default:
      break;
    }
  }

  // Managing shoot key
  // Drop bonus box or medkit when outside a turn
  // Shoot when in turn
  if (key == KEY_SHOOT) {

    if (Game::GetInstance()->ReadState() == Game::END_TURN) {
      Game::GetInstance()->RequestBonusBoxDrop();
    } else if (Game::GetInstance()->ReadState() == Game::PLAYING &&
               ActiveTeam().IsLocalHuman() &&
               !ActiveCharacter().IsDead()) {
      ActiveTeam().AccessWeapon().HandleKeyReleased_Shoot();
    }
    return;
  }

  { // Managing keys related to character moves
    // Available only when local
    if (!ActiveTeam().IsLocalHuman()) return;
    if (ActiveCharacter().IsDead()) return;
    if (Game::GetInstance()->ReadState() == Game::END_TURN) return;

    switch (key) {
      case KEY_MOVE_RIGHT:
        ActiveCharacter().HandleKeyReleased_MoveRight(false);
        break;
      case KEY_MOVE_RIGHT_SLOWLY:
        ActiveCharacter().HandleKeyReleased_MoveRight(true);
        break;
      case KEY_MOVE_LEFT:
        ActiveCharacter().HandleKeyReleased_MoveLeft(false);
        break;
      case KEY_MOVE_LEFT_SLOWLY:
        ActiveCharacter().HandleKeyReleased_MoveLeft(true);
        break;
      case KEY_UP:
        ActiveCharacter().HandleKeyReleased_Up(false);
        break;
      case KEY_UP_SLOWLY:
        ActiveCharacter().HandleKeyReleased_Up(true);
        break;
      case KEY_DOWN:
        ActiveCharacter().HandleKeyReleased_Down(false);
        break;
      case KEY_DOWN_SLOWLY:
        ActiveCharacter().HandleKeyReleased_Down(true);
        break;
      case KEY_JUMP:
        ActiveCharacter().HandleKeyReleased_Jump();
        break;
      case KEY_HIGH_JUMP:
        ActiveCharacter().HandleKeyReleased_HighJump();
        break;
      case KEY_BACK_JUMP:
        ActiveCharacter().HandleKeyReleased_BackJump();
        break;
      default:
        if (Game::GetInstance()->ReadState() == Game::HAS_PLAYED)
          return;
        break;
    }
    if (Game::GetInstance()->ReadState() == Game::PLAYING) {
      switch (key) {

      case KEY_MOVE_RIGHT:
        ActiveTeam().AccessWeapon().HandleKeyReleased_MoveRight(false);
        return;
      case KEY_MOVE_RIGHT_SLOWLY:
        ActiveTeam().AccessWeapon().HandleKeyReleased_MoveRight(true);
        return;
      case KEY_MOVE_LEFT:
        ActiveTeam().AccessWeapon().HandleKeyReleased_MoveLeft(false);
        return;
      case KEY_MOVE_LEFT_SLOWLY:
        ActiveTeam().AccessWeapon().HandleKeyReleased_MoveLeft(true);
        return;
      case KEY_UP:
        ActiveTeam().AccessWeapon().HandleKeyReleased_Up(false);
        return;
      case KEY_UP_SLOWLY:
        ActiveTeam().AccessWeapon().HandleKeyReleased_Up(true);
        return;
      case KEY_DOWN:
        ActiveTeam().AccessWeapon().HandleKeyReleased_Down(false);
        return;
      case KEY_DOWN_SLOWLY:
        ActiveTeam().AccessWeapon().HandleKeyReleased_Down(true);
        return;
      case KEY_JUMP:
        ActiveTeam().AccessWeapon().HandleKeyReleased_Jump();
        return;
      case KEY_HIGH_JUMP:
        ActiveTeam().AccessWeapon().HandleKeyReleased_HighJump();
        return;
      case KEY_BACK_JUMP:
        ActiveTeam().AccessWeapon().HandleKeyReleased_BackJump();
        return;

        // Shoot key
      case KEY_SHOOT:
        ActiveTeam().AccessWeapon().HandleKeyReleased_Shoot();
        return;

        // Other keys usefull for weapons
      case KEY_WEAPON_1:
        ActiveTeam().AccessWeapon().HandleKeyReleased_Num1();
        return;
      case KEY_WEAPON_2:
        ActiveTeam().AccessWeapon().HandleKeyReleased_Num2();
        return;
      case KEY_WEAPON_3:
        ActiveTeam().AccessWeapon().HandleKeyReleased_Num3();
        return;
      case KEY_WEAPON_4:
        ActiveTeam().AccessWeapon().HandleKeyReleased_Num4();
        return;
      case KEY_WEAPON_5:
        ActiveTeam().AccessWeapon().HandleKeyReleased_Num5();
        return;
      case KEY_WEAPON_6:
        ActiveTeam().AccessWeapon().HandleKeyReleased_Num6();
        return;
      case KEY_WEAPON_7:
        ActiveTeam().AccessWeapon().HandleKeyReleased_Num7();
        return;
      case KEY_WEAPON_8:
        ActiveTeam().AccessWeapon().HandleKeyReleased_Num8();
        return;
      case KEY_WEAPON_9:
        ActiveTeam().AccessWeapon().HandleKeyReleased_Num9();
        return;
      case KEY_WEAPON_LESS:
        ActiveTeam().AccessWeapon().HandleKeyReleased_Less();
        return;
      case KEY_WEAPON_MORE:
        ActiveTeam().AccessWeapon().HandleKeyReleased_More();
        return;
      default:
        break;
      }
    }
  }

  { // Managing keys related to change of character or weapon

    if (Game::GetInstance()->ReadState() != Game::PLAYING ||
        !ActiveTeam().GetWeapon().CanChangeWeapon() ||
        !ActiveTeam().IsLocalHuman())
      return;

    Weapon::category_t weapon_sort = Weapon::INVALID;

    switch(key) {

    case KEY_NEXT_CHARACTER:
      if (GameMode::GetInstance()->AllowCharacterSelection()) {
        SDLMod mod = SDL_GetModState();
        if (mod & KMOD_CTRL) {
          ActiveTeam().PreviousCharacter();
        } else {
          ActiveTeam().NextCharacter();
        }
        ActionHandler::GetInstance()->NewActionActiveCharacter();
      }
      return;

    case KEY_WEAPONS1:
      weapon_sort = Weapon::HEAVY;
      break;
    case KEY_WEAPONS2:
      weapon_sort = Weapon::RIFLE;
      break;
    case KEY_WEAPONS3:
      weapon_sort = Weapon::THROW;
      break;
    case KEY_WEAPONS4:
      weapon_sort = Weapon::SPECIAL;
      break;
    case KEY_WEAPONS5:
      weapon_sort = Weapon::DUEL;
      break;
    case KEY_WEAPONS6:
      weapon_sort = Weapon::MOVE;
      break;
    case KEY_WEAPONS7:
      weapon_sort = Weapon::TOOL;
      break;
    default:
      // Key not supported
      return;
    }

    if (weapon_sort != Weapon::INVALID && ActiveTeam().GetWeapon().CanChangeWeapon()) {
      Weapon::Weapon_type weapon;
      WeaponsList * weapons_list = Game::GetInstance()->GetWeaponsList();
      if (weapons_list->GetWeaponBySort(weapon_sort, weapon)) {
        ASSERT (weapon >= Weapon::FIRST && weapon <= Weapon::LAST);
        ActionHandler::GetInstance()->NewAction(new Action(Action::ACTION_PLAYER_CHANGE_WEAPON, weapon));
      }
    }
  }
}
示例#22
0
文件: sdl_v.cpp 项目: tony/openttd
int VideoDriver_SDL::PollEvent()
{
	SDL_Event ev;

	if (!SDL_CALL SDL_PollEvent(&ev)) return -2;

	switch (ev.type) {
		case SDL_MOUSEMOTION:
			if (_cursor.UpdateCursorPosition(ev.motion.x, ev.motion.y, true)) {
				SDL_CALL SDL_WarpMouse(_cursor.pos.x, _cursor.pos.y);
			}
			HandleMouseEvents();
			break;

		case SDL_MOUSEBUTTONDOWN:
			if (_rightclick_emulate && SDL_CALL SDL_GetModState() & KMOD_CTRL) {
				ev.button.button = SDL_BUTTON_RIGHT;
			}

			switch (ev.button.button) {
				case SDL_BUTTON_LEFT:
					_left_button_down = true;
					break;

				case SDL_BUTTON_RIGHT:
					_right_button_down = true;
					_right_button_clicked = true;
					break;

				case SDL_BUTTON_WHEELUP:   _cursor.wheel--; break;
				case SDL_BUTTON_WHEELDOWN: _cursor.wheel++; break;

				default: break;
			}
			HandleMouseEvents();
			break;

		case SDL_MOUSEBUTTONUP:
			if (_rightclick_emulate) {
				_right_button_down = false;
				_left_button_down = false;
				_left_button_clicked = false;
			} else if (ev.button.button == SDL_BUTTON_LEFT) {
				_left_button_down = false;
				_left_button_clicked = false;
			} else if (ev.button.button == SDL_BUTTON_RIGHT) {
				_right_button_down = false;
			}
			HandleMouseEvents();
			break;

		case SDL_ACTIVEEVENT:
			if (!(ev.active.state & SDL_APPMOUSEFOCUS)) break;

			if (ev.active.gain) { // mouse entered the window, enable cursor
				_cursor.in_window = true;
			} else {
				UndrawMouseCursor(); // mouse left the window, undraw cursor
				_cursor.in_window = false;
			}
			break;

		case SDL_QUIT:
			HandleExitGameRequest();
			break;

		case SDL_KEYDOWN: // Toggle full-screen on ALT + ENTER/F
			if ((ev.key.keysym.mod & (KMOD_ALT | KMOD_META)) &&
					(ev.key.keysym.sym == SDLK_RETURN || ev.key.keysym.sym == SDLK_f)) {
				ToggleFullScreen(!_fullscreen);
			} else {
				WChar character;
				uint keycode = ConvertSdlKeyIntoMy(&ev.key.keysym, &character);
				HandleKeypress(keycode, character);
			}
			break;

		case SDL_VIDEORESIZE: {
			int w = max(ev.resize.w, 64);
			int h = max(ev.resize.h, 64);
			CreateMainSurface(w, h);
			break;
		}
		case SDL_VIDEOEXPOSE: {
			/* Force a redraw of the entire screen. Note
			 * that SDL 1.2 seems to do this automatically
			 * in most cases, but 1.3 / 2.0 does not. */
		        _num_dirty_rects = MAX_DIRTY_RECTS + 1;
			break;
		}
	}
	return -1;
}
示例#23
0
/**
 * \brief Returns whether the SHIFT key is currently down.
 *
 * There is no distinction between the right and left SHIFT keys in this function.
 *
 * \return true if the SHIFT key is currently down
 */
bool InputEvent::is_shift_down() {

  SDL_Keymod mod = SDL_GetModState();
  return mod & KMOD_SHIFT;
}
示例#24
0
文件: sdl_v.cpp 项目: tony/openttd
void VideoDriver_SDL::MainLoop()
{
	uint32 cur_ticks = SDL_CALL SDL_GetTicks();
	uint32 last_cur_ticks = cur_ticks;
	uint32 next_tick = cur_ticks + MILLISECONDS_PER_TICK;
	uint32 mod;
	int numkeys;
	Uint8 *keys;

	CheckPaletteAnim();

	if (_draw_threaded) {
		/* Initialise the mutex first, because that's the thing we *need*
		 * directly in the newly created thread. */
		_draw_mutex = ThreadMutex::New();
		if (_draw_mutex == NULL) {
			_draw_threaded = false;
		} else {
			_draw_mutex->BeginCritical();
			_draw_continue = true;

			_draw_threaded = ThreadObject::New(&DrawSurfaceToScreenThread, NULL, &_draw_thread, "ottd:draw-sdl");

			/* Free the mutex if we won't be able to use it. */
			if (!_draw_threaded) {
				_draw_mutex->EndCritical();
				delete _draw_mutex;
				_draw_mutex = NULL;
			} else {
				/* Wait till the draw mutex has started itself. */
				_draw_mutex->WaitForSignal();
			}
		}
	}

	DEBUG(driver, 1, "SDL: using %sthreads", _draw_threaded ? "" : "no ");

	for (;;) {
		uint32 prev_cur_ticks = cur_ticks; // to check for wrapping
		InteractiveRandom(); // randomness

		while (PollEvent() == -1) {}
		if (_exit_game) break;

		mod = SDL_CALL SDL_GetModState();
#if SDL_VERSION_ATLEAST(1, 3, 0)
		keys = SDL_CALL SDL_GetKeyboardState(&numkeys);
#else
		keys = SDL_CALL SDL_GetKeyState(&numkeys);
#endif
#if defined(_DEBUG)
		if (_shift_pressed)
#else
		/* Speedup when pressing tab, except when using ALT+TAB
		 * to switch to another application */
#if SDL_VERSION_ATLEAST(1, 3, 0)
		if (keys[SDL_SCANCODE_TAB] && (mod & KMOD_ALT) == 0)
#else
		if (keys[SDLK_TAB] && (mod & KMOD_ALT) == 0)
#endif /* SDL_VERSION_ATLEAST(1, 3, 0) */
#endif /* defined(_DEBUG) */
		{
			if (!_networking && _game_mode != GM_MENU) _fast_forward |= 2;
		} else if (_fast_forward & 2) {
			_fast_forward = 0;
		}

		cur_ticks = SDL_CALL SDL_GetTicks();
		if (cur_ticks >= next_tick || (_fast_forward && !_pause_mode) || cur_ticks < prev_cur_ticks) {
			_realtime_tick += cur_ticks - last_cur_ticks;
			last_cur_ticks = cur_ticks;
			next_tick = cur_ticks + MILLISECONDS_PER_TICK;

			bool old_ctrl_pressed = _ctrl_pressed;

			_ctrl_pressed  = !!(mod & KMOD_CTRL);
			_shift_pressed = !!(mod & KMOD_SHIFT);

			/* determine which directional keys are down */
			_dirkeys =
#if SDL_VERSION_ATLEAST(1, 3, 0)
				(keys[SDL_SCANCODE_LEFT]  ? 1 : 0) |
				(keys[SDL_SCANCODE_UP]    ? 2 : 0) |
				(keys[SDL_SCANCODE_RIGHT] ? 4 : 0) |
				(keys[SDL_SCANCODE_DOWN]  ? 8 : 0);
#else
				(keys[SDLK_LEFT]  ? 1 : 0) |
				(keys[SDLK_UP]    ? 2 : 0) |
				(keys[SDLK_RIGHT] ? 4 : 0) |
				(keys[SDLK_DOWN]  ? 8 : 0);
#endif
			if (old_ctrl_pressed != _ctrl_pressed) HandleCtrlChanged();

			/* The gameloop is the part that can run asynchronously. The rest
			 * except sleeping can't. */
			if (_draw_mutex != NULL) _draw_mutex->EndCritical();

			GameLoop();

			if (_draw_mutex != NULL) _draw_mutex->BeginCritical();

			UpdateWindows();
			_local_palette = _cur_palette;
		} else {
			/* Release the thread while sleeping */
			if (_draw_mutex != NULL) _draw_mutex->EndCritical();
			CSleep(1);
			if (_draw_mutex != NULL) _draw_mutex->BeginCritical();

			NetworkDrawChatMessage();
			DrawMouseCursor();
		}

		/* End of the critical part. */
		if (_draw_mutex != NULL && !HasModalProgress()) {
			_draw_mutex->SendSignal();
		} else {
			/* Oh, we didn't have threads, then just draw unthreaded */
			CheckPaletteAnim();
			DrawSurfaceToScreen();
		}
	}

	if (_draw_mutex != NULL) {
		_draw_continue = false;
		/* Sending signal if there is no thread blocked
		 * is very valid and results in noop */
		_draw_mutex->SendSignal();
		_draw_mutex->EndCritical();
		_draw_thread->Join();

		delete _draw_mutex;
		delete _draw_thread;

		_draw_mutex = NULL;
		_draw_thread = NULL;
	}
}
示例#25
0
/**
 * \brief Returns whether the ALT key is currently down.
 *
 * There is no distinction between the right and left ALT keys in this function.
 *
 * \return true if the ALT key is currently down
 */
bool InputEvent::is_alt_down() {

  SDL_Keymod mod = SDL_GetModState();
  return mod & KMOD_ALT;
}
示例#26
0
u16 LocalEvent::KeyMod(void) const
{
    return SDL_GetModState();
}
示例#27
0
/**
 * \brief Returns whether the num lock key is currently active.
 * \return \c true if the num lock key is currently active.
 */
bool InputEvent::is_num_lock_on() {

  SDL_Keymod mod = SDL_GetModState();
  return mod & KMOD_NUM;
}
示例#28
0
int Projectile::calculateTrajectory(double accuracy, Position originVoxel)
{
	Tile *targetTile = _save->getTile(_action.target);
	BattleUnit *bu = _action.actor;
	
	int test = _save->getTileEngine()->calculateLine(originVoxel, _targetVoxel, false, &_trajectory, bu);
	if (test != V_EMPTY &&
		!_trajectory.empty() &&
		_action.actor->getFaction() == FACTION_PLAYER &&
		_action.autoShotCounter == 1 &&
		((SDL_GetModState() & KMOD_CTRL) == 0 || !Options::forceFire) &&
		_save->getBattleGame()->getPanicHandled() &&
		_action.type != BA_LAUNCH)
	{
		Position hitPos = Position(_trajectory.at(0).x/16, _trajectory.at(0).y/16, _trajectory.at(0).z/24);
		if (test == V_UNIT && _save->getTile(hitPos) && _save->getTile(hitPos)->getUnit() == 0) //no unit? must be lower
		{
			hitPos = Position(hitPos.x, hitPos.y, hitPos.z-1);
		}

		if (hitPos != _action.target && _action.result == "")
		{
			if (test == V_NORTHWALL)
			{
				if (hitPos.y - 1 != _action.target.y)
				{
					_trajectory.clear();
					return V_EMPTY;
				}
			}
			else if (test == V_WESTWALL)
			{
				if (hitPos.x - 1 != _action.target.x)
				{
					_trajectory.clear();
					return V_EMPTY;
				}
			}
			else if (test == V_UNIT)
			{
				BattleUnit *hitUnit = _save->getTile(hitPos)->getUnit();
				BattleUnit *targetUnit = targetTile->getUnit();
				if (hitUnit != targetUnit)
				{
					_trajectory.clear();
					return V_EMPTY;
				}
			}
			else
			{
				_trajectory.clear();
				return V_EMPTY;
			}
		}
	}

	_trajectory.clear();

	bool extendLine = true;
	// even guided missiles drift, but how much is based on
	// the shooter's faction, rather than accuracy.
	if (_action.type == BA_LAUNCH)
	{
		if (_action.actor->getFaction() == FACTION_PLAYER)
		{
			accuracy = 0.60;
		}
		else
		{
			accuracy = 0.55;
		}
		extendLine = _action.waypoints.size() <= 1;
	}

	// apply some accuracy modifiers.
	// This will results in a new target voxel
	applyAccuracy(originVoxel, &_targetVoxel, accuracy, false, targetTile, extendLine);

	// finally do a line calculation and store this trajectory.
	return _save->getTileEngine()->calculateLine(originVoxel, _targetVoxel, true, &_trajectory, bu);
}
示例#29
0
//
// I_GetEvent
//
void I_GetEvent (void)
{
   event_t event;
   event_t mouseevent = {ev_mouse, 0, 0, 0};
   static int mbuttons = 0;
   int sendmouseevent = 0;

   SDL_Event ev;

	if (!havefocus)
		I_PauseMouse();
	else
	{
		I_ResumeMouse();
	}

   while(SDL_PollEvent(&ev))
   {
      event.data1 = event.data2 = event.data3 = 0;
      switch(ev.type)
      {
         case SDL_QUIT:
            AddCommandString("menu_quit");
            break;
         // Resizable window mode resolutions
         case SDL_VIDEORESIZE:
         {
             if (!mousegrabbed && !vid_fullscreen)
             {
                char Command[64];

                snprintf(Command, sizeof(Command), "vid_setmode %d %d", ev.resize.w, ev.resize.h);

                AddCommandString(Command);

                vid_defwidth.Set((float)ev.resize.w);
				vid_defheight.Set((float)ev.resize.h);
             }
         }
         break;

		case SDL_ACTIVEEVENT:
			// need to update our focus state
			UpdateFocus();
		break;

         case SDL_KEYDOWN:
            event.type = ev_keydown;
            event.data1 = ev.key.keysym.sym;

            if(event.data1 >= SDLK_KP0 && event.data1 <= SDLK_KP9)
               event.data2 = event.data3 = '0' + (event.data1 - SDLK_KP0);
            else if(event.data1 == SDLK_KP_PERIOD)
               event.data2 = event.data3 = '.';
            else if(event.data1 == SDLK_KP_DIVIDE)
               event.data2 = event.data3 = '/';
            else if(event.data1 == SDLK_KP_ENTER)
               event.data2 = event.data3 = '\r';
            else if ( (ev.key.keysym.unicode & 0xFF80) == 0 )
               event.data2 = event.data3 = ev.key.keysym.unicode;
            else
               event.data2 = event.data3 = 0;

#ifdef _XBOX
			// Fix for ENTER key on Xbox
            if(event.data1 == SDLK_RETURN)
               event.data2 = event.data3 = '\r';
#endif

#ifdef WIN32
            //HeX9109: Alt+F4 for cheats! Thanks Spleen
            if(event.data1 == SDLK_F4 && SDL_GetModState() & (KMOD_LALT | KMOD_RALT))
                AddCommandString("menu_quit");
            // SoM: Ignore the tab portion of alt-tab presses
            if(event.data1 == SDLK_TAB && SDL_GetModState() & (KMOD_LALT | KMOD_RALT))
               event.data1 = event.data2 = event.data3 = 0;
            else
#endif
         D_PostEvent(&event);
         break;

         case SDL_KEYUP:
            event.type = ev_keyup;
            event.data1 = ev.key.keysym.sym;
            if ( (ev.key.keysym.unicode & 0xFF80) == 0 )
               event.data2 = event.data3 = ev.key.keysym.unicode;
            else
               event.data2 = event.data3 = 0;
         D_PostEvent(&event);
         break;

         case SDL_MOUSEMOTION:
            if(flushmouse)
            {
               flushmouse = false;
               break;
            }
            if (!havefocus)
				break;
			// denis - ignore artificially inserted events (see SDL_WarpMouse below)
			if(ev.motion.x == screen->width/2 &&
			   ev.motion.y == screen->height/2)
			{
				break;
			}
            mouseevent.data2 += AccelerateMouse(ev.motion.xrel);
            mouseevent.data3 -= AccelerateMouse(ev.motion.yrel);
            sendmouseevent = 1;
         break;

         case SDL_MOUSEBUTTONDOWN:
            if(nomouse || !havefocus)
				break;
            event.type = ev_keydown;
            if(ev.button.button == SDL_BUTTON_LEFT)
            {
               event.data1 = KEY_MOUSE1;
               mbuttons |= 1;
            }
            else if(ev.button.button == SDL_BUTTON_RIGHT)
            {
               event.data1 = KEY_MOUSE2;
               mbuttons |= 2;
            }
            else if(ev.button.button == SDL_BUTTON_MIDDLE)
            {
               event.data1 = KEY_MOUSE3;
               mbuttons |= 4;
            }
            else if(ev.button.button == SDL_BUTTON_WHEELUP)
               event.data1 = KEY_MWHEELUP;
            else if(ev.button.button == SDL_BUTTON_WHEELDOWN)
               event.data1 = KEY_MWHEELDOWN;

		D_PostEvent(&event);
		break;

	case SDL_MOUSEBUTTONUP:
            if(nomouse || !havefocus)
				break;
            event.type = ev_keyup;
            if(ev.button.button == SDL_BUTTON_LEFT)
            {
               event.data1 = KEY_MOUSE1;
               mbuttons &= ~1;
            }
            else if(ev.button.button == SDL_BUTTON_RIGHT)
            {
               event.data1 = KEY_MOUSE2;
               mbuttons &= ~2;
            }
            else if(ev.button.button == SDL_BUTTON_MIDDLE)
            {
               event.data1 = KEY_MOUSE3;
               mbuttons &= ~4;
            }
            else if(ev.button.button == SDL_BUTTON_WHEELUP)
               event.data1 = KEY_MWHEELUP;
            else if(ev.button.button == SDL_BUTTON_WHEELDOWN)
               event.data1 = KEY_MWHEELDOWN;

		D_PostEvent(&event);
		break;
	case SDL_JOYBUTTONDOWN:
		if(ev.jbutton.which == joy_active)
		{
			event.type = ev_keydown;
			event.data1 = ev.jbutton.button + KEY_JOY1;
			event.data2 = event.data1;

			D_PostEvent(&event);
			break;
		}
	case SDL_JOYBUTTONUP:
		if(ev.jbutton.which == joy_active)
		{
			event.type = ev_keyup;
			event.data1 = ev.jbutton.button + KEY_JOY1;
			event.data2 = event.data1;

			D_PostEvent(&event);
			break;
		}
	case SDL_JOYAXISMOTION:
		if(ev.jaxis.which == joy_active)
		{
			event.type = ev_joystick;
			event.data1 = 0;
			event.data2 = ev.jaxis.axis;
			if( (ev.jaxis.value < JOY_DEADZONE) && (ev.jaxis.value > -JOY_DEADZONE) )
				event.data3 = 0;
			else
				event.data3 = ev.jaxis.value;

			D_PostEvent(&event);
			break;
		}
	case SDL_JOYHATMOTION:
		if(ev.jhat.which == joy_active)
		{
			// Each of these need to be tested because more than one can be pressed and a
			// unique event is needed for each
			if(ev.jhat.value & SDL_HAT_UP)
				RegisterJoystickEvent(&ev, SDL_HAT_UP);
			if(ev.jhat.value & SDL_HAT_RIGHT)
				RegisterJoystickEvent(&ev, SDL_HAT_RIGHT);
			if(ev.jhat.value & SDL_HAT_DOWN)
				RegisterJoystickEvent(&ev, SDL_HAT_DOWN);
			if(ev.jhat.value & SDL_HAT_LEFT)
				RegisterJoystickEvent(&ev, SDL_HAT_LEFT);

			break;
		}
      };
   }

   if(!nomouse)
   {
       if(sendmouseevent)
       {
          mouseevent.data1 = mbuttons;
          D_PostEvent(&mouseevent);
       }

       if(mousegrabbed && screen)
       {
          SDL_WarpMouse(screen->width/ 2, screen->height / 2);
       }
   }

   if(use_joystick)
       UpdateJoystickEvents();
}
示例#30
0
int Application::exec()
{
  bool done = false;
  while (!done)
  {
    SDL_Event e;
    if (SDL_WaitEvent(&e))
    {
      switch (e.type)
      {
      case SDL_WINDOWEVENT:
        {
          Widget *w = widgetByWindowId(e.window.windowID);
          switch (e.window.event)
          {
          case SDL_WINDOWEVENT_SHOWN:
            std::cout << "Window " << e.window.windowID << " shown" << std::endl;
            break;
          case SDL_WINDOWEVENT_HIDDEN:
            std::cout << "Window " << e.window.windowID << " hidden" << std::endl;
            break;
          case SDL_WINDOWEVENT_EXPOSED:
            {
              needUpdateWithoutRedraw_ = w;
              break;
            }
          case SDL_WINDOWEVENT_MOVED:
            break;
          case SDL_WINDOWEVENT_RESIZED:
            {
              w->resize(e.window.data1, e.window.data2);
#if __APPLE__==1
              SDL_RenderPresent(w->renderer_); // hack for MacOS X
#endif
              break;
            }
          case SDL_WINDOWEVENT_MINIMIZED:
            std::cout << "Window " << e.window.windowID << " minimized" << std::endl;
            break;
          case SDL_WINDOWEVENT_MAXIMIZED:
            std::cout << "Window " << e.window.windowID << " maximized" << std::endl;
            break;
          case SDL_WINDOWEVENT_RESTORED:
            std::cout << "Window " << e.window.windowID << " restored" << std::endl;
            break;
          case SDL_WINDOWEVENT_ENTER:
            std::cout << "Mouse entered window " << e.window.windowID << std::endl;
            break;
          case SDL_WINDOWEVENT_LEAVE:
            std::cout << "Mouse left window " << e.window.windowID << std::endl;
            break;
          case SDL_WINDOWEVENT_FOCUS_GAINED:
            std::cout << "Window " << e.window.windowID << " gained keyboard focus" << std::endl;
            break;
          case SDL_WINDOWEVENT_FOCUS_LOST:
            std::cout << "Window " << e.window.windowID << " lost keyboard focus" << std::endl;
            break;
          case SDL_WINDOWEVENT_CLOSE:
            std::cout << "Window " << e.window.windowID << " closed" << std::endl;
            break;
          default:
            std::cout << "Window " << e.window.windowID << " got unknown event " << static_cast<int>(e.window.event) << std::endl;
            break;
          }
          break;
        }
      case SDL_KEYDOWN:
        {
          KeyEvent ke { static_cast<KeyEvent::Key>(e.key.keysym.sym), SDL_GetModState(), static_cast<bool>(e.key.repeat) };
          auto w = focusWidget();
          if (!w)
            w = widgetByWindowId(e.key.windowID);
          else if (w->ancestor() != widgetByWindowId(e.key.windowID))
          {
            std::cerr << "Unknown windowID " << e.key.windowID << std::endl;
            break;
          }
          while (w)
          {
            if (w->keyPressEvent(ke))
              break;
            w = w->parent();
          }
          break;
        }
      case SDL_KEYUP:
        {
          KeyEvent ke { static_cast<KeyEvent::Key>(e.key.keysym.sym), SDL_GetModState(), static_cast<bool>(e.key.repeat) };
          auto w = focusWidget();
          if (!w)
            w = widgetByWindowId(e.key.windowID);
          else if (w->ancestor() != widgetByWindowId(e.key.windowID))
          {
            std::cerr << "Unknown windowID " << e.key.windowID << std::endl;
            break;
          }

          while (w)
          {
            if (w->keyReleaseEvent(ke))
              break;
            w = w->parent();
          }
          break;
        }
      case SDL_TEXTINPUT:
        {
          TextInputEvent tie { toUtf16(e.text.text) };
          auto w = focusWidget();
          if (!w)
            w = widgetByWindowId(e.key.windowID);
          else if (w->ancestor() != widgetByWindowId(e.key.windowID))
          {
            std::cerr << "Unknown windowID " << e.key.windowID << std::endl;
            break;
          }

          while (w)
          {
            if (w->textInputEvent(tie))
              break;
            w = w->parent();
          }
          break;
        }
      case SDL_QUIT:
        done = true;
        break;
      }
    }
    const auto isEmpty = (SDL_PeepEvents(&e, 1, SDL_PEEKEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT) == 0);
    if (isEmpty || SDL_GetTicks() > lastUpdate_ + 1000 / 60)
    {
      auto x = SDL_GetTicks();
      for (auto w: widgetList_)
        if (w->needRepaint())
        {
          PaintEvent e;
          w->internalPaint(e);
        }
      if (needUpdateWithoutRedraw_)
      {
        needUpdateWithoutRedraw_->updateWithoutRedraw();
        needUpdateWithoutRedraw_ = nullptr;
      }
      lastUpdate_ = SDL_GetTicks();
      std::cout << "Update time: " << lastUpdate_ - x << " " <<
        (lastUpdate_ - x > 0 ? 1000 / (lastUpdate_ - x) : 999)<< "fps" << std::endl;
    }
    for (auto obj: deletingObjects_)
      delete obj;
    deletingObjects_.clear();
  }
  return 0;
}