|
|
1.1 root 1: /* $Id: gtk-mouse.c,v 1.1 2003/07/31 01:41:48 fredette Exp $ */
2:
3: /* host/gtk/gtk-mouse.c - GTK mouse support: */
4:
5: /*
6: * Copyright (c) 2003 Matt Fredette
7: * All rights reserved.
8: *
9: * Redistribution and use in source and binary forms, with or without
10: * modification, are permitted provided that the following conditions
11: * are met:
12: * 1. Redistributions of source code must retain the above copyright
13: * notice, this list of conditions and the following disclaimer.
14: * 2. Redistributions in binary form must reproduce the above copyright
15: * notice, this list of conditions and the following disclaimer in the
16: * documentation and/or other materials provided with the distribution.
17: * 3. All advertising materials mentioning features or use of this software
18: * must display the following acknowledgement:
19: * This product includes software developed by Matt Fredette.
20: * 4. The name of the author may not be used to endorse or promote products
21: * derived from this software without specific prior written permission.
22: *
23: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
27: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33: * POSSIBILITY OF SUCH DAMAGE.
34: */
35:
36: #include <tme/common.h>
37: _TME_RCSID("$Id: gtk-mouse.c,v 1.1 2003/07/31 01:41:48 fredette Exp $");
38:
39: /* includes: */
40: #include "gtk-display.h"
41: #include <gdk/gdkkeysyms.h>
42:
43: /* macros: */
44: #define TME_GTK_MOUSE_CURSOR_WIDTH (16)
45: #define TME_GTK_MOUSE_CURSOR_HEIGHT (16)
46:
47: /* types: */
48:
49: /* globals: */
50:
51: /* our invisible cursor: */
52: static const unsigned char _tme_gtk_mouse_cursor_source[(TME_GTK_MOUSE_CURSOR_WIDTH
53: * TME_GTK_MOUSE_CURSOR_HEIGHT
54: / 8)] =
55: {
56: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
59: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
60: };
61: static const unsigned char _tme_gtk_mouse_cursor_mask[(TME_GTK_MOUSE_CURSOR_WIDTH
62: * TME_GTK_MOUSE_CURSOR_HEIGHT
63: / 8)] =
64: {
65: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69: };
70: static GdkColor _tme_gtk_mouse_cursor_color = { 0, 0, 0, 0 };
71:
72: /* if X11 support is present: */
73: #ifndef X_DISPLAY_MISSING
74:
75: /* includes: */
76: #include <gdk/gdkx.h>
77: #include <X11/Xlib.h>
78:
79: #if TME_MOUSE_EVENT_TIME_UNDEF != CurrentTime
80: #error "TME_MOUSE_EVENT_TIME_UNDEF and CurrentTime disagree"
81: #endif
82:
83: /* this warps the pointer to the middle of the GtkImage: */
84: static void
85: _tme_gtk_mouse_warp_pointer(struct tme_gtk_screen *screen)
86: {
87: XWarpPointer(GDK_DISPLAY(),
88: None,
89: GDK_WINDOW_XWINDOW(screen->tme_gtk_screen_gtkimage->window),
90: 0, 0, 0, 0,
91: screen->tme_gtk_screen_mouse_warp_x,
92: screen->tme_gtk_screen_mouse_warp_y);
93: }
94:
95: #endif /* !X_DISPLAY_MISSING */
96:
97: /* this is for debugging only: */
98: #if 0
99: #include <stdio.h>
100: void
101: _tme_gtk_mouse_debug(const struct tme_mouse_event *event)
102: {
103: fprintf(stderr,
104: "buttons = 0x%02x dx=%d dy=%d\n",
105: event->tme_mouse_event_buttons,
106: event->tme_mouse_event_delta_x,
107: event->tme_mouse_event_delta_y);
108: }
109: #else
110: #define _tme_gtk_mouse_debug(e) do { } while (/* CONSTCOND */ 0)
111: #endif
112:
113: /* this is a GTK callback for a mouse event in the framebuffer event box: */
114: static int
115: _tme_gtk_mouse_mouse_event(GtkWidget *widget,
116: GdkEvent *gdk_event_raw,
117: struct tme_gtk_screen *screen)
118: {
119: struct tme_gtk_display *display;
120: struct tme_mouse_event tme_event;
121: guint x;
122: guint y;
123: guint state, button;
124: unsigned int buttons;
125: int was_empty;
126: int new_callouts;
127: int rc;
128:
129: /* start the tme event: */
130: tme_event.tme_mouse_event_delta_units
131: = TME_MOUSE_UNITS_UNKNOWN;
132:
133: /* recover our data structure: */
134: display = screen->tme_gtk_screen_display;
135:
136: /* lock the mutex: */
137: tme_mutex_lock(&display->tme_gtk_display_mutex);
138:
139: /* if this is motion: */
140: if (gdk_event_raw->type == GDK_MOTION_NOTIFY) {
141:
142: /* this event must have happened in the gtkimage: */
143: assert (gdk_event_raw->motion.window
144: == screen->tme_gtk_screen_gtkimage->window);
145:
146: /* set the event time: */
147: tme_event.tme_mouse_event_time
148: = gdk_event_raw->motion.time;
149:
150: /* the buttons haven't changed: */
151: tme_event.tme_mouse_event_buttons =
152: screen->tme_gtk_screen_mouse_buttons_last;
153:
154: /* if the pointer position hasn't changed either, return now.
155: every time we warp the pointer we will get a motion event, and
156: this should ignore those events: */
157: x = gdk_event_raw->motion.x;
158: y = gdk_event_raw->motion.y;
159: if (x == screen->tme_gtk_screen_mouse_warp_x
160: && y == screen->tme_gtk_screen_mouse_warp_y) {
161:
162: /* unlock the mutex: */
163: tme_mutex_unlock(&display->tme_gtk_display_mutex);
164:
165: /* stop propagating this event: */
166: return (TRUE);
167: }
168:
169: /* warp the pointer back to center: */
170: _tme_gtk_mouse_warp_pointer(screen);
171: }
172:
173: /* otherwise, this must be a button press or a release: */
174: else {
175: assert (gdk_event_raw->type == GDK_BUTTON_PRESS
176: || gdk_event_raw->type == GDK_BUTTON_RELEASE);
177:
178: /* this event must have happened in the gtkimage: */
179: assert (gdk_event_raw->button.window
180: == screen->tme_gtk_screen_gtkimage->window);
181:
182: /* set the event time: */
183: tme_event.tme_mouse_event_time
184: = gdk_event_raw->button.time;
185:
186: /* get the pointer position: */
187: x = gdk_event_raw->button.x;
188: y = gdk_event_raw->button.y;
189:
190: /* make the buttons mask: */
191: buttons = 0;
192: button = gdk_event_raw->button.button;
193: state = gdk_event_raw->button.state;
194: #define _TME_GTK_MOUSE_BUTTON(i, gdk, tme) \
195: if ((button == i) \
196: ? (gdk_event_raw->type == GDK_BUTTON_PRESS) \
197: : (state & gdk)) \
198: buttons |= tme
199: _TME_GTK_MOUSE_BUTTON(1, GDK_BUTTON1_MASK, TME_MOUSE_BUTTON_0);
200: _TME_GTK_MOUSE_BUTTON(2, GDK_BUTTON2_MASK, TME_MOUSE_BUTTON_1);
201: _TME_GTK_MOUSE_BUTTON(3, GDK_BUTTON3_MASK, TME_MOUSE_BUTTON_2);
202: _TME_GTK_MOUSE_BUTTON(4, GDK_BUTTON4_MASK, TME_MOUSE_BUTTON_3);
203: _TME_GTK_MOUSE_BUTTON(5, GDK_BUTTON5_MASK, TME_MOUSE_BUTTON_4);
204: #undef _TME_GTK_MOUSE_BUTTON
205: tme_event.tme_mouse_event_buttons = buttons;
206: screen->tme_gtk_screen_mouse_buttons_last = buttons;
207: }
208:
209: /* make the deltas: */
210: tme_event.tme_mouse_event_delta_x =
211: (((int) x)
212: - ((int) screen->tme_gtk_screen_mouse_warp_x));
213: tme_event.tme_mouse_event_delta_y =
214: (((int) y)
215: - ((int) screen->tme_gtk_screen_mouse_warp_y));
216:
217: /* assume that we won't need any new callouts: */
218: new_callouts = 0;
219:
220: /* remember if the mouse buffer was empty: */
221: was_empty
222: = tme_mouse_buffer_is_empty(display->tme_gtk_display_mouse_buffer);
223:
224: /* add this tme event to the mouse buffer: */
225: _tme_gtk_mouse_debug(&tme_event);
226: rc = tme_mouse_buffer_copyin(display->tme_gtk_display_mouse_buffer,
227: &tme_event);
228: assert (rc == TME_OK);
229:
230: /* if the mouse buffer was empty and now it isn't,
231: call out the mouse controls: */
232: if (was_empty
233: && !tme_mouse_buffer_is_empty(display->tme_gtk_display_mouse_buffer)) {
234: new_callouts |= TME_GTK_DISPLAY_CALLOUT_MOUSE_CTRL;
235: }
236:
237: /* run any callouts: */
238: _tme_gtk_display_callout(display, new_callouts);
239:
240: /* unlock the mutex: */
241: tme_mutex_unlock(&display->tme_gtk_display_mutex);
242:
243: /* stop propagating this event: */
244: return (TRUE);
245: }
246:
247: /* this is a GTK callback for an event in the event box containing the
248: mouse label: */
249: static int
250: _tme_gtk_mouse_ebox_event(GtkWidget *widget,
251: GdkEvent *gdk_event_raw,
252: struct tme_gtk_screen *screen)
253: {
254: struct tme_gtk_display *display;
255: int rc;
256: gint junk;
257: char *status;
258:
259: /* if this is an enter notify event, grab the focus and continue
260: propagating the event: */
261: if (gdk_event_raw->type == GDK_ENTER_NOTIFY) {
262: gtk_widget_grab_focus(widget);
263: return (FALSE);
264: }
265:
266: /* if this is not a key press event, continue propagating it now: */
267: if (gdk_event_raw->type != GDK_KEY_PRESS) {
268: return (FALSE);
269: }
270:
271: /* recover our data structure: */
272: display = screen->tme_gtk_screen_display;
273:
274: /* lock the mutex: */
275: tme_mutex_lock(&display->tme_gtk_display_mutex);
276:
277: /* the mouse must not be on already: */
278: assert (screen->tme_gtk_screen_mouse_keyval
279: == GDK_VoidSymbol);
280:
281: /* this keyval must not be GDK_VoidSymbol: */
282: assert (gdk_event_raw->key.keyval
283: != GDK_VoidSymbol);
284:
285: /* set the text on the mouse label: */
286: gtk_label_set_text(GTK_LABEL(screen->tme_gtk_screen_mouse_label),
287: _("Mouse is on"));
288:
289: /* push the mouse status onto the statusbar: */
290: status = NULL;
291: tme_output_append(&status,
292: _("Press the %s key to turn the mouse off"),
293: gdk_keyval_name(gdk_event_raw->key.keyval));
294: gtk_statusbar_push(GTK_STATUSBAR(screen->tme_gtk_screen_mouse_statusbar),
295: screen->tme_gtk_screen_mouse_statusbar_cid,
296: status);
297: tme_free(status);
298:
299: /* if the original events mask on the framebuffer event box have
300: never been saved, save them now, and add the mouse events: */
301: if (screen->tme_gtk_screen_mouse_events_old == 0) {
302: screen->tme_gtk_screen_mouse_events_old
303: = gdk_window_get_events(screen->tme_gtk_screen_event_box->window);
304: gtk_widget_add_events(screen->tme_gtk_screen_event_box,
305: GDK_POINTER_MOTION_MASK
306: | GDK_BUTTON_PRESS_MASK
307: | GDK_BUTTON_RELEASE_MASK);
308: }
309:
310: /* get the current width and height of the framebuffer gtkimage, and
311: halve them to get the warp center: */
312: gdk_window_get_geometry(screen->tme_gtk_screen_gtkimage->window,
313: &junk,
314: &junk,
315: &screen->tme_gtk_screen_mouse_warp_x,
316: &screen->tme_gtk_screen_mouse_warp_y,
317: &junk);
318: screen->tme_gtk_screen_mouse_warp_x >>= 1;
319: screen->tme_gtk_screen_mouse_warp_y >>= 1;
320:
321: /* warp the pointer to center: */
322: _tme_gtk_mouse_warp_pointer(screen);
323:
324: /* grab the pointer: */
325: rc
326: = gdk_pointer_grab(screen->tme_gtk_screen_gtkimage->window,
327: TRUE,
328: GDK_POINTER_MOTION_MASK
329: | GDK_BUTTON_PRESS_MASK
330: | GDK_BUTTON_RELEASE_MASK,
331: screen->tme_gtk_screen_gtkimage->window,
332: display->tme_gtk_display_mouse_cursor,
333: gdk_event_raw->key.time);
334: assert (rc == 0);
335:
336: /* we are now in mouse mode: */
337: screen->tme_gtk_screen_mouse_keyval
338: = gdk_event_raw->key.keyval;
339:
340: /* unlock the mutex: */
341: tme_mutex_unlock(&display->tme_gtk_display_mutex);
342:
343: /* stop propagating this event: */
344: return (TRUE);
345: }
346:
347: /* this turns mouse mode off. it is called with the mutex locked: */
348: void
349: _tme_gtk_mouse_mode_off(struct tme_gtk_screen *screen,
350: guint32 time)
351: {
352: /* the mouse must be on: */
353: assert (screen->tme_gtk_screen_mouse_keyval
354: != GDK_VoidSymbol);
355:
356: /* ungrab the pointer: */
357: gdk_pointer_ungrab(time);
358:
359: /* restore the old events mask on the event box: */
360: gdk_window_set_events(screen->tme_gtk_screen_event_box->window,
361: screen->tme_gtk_screen_mouse_events_old);
362:
363: /* pop our message off of the statusbar: */
364: gtk_statusbar_pop(GTK_STATUSBAR(screen->tme_gtk_screen_mouse_statusbar),
365: screen->tme_gtk_screen_mouse_statusbar_cid);
366:
367: /* restore the text on the mouse label: */
368: gtk_label_set_text(GTK_LABEL(screen->tme_gtk_screen_mouse_label),
369: _("Mouse is off"));
370:
371: /* the mouse is now off: */
372: screen->tme_gtk_screen_mouse_keyval = GDK_VoidSymbol;
373: }
374:
375: /* this is called when the mouse controls change: */
376: static int
377: _tme_gtk_mouse_ctrl(struct tme_mouse_connection *conn_mouse,
378: unsigned int ctrl)
379: {
380: struct tme_gtk_display *display;
381:
382: /* recover our data structure: */
383: display = conn_mouse
384: ->tme_mouse_connection.tme_connection_element->tme_element_private;
385:
386: /* XXX TBD */
387: abort();
388:
389: return (TME_OK);
390: }
391:
392: /* this is called to read the mouse: */
393: static int
394: _tme_gtk_mouse_read(struct tme_mouse_connection *conn_mouse,
395: struct tme_mouse_event *event,
396: unsigned int count)
397: {
398: struct tme_gtk_display *display;
399: int rc;
400:
401: /* recover our data structure: */
402: display = conn_mouse
403: ->tme_mouse_connection.tme_connection_element->tme_element_private;
404:
405: /* lock the mutex: */
406: tme_mutex_lock(&display->tme_gtk_display_mutex);
407:
408: /* copy an event out of the mouse buffer: */
409: rc = tme_mouse_buffer_copyout(display->tme_gtk_display_mouse_buffer,
410: event,
411: count);
412:
413: /* unlock the mutex: */
414: tme_mutex_unlock(&display->tme_gtk_display_mutex);
415:
416: return (rc);
417: }
418:
419: /* this breaks a mouse connection: */
420: static int
421: _tme_gtk_mouse_connection_break(struct tme_connection *conn,
422: unsigned int state)
423: {
424: abort();
425: }
426:
427: /* this makes a new mouse connection: */
428: static int
429: _tme_gtk_mouse_connection_make(struct tme_connection *conn,
430: unsigned int state)
431: {
432: struct tme_gtk_display *display;
433:
434: /* recover our data structure: */
435: display = conn->tme_connection_element->tme_element_private;
436:
437: /* both sides must be mouse connections: */
438: assert(conn->tme_connection_type
439: == TME_CONNECTION_MOUSE);
440: assert(conn->tme_connection_other->tme_connection_type
441: == TME_CONNECTION_MOUSE);
442:
443: /* we are always set up to answer calls across the connection, so we
444: only have to do work when the connection has gone full, namely
445: taking the other side of the connection: */
446: if (state == TME_CONNECTION_FULL) {
447:
448: /* save our connection: */
449: tme_mutex_lock(&display->tme_gtk_display_mutex);
450: display->tme_gtk_display_mouse_connection
451: = (struct tme_mouse_connection *) conn->tme_connection_other;
452: tme_mutex_unlock(&display->tme_gtk_display_mutex);
453: }
454:
455: return (TME_OK);
456: }
457:
458: /* this scores a mouse connection: */
459: static int
460: _tme_gtk_mouse_connection_score(struct tme_connection *conn,
461: unsigned int *_score)
462: {
463: struct tme_mouse_connection *conn_mouse;
464:
465: /* both sides must be mouse connections: */
466: assert(conn->tme_connection_type == TME_CONNECTION_MOUSE);
467: assert(conn->tme_connection_other->tme_connection_type == TME_CONNECTION_MOUSE);
468:
469: /* the other side cannot be a real mouse: */
470: conn_mouse
471: = (struct tme_mouse_connection *) conn->tme_connection_other;
472: *_score = (conn_mouse->tme_mouse_connection_read == NULL);
473: return (TME_OK);
474: }
475:
476: /* this makes a new connection side for a GTK mouse: */
477: int
478: _tme_gtk_mouse_connections_new(struct tme_gtk_display *display,
479: struct tme_connection **_conns)
480: {
481: struct tme_mouse_connection *conn_mouse;
482: struct tme_connection *conn;
483:
484: /* if we don't have a mouse connection yet: */
485: if (display->tme_gtk_display_mouse_connection == NULL) {
486:
487: /* create our side of a mouse connection: */
488: conn_mouse = tme_new0(struct tme_mouse_connection, 1);
489: conn = &conn_mouse->tme_mouse_connection;
490:
491: /* fill in the generic connection: */
492: conn->tme_connection_next = *_conns;
493: conn->tme_connection_type = TME_CONNECTION_MOUSE;
494: conn->tme_connection_score = _tme_gtk_mouse_connection_score;
495: conn->tme_connection_make = _tme_gtk_mouse_connection_make;
496: conn->tme_connection_break = _tme_gtk_mouse_connection_break;
497:
498: /* fill in the mouse connection: */
499: conn_mouse->tme_mouse_connection_ctrl = _tme_gtk_mouse_ctrl;
500: conn_mouse->tme_mouse_connection_read = _tme_gtk_mouse_read;
501:
502: /* return the connection side possibility: */
503: *_conns = conn;
504: }
505:
506: /* done: */
507: return (TME_OK);
508: }
509:
510: /* this attaches the GTK mouse to a new screen: */
511: void
512: _tme_gtk_mouse_attach(struct tme_gtk_screen *screen)
513: {
514: struct tme_gtk_display *display;
515: GtkWidget *hbox0;
516: GtkWidget *ebox;
517:
518: /* get the display: */
519: display = screen->tme_gtk_screen_display;
520:
521: /* create the horizontal packing box for the mouse controls: */
522: hbox0 = gtk_hbox_new(FALSE, 0);
523:
524: /* pack the horizontal packing box into the outer vertical packing box: */
525: gtk_box_pack_start(GTK_BOX(screen->tme_gtk_screen_vbox0),
526: hbox0,
527: FALSE, FALSE, 0);
528:
529: /* show the horizontal packing box: */
530: gtk_widget_show(hbox0);
531:
532: /* create the event box for the mouse on label: */
533: ebox = gtk_event_box_new();
534:
535: /* pack the event box into the horizontal packing box: */
536: gtk_box_pack_start(GTK_BOX(hbox0),
537: ebox,
538: FALSE, FALSE, 0);
539:
540: /* set the tip on the event box, which will eventually contain the mouse on label: */
541: gtk_tooltips_set_tip(GTK_TOOLTIPS(display->tme_gtk_display_tooltips),
542: ebox,
543: "Press a key here to turn the mouse on. The same key " \
544: "will turn the mouse off.",
545: NULL);
546:
547: /* make sure the event box gets key_press events: */
548: gtk_widget_add_events(ebox,
549: GDK_KEY_PRESS_MASK);
550:
551: /* set a signal handler for the event box events: */
552: gtk_signal_connect(GTK_OBJECT(ebox),
553: "event",
554: GTK_SIGNAL_FUNC(_tme_gtk_mouse_ebox_event),
555: screen);
556:
557: /* the event box can focus: */
558: GTK_WIDGET_SET_FLAGS(ebox, GTK_CAN_FOCUS);
559:
560: /* show the event box: */
561: gtk_widget_show(ebox);
562:
563: /* create the mouse on label: */
564: screen->tme_gtk_screen_mouse_label
565: = gtk_label_new(_("Mouse is off"));
566:
567: /* add the mouse on label to the event box: */
568: gtk_container_add(GTK_CONTAINER(ebox),
569: screen->tme_gtk_screen_mouse_label);
570:
571: /* show the mouse on label: */
572: gtk_widget_show(screen->tme_gtk_screen_mouse_label);
573:
574: /* create the mouse statusbar: */
575: screen->tme_gtk_screen_mouse_statusbar
576: = gtk_statusbar_new();
577:
578: /* pack the mouse statusbar into the horizontal packing box: */
579: gtk_box_pack_start(GTK_BOX(hbox0),
580: screen->tme_gtk_screen_mouse_statusbar,
581: TRUE, TRUE, 10);
582:
583: /* show the mouse statusbar: */
584: gtk_widget_show(screen->tme_gtk_screen_mouse_statusbar);
585:
586: /* push an initial message onto the statusbar: */
587: screen->tme_gtk_screen_mouse_statusbar_cid
588: = gtk_statusbar_get_context_id(GTK_STATUSBAR(screen->tme_gtk_screen_mouse_statusbar),
589: "mouse context");
590: gtk_statusbar_push(GTK_STATUSBAR(screen->tme_gtk_screen_mouse_statusbar),
591: screen->tme_gtk_screen_mouse_statusbar_cid,
592: _("The Machine Emulator"));
593:
594: /* although the event mask doesn't include these events yet,
595: set a signal handler for the mouse events: */
596: gtk_signal_connect(GTK_OBJECT(screen->tme_gtk_screen_event_box),
597: "motion_notify_event",
598: GTK_SIGNAL_FUNC(_tme_gtk_mouse_mouse_event),
599: screen);
600: gtk_signal_connect(GTK_OBJECT(screen->tme_gtk_screen_event_box),
601: "button_press_event",
602: GTK_SIGNAL_FUNC(_tme_gtk_mouse_mouse_event),
603: screen);
604: gtk_signal_connect(GTK_OBJECT(screen->tme_gtk_screen_event_box),
605: "button_release_event",
606: GTK_SIGNAL_FUNC(_tme_gtk_mouse_mouse_event),
607: screen);
608:
609: /* mouse mode is off: */
610: screen->tme_gtk_screen_mouse_keyval = GDK_VoidSymbol;
611: }
612:
613: /* this initializes mouse part of the display: */
614: void
615: _tme_gtk_mouse_new(struct tme_gtk_display *display)
616: {
617: GdkPixmap *source, *mask;
618:
619: /* we have no mouse connection: */
620: display->tme_gtk_display_mouse_connection = NULL;
621:
622: /* allocate the mouse buffer: */
623: display->tme_gtk_display_mouse_buffer
624: = tme_mouse_buffer_new(1024);
625:
626: /* create the mouse cursor: */
627: source
628: = gdk_bitmap_create_from_data(NULL,
629: _tme_gtk_mouse_cursor_source,
630: TME_GTK_MOUSE_CURSOR_WIDTH,
631: TME_GTK_MOUSE_CURSOR_HEIGHT);
632: mask
633: = gdk_bitmap_create_from_data (NULL,
634: _tme_gtk_mouse_cursor_mask,
635: TME_GTK_MOUSE_CURSOR_WIDTH,
636: TME_GTK_MOUSE_CURSOR_HEIGHT);
637: display->tme_gtk_display_mouse_cursor
638: = gdk_cursor_new_from_pixmap(source,
639: mask,
640: &_tme_gtk_mouse_cursor_color,
641: &_tme_gtk_mouse_cursor_color,
642: 0,
643: 0);
644: gdk_pixmap_unref(source);
645: gdk_pixmap_unref(mask);
646: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.