/* * Start kdump: create a LGR log entry, store status of all CPUs and * branch to __do_machine_kdump. */ static noinline void __machine_kdump(void *image) { int this_cpu, cpu; lgr_info_log(); /* Get status of the other CPUs */ this_cpu = smp_find_processor_id(stap()); for_each_online_cpu(cpu) { if (cpu == this_cpu) continue; if (smp_store_status(cpu)) continue; } /* Store status of the boot CPU */ if (MACHINE_HAS_VX) save_vx_regs((void *) &S390_lowcore.vector_save_area); /* * To create a good backchain for this CPU in the dump store_status * is passed the address of a function. The address is saved into * the PSW save area of the boot CPU and the function is invoked as * a tail call of store_status. The backchain in the dump will look * like this: * restart_int_handler -> __machine_kexec -> __do_machine_kdump * The call to store_status() will not return. */ store_status(__do_machine_kdump, image); }
void warp_real_mouse_y(Uint32 my) { struct buffered_status *status = store_status(); int mx_real, my_real, y = my / 14; status->mouse_y = y; status->real_mouse_y = my; set_screen_coords(status->real_mouse_x, my, &mx_real, &my_real); real_warp_mouse(mx_real, my_real); }
void warp_real_mouse_x(Uint32 mx) { struct buffered_status *status = store_status(); int mx_real, my_real, x = mx / 8; status->mouse_x = x; status->real_mouse_x = mx; set_screen_coords(mx, status->real_mouse_y, &mx_real, &my_real); real_warp_mouse(mx_real, my_real); }
void wait_event(void) { struct buffered_status *status = store_status(); status->key = IKEY_UNKNOWN; status->unicode = 0; status->mouse_moved = 0; status->mouse_button = 0; __wait_event(); update_autorepeat(); }
void warp_mouse(Uint32 x, Uint32 y) { int mx_real, my_real, mx = (x * 8) + 4, my = (y * 14) + 7; struct buffered_status *status = store_status(); status->mouse_x = x; status->mouse_y = y; status->real_mouse_x = mx; status->real_mouse_y = my; set_screen_coords(mx, my, &mx_real, &my_real); real_warp_mouse(mx_real, my_real); }
static void bump_status(void) { Uint16 last_store_offset = input.store_offset; input.store_offset = (input.store_offset + 1) % num_buffered_events; input.load_offset = (input.store_offset + 1) % num_buffered_events; // No event buffering; nothing to do if(input.store_offset == input.load_offset) return; // Some events can "echo" from the previous buffer memcpy(store_status(), &input.buffer[last_store_offset], sizeof(struct buffered_status)); }
bool update_event_status(void) { struct buffered_status *status = store_status(); bool rval; status->key = IKEY_UNKNOWN; status->unicode = 0; status->mouse_moved = 0; status->mouse_button = 0; rval = __update_event_status(); rval |= update_autorepeat(); return rval; }
void force_last_key(enum keycode_type type, int val) { struct buffered_status *status = store_status(); switch(type) { case keycode_pc_xt: { enum keycode second; status->key_pressed = convert_xt_internal(val, &second); break; } case keycode_internal: { status->key_pressed = (enum keycode)val; break; } default: break; } }
static Octstr *httpd_store_status(List *cgivars, int status_type) { Octstr *reply; if ((reply = httpd_check_authorization(cgivars, 1))!= NULL) return reply; return store_status(status_type); }
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; }
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; } #if SDL_VERSION_ATLEAST(2,0,0) // emulate the X11-style "wheel is a button" that SDL 1.2 used case SDL_MOUSEWHEEL: { SDL_Event fake_event; fake_event.type = SDL_MOUSEBUTTONDOWN; fake_event.button.windowID = event->wheel.windowID; fake_event.button.which = event->wheel.which; fake_event.button.state = SDL_PRESSED; fake_event.button.x = 0; fake_event.button.y = 0; if(event->wheel.y < 0) fake_event.button.button = MOUSE_BUTTON_WHEELDOWN; else fake_event.button.button = MOUSE_BUTTON_WHEELUP; SDL_PushEvent(&fake_event); fake_event.type = SDL_MOUSEBUTTONUP; fake_event.button.state = SDL_RELEASED; SDL_PushEvent(&fake_event); break; } #endif // SDL_VERSION_ATLEAST(2,0,0) 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) { joystick_key_press(status, stuffed_key, stuffed_key); if(last_axis == (digital_value ^ 1)) { joystick_key_release(status, input.joystick_axis_map[which][axis][last_axis]); } } } else if(last_axis != -1) { joystick_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) joystick_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) joystick_key_release(status, stuffed_key); break; } case SDL_JOYHATMOTION: { int which = event->jhat.which; int dir = event->jhat.value; enum keycode key_up = input.joystick_hat_map[which][0]; enum keycode key_down = input.joystick_hat_map[which][1]; enum keycode key_left = input.joystick_hat_map[which][2]; enum keycode key_right = input.joystick_hat_map[which][3]; //if(dir & SDL_HAT_CENTERED) { joystick_key_release(status, key_up); joystick_key_release(status, key_down); joystick_key_release(status, key_left); joystick_key_release(status, key_right); } if(dir & SDL_HAT_UP) { if (key_up) joystick_key_press(status, key_up, key_up); } if(dir & SDL_HAT_DOWN) { if (key_down) joystick_key_press(status, key_down, key_down); } if(dir & SDL_HAT_LEFT) { if (key_left) joystick_key_press(status, key_left, key_left); } if(dir & SDL_HAT_RIGHT) { if (key_right) joystick_key_press(status, key_right, key_right); } break; } default: return false; } return true; }
int main(int argc, char **argv) { char id[UUID_STR_LEN + 1]; int cf_index, ret, type; Octstr *os, *store_type, *store_location, *status; Msg *msg; CfgGroup *grp; conf_file = NULL; gwlib_init(); //This can be overwritten with the -v flag at runtime log_set_output_level(DEFAULT_LOG_LEVEL); cf_index = get_and_set_debugs(argc, argv, check_args); if (argv[cf_index] == NULL) { print_usage(argv[0]); goto error; } if (conf_file == NULL) conf_file = octstr_create("kannel.conf"); cfg = cfg_create(conf_file); if (cfg_read(cfg) == -1) panic(0, "Couldn't read configuration from `%s'.", octstr_get_cstr(conf_file)); info(0, "1"); grp = cfg_get_single_group(cfg, octstr_imm("core")); if (grp == NULL) { printf("FATAL: Could not load Kannel's core group. Exiting.\n"); return 2; } store_location = cfg_get(grp, octstr_imm("store-location")); store_type = cfg_get(grp, octstr_imm("store-type")); store_init(store_type, store_location, -1, msg_pack, msg_unpack_wrapper); switch (command) { case COMMAND_LIST: printf("Listing records %d -> %d\n", list_from+1, list_limit); print_header(); store_load(print_msg); if (counter == 0) { printf("|%60s%14s%60s|\n", "", "Store is Empty", ""); } print_sep(); break; case COMMAND_DELETE: store_load(msg_count); msg = msg_create(ack); msg->ack.nack = ack_failed; msg->ack.time = time(NULL); uuid_parse(octstr_get_cstr(param_1), msg->ack.id); ret = store_save(msg); if (ret == 0) { printf("Deleted message %s\n", octstr_get_cstr(param_1)); counter--; } else { printf("Could not delete message %s\n", octstr_get_cstr(param_1)); } msg_destroy(msg); break; case COMMAND_EXPORT: counter = 0; type = 0; list = gwlist_create(); store_load(msg_push); printf("Exporting %ld messages...\n", gwlist_len(list)); if ((octstr_compare(param_1, octstr_imm("file")) == 0) || (octstr_compare(param_1, octstr_imm("spool")) == 0)) { store_shutdown(); store_init(param_1, param_2, -1, msg_pack, msg_unpack_wrapper); store_load(msg_count); while ((os = gwlist_extract_first(list)) != NULL) { msg = msg_unpack_wrapper(os); if (msg != NULL) { ret = store_save(msg); if (ret == 0) { counter++; } else { printf("Error saving message\n"); } } else { printf("Error extracting message\n"); } msg_destroy(msg); } status = NULL; } else if (octstr_compare(param_1, octstr_imm("text")) == 0) { status = store_status(BBSTATUS_TEXT); } else if (octstr_compare(param_1, octstr_imm("html")) == 0) { status = store_status(BBSTATUS_HTML); } else if (octstr_compare(param_1, octstr_imm("xml")) == 0) { status = store_status(BBSTATUS_XML); } else { status = NULL; } if (status != NULL) { file = fopen(octstr_get_cstr(param_2), "w"); if (file == NULL) { error(errno, "Failed to open '%s' for writing, cannot create output file", octstr_get_cstr(param_2)); return -1; } octstr_print(file, status); fflush(file); if (file != NULL) fclose(file); //printf("%s", octstr_get_cstr(status)); } gwlist_destroy(list, octstr_destroy_item); break; default: break; } octstr_destroy(store_type); octstr_destroy(store_location); cfg_destroy(cfg); store_shutdown(); error: gwlib_shutdown(); return 1; }
static bool update_autorepeat(void) { struct buffered_status *status = store_status(); bool rval = false; // Repeat code Uint8 last_key_state = status->keymap[status->key_repeat]; Uint8 last_mouse_state = status->mouse_repeat_state; if(last_key_state) { Uint32 new_time = get_ticks(); Uint32 ms_difference = new_time - status->keypress_time; if(last_key_state == 1) { if(ms_difference > KEY_REPEAT_START) { status->keypress_time = new_time; status->keymap[status->key_repeat] = 2; status->key = status->key_repeat; status->unicode = status->unicode_repeat; rval = true; } } else { if(ms_difference > KEY_REPEAT_RATE) { status->keypress_time = new_time; status->key = status->key_repeat; status->unicode = status->unicode_repeat; rval = true; } } } else if(input.repeat_stack_pointer) { // Take repeat off the stack. input.repeat_stack_pointer--; status->key_repeat = input.key_repeat_stack[input.repeat_stack_pointer]; status->unicode_repeat = input.unicode_repeat_stack[input.repeat_stack_pointer]; status->keypress_time = get_ticks(); } if(last_mouse_state) { Uint32 new_time = get_ticks(); Uint32 ms_difference = new_time - status->mouse_time; if(status->mouse_drag_state == -1) status->mouse_drag_state = 0; else status->mouse_drag_state = 1; if(last_mouse_state == 1) { if(ms_difference > MOUSE_REPEAT_START) { status->mouse_time = new_time; status->mouse_repeat_state = 2; status->mouse_button = status->mouse_repeat; rval = true; } } else { if(ms_difference > MOUSE_REPEAT_RATE) { status->mouse_time = new_time; status->mouse_button = status->mouse_repeat; rval = true; } } } bump_status(); return rval; }