~jakub/helenos/ia64-revival

« back to all changes in this revision

Viewing changes to uspace/drv/bus/usb/usbhid/kbd/kbdrepeat.c

  • Committer: Jakub Jermar
  • Date: 2012-02-18 16:47:38 UTC
  • mfrom: (527.1.874 HelenOS.mainline)
  • Revision ID: jakub@jermar.eu-20120218164738-abnijv1f5ckddwd9
MergeĀ mainlineĀ changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
44
44
#include "kbdrepeat.h"
45
45
#include "kbddev.h"
46
46
 
47
 
 
48
 
/** Delay between auto-repeat state checks when no key is being repeated. */
49
 
static unsigned int CHECK_DELAY = 10000;
50
 
 
51
 
/*----------------------------------------------------------------------------*/
52
47
/**
53
48
 * Main loop handling the auto-repeat of keys.
54
49
 *
59
54
 *
60
55
 * If the same key is still pressed, it uses the delay between repeats stored
61
56
 * in the keyboard structure to wait until the key should be repeated.
62
 
 * 
 
57
 *
63
58
 * If the currently repeated key is not pressed any more (
64
 
 * usb_kbd_repeat_stop() was called), it stops repeating it and starts 
 
59
 * usb_kbd_repeat_stop() was called), it stops repeating it and starts
65
60
 * checking again.
66
61
 *
67
62
 * @note For accessing the keyboard device auto-repeat information a fibril
68
63
 *       mutex (repeat_mtx) from the @a kbd structure is used.
69
 
 * 
 
64
 *
70
65
 * @param kbd Keyboard device structure.
71
66
 */
72
67
static void usb_kbd_repeat_loop(usb_kbd_t *kbd)
73
68
{
74
69
        unsigned int delay = 0;
75
 
        
 
70
 
76
71
        usb_log_debug("Starting autorepeat loop.\n");
77
72
 
78
73
        while (true) {
79
 
                // check if the kbd structure is usable
 
74
                /* Check if the kbd structure is usable. */
80
75
                if (!usb_kbd_is_initialized(kbd)) {
81
 
                        if (usb_kbd_is_ready_to_destroy(kbd)) {
82
 
                                usb_kbd_free(&kbd);
83
 
                                assert(kbd == NULL);
84
 
                        }
 
76
                        usb_log_warning("kbd not ready, exiting autorepeat.\n");
85
77
                        return;
86
78
                }
87
 
                
88
 
                fibril_mutex_lock(kbd->repeat_mtx);
 
79
 
 
80
                fibril_mutex_lock(&kbd->repeat_mtx);
89
81
 
90
82
                if (kbd->repeat.key_new > 0) {
91
83
                        if (kbd->repeat.key_new == kbd->repeat.key_repeated) {
92
 
                                usb_log_debug2("Repeating key: %u.\n", 
 
84
                                usb_log_debug2("Repeating key: %u.\n",
93
85
                                    kbd->repeat.key_repeated);
94
 
                                // ugly hack with the NULL
95
 
                                usb_kbd_push_ev(NULL, kbd, KEY_PRESS, 
 
86
                                usb_kbd_push_ev(kbd, KEY_PRESS,
96
87
                                    kbd->repeat.key_repeated);
97
88
                                delay = kbd->repeat.delay_between;
98
89
                        } else {
109
100
                        }
110
101
                        delay = CHECK_DELAY;
111
102
                }
112
 
                fibril_mutex_unlock(kbd->repeat_mtx);
113
 
                
 
103
                fibril_mutex_unlock(&kbd->repeat_mtx);
114
104
                async_usleep(delay);
115
105
        }
116
106
}
117
 
 
118
107
/*----------------------------------------------------------------------------*/
119
108
/**
120
109
 * Main routine to be executed by a fibril for handling auto-repeat.
121
110
 *
122
111
 * Starts the loop for checking changes in auto-repeat.
123
 
 * 
 
112
 *
124
113
 * @param arg User-specified argument. Expects pointer to the keyboard device
125
114
 *            structure representing the keyboard.
126
115
 *
130
119
int usb_kbd_repeat_fibril(void *arg)
131
120
{
132
121
        usb_log_debug("Autorepeat fibril spawned.\n");
133
 
        
 
122
 
134
123
        if (arg == NULL) {
135
124
                usb_log_error("No device!\n");
136
125
                return EINVAL;
137
126
        }
138
 
        
139
 
        usb_kbd_t *kbd = (usb_kbd_t *)arg;
140
 
        
 
127
 
 
128
        usb_kbd_t *kbd = arg;
 
129
 
141
130
        usb_kbd_repeat_loop(kbd);
142
 
        
 
131
 
143
132
        return EOK;
144
133
}
145
 
 
146
134
/*----------------------------------------------------------------------------*/
147
135
/**
148
136
 * Start repeating particular key.
156
144
 */
157
145
void usb_kbd_repeat_start(usb_kbd_t *kbd, unsigned int key)
158
146
{
159
 
        fibril_mutex_lock(kbd->repeat_mtx);
 
147
        fibril_mutex_lock(&kbd->repeat_mtx);
160
148
        kbd->repeat.key_new = key;
161
 
        fibril_mutex_unlock(kbd->repeat_mtx);
 
149
        fibril_mutex_unlock(&kbd->repeat_mtx);
162
150
}
163
 
 
164
151
/*----------------------------------------------------------------------------*/
165
152
/**
166
153
 * Stop repeating particular key.
167
154
 *
168
155
 * @note Only one key is repeated at any time, but this function may be called
169
 
 *       even with key that is not currently repeated (in that case nothing 
 
156
 *       even with key that is not currently repeated (in that case nothing
170
157
 *       happens).
171
158
 *
172
159
 * @param kbd Keyboard device structure.
174
161
 */
175
162
void usb_kbd_repeat_stop(usb_kbd_t *kbd, unsigned int key)
176
163
{
177
 
        fibril_mutex_lock(kbd->repeat_mtx);
 
164
        fibril_mutex_lock(&kbd->repeat_mtx);
178
165
        if (key == kbd->repeat.key_new) {
179
166
                kbd->repeat.key_new = 0;
180
167
        }
181
 
        fibril_mutex_unlock(kbd->repeat_mtx);
 
168
        fibril_mutex_unlock(&kbd->repeat_mtx);
182
169
}
183
 
 
184
170
/**
185
171
 * @}
186
172
 */