Beispiel #1
0
void TestRollover(CuTest *tc) {
  START_KEY_CAPTURE;

  CuAssertIntEquals(tc, 0, active_layer);

  SHOULDNOT_SEND;
  key_press(5);//F or layer 1
  VERIFY_DIDNOT_SEND;
  CuAssertIntEquals(tc, 1, active_layer);

  key_press(6);//0 or 1 depending on layer
  EXPECT_SENT(3);
  CuAssertIntEquals(tc, 0, active_layer);//layer already reset

  key_release(5);
  CuAssertIntEquals(tc, 0, active_layer);

  key_release(6);
  EXPECT_SENT(4);

  VERIFY KEY(F);
  THEN   NOKEYS;
  THEN   KEY(0);
  THEN   NOKEYS;
}
Beispiel #2
0
void TestLayerLockActsAsLayerShift(CuTest *tc) {
  START_KEY_CAPTURE;

  SHOULDNOT_SEND;
  key_press(7);//;layer 1
  CuAssertIntEquals(tc, 1, active_layer);
  VERIFY_DIDNOT_SEND;

  make_dualrole_modifier_possible();//pretend enough time has passed
  key_press(6);//0 or 1 depending on layer
  key_release(6);

  SHOULDNOT_SEND;
  key_release(7);
  CuAssertIntEquals(tc, 0, active_layer);
  VERIFY_DIDNOT_SEND;

  key_press(6);//0 or 1 depending on layer
  key_release(6);

  VERIFY KEY(1);
  THEN   NOKEYS;

  THEN KEY(0);
  THEN   NOKEYS;
}
Beispiel #3
0
	Input InputManager::get_input(){
		static bool exit = false;

		frame_text.resize(0);

		SDL_Event evnt;
		SDL_StartTextInput();

		//Will keep looping until there are no more events to process
		while (SDL_PollEvent(&evnt)) {
			switch (evnt.type) {
			case SDL_QUIT:
				return Input::EXIT_REQUEST;
				break;
			case SDL_MOUSEMOTION:

				set_mouse_coords((F32)evnt.motion.x, (F32)evnt.motion.y);

				break;
			case SDL_TEXTINPUT:
				frame_text += evnt.text.text;
				break;
			case SDL_KEYDOWN:
				key_press(evnt.key.keysym.sym , KEYBOARD);
				break;
			case SDL_KEYUP:
				key_release(evnt.key.keysym.sym , KEYBOARD);
				break;
			case SDL_MOUSEBUTTONDOWN:
				key_press(evnt.button.button , MOUSE);
				break;
			case SDL_MOUSEBUTTONUP:
				key_release(evnt.button.button , MOUSE);
				break;
			case SDL_JOYBUTTONDOWN:  /* Handle Joystick Button Presses */
				key_press(evnt.jbutton.button , CONTROLLER);
				break;
			case SDL_JOYBUTTONUP:  /* Handle Joystick Button Presses */
				key_release(evnt.jbutton.button , CONTROLLER);
				break;
			case SDL_JOYAXISMOTION:
				
				switch (evnt.jaxis.axis){
				case 0: set_controller_axis_coord(&m_controller_LX_coords.x, evnt.jaxis.value); break;
				case 1: set_controller_axis_coord(&m_controller_LX_coords.y, evnt.jaxis.value); break;
				case 2: set_controller_axis_coord(&m_controller_RX_coords.x, evnt.jaxis.value); break;
				case 3: set_controller_axis_coord(&m_controller_RX_coords.y, evnt.jaxis.value); break;
				}
				
					
			}
		}

		SDL_StopTextInput();

		if (is_key_pressed(SDLK_ESCAPE,KEYBOARD))exit = !exit;
		if(!exit)SDL_WarpMouseInWindow(m_window, WINDOW_WIDTH / 2.0f, WINDOW_HEIGHT / 2.0f);

		return Input::OK;
	}
Beispiel #4
0
void TestLayerLock(CuTest* tc)
{
  START_KEY_CAPTURE;

  SHOULDNOT_SEND;
  key_press(7);//toggle layer to 1
  CuAssertIntEquals(tc, 1, active_layer);
  key_release(7);
  CuAssertIntEquals(tc, 1, active_layer);
  VERIFY_DIDNOT_SEND;

  key_press(6);//0 or 1 depending on layer
  key_release(6);

  SHOULDNOT_SEND;
  key_press(7);//toggle layer to 0
  CuAssertIntEquals(tc, 0, active_layer);
  key_release(7);
  CuAssertIntEquals(tc, 0, active_layer);
  VERIFY_DIDNOT_SEND;

  key_press(6);//0 or 1 depending on layer
  key_release(6);

  VERIFY KEY(1);
  THEN   NOKEYS;

  THEN KEY(0);
  THEN   NOKEYS;
}
Beispiel #5
0
void TestComplicated(CuTest *tc) {
  START_KEY_CAPTURE;

  SHOULDNOT_SEND;
  key_press(5);//F or layer 1
  VERIFY_DIDNOT_SEND;
  CuAssertIntEquals(tc, 1, active_layer);
  make_dualrole_modifier_possible();//pretend enough time has passed

  key_press(0);//LSFT of LBRACKET
  key_release(0);

  CuAssertIntEquals(tc, 1, active_layer);

  SHOULDNOT_SEND;
  key_release(5);
  VERIFY_DIDNOT_SEND;

  CuAssertIntEquals(tc, 0, active_layer);

  EXPECT_SENT(4);
  VERIFY NOKEYS WITH(LSFT);
  THEN NOKEYS NOMODS;
  THEN KEY(LBRACKET);
  THEN NOKEYS;
}
Beispiel #6
0
void TestModifierTapRelease(CuTest *tc) {
  START_KEY_CAPTURE;

  key_press(4);//lshift or z
  make_dualrole_modifier_possible();//pretend enough time has passed
  key_press(0);
  key_release(4);
  key_release(0);

  VERIFY NOKEYS WITH(LSFT);
  THEN   KEY(A) WITH(LSFT);
  THEN   KEY(A) NOMODS;
  THEN   NOKEYS NOMODS;
}
int main(void) {
  uint8_t row, col, key_id;

  init();

  for(;;) {
    _delay_ms(5);                                //  Debouncing
    for(col=0; col<NCOL; col++) {
      *col_port[col] &= ~col_bit[col];
      _delay_us(1);
      for(row=0; row<NROW; row++) {
	key_id = col*NROW+row;
	if(!(*row_port[row] & row_bit[row])) {
	  if(!pressed[key_id])
	    key_press(key_id);
	}
	else if(pressed[key_id])
	  key_release(key_id);
      }
      *col_port[col] |= col_bit[col];
    }

    //    OCR1B++; OCR1C++;

    // TODO fixed keyboard leds.  I disabled as I cannot test them
    //PORTB = (PORTB & 0b00111111) | ((keyboard_leds << 5) & 0b11000000);
    //DDRB  = (DDRB  & 0b00111111) | ((keyboard_leds << 5) & 0b11000000);

  }
}
Beispiel #8
0
void TestKey(CuTest* tc)
{
  START_KEY_CAPTURE;

  key_press(0);//A
  key_release(0);

  key_press(0);//A
  key_release(0);

  EXPECT_SENT(4);
  VERIFY KEY(A);
  THEN   NOKEYS;
  THEN   KEY(A);
  THEN   NOKEYS;
}
void main()
{
  TRISB=0x00;
	TRISA=0x3C;
	TRISC=0x00;
  ADCON1=0x06;
  init_lcd();
  init();
  GIE=1;
  PEIE=1;
  //test_display();

  cmd_wr(0x80);
  for(i=0;i<=12;i++)
  {
   data_wr(cnt[i]);
  }

  while(1)
  {
  	while(key_ready!=1);
	a=key_code;
	ds1=ascii_tab[a];
	key_release();
	lcd_disp();
  }  
}
Beispiel #10
0
void HistoryComboBox::focusOutEvent(QFocusEvent *e)
{
    QKeyEvent key_press(QKeyEvent::KeyPress, Qt::Key_Return, Qt::NoModifier, QString(), false, 0 );
    QApplication::sendEvent(this, &key_press);

    QKeyEvent key_release(QKeyEvent::KeyRelease, Qt::Key_Return, Qt::NoModifier, QString(), false, 0 );
    QApplication::sendEvent(this, &key_release);

    QComboBox::focusOutEvent(e);
}
Beispiel #11
0
void TestKeyModded(CuTest* tc)
{
  START_KEY_CAPTURE;

  key_press(3);//sD
  key_release(3);

  EXPECT_SENT(3);
  VERIFY NOKEYS WITH(LSFT);
  THEN KEY(D) WITH(LSFT);
  THEN NOKEYS;
}
Beispiel #12
0
void TestCancel(CuTest *tc) {
  START_KEY_CAPTURE;

  SHOULDNOT_SEND;
  key_press(5);//F or layer 1
  VERIFY_DIDNOT_SEND;
  make_dualrole_tap_impossible();//pretend too much time has passed

  SHOULDNOT_SEND;
  key_release(5);
  VERIFY_DIDNOT_SEND;
}
Beispiel #13
0
void TestLayerShiftOrKeyCanTap(CuTest *tc) {
  START_KEY_CAPTURE;

  SHOULDNOT_SEND;
  key_press(5);//F or layer 1
  CuAssertIntEquals(tc, 1, active_layer);
  VERIFY_DIDNOT_SEND;

  key_release(5);
  CuAssertIntEquals(tc, 0, active_layer);

  key_press(0);
  key_release(0);
  CuAssertIntEquals(tc, 0, active_layer);

  VERIFY KEY(F);
  THEN   NOKEYS;

  THEN KEY(A);
  THEN   NOKEYS;
}
Beispiel #14
0
void TestModifierOrKeyCanMod(CuTest *tc) {
  START_KEY_CAPTURE;

  key_press(4);//shift or Z
  make_dualrole_modifier_possible();//pretend enough time has passed
  key_press(0);//A
  key_release(0);
  key_release(4);

  key_press(0);//A
  key_release(0);

  EXPECT_SENT(6);
  VERIFY NOKEYS WITH(LSFT);
  THEN   KEY(A) WITH(LSFT);
  THEN   NOKEYS WITH(LSFT);
  THEN   NOKEYS NOMODS;

  THEN   KEY(A) NOMODS;
  THEN   NOKEYS NOMODS;
}
Beispiel #15
0
void TestModifierTapModded(CuTest *tc) {
  START_KEY_CAPTURE;

  key_press(2);//rshift or )
  key_release(2);

  EXPECT_SENT(5);
  VERIFY NOKEYS WITH(RSFT);
  THEN   NOKEYS NOMODS;
  THEN   NOKEYS WITH(LSFT);
  THEN   KEY(9) WITH(LSFT);
  THEN   NOKEYS NOMODS;
}
Beispiel #16
0
void TestModifierOrKeyCanTap(CuTest *tc) {
  START_KEY_CAPTURE;

  key_press(4);//shift or Z
  key_release(4);


  EXPECT_SENT(4);
  VERIFY NOKEYS WITH(LSFT);
  THEN   NOKEYS NOMODS;
  THEN   KEY(Z) NOMODS;
  THEN   NOKEYS NOMODS;
}
Beispiel #17
0
void TestSpaceFn(CuTest *tc) {
  START_KEY_CAPTURE;

  key_press(3);
  key_release(3);

  SHOULDNOT_SEND;
  key_press(16*8+6);//SPACE
  CuAssertIntEquals(tc, 1, active_layer);
  VERIFY_DIDNOT_SEND;

  key_release(16*8+6);//SPACE
  CuAssertIntEquals(tc, 0, active_layer);

  SHOULDNOT_SEND;
  key_press(16*8+6);//SPACE
  CuAssertIntEquals(tc, 1, active_layer);
  VERIFY_DIDNOT_SEND;

  make_dualrole_modifier_possible();//pretend enough time has passed

  key_press(11*8+3);//K or down
  key_release(11*8+3);

  SHOULDNOT_SEND;
  key_release(16*8+6);//SPACE
  CuAssertIntEquals(tc, 0, active_layer);
  VERIFY_DIDNOT_SEND;

  VERIFY NOKEYS WITH(RGUI);
  THEN   NOKEYS NOMODS;
  THEN   KEY(SPACE) NOMODS;
  THEN   NOKEYS NOMODS;

  THEN   KEY(DOWN);
  THEN   NOKEYS;
}
Beispiel #18
0
void TestModModded(CuTest* tc)
{
  START_KEY_CAPTURE;

  SHOULDNOT_SEND;
  key_press(7);//toggle layer to 1
  CuAssertIntEquals(tc, 1, active_layer);
  key_release(7);
  CuAssertIntEquals(tc, 1, active_layer);
  VERIFY_DIDNOT_SEND;

  key_press(2);//sLALT
  key_release(2);//sLALT

  SHOULDNOT_SEND;
  key_press(7);//toggle layer to 0
  CuAssertIntEquals(tc, 0, active_layer);
  key_release(7);
  CuAssertIntEquals(tc, 0, active_layer);
  VERIFY_DIDNOT_SEND;

  VERIFY NOKEYS WITH(LSFT|LALT);
  THEN NOKEYS;
}
Beispiel #19
0
void scan() {
  for (ic = 0; ic < COLS_COUNT; ic += 1) {
    digitalWrite(cols_pins[ic], HIGH);

    for (ir = 0; ir < ROWS_COUNT; ir += 1) {
      if (!keymap[ir][ic])
        continue;

      if (digitalRead(rows_pins[ir]))
        key_press(keymap[ir][ic]);
      else
        key_release(keymap[ir][ic]);
    }

    digitalWrite(cols_pins[ic], LOW);
  }
}
void keyprocess()
{
 switch(key_code)
 	{
	 case 'A':
	 			process_a();
				break;

	 case 'B' :
	 			process_b();
				break;
	 case 'C' :
	 			process_c();
				break;
	}
	key_release();
}
Beispiel #21
0
void replay_keypresses(void)
{
  uint8_t i, k;

  clear_pressed();

  // Go through all keys in the replay buf. We can determine whether
  // a command is a key press or release based on whether the key
  // is already pressed.
  for (i = 0; i < replay_buf_len; ++i) {
    k = replay_buf[i];
    if (!key[k].pressed) {
      key_press(k);
    } else {
      key_release(k);
    }
  }
}
Beispiel #22
0
void poll() {
	uint8_t row, col, key_id;
	for (row=0; row<ROWS; row++) { // scan rows
		*row_port[row] &= ~row_bit[row];
		_delay_us(1);
		for (col=0; col<COLS; col++) { // read columns
			key_id = col*ROWS+row;
			if (! (*col_pin[col] & col_bit[col])) { // press key
				if (! pressed[key_id]) {
					key_press(key_id);
				}
			} else if (pressed[key_id]) { // release key
				key_release(key_id);
			}
		}
		*row_port[row] |= row_bit[row];
	}
	if (caps_lock_led != (keyboard_leds & LED_CAPS_LOCK)) { // change layout
		caps_lock_change_layer();
	}
	//if (keyboard_leds) LED_ON; else LED_OFF;
	repeat_tick();
	_delay_ms(5);
}
Beispiel #23
0
static bool process_event(union event *ev)
{
  struct buffered_status *status = store_status();
  bool rval = true;

  switch(ev->type)
  {
    case EVENT_BUTTON_DOWN:
    {
      Uint32 button = map_button(ev->button.pad, ev->button.button);
      rval = false;
      if((ev->button.pad == 0) && pointing)
      {
        Uint32 mousebutton;
        switch(ev->button.button)
        {
          case WPAD_BUTTON_A: mousebutton = MOUSE_BUTTON_LEFT; break;
          case WPAD_BUTTON_B: mousebutton = MOUSE_BUTTON_RIGHT; break;
          default: mousebutton = 0; break;
        }
        if(mousebutton)
        {
          status->mouse_button = mousebutton;
          status->mouse_repeat = mousebutton;
          status->mouse_button_state |= MOUSE_BUTTON(mousebutton);
          status->mouse_repeat_state = 1;
          status->mouse_drag_state = -1;
          status->mouse_time = get_ticks();
          button = 256;
          rval = true;
        }
      }
      if((button < 256))
      {
        enum keycode skey = input.joystick_button_map[ev->button.pad][button];
        if(skey && (status->keymap[skey] == 0))
        {
          key_press(status, skey, skey);
          rval = true;
        }
      }
      else
      {
        if((ev->button.pad < 4) && ((ev->button.button == WPAD_BUTTON_HOME) ||
         ((ext_type[ev->button.pad] == WPAD_EXP_CLASSIC) &&
         (ev->button.button == WPAD_CLASSIC_BUTTON_HOME))))
        {
          status->keymap[IKEY_ESCAPE] = 1;
          status->key = IKEY_ESCAPE;
          status->keypress_time = get_ticks();
          rval = true;
          break;
        }
      }
      break;
    }
    case EVENT_BUTTON_UP:
    {
      Uint32 button = map_button(ev->button.pad, ev->button.button);
      rval = false;
      if((ev->button.pad == 0) && status->mouse_button_state)
      {
        Uint32 mousebutton;
        switch(ev->button.button)
        {
          case WPAD_BUTTON_A: mousebutton = MOUSE_BUTTON_LEFT; break;
          case WPAD_BUTTON_B: mousebutton = MOUSE_BUTTON_RIGHT; break;
          default: mousebutton = 0; break;
        }
        if(mousebutton &&
         (status->mouse_button_state & MOUSE_BUTTON(mousebutton)))
        {
          status->mouse_button_state &= ~MOUSE_BUTTON(mousebutton);
          status->mouse_repeat = 0;
          status->mouse_drag_state = 0;
          status->mouse_repeat_state = 0;
          button = 256;
          rval = true;
        }
      }
      if((button < 256))
      {
        enum keycode skey = input.joystick_button_map[ev->button.pad][button];
        if(skey)
        {
          key_release(status, skey);
          rval = true;
        }
      }
      break;
    }
    case EVENT_AXIS_MOVE:
    {
      int digital_value = -1;
      int axis = ev->axis.axis;
      int last_axis;
      enum keycode skey;
      if(ev->axis.pad < 4)
      {
        switch(ext_type[ev->axis.pad])
        {
          case WPAD_EXP_NUNCHUK: break;
          case WPAD_EXP_CLASSIC: axis += 2; break;
          case WPAD_EXP_GUITARHERO3: axis += 6; break;
          default: axis = 256; break; // Not supposed to happen
        }
      }
      if(axis == 256) break;
      last_axis = status->axis[ev->axis.pad][axis];

      if(ev->axis.pos > 10000)
        digital_value = 1;
      else if(ev->axis.pos < -10000)
        digital_value = 0;

      if(digital_value != -1)
      {
        skey = input.joystick_axis_map[ev->axis.pad][axis][digital_value];
        if(skey)
        {
          if(status->keymap[skey] == 0)
            key_press(status, skey, skey);

          if(last_axis == (digital_value ^ 1))
          {
            skey = input.joystick_axis_map[ev->axis.pad][axis][last_axis];
            key_release(status, skey);
          }
        }
      }
      else
      {
        if(last_axis != -1)
        {
          skey = input.joystick_axis_map[ev->axis.pad][axis][last_axis];
          if(skey)
            key_release(status, skey);
        }
      }
      status->axis[ev->axis.pad][axis] = digital_value;
      break;
    }
    case EVENT_CHANGE_EXT:
    {
      ext_type[ev->ext.pad] = ev->ext.ext;
      break;
    }
    case EVENT_POINTER_MOVE:
    {
      pointing = 1;
      status->mouse_moved = true;
      status->real_mouse_x = ev->pointer.x;
      status->real_mouse_y = ev->pointer.y;
      status->mouse_x = ev->pointer.x / 8;
      status->mouse_y = ev->pointer.y / 14;
      break;
    }
    case EVENT_POINTER_OUT:
    {
      pointing = 0;
      break;
    }
    case EVENT_KEY_DOWN:
    {
      enum keycode ckey = convert_USB_internal(ev->key.key);
      if(!ckey)
      {
        if(ev->key.unicode)
          ckey = IKEY_UNICODE;
        else
        {
          rval = false;
          break;
        }
      }

      if((ckey == IKEY_RETURN) &&
       get_alt_status(keycode_internal) &&
       get_ctrl_status(keycode_internal))
      {
        toggle_fullscreen();
        break;
      }

      if(ckey == IKEY_F12)
      {
        dump_screen();
        break;
      }

      if(status->key_repeat &&
       (status->key_repeat != IKEY_LSHIFT) &&
       (status->key_repeat != IKEY_RSHIFT) &&
       (status->key_repeat != IKEY_LALT) &&
       (status->key_repeat != IKEY_RALT) &&
       (status->key_repeat != IKEY_LCTRL) &&
       (status->key_repeat != IKEY_RCTRL))
      {
        // Stack current repeat key if it isn't shift, alt, or ctrl
        if(input.repeat_stack_pointer != KEY_REPEAT_STACK_SIZE)
        {
          input.key_repeat_stack[input.repeat_stack_pointer] =
           status->key_repeat;
          input.unicode_repeat_stack[input.repeat_stack_pointer] =
           status->unicode_repeat;
          input.repeat_stack_pointer++;
        }
      }

      key_press(status, ckey, ev->key.unicode);
      break;
    }
    case EVENT_KEY_UP:
    {
      enum keycode ckey = convert_USB_internal(ev->key.key);
      if(!ckey)
      {
        if(status->keymap[IKEY_UNICODE])
          ckey = IKEY_UNICODE;
        else
        {
          rval = false;
          break;
        }
      }

      status->keymap[ckey] = 0;
      if(status->key_repeat == ckey)
      {
        status->key_repeat = IKEY_UNKNOWN;
        status->unicode_repeat = 0;
      }
      status->key_release = ckey;
      break;
    }
    case EVENT_KEY_LOCKS:
    {
      status->numlock_status = !!(ev->locks.locks & MOD_NUMLOCK);
      status->caps_status = !!(ev->locks.locks & MOD_CAPSLOCK);
      break;
    }
    case EVENT_MOUSE_MOVE:
    {
      int mx = status->real_mouse_x + ev->mmove.dx;
      int my = status->real_mouse_y + ev->mmove.dy;

      if(mx < 0)
        mx = 0;
      if(my < 0)
        my = 0;
      if(mx >= 640)
        mx = 639;
      if(my >= 350)
        my = 349;

      status->real_mouse_x = mx;
      status->real_mouse_y = my;
      status->mouse_x = mx / 8;
      status->mouse_y = my / 14;
      status->mouse_moved = true;
      break;
    }
    case EVENT_MOUSE_BUTTON_DOWN:
    {
      Uint32 button = 0;
      switch (ev->mbutton.button)
      {
        case USB_MOUSE_BTN_LEFT:
          button = MOUSE_BUTTON_LEFT;
          break;
        case USB_MOUSE_BTN_RIGHT:
          button = MOUSE_BUTTON_RIGHT;
          break;
        case USB_MOUSE_BTN_MIDDLE:
          button = MOUSE_BUTTON_MIDDLE;
          break;
        default:
          break;
      }

      if(!button)
        break;

      status->mouse_button = button;
      status->mouse_repeat = button;
      status->mouse_button_state |= MOUSE_BUTTON(button);
      status->mouse_repeat_state = 1;
      status->mouse_drag_state = -1;
      status->mouse_time = get_ticks();
      break;
    }
    case EVENT_MOUSE_BUTTON_UP:
    {
      Uint32 button = 0;
      switch (ev->mbutton.button)
      {
        case USB_MOUSE_BTN_LEFT:
          button = MOUSE_BUTTON_LEFT;
          break;
        case USB_MOUSE_BTN_RIGHT:
          button = MOUSE_BUTTON_RIGHT;
          break;
        case USB_MOUSE_BTN_MIDDLE:
          button = MOUSE_BUTTON_MIDDLE;
          break;
        default:
          break;
      }

      if(!button)
        break;

      status->mouse_button_state &= ~MOUSE_BUTTON(button);
      status->mouse_repeat = 0;
      status->mouse_drag_state = 0;
      status->mouse_repeat_state = 0;
      break;
    }
    default:
    {
      rval = false;
      break;
    }
  }

  return rval;
}
Beispiel #24
0
int		key_release_hook(int keycode, t_env *e)
{
	key_release(&e->key, keycode);
	return (0);
}
Beispiel #25
0
static bool process_event(SDL_Event *event)
{
  struct buffered_status *status = store_status();
  enum keycode ckey;

  /* SDL's numlock keyboard modifier handling seems to be broken on X11,
   * and it will only get numlock's status right on application init. We
   * can trust this value once, and then toggle based on user presses of
   * the numlock key.
   *
   * On Windows, KEYDOWN/KEYUP seem to be sent separately, to indicate
   * enabling or disabling of numlock. But on X11, both KEYDOWN/KEYUP are
   * sent for each toggle, so this must be handled differently.
   *
   * What a mess!
   */
  if(!numlock_status_initialized)
  {
    status->numlock_status = !!(SDL_GetModState() & KMOD_NUM);
    numlock_status_initialized = true;
  }

  switch(event->type)
  {
    case SDL_QUIT:
    {
      // Stuff an escape
      status->key = IKEY_ESCAPE;
      status->keymap[IKEY_ESCAPE] = 1;
      status->keypress_time = get_ticks();
      break;
    }

#if SDL_VERSION_ATLEAST(2,0,0)
    case SDL_WINDOWEVENT:
    {
      switch(event->window.event)
      {
        case SDL_WINDOWEVENT_RESIZED:
        {
          resize_screen(event->window.data1, event->window.data2);
          break;
        }

        case SDL_WINDOWEVENT_FOCUS_LOST:
        {
          // Pause while minimized
          if(input.unfocus_pause)
          {
            while(1)
            {
              SDL_WaitEvent(event);

              if(event->type == SDL_WINDOWEVENT &&
                 event->window.event == SDL_WINDOWEVENT_FOCUS_GAINED)
                break;
            }
          }
          break;
        }
      }

      break;
    }
#else // !SDL_VERSION_ATLEAST(2,0,0)
    case SDL_VIDEORESIZE:
    {
      resize_screen(event->resize.w, event->resize.h);
      break;
    }

    case SDL_ACTIVEEVENT:
    {
      if(input.unfocus_pause)
      {
        // Pause while minimized
        if(event->active.state & (SDL_APPACTIVE | SDL_APPINPUTFOCUS))
        {
          // Wait for SDL_APPACTIVE with gain of 1
          do
          {
            SDL_WaitEvent(event);
          } while((event->type != SDL_ACTIVEEVENT) ||
           (event->active.state & ~(SDL_APPACTIVE | SDL_APPINPUTFOCUS)));
        }
      }
      break;
    }
#endif // !SDL_VERSION_ATLEAST(2,0,0)

    case SDL_MOUSEMOTION:
    {
      SDL_Window *window = SDL_GetWindowFromID(sdl_window_id);
      int mx_real = event->motion.x;
      int my_real = event->motion.y;
      int mx, my, min_x, min_y, max_x, max_y;
      get_screen_coords(mx_real, my_real, &mx, &my, &min_x,
       &min_y, &max_x, &max_y);

      if(mx > 639)
        SDL_WarpMouseInWindow(window, max_x, my_real);

      if(mx < 0)
        SDL_WarpMouseInWindow(window, min_x, my_real);

      if(my > 349)
        SDL_WarpMouseInWindow(window, mx_real, max_y);

      if(my < 0)
        SDL_WarpMouseInWindow(window, mx_real, min_y);

      status->real_mouse_x = mx;
      status->real_mouse_y = my;
      status->mouse_x = mx / 8;
      status->mouse_y = my / 14;
      status->mouse_moved = true;
      break;
    }

    case SDL_MOUSEBUTTONDOWN:
    {
      status->mouse_button = event->button.button;
      status->mouse_repeat = event->button.button;
      status->mouse_button_state |= SDL_BUTTON(event->button.button);
      status->mouse_repeat_state = 1;
      status->mouse_drag_state = -1;
      status->mouse_time = SDL_GetTicks();
      break;
    }

    case SDL_MOUSEBUTTONUP:
    {
      status->mouse_button_state &= ~SDL_BUTTON(event->button.button);
      status->mouse_repeat = 0;
      status->mouse_drag_state = 0;
      status->mouse_repeat_state = 0;
      break;
    }

    case SDL_KEYDOWN:
    {
      Uint16 unicode = 0;

#if SDL_VERSION_ATLEAST(2,0,0)
      // FIXME: SDL 2.0 finally implements proper key repeat.
      // We should probably use it instead of our hand-rolled stuff.
      if(event->key.repeat)
        break;
#endif

      ckey = convert_SDL_internal(event->key.keysym.sym);
      if(!ckey)
      {
#if !SDL_VERSION_ATLEAST(2,0,0)
        if(!event->key.keysym.unicode)
          break;
#endif
        ckey = IKEY_UNICODE;
      }

#if SDL_VERSION_ATLEAST(2,0,0)
      // SDL 2.0 sends the raw key and translated 'text' as separate events.
      // There is no longer a UNICODE mode that sends both at once.
      // Because of the way the SDL 1.2 assumption is embedded deeply in
      // the MZX event queue processor, emulate the 1.2 behaviour by waiting
      // for a TEXTINPUT event after a KEYDOWN.
      if(SDL_WaitEventTimeout(event, 1))
      {
        if(event->type == SDL_TEXTINPUT)
          unicode = event->text.text[0] | event->text.text[1] << 8;
        else
          SDL_PushEvent(event);
      }
#else
      unicode = event->key.keysym.unicode;
#endif

      if((ckey == IKEY_RETURN) &&
       get_alt_status(keycode_internal) &&
       get_ctrl_status(keycode_internal))
      {
        toggle_fullscreen();
        break;
      }

      if(ckey == IKEY_CAPSLOCK)
      {
        status->caps_status = true;
      }

      if(ckey == IKEY_NUMLOCK)
      {
#if !SDL_VERSION_ATLEAST(2,0,0) && defined(__WIN32__)
        status->numlock_status = true;
#endif
        break;
      }

      if(ckey == IKEY_F12)
      {
        dump_screen();
        break;
      }

      // Ignore alt + tab
      if((ckey == IKEY_TAB) && get_alt_status(keycode_internal))
      {
        break;
      }

      if(status->key_repeat &&
       (status->key_repeat != IKEY_LSHIFT) &&
       (status->key_repeat != IKEY_RSHIFT) &&
       (status->key_repeat != IKEY_LALT) &&
       (status->key_repeat != IKEY_RALT) &&
       (status->key_repeat != IKEY_LCTRL) &&
       (status->key_repeat != IKEY_RCTRL))
      {
        // Stack current repeat key if it isn't shift, alt, or ctrl
        if(input.repeat_stack_pointer != KEY_REPEAT_STACK_SIZE)
        {
          input.key_repeat_stack[input.repeat_stack_pointer] =
           status->key_repeat;
          input.unicode_repeat_stack[input.repeat_stack_pointer] =
           status->unicode_repeat;
          input.repeat_stack_pointer++;
        }
      }

      key_press(status, ckey, unicode);
      break;
    }

    case SDL_KEYUP:
    {
#if SDL_VERSION_ATLEAST(2,0,0)
      // FIXME: SDL 2.0 finally implements proper key repeat.
      // We should probably use it instead of our hand-rolled stuff.
      if(event->key.repeat)
        break;
#endif

      ckey = convert_SDL_internal(event->key.keysym.sym);
      if(!ckey)
      {
#if !SDL_VERSION_ATLEAST(2,0,0)
        if(!status->keymap[IKEY_UNICODE])
          break;
#endif
        ckey = IKEY_UNICODE;
      }

      if(ckey == IKEY_NUMLOCK)
      {
#if !SDL_VERSION_ATLEAST(2,0,0) && defined(__WIN32__)
        status->numlock_status = false;
#else
        status->numlock_status = !status->numlock_status;
#endif
        break;
      }

      if(ckey == IKEY_CAPSLOCK)
      {
        status->caps_status = false;
      }

      status->keymap[ckey] = 0;
      if(status->key_repeat == ckey)
      {
        status->key_repeat = IKEY_UNKNOWN;
        status->unicode_repeat = 0;
      }
      status->key_release = ckey;
      break;
    }

    case SDL_JOYAXISMOTION:
    {
      int axis_value = event->jaxis.value;
      int digital_value = -1;
      int which = event->jaxis.which;
      int axis = event->jaxis.axis;
      Sint8 last_axis = status->axis[which][axis];
      enum keycode stuffed_key;

      if(axis_value > 10000)
        digital_value = 1;
      else

      if(axis_value < -10000)
        digital_value = 0;

      if(digital_value != -1)
      {
        stuffed_key =
          input.joystick_axis_map[which][axis][digital_value];

        if(stuffed_key)
        {
          if(status->keymap[stuffed_key] == 0)
            key_press(status, stuffed_key, stuffed_key);

          if(last_axis == (digital_value ^ 1))
          {
            key_release(status,
             input.joystick_axis_map[which][axis][last_axis]);
          }
        }
      }
      else if(last_axis != -1)
      {
        key_release(status,
          input.joystick_axis_map[which][axis][last_axis]);
      }

      status->axis[which][axis] = digital_value;
      break;
    }

    case SDL_JOYBUTTONDOWN:
    {
      int which = event->jbutton.which;
      int button = event->jbutton.button;
      enum keycode stuffed_key = input.joystick_button_map[which][button];

      if(stuffed_key && (status->keymap[stuffed_key] == 0))
        key_press(status, stuffed_key, stuffed_key);

      break;
    }

    case SDL_JOYBUTTONUP:
    {
      int which = event->jbutton.which;
      int button = event->jbutton.button;
      enum keycode stuffed_key = input.joystick_button_map[which][button];

      if(stuffed_key)
        key_release(status, stuffed_key);

      break;
    }

    default:
      return false;
  }

  return true;
}