kbdrepeat.c

Go to the documentation of this file.
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 

Generated on Thu Jun 2 07:45:44 2011 for HelenOS/USB by  doxygen 1.4.7