static int windows_filter_pump(const SDL_Event *event) { //handle multimedia button events if (event->type == SDL_SYSWMEVENT) { SDL_SysWMmsg *wmmsg; wmmsg = event->syswm.msg; if (wmmsg->msg == WM_APPCOMMAND) { switch (GET_APPCOMMAND_LPARAM(wmmsg->lParam)) { case APPCOMMAND_MEDIA_NEXTTRACK: jive_send_key_event(JIVE_EVENT_KEY_PRESS, JIVE_KEY_FWD, jive_jiffies()); return 0; // return non-zero, because we have handled the message (see MSDN doc) case APPCOMMAND_MEDIA_PREVIOUSTRACK: jive_send_key_event(JIVE_EVENT_KEY_PRESS, JIVE_KEY_REW, jive_jiffies()); return 0; case APPCOMMAND_MEDIA_PLAY_PAUSE: jive_send_key_event(JIVE_EVENT_KEY_PRESS, JIVE_KEY_PAUSE, jive_jiffies()); return 0; case APPCOMMAND_VOLUME_DOWN: jive_send_key_event(JIVE_EVENT_KEY_DOWN, JIVE_KEY_VOLUME_DOWN, jive_jiffies()); jive_send_key_event(JIVE_EVENT_KEY_UP, JIVE_KEY_VOLUME_DOWN, jive_jiffies()); return 0; case APPCOMMAND_VOLUME_UP: jive_send_key_event(JIVE_EVENT_KEY_DOWN, JIVE_KEY_VOLUME_UP, jive_jiffies()); jive_send_key_event(JIVE_EVENT_KEY_UP, JIVE_KEY_VOLUME_UP, jive_jiffies()); return 0; //todo: APPCOMMAND_MEDIA_STOP or JIVE_KEY_VOLUME_UP - do anything for these? default : break; } } } return 1; }
void jive_send_char_press_event(Uint16 unicode) { JiveEvent event; memset(&event, 0, sizeof(JiveEvent)); event.type = JIVE_EVENT_CHAR_PRESS; event.ticks = jive_jiffies(); event.u.text.unicode = unicode; jive_queue_event(&event); }
void jive_send_gesture_event(JiveGesture code) { JiveEvent event; memset(&event, 0, sizeof(JiveEvent)); event.type = JIVE_EVENT_GESTURE; event.ticks = jive_jiffies(); event.u.gesture.code = code; jive_queue_event(&event); }
static void process_timers(lua_State *L) { JiveEvent jevent; Uint32 now; memset(&jevent, 0, sizeof(JiveEvent)); jevent.ticks = now = jive_jiffies(); if (pointer_timeout && pointer_timeout < now) { SDL_ShowCursor(SDL_DISABLE); pointer_timeout = 0; } if (mouse_timeout && mouse_timeout < now) { if (mouse_state == MOUSE_STATE_DOWN) { jevent.type = JIVE_EVENT_MOUSE_HOLD; jevent.u.mouse.x = (mouse_timeout_arg >> 0) & 0xFFFF; jevent.u.mouse.y = (mouse_timeout_arg >> 16) & 0xFFFF; mouse_state = MOUSE_STATE_SENT; do_dispatch_event(L, &jevent); } mouse_timeout = 0; }
/* dns resolver thread */ static int dns_resolver_thread(void *p) { socket_t fd = (long) p; struct hostent *hostent; struct in_addr **addr, byaddr; char **alias; size_t len; char *buf; char *failed_error = NULL; Uint32 failed_timeout = 0; while (1) { if (recv(fd, &len, sizeof(len), 0) < 0) { /* broken pipe */ return 0; } buf = malloc(len + 1); if (recv(fd, buf, len, 0) < 0) { /* broken pipe */ free(buf); return 0; } buf[len] = '\0'; if (failed_error && stat_resolv_conf()) { #ifndef _WIN32 //reload resolv.conf res_init(); #endif } else if (failed_error && !stat_resolv_conf()) { Uint32 now = jive_jiffies(); if (now - failed_timeout < RESOLV_TIMEOUT) { write_str(fd, failed_error); free(buf); continue; } } failed_error = NULL; if (inet_aton(buf, &byaddr)) { hostent = gethostbyaddr((char *) &byaddr, sizeof(addr), AF_INET); } else { hostent = gethostbyname(buf); } free(buf); if (hostent == NULL) { /* error */ switch (h_errno) { case HOST_NOT_FOUND: write_str(fd, "Not found"); break; case NO_DATA: write_str(fd, "No data"); break; case NO_RECOVERY: failed_error = "No recovery"; failed_timeout = jive_jiffies(); write_str(fd, failed_error); break; case TRY_AGAIN: failed_error = "Try again"; failed_timeout = jive_jiffies(); write_str(fd, failed_error); break; } } else { write_str(fd, ""); // no error write_str(fd, hostent->h_name); alias = hostent->h_aliases; while (*alias) { write_str(fd, *alias); alias++; } write_str(fd, ""); // end of aliases addr = (struct in_addr **) hostent->h_addr_list; while (*addr) { write_str(fd, inet_ntoa(**addr)); addr++; } write_str(fd, ""); // end if addrs } } }
int jiveL_dispatch_event(lua_State *L) { Uint32 r = 0; Uint32 t0 = 0, t1 = 0; clock_t c0 = 0, c1 = 0; /* stack is: * 1: framework * 2: widget * 3: event */ if (perfwarn.event) { t0 = jive_jiffies(); c0 = clock(); } lua_pushcfunction(L, jive_traceback); /* push traceback function */ // call global event listeners if (jive_getmethod(L, 1, "_event")) { lua_pushvalue(L, 1); // framework lua_pushvalue(L, 3); // event lua_pushboolean(L, 1); // global listeners if (lua_pcall(L, 3, 1, 4) != 0) { LOG_WARN(log_ui_draw, "error in event function:\n\t%s\n", lua_tostring(L, -1)); return 0; } r |= lua_tointeger(L, -1); lua_pop(L, 1); } /* by default send the event to the top window. fetch that top * window here in case the global event handler has modified * the window stack. */ if (lua_isnil(L, 2)) { lua_getfield(L, 1, "windowStack"); if (lua_objlen(L, -1) == 0) { lua_pop(L, 1); return 0; } lua_rawgeti(L, -1, 1); lua_replace(L, 2); } // call widget event handler, unless the event is consumed if (!(r & JIVE_EVENT_CONSUME) && jive_getmethod(L, 2, "_event")) { lua_pushvalue(L, 2); // widget lua_pushvalue(L, 3); // event if (lua_pcall(L, 2, 1, 4) != 0) { LOG_WARN(log_ui_draw, "error in event function:\n\t%s\n", lua_tostring(L, -1)); return 0; } r |= lua_tointeger(L, -1); lua_pop(L, 1); } // call unused event listeners, unless the event is consumed if (!(r & JIVE_EVENT_CONSUME) && jive_getmethod(L, 1, "_event")) { lua_pushvalue(L, 1); // framework lua_pushvalue(L, 3); // event lua_pushboolean(L, 0); // unused listeners if (lua_pcall(L, 3, 1, 4) != 0) { LOG_WARN(log_ui_draw, "error in event function:\n\t%s\n", lua_tostring(L, -1)); return 0; } r |= lua_tointeger(L, -1); lua_pop(L, 1); } if (perfwarn.event) { t1 = jive_jiffies(); c1 = clock(); if (t1-t0 > perfwarn.event) { printf("process_event > %dms: %4dms (%dms) ", perfwarn.event, t1-t0, (int)((c1-c0) * 1000 / CLOCKS_PER_SEC)); lua_getglobal(L, "tostring"); lua_pushvalue(L, 2); lua_call(L, 1, 1); lua_pushcfunction(L, jiveL_event_tostring); lua_pushvalue(L, 3); lua_call(L, 1, 1); printf("[widget:%s event:%s]\n", lua_tostring(L, -2), lua_tostring(L, -1)); lua_pop(L, 2); } } lua_pushinteger(L, r); return 1; }
static int _draw_screen(lua_State *L) { JiveSurface *srf; Uint32 t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0; clock_t c0 = 0, c1 = 0; bool_t standalone_draw, drawn = false; JIVEL_STACK_CHECK_BEGIN(L); /* stack is: * 1: framework * 2: surface (in screen format) * 3: standalone_draw (used to draw screen to a new surface) */ srf = tolua_tousertype(L, 2, 0); standalone_draw = lua_toboolean(L, 3); /* Exit if we have no windows, nothing to draw */ lua_getfield(L, 1, "windowStack"); if (lua_objlen(L, -1) == 0) { lua_pop(L, 1); JIVEL_STACK_CHECK_ASSERT(L); return 0; } lua_rawgeti(L, -1, 1); // topwindow if (perfwarn.screen) { t0 = jive_jiffies(); c0 = clock(); } do { jive_origin = next_jive_origin; /* Layout window and widgets */ if (jive_getmethod(L, -1, "checkLayout")) { lua_pushvalue(L, -2); lua_call(L, 1, 0); } /* check in case the origin changes during layout */ } while (jive_origin != next_jive_origin); if (perfwarn.screen) t1 = jive_jiffies(); /* Widget animations - don't update in a standalone draw as its not the main screen update */ if (!standalone_draw) { lua_getfield(L, 1, "animations"); lua_pushnil(L); while (lua_next(L, -2) != 0) { lua_getfield(L, -1, "animations"); lua_pushnil(L); while (lua_next(L, -2) != 0) { int frame; /* stack is: * -2: key * -1: table */ lua_rawgeti(L, -1, 2); frame = lua_tointeger(L, -1) - 1; if (frame == 0) { lua_rawgeti(L, -2, 1); // function lua_pushvalue(L, -6); // widget lua_call(L, 1, 0); // function is poped by lua_call lua_rawgeti(L, -2, 3); lua_rawseti(L, -3, 2); } else { lua_pushinteger(L, frame); lua_rawseti(L, -3, 2); } lua_pop(L, 2); } lua_pop(L, 2); } lua_pop(L, 1); } if (perfwarn.screen) t2 = jive_jiffies(); /* Window transitions */ lua_getfield(L, 1, "transition"); if (!lua_isnil(L, -1)) { /* Draw background */ jive_surface_set_clip(srf, NULL); jive_tile_set_alpha(jive_background, 0); // no alpha channel jive_tile_blit(jive_background, srf, 0, 0, screen_w, screen_h); if (perfwarn.screen) t3 = jive_jiffies(); /* Animate screen transition */ lua_pushvalue(L, -1); lua_pushvalue(L, -3); // widget lua_pushvalue(L, 2); // surface lua_call(L, 2, 0); drawn = true; } else if (jive_dirty_region.w || standalone_draw) { SDL_Rect dirty; /* only redraw dirty region for non standalone draws */ if (!standalone_draw) { jive_rect_union(&jive_dirty_region, &last_dirty_region, &dirty); jive_surface_set_clip(srf, &dirty); } #if 0 printf("REDRAW: %d,%d %dx%d\n", jive_dirty_region.x, jive_dirty_region.y, jive_dirty_region.w, jive_dirty_region.h); printf("--> %d,%d %dx%d\n", dirty.x, dirty.y, dirty.w, dirty.h); #endif /* Draw background */ jive_tile_blit(jive_background, srf, 0, 0, screen_w, screen_h); if (perfwarn.screen) t3 = jive_jiffies(); /* Draw screen */ if (jive_getmethod(L, -2, "draw")) { lua_pushvalue(L, -3); // widget lua_pushvalue(L, 2); // surface lua_pushinteger(L, JIVE_LAYER_ALL); // layer lua_call(L, 3, 0); } #if 0 // show the dirty region for debug purposes: jive_surface_rectangleColor(srf, jive_dirty_region.x, jive_dirty_region.y, jive_dirty_region.x + jive_dirty_region.w, jive_dirty_region.y + jive_dirty_region.h, 0xFFFFFFFF); #endif /* clear the dirty region for non standalone draws */ if (!standalone_draw) { memcpy(&last_dirty_region, &jive_dirty_region, sizeof(last_dirty_region)); jive_dirty_region.w = 0; } drawn = true; } if (perfwarn.screen) { t4 = jive_jiffies(); c1 = clock(); if (t4-t0 > perfwarn.screen) { if (!t3) { t3 = t2; } printf("update_screen > %dms: %4dms (%dms) [layout:%dms animate:%dms background:%dms draw:%dms]\n", perfwarn.screen, t4-t0, (int)((c1-c0) * 1000 / CLOCKS_PER_SEC), t1-t0, t2-t1, t3-t2, t4-t3); } } lua_pop(L, 3); JIVEL_STACK_CHECK_END(L); lua_pushboolean(L, drawn); return 1; }
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); }
int jiveL_get_ticks(lua_State *L) { lua_pushinteger(L, jive_jiffies()); return 1; }
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); }