Statistics
| Branch: | Revision:

root / input.c @ 46aaebff

History | View | Annotate | Download (7.7 kB)

1
/*
2
 * QEMU System Emulator
3
 *
4
 * Copyright (c) 2003-2008 Fabrice Bellard
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24

    
25
#include "sysemu.h"
26
#include "net.h"
27
#include "monitor.h"
28
#include "console.h"
29
#include "qjson.h"
30

    
31
static QEMUPutKBDEvent *qemu_put_kbd_event;
32
static void *qemu_put_kbd_event_opaque;
33
static QTAILQ_HEAD(, QEMUPutLEDEntry) led_handlers = QTAILQ_HEAD_INITIALIZER(led_handlers);
34
static QTAILQ_HEAD(, QEMUPutMouseEntry) mouse_handlers =
35
    QTAILQ_HEAD_INITIALIZER(mouse_handlers);
36
static NotifierList mouse_mode_notifiers = 
37
    NOTIFIER_LIST_INITIALIZER(mouse_mode_notifiers);
38

    
39
void qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
40
{
41
    qemu_put_kbd_event_opaque = opaque;
42
    qemu_put_kbd_event = func;
43
}
44

    
45
void qemu_remove_kbd_event_handler(void)
46
{
47
    qemu_put_kbd_event_opaque = NULL;
48
    qemu_put_kbd_event = NULL;
49
}
50

    
51
static void check_mode_change(void)
52
{
53
    static int current_is_absolute, current_has_absolute;
54
    int is_absolute;
55
    int has_absolute;
56

    
57
    is_absolute = kbd_mouse_is_absolute();
58
    has_absolute = kbd_mouse_has_absolute();
59

    
60
    if (is_absolute != current_is_absolute ||
61
        has_absolute != current_has_absolute) {
62
        notifier_list_notify(&mouse_mode_notifiers);
63
    }
64

    
65
    current_is_absolute = is_absolute;
66
    current_has_absolute = has_absolute;
67
}
68

    
69
QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
70
                                                void *opaque, int absolute,
71
                                                const char *name)
72
{
73
    QEMUPutMouseEntry *s;
74
    static int mouse_index = 0;
75

    
76
    s = qemu_mallocz(sizeof(QEMUPutMouseEntry));
77

    
78
    s->qemu_put_mouse_event = func;
79
    s->qemu_put_mouse_event_opaque = opaque;
80
    s->qemu_put_mouse_event_absolute = absolute;
81
    s->qemu_put_mouse_event_name = qemu_strdup(name);
82
    s->index = mouse_index++;
83

    
84
    QTAILQ_INSERT_TAIL(&mouse_handlers, s, node);
85

    
86
    check_mode_change();
87

    
88
    return s;
89
}
90

    
91
void qemu_activate_mouse_event_handler(QEMUPutMouseEntry *entry)
92
{
93
    QTAILQ_REMOVE(&mouse_handlers, entry, node);
94
    QTAILQ_INSERT_HEAD(&mouse_handlers, entry, node);
95

    
96
    check_mode_change();
97
}
98

    
99
void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry)
100
{
101
    QTAILQ_REMOVE(&mouse_handlers, entry, node);
102

    
103
    qemu_free(entry->qemu_put_mouse_event_name);
104
    qemu_free(entry);
105

    
106
    check_mode_change();
107
}
108

    
109
QEMUPutLEDEntry *qemu_add_led_event_handler(QEMUPutLEDEvent *func,
110
                                            void *opaque)
111
{
112
    QEMUPutLEDEntry *s;
113

    
114
    s = qemu_mallocz(sizeof(QEMUPutLEDEntry));
115

    
116
    s->put_led = func;
117
    s->opaque = opaque;
118
    QTAILQ_INSERT_TAIL(&led_handlers, s, next);
119
    return s;
120
}
121

    
122
void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry)
123
{
124
    if (entry == NULL)
125
        return;
126
    QTAILQ_REMOVE(&led_handlers, entry, next);
127
    qemu_free(entry);
128
}
129

    
130
void kbd_put_keycode(int keycode)
131
{
132
    if (qemu_put_kbd_event) {
133
        qemu_put_kbd_event(qemu_put_kbd_event_opaque, keycode);
134
    }
135
}
136

    
137
void kbd_put_ledstate(int ledstate)
138
{
139
    QEMUPutLEDEntry *cursor;
140

    
141
    QTAILQ_FOREACH(cursor, &led_handlers, next) {
142
        cursor->put_led(cursor->opaque, ledstate);
143
    }
144
}
145

    
146
void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
147
{
148
    QEMUPutMouseEntry *entry;
149
    QEMUPutMouseEvent *mouse_event;
150
    void *mouse_event_opaque;
151
    int width;
152

    
153
    if (QTAILQ_EMPTY(&mouse_handlers)) {
154
        return;
155
    }
156

    
157
    entry = QTAILQ_FIRST(&mouse_handlers);
158

    
159
    mouse_event = entry->qemu_put_mouse_event;
160
    mouse_event_opaque = entry->qemu_put_mouse_event_opaque;
161

    
162
    if (mouse_event) {
163
        if (graphic_rotate) {
164
            if (entry->qemu_put_mouse_event_absolute)
165
                width = 0x7fff;
166
            else
167
                width = graphic_width - 1;
168
            mouse_event(mouse_event_opaque,
169
                        width - dy, dx, dz, buttons_state);
170
        } else
171
            mouse_event(mouse_event_opaque,
172
                        dx, dy, dz, buttons_state);
173
    }
174
}
175

    
176
int kbd_mouse_is_absolute(void)
177
{
178
    if (QTAILQ_EMPTY(&mouse_handlers)) {
179
        return 0;
180
    }
181

    
182
    return QTAILQ_FIRST(&mouse_handlers)->qemu_put_mouse_event_absolute;
183
}
184

    
185
int kbd_mouse_has_absolute(void)
186
{
187
    QEMUPutMouseEntry *entry;
188

    
189
    QTAILQ_FOREACH(entry, &mouse_handlers, node) {
190
        if (entry->qemu_put_mouse_event_absolute) {
191
            return 1;
192
        }
193
    }
194

    
195
    return 0;
196
}
197

    
198
static void info_mice_iter(QObject *data, void *opaque)
199
{
200
    QDict *mouse;
201
    Monitor *mon = opaque;
202

    
203
    mouse = qobject_to_qdict(data);
204
    monitor_printf(mon, "%c Mouse #%" PRId64 ": %s%s\n",
205
                  (qdict_get_bool(mouse, "current") ? '*' : ' '),
206
                   qdict_get_int(mouse, "index"), qdict_get_str(mouse, "name"),
207
                   qdict_get_bool(mouse, "absolute") ? " (absolute)" : "");
208
}
209

    
210
void do_info_mice_print(Monitor *mon, const QObject *data)
211
{
212
    QList *mice_list;
213

    
214
    mice_list = qobject_to_qlist(data);
215
    if (qlist_empty(mice_list)) {
216
        monitor_printf(mon, "No mouse devices connected\n");
217
        return;
218
    }
219

    
220
    qlist_iter(mice_list, info_mice_iter, mon);
221
}
222

    
223
void do_info_mice(Monitor *mon, QObject **ret_data)
224
{
225
    QEMUPutMouseEntry *cursor;
226
    QList *mice_list;
227
    int current;
228

    
229
    mice_list = qlist_new();
230

    
231
    if (QTAILQ_EMPTY(&mouse_handlers)) {
232
        goto out;
233
    }
234

    
235
    current = QTAILQ_FIRST(&mouse_handlers)->index;
236

    
237
    QTAILQ_FOREACH(cursor, &mouse_handlers, node) {
238
        QObject *obj;
239
        obj = qobject_from_jsonf("{ 'name': %s,"
240
                                 "  'index': %d,"
241
                                 "  'current': %i,"
242
                                 "  'absolute': %i }",
243
                                 cursor->qemu_put_mouse_event_name,
244
                                 cursor->index,
245
                                 cursor->index == current,
246
                                 !!cursor->qemu_put_mouse_event_absolute);
247
        qlist_append_obj(mice_list, obj);
248
    }
249

    
250
out:
251
    *ret_data = QOBJECT(mice_list);
252
}
253

    
254
void do_mouse_set(Monitor *mon, const QDict *qdict)
255
{
256
    QEMUPutMouseEntry *cursor;
257
    int index = qdict_get_int(qdict, "index");
258
    int found = 0;
259

    
260
    if (QTAILQ_EMPTY(&mouse_handlers)) {
261
        monitor_printf(mon, "No mouse devices connected\n");
262
        return;
263
    }
264

    
265
    QTAILQ_FOREACH(cursor, &mouse_handlers, node) {
266
        if (cursor->index == index) {
267
            found = 1;
268
            qemu_activate_mouse_event_handler(cursor);
269
            break;
270
        }
271
    }
272

    
273
    if (!found) {
274
        monitor_printf(mon, "Mouse at given index not found\n");
275
    }
276

    
277
    check_mode_change();
278
}
279

    
280
void qemu_add_mouse_mode_change_notifier(Notifier *notify)
281
{
282
    notifier_list_add(&mouse_mode_notifiers, notify);
283
}
284

    
285
void qemu_remove_mouse_mode_change_notifier(Notifier *notify)
286
{
287
    notifier_list_remove(&mouse_mode_notifiers, notify);
288
}