예제 #1
0
static int process_event(lua_State *L, SDL_Event *event) {
	JiveEvent jevent;
	Uint32 now;

	memset(&jevent, 0, sizeof(JiveEvent));
	jevent.ticks = now = jive_jiffies();

	switch (event->type) {
	case SDL_QUIT:
		jiveL_quit(L);
		exit(0);
		break;

	case SDL_MOUSEBUTTONDOWN:
		/* map the mouse scroll wheel to up/down */
		if (event->button.button == SDL_BUTTON_WHEELUP) {
			jevent.type = JIVE_EVENT_SCROLL;
			--(jevent.u.scroll.rel);
			break;
		}
		else if (event->button.button == SDL_BUTTON_WHEELDOWN) {
			jevent.type = JIVE_EVENT_SCROLL;
			++(jevent.u.scroll.rel);
			break;
		}

		// Fall through

	case SDL_MOUSEBUTTONUP:
		if (event->button.button == SDL_BUTTON_LEFT) {
			if (event->button.state == SDL_PRESSED) {
				jevent.type = JIVE_EVENT_MOUSE_DOWN;
				jevent.u.mouse.x = event->button.x;
				jevent.u.mouse.y = event->button.y;
			}
			else {
				jevent.type = JIVE_EVENT_MOUSE_UP;
				jevent.u.mouse.x = event->button.x;
				jevent.u.mouse.y = event->button.y;
			}
		}

		if (event->type == SDL_MOUSEBUTTONDOWN) {
			if (mouse_state == MOUSE_STATE_NONE) {
				mouse_state = MOUSE_STATE_DOWN;
				mouse_timeout_arg = (event->button.y << 16) | event->button.x;
				mouse_timeout = now + HOLD_TIMEOUT;
				mouse_long_timeout = now + LONG_HOLD_TIMEOUT;

				mouse_origin_x = event->button.x;
				mouse_origin_y = event->button.y;
				break;
			}
		}
		else /* SDL_MOUSEBUTTONUP */ {
			if (mouse_state == MOUSE_STATE_DOWN) {
				/*
				 * MOUSE_PRESSED and MOUSE_UP events
				 */
				JiveEvent up;

				memset(&up, 0, sizeof(JiveEvent));
				up.type = JIVE_EVENT_MOUSE_PRESS;
				up.ticks = jive_jiffies();
				up.u.mouse.x = event->button.x;
				up.u.mouse.y = event->button.y;
				do_dispatch_event(L, &up);
			}

			mouse_timeout = 0;
			mouse_long_timeout = 0;
			mouse_state = MOUSE_STATE_NONE;
		}
		break;

	case SDL_MOUSEMOTION:

		/* show mouse cursor */
		if (pointer_timeout == 0) {
			SDL_ShowCursor(SDL_ENABLE);
		}
		pointer_timeout = now + POINTER_TIMEOUT;

		if (event->motion.state & SDL_BUTTON(1)) {
			if ( (mouse_state == MOUSE_STATE_DOWN || mouse_state == MOUSE_STATE_SENT)) {
				jevent.type = JIVE_EVENT_MOUSE_DRAG;
				jevent.u.mouse.x = event->motion.x;
				jevent.u.mouse.y = event->motion.y;
			}
		}
		else {
			jevent.type = JIVE_EVENT_MOUSE_MOVE;
			jevent.u.mouse.x = event->motion.x;
			jevent.u.mouse.y = event->motion.y;
		}
		break;

	case SDL_KEYDOWN:
		if (event->key.keysym.mod == KMOD_NONE || event->key.keysym.mod == KMOD_NUM) {
			if (event->key.keysym.sym == SDLK_UP) {
				jevent.type = JIVE_EVENT_SCROLL;
				--(jevent.u.scroll.rel);
				break;
			}
			else if (event->key.keysym.sym == SDLK_DOWN) {
				jevent.type = JIVE_EVENT_SCROLL;
				++(jevent.u.scroll.rel);
				break;
			}
		}
		// Fall through

	case SDL_KEYUP: {
		struct jive_keymap *entry = keymap;

#ifdef EMULATE_IR
		if (event->key.keysym.mod & (KMOD_ALT|KMOD_MODE)) {
			struct jive_keyir *ir = irmap;

			while (ir->keysym != SDLK_UNKNOWN) {
				if (ir->keysym == event->key.keysym.sym) {
					break;
				}
				ir++;
			}
			if (ir->keysym == SDLK_UNKNOWN) {
				break;
			}

			if (event->type == SDL_KEYDOWN) {
				jevent.type = JIVE_EVENT_IR_DOWN;
				jevent.u.ir.code = ir->code;
			}
			else {
				JiveEvent irup;

				jevent.type = JIVE_EVENT_IR_PRESS;
				jevent.u.ir.code = ir->code;

				memset(&irup, 0, sizeof(JiveEvent));
				irup.type = JIVE_EVENT_IR_UP;
				irup.ticks = jive_jiffies();
				irup.u.ir.code = ir->code;
				jive_queue_event(&irup);
			}

			break;
		}
#endif

		while (entry->keysym != SDLK_UNKNOWN) {
			if (entry->keysym == event->key.keysym.sym) {
				if (event->type == SDL_KEYDOWN && (!entry->mod || entry->mod == event->key.keysym.mod)) {
					// match a key with same modifiers if present on keydown
					break;
				}
				if (event->type == SDL_KEYUP && (key_mask & entry->keycode)) {
					// match a key which is currently marked as down ignoring modifiers as they may have changed
					break;
				}
			}
			entry++;
		}

		if (entry->keysym == SDLK_UNKNOWN) {
			// handle regular character keys ('a', 't', etc..)
			if (event->type == SDL_KEYDOWN && event->key.keysym.unicode != 0) {
				jevent.type = JIVE_EVENT_CHAR_PRESS;
				if (event->key.keysym.sym == SDLK_BACKSPACE) {
					//special case for Backspace, where value set is not ascii value, instead pass backspace ascii value
					jevent.u.text.unicode = 8;
				} else {
					jevent.u.text.unicode = event->key.keysym.unicode;
				}
			}
		}

		/* handle pgup/upgn and cursors as repeatable keys */
		else if (entry->keysym == SDLK_PAGEUP || entry->keysym == SDLK_PAGEDOWN ||
				entry->keysym == SDLK_UP || entry->keysym == SDLK_DOWN || entry->keysym == SDLK_LEFT || entry->keysym == SDLK_RIGHT) {
			if (event->type == SDL_KEYDOWN) {
				jevent.type = JIVE_EVENT_KEY_PRESS;
				jevent.ticks = jive_jiffies();
				jevent.u.key.code = entry->keycode;
			}
		}
		
		else if (event->type == SDL_KEYDOWN) {
			if (key_mask & entry->keycode) {
				// ignore key repeats
				return 0;
			}
			if (key_mask == 0) {
				key_state = KEY_STATE_NONE;
			}

			switch (key_state) {
			case KEY_STATE_NONE:
				key_state = KEY_STATE_DOWN;
				// fall through

			case KEY_STATE_DOWN: {
				key_mask |= entry->keycode;

				jevent.type = JIVE_EVENT_KEY_DOWN;
				jevent.u.key.code = entry->keycode;

				key_timeout = now + HOLD_TIMEOUT;
				break;
			 }

			case KEY_STATE_SENT:
				break;
			}
		}
		else /* SDL_KEYUP */ {
			if (! (key_mask & entry->keycode)) {
				// ignore repeated key ups
				return 0;
			}

			switch (key_state) {
			case KEY_STATE_NONE:
				break;

			case KEY_STATE_DOWN: {
				/*
				 * KEY_PRESSED and KEY_UP events
				 */
				JiveEvent keyup;

				jevent.type = JIVE_EVENT_KEY_PRESS;
				jevent.u.key.code = key_mask;

				memset(&keyup, 0, sizeof(JiveEvent));
				keyup.type = JIVE_EVENT_KEY_UP;
				keyup.ticks = jive_jiffies();
				keyup.u.key.code = entry->keycode;
				jive_queue_event(&keyup);

				key_state = KEY_STATE_SENT;
				break;
			}

			case KEY_STATE_SENT: {
				/*
				 * KEY_UP event
				 */
				jevent.type = JIVE_EVENT_KEY_UP;
				jevent.u.key.code = entry->keycode;
				break;
			}
			}

			key_timeout = 0;
			key_mask &= ~(entry->keycode);
			if (key_mask == 0) {
				key_state = KEY_STATE_NONE;
			}
		}
		break;
	}

	case SDL_USEREVENT:
		assert(event->user.code == JIVE_USER_EVENT_EVENT);

		memcpy(&jevent, event->user.data1, sizeof(JiveEvent));
		free(event->user.data1);
		break;

	case SDL_VIDEORESIZE: {
		JiveSurface *srf;
		int bpp = 16;

		screen_w = event->resize.w;
		screen_h = event->resize.h;

		srf = jive_surface_set_video_mode(screen_w, screen_h, bpp, jive_surface_isSDLFullScreen(NULL));

		if (!srf) {
			LOG_ERROR(log_ui_draw, "Video mode not supported: %dx%d\n", screen_w, screen_h);

			SDL_Quit();
			exit(-1);
		}

		lua_getfield(L, 1, "screen");

		lua_getfield(L, -1, "bounds");
		lua_pushinteger(L, screen_w);
		lua_rawseti(L, -2, 3);
		lua_pushinteger(L, screen_h);
		lua_rawseti(L, -2, 4);
		lua_pop(L, 1);

		tolua_pushusertype(L, srf, "Surface");
		lua_setfield(L, -2, "surface");

		lua_pop(L, 1);

		next_jive_origin++;

		jevent.type = JIVE_EVENT_WINDOW_RESIZE;
		
		/* Avoid mouse_up causing a mouse press event to occur */
		mouse_state = MOUSE_STATE_NONE;
		break;

	}

	default:
		return 0;
	}

	return do_dispatch_event(L, &jevent);
}
예제 #2
0
static int process_event(lua_State *L, SDL_Event *event) {
	JiveEvent jevent;
	Uint32 now;

	memset(&jevent, 0, sizeof(JiveEvent));
	jevent.ticks = now = jive_jiffies();

	switch (event->type) {
	case SDL_QUIT:
		jiveL_quit(L);
		exit(0);
		break;

	case SDL_MOUSEBUTTONDOWN:
		/* map the mouse scroll wheel to up/down */
		if (event->button.button == SDL_BUTTON_WHEELUP) {
			jevent.type = JIVE_EVENT_SCROLL;
			--(jevent.u.scroll.rel);
			break;
		}
		else if (event->button.button == SDL_BUTTON_WHEELDOWN) {
			jevent.type = JIVE_EVENT_SCROLL;
			++(jevent.u.scroll.rel);
			break;
		}

		// Fall through

	case SDL_MOUSEBUTTONUP:
		if (event->button.button == SDL_BUTTON_LEFT) {
			if (event->button.state == SDL_PRESSED) {
				jevent.type = JIVE_EVENT_MOUSE_DOWN;
				jevent.u.mouse.x = event->button.x;
				jevent.u.mouse.y = event->button.y;
			}
			else {
				jevent.type = JIVE_EVENT_MOUSE_UP;
				jevent.u.mouse.x = event->button.x;
				jevent.u.mouse.y = event->button.y;
			}
		}

		if (event->type == SDL_MOUSEBUTTONDOWN) {
			if (mouse_state == MOUSE_STATE_NONE) {
				mouse_state = MOUSE_STATE_DOWN;
				mouse_timeout_arg = (event->button.y << 16) | event->button.x;
				mouse_timeout = now + HOLD_TIMEOUT;
				mouse_long_timeout = now + LONG_HOLD_TIMEOUT;

				mouse_origin_x = event->button.x;
				mouse_origin_y = event->button.y;
				break;
			}
		}
		else /* SDL_MOUSEBUTTONUP */ {
			if (mouse_state == MOUSE_STATE_DOWN) {
				/*
				 * MOUSE_PRESSED and MOUSE_UP events
				 */
				JiveEvent up;

				memset(&up, 0, sizeof(JiveEvent));
				up.type = JIVE_EVENT_MOUSE_PRESS;
				up.ticks = jive_jiffies();
				up.u.mouse.x = event->button.x;
				up.u.mouse.y = event->button.y;
				do_dispatch_event(L, &up);
			}

			mouse_timeout = 0;
			mouse_long_timeout = 0;
			mouse_state = MOUSE_STATE_NONE;
		}
		break;

	case SDL_MOUSEMOTION:

		/* show mouse cursor */
		if (pointer_timeout == 0) {
			SDL_ShowCursor(SDL_ENABLE);
		}
		pointer_timeout = now + POINTER_TIMEOUT;

		if (event->motion.state & SDL_BUTTON(1)) {
			if ( (mouse_state == MOUSE_STATE_DOWN || mouse_state == MOUSE_STATE_SENT)) {
				jevent.type = JIVE_EVENT_MOUSE_DRAG;
				jevent.u.mouse.x = event->motion.x;
				jevent.u.mouse.y = event->motion.y;
			}
		}
		else {
			jevent.type = JIVE_EVENT_MOUSE_MOVE;
			jevent.u.mouse.x = event->motion.x;
			jevent.u.mouse.y = event->motion.y;
		}
		break;

	case SDL_KEYDOWN:
		/*
		  this emulates the scrollwheel using keypresses - remove for them moment as we want 4 way navigation

		if (event->key.keysym.mod == KMOD_NONE || event->key.keysym.mod == KMOD_NUM) {
			if (event->key.keysym.sym == SDLK_UP) {
				jevent.type = JIVE_EVENT_SCROLL;
				--(jevent.u.scroll.rel);
				break;
			}
			else if (event->key.keysym.sym == SDLK_DOWN) {
				jevent.type = JIVE_EVENT_SCROLL;
				++(jevent.u.scroll.rel);
				break;
			}
		}
		*/
		// Fall through

	case SDL_KEYUP: {
		struct jive_keymap *entry = keymap;
		
		if (event->key.keysym.mod & (KMOD_ALT|KMOD_MODE)) {
			/* simulate IR input, using alt key */
			struct jive_keyir *ir = irmap;

			while (ir->keysym != SDLK_UNKNOWN) {
				if (ir->keysym == event->key.keysym.sym) {
					break;
				}
				ir++;
			}
			if (ir->keysym == SDLK_UNKNOWN) {
				break;
			}

			if (event->type == SDL_KEYDOWN) {
				jevent.type = JIVE_EVENT_IR_DOWN;
				jevent.u.ir.code = ir->code;
			}
			else {
				JiveEvent irup;

				jevent.type = JIVE_EVENT_IR_PRESS;
				jevent.u.ir.code = ir->code;

				memset(&irup, 0, sizeof(JiveEvent));
				irup.type = JIVE_EVENT_IR_UP;
				irup.ticks = jive_jiffies();
				irup.u.ir.code = ir->code;
				jive_queue_event(&irup);
			}

			break;
		}

		while (entry->keysym != SDLK_UNKNOWN) {
			if (entry->keysym == event->key.keysym.sym) {
				break;
			}
			entry++;
		}

		if (entry->keysym == SDLK_UNKNOWN) {
			// handle regular character keys ('a', 't', etc..)
			if (event->type == SDL_KEYDOWN && event->key.keysym.unicode != 0) {
				jevent.type = JIVE_EVENT_CHAR_PRESS;
				if (event->key.keysym.sym == SDLK_BACKSPACE) {
					//special case for Backspace, where value set is not ascii value, instead pass backspace ascii value
					jevent.u.text.unicode = 8;
				} else {
					jevent.u.text.unicode = event->key.keysym.unicode;
				}
			}
		}

		/* handle pgup/upgn as repeatable keys */
		else if (entry->keysym == SDLK_PAGEUP || entry->keysym == SDLK_PAGEDOWN ||
				 entry->keysym == SDLK_UP || entry->keysym == SDLK_DOWN || entry->keysym == SDLK_LEFT || entry->keysym == SDLK_RIGHT ) {
			if (event->type == SDL_KEYDOWN) {
				jevent.type = JIVE_EVENT_KEY_PRESS;
				jevent.ticks = jive_jiffies();
				jevent.u.key.code = entry->keycode;
			}
		}
		
		else if (event->type == SDL_KEYDOWN) {
			if (key_mask & entry->keycode) {
				// ignore key repeats
				return 0;
			}
			if (key_mask == 0) {
				key_state = KEY_STATE_NONE;
			}

			switch (key_state) {
			case KEY_STATE_NONE:
				key_state = KEY_STATE_DOWN;
				// fall through

			case KEY_STATE_DOWN: {
				key_mask |= entry->keycode;

				jevent.type = JIVE_EVENT_KEY_DOWN;
				jevent.u.key.code = entry->keycode;

				key_timeout = now + HOLD_TIMEOUT;
				break;
			 }

			case KEY_STATE_SENT:
				break;
			}
		}
		else /* SDL_KEYUP */ {
			if (! (key_mask & entry->keycode)) {
				// ignore repeated key ups
				return 0;
			}

			switch (key_state) {
			case KEY_STATE_NONE:
				break;

			case KEY_STATE_DOWN: {
				/*
				 * KEY_PRESSED and KEY_UP events
				 */
				JiveEvent keyup;

				jevent.type = JIVE_EVENT_KEY_PRESS;
				jevent.u.key.code = key_mask;

				memset(&keyup, 0, sizeof(JiveEvent));
				keyup.type = JIVE_EVENT_KEY_UP;
				keyup.ticks = jive_jiffies();
				keyup.u.key.code = entry->keycode;
				jive_queue_event(&keyup);

				key_state = KEY_STATE_SENT;
				break;
			}

			case KEY_STATE_SENT: {
				/*
				 * KEY_UP event
				 */
				jevent.type = JIVE_EVENT_KEY_UP;
				jevent.u.key.code = entry->keycode;
				break;
			}
			}

			key_timeout = 0;
			key_mask &= ~(entry->keycode);
			if (key_mask == 0) {
				key_state = KEY_STATE_NONE;
			}
		}
		break;
	}

	case SDL_USEREVENT:
		assert(event->user.code == JIVE_USER_EVENT_EVENT);

		memcpy(&jevent, event->user.data1, sizeof(JiveEvent));
		free(event->user.data1);
		break;

		/* disable for the moment as it causes continual resizing
		   if the event for a resize gets delayed as we have a stack of resize notifications which cause resize to the old size

	case SDL_VIDEORESIZE: {
		JiveSurface *srf;
		int bpp = 16;

		screen_w = event->resize.w;
		screen_h = event->resize.h;

		srf = jive_surface_set_video_mode(screen_w, screen_h, bpp, false);

		lua_getfield(L, 1, "screen");

		lua_getfield(L, -1, "bounds");
		lua_pushinteger(L, screen_w);
		lua_rawseti(L, -2, 3);
		lua_pushinteger(L, screen_h);
		lua_rawseti(L, -2, 4);
		lua_pop(L, 1);

		JiveSurface **p = (JiveSurface **)lua_newuserdata(L, sizeof(JiveSurface *));
		*p = jive_surface_ref(srf);
		luaL_getmetatable(L, "JiveSurface");
		lua_setmetatable(L, -2);

		lua_setfield(L, -2, "surface");

		lua_pop(L, 1);

		next_jive_origin++;

		jevent.type = JIVE_EVENT_WINDOW_RESIZE;
		
		mouse_state = MOUSE_STATE_NONE;
		break;

	}
	*/

	default:
		return 0;
	}

	return do_dispatch_event(L, &jevent);
}