00001 /* 00002 * Copyright (c) 2011 Lubos Slovak 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 00009 * - Redistributions of source code must retain the above copyright 00010 * notice, this list of conditions and the following disclaimer. 00011 * - Redistributions in binary form must reproduce the above copyright 00012 * notice, this list of conditions and the following disclaimer in the 00013 * documentation and/or other materials provided with the distribution. 00014 * - The name of the author may not be used to endorse or promote products 00015 * derived from this software without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 00018 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00019 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 00020 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 00021 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 00022 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00023 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00024 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00025 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00026 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00027 */ 00028 00037 #include <fibril_synch.h> 00038 #include <io/keycode.h> 00039 #include <io/console.h> 00040 #include <errno.h> 00041 00042 #include <usb/debug.h> 00043 00044 #include "kbdrepeat.h" 00045 #include "kbddev.h" 00046 00047 00049 static unsigned int CHECK_DELAY = 10000; 00050 00051 /*----------------------------------------------------------------------------*/ 00072 static void usb_kbd_repeat_loop(usb_kbd_t *kbd) 00073 { 00074 unsigned int delay = 0; 00075 00076 usb_log_debug("Starting autorepeat loop.\n"); 00077 00078 while (true) { 00079 // check if the kbd structure is usable 00080 if (!usb_kbd_is_initialized(kbd)) { 00081 if (usb_kbd_is_ready_to_destroy(kbd)) { 00082 usb_kbd_free(&kbd); 00083 assert(kbd == NULL); 00084 } 00085 return; 00086 } 00087 00088 fibril_mutex_lock(kbd->repeat_mtx); 00089 00090 if (kbd->repeat.key_new > 0) { 00091 if (kbd->repeat.key_new == kbd->repeat.key_repeated) { 00092 usb_log_debug2("Repeating key: %u.\n", 00093 kbd->repeat.key_repeated); 00094 // ugly hack with the NULL 00095 usb_kbd_push_ev(NULL, kbd, KEY_PRESS, 00096 kbd->repeat.key_repeated); 00097 delay = kbd->repeat.delay_between; 00098 } else { 00099 usb_log_debug("New key to repeat: %u.\n", 00100 kbd->repeat.key_new); 00101 kbd->repeat.key_repeated = kbd->repeat.key_new; 00102 delay = kbd->repeat.delay_before; 00103 } 00104 } else { 00105 if (kbd->repeat.key_repeated > 0) { 00106 usb_log_debug("Stopping to repeat key: %u.\n", 00107 kbd->repeat.key_repeated); 00108 kbd->repeat.key_repeated = 0; 00109 } 00110 delay = CHECK_DELAY; 00111 } 00112 fibril_mutex_unlock(kbd->repeat_mtx); 00113 00114 async_usleep(delay); 00115 } 00116 } 00117 00118 /*----------------------------------------------------------------------------*/ 00130 int usb_kbd_repeat_fibril(void *arg) 00131 { 00132 usb_log_debug("Autorepeat fibril spawned.\n"); 00133 00134 if (arg == NULL) { 00135 usb_log_error("No device!\n"); 00136 return EINVAL; 00137 } 00138 00139 usb_kbd_t *kbd = (usb_kbd_t *)arg; 00140 00141 usb_kbd_repeat_loop(kbd); 00142 00143 return EOK; 00144 } 00145 00146 /*----------------------------------------------------------------------------*/ 00157 void usb_kbd_repeat_start(usb_kbd_t *kbd, unsigned int key) 00158 { 00159 fibril_mutex_lock(kbd->repeat_mtx); 00160 kbd->repeat.key_new = key; 00161 fibril_mutex_unlock(kbd->repeat_mtx); 00162 } 00163 00164 /*----------------------------------------------------------------------------*/ 00175 void usb_kbd_repeat_stop(usb_kbd_t *kbd, unsigned int key) 00176 { 00177 fibril_mutex_lock(kbd->repeat_mtx); 00178 if (key == kbd->repeat.key_new) { 00179 kbd->repeat.key_new = 0; 00180 } 00181 fibril_mutex_unlock(kbd->repeat_mtx); 00182 } 00183