|
|
1.1.1.2 ! root 1: /* $Id: gtk-mouse.c,v 1.3 2007/03/03 15:33:22 fredette Exp $ */ 1.1 root 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> 1.1.1.2 ! root 37: _TME_RCSID("$Id: gtk-mouse.c,v 1.3 2007/03/03 15:33:22 fredette Exp $"); 1.1 root 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: */ 1.1.1.2 ! root 52: static const gchar _tme_gtk_mouse_cursor_source[(TME_GTK_MOUSE_CURSOR_WIDTH ! 53: * TME_GTK_MOUSE_CURSOR_HEIGHT ! 54: / 8)] = 1.1 root 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: }; 1.1.1.2 ! root 61: static const gchar _tme_gtk_mouse_cursor_mask[(TME_GTK_MOUSE_CURSOR_WIDTH ! 62: * TME_GTK_MOUSE_CURSOR_HEIGHT ! 63: / 8)] = 1.1 root 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; 1.1.1.2 ! root 121: gint x; ! 122: gint y; 1.1 root 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: 1.1.1.2 ! root 173: /* otherwise, if this is a double- or triple-click: */ ! 174: else if (gdk_event_raw->type == GDK_2BUTTON_PRESS ! 175: || gdk_event_raw->type == GDK_3BUTTON_PRESS) { ! 176: ! 177: /* we ignore double- and triple-click events, since normal button ! 178: press and release events are always generated also: */ ! 179: ! 180: /* unlock the mutex: */ ! 181: tme_mutex_unlock(&display->tme_gtk_display_mutex); ! 182: ! 183: /* stop propagating this event: */ ! 184: return (TRUE); ! 185: } ! 186: 1.1 root 187: /* otherwise, this must be a button press or a release: */ 188: else { 189: assert (gdk_event_raw->type == GDK_BUTTON_PRESS 190: || gdk_event_raw->type == GDK_BUTTON_RELEASE); 191: 192: /* this event must have happened in the gtkimage: */ 193: assert (gdk_event_raw->button.window 194: == screen->tme_gtk_screen_gtkimage->window); 195: 196: /* set the event time: */ 197: tme_event.tme_mouse_event_time 198: = gdk_event_raw->button.time; 199: 200: /* get the pointer position: */ 201: x = gdk_event_raw->button.x; 202: y = gdk_event_raw->button.y; 203: 204: /* make the buttons mask: */ 205: buttons = 0; 206: button = gdk_event_raw->button.button; 207: state = gdk_event_raw->button.state; 208: #define _TME_GTK_MOUSE_BUTTON(i, gdk, tme) \ 209: if ((button == i) \ 210: ? (gdk_event_raw->type == GDK_BUTTON_PRESS) \ 211: : (state & gdk)) \ 212: buttons |= tme 213: _TME_GTK_MOUSE_BUTTON(1, GDK_BUTTON1_MASK, TME_MOUSE_BUTTON_0); 214: _TME_GTK_MOUSE_BUTTON(2, GDK_BUTTON2_MASK, TME_MOUSE_BUTTON_1); 215: _TME_GTK_MOUSE_BUTTON(3, GDK_BUTTON3_MASK, TME_MOUSE_BUTTON_2); 216: _TME_GTK_MOUSE_BUTTON(4, GDK_BUTTON4_MASK, TME_MOUSE_BUTTON_3); 217: _TME_GTK_MOUSE_BUTTON(5, GDK_BUTTON5_MASK, TME_MOUSE_BUTTON_4); 218: #undef _TME_GTK_MOUSE_BUTTON 219: tme_event.tme_mouse_event_buttons = buttons; 220: screen->tme_gtk_screen_mouse_buttons_last = buttons; 221: } 222: 223: /* make the deltas: */ 224: tme_event.tme_mouse_event_delta_x = 225: (((int) x) 226: - ((int) screen->tme_gtk_screen_mouse_warp_x)); 227: tme_event.tme_mouse_event_delta_y = 228: (((int) y) 229: - ((int) screen->tme_gtk_screen_mouse_warp_y)); 230: 231: /* assume that we won't need any new callouts: */ 232: new_callouts = 0; 233: 234: /* remember if the mouse buffer was empty: */ 235: was_empty 236: = tme_mouse_buffer_is_empty(display->tme_gtk_display_mouse_buffer); 237: 238: /* add this tme event to the mouse buffer: */ 239: _tme_gtk_mouse_debug(&tme_event); 240: rc = tme_mouse_buffer_copyin(display->tme_gtk_display_mouse_buffer, 241: &tme_event); 242: assert (rc == TME_OK); 243: 244: /* if the mouse buffer was empty and now it isn't, 245: call out the mouse controls: */ 246: if (was_empty 247: && !tme_mouse_buffer_is_empty(display->tme_gtk_display_mouse_buffer)) { 248: new_callouts |= TME_GTK_DISPLAY_CALLOUT_MOUSE_CTRL; 249: } 250: 251: /* run any callouts: */ 252: _tme_gtk_display_callout(display, new_callouts); 253: 254: /* unlock the mutex: */ 255: tme_mutex_unlock(&display->tme_gtk_display_mutex); 256: 257: /* stop propagating this event: */ 258: return (TRUE); 259: } 260: 261: /* this is a GTK callback for an event in the event box containing the 262: mouse label: */ 263: static int 264: _tme_gtk_mouse_ebox_event(GtkWidget *widget, 265: GdkEvent *gdk_event_raw, 266: struct tme_gtk_screen *screen) 267: { 268: struct tme_gtk_display *display; 269: int rc; 270: gint junk; 271: char *status; 272: 273: /* if this is an enter notify event, grab the focus and continue 274: propagating the event: */ 275: if (gdk_event_raw->type == GDK_ENTER_NOTIFY) { 276: gtk_widget_grab_focus(widget); 277: return (FALSE); 278: } 279: 280: /* if this is not a key press event, continue propagating it now: */ 281: if (gdk_event_raw->type != GDK_KEY_PRESS) { 282: return (FALSE); 283: } 284: 285: /* recover our data structure: */ 286: display = screen->tme_gtk_screen_display; 287: 288: /* lock the mutex: */ 289: tme_mutex_lock(&display->tme_gtk_display_mutex); 290: 291: /* the mouse must not be on already: */ 292: assert (screen->tme_gtk_screen_mouse_keyval 293: == GDK_VoidSymbol); 294: 295: /* this keyval must not be GDK_VoidSymbol: */ 296: assert (gdk_event_raw->key.keyval 297: != GDK_VoidSymbol); 298: 299: /* set the text on the mouse label: */ 300: gtk_label_set_text(GTK_LABEL(screen->tme_gtk_screen_mouse_label), 301: _("Mouse is on")); 302: 303: /* push the mouse status onto the statusbar: */ 304: status = NULL; 305: tme_output_append(&status, 306: _("Press the %s key to turn the mouse off"), 307: gdk_keyval_name(gdk_event_raw->key.keyval)); 308: gtk_statusbar_push(GTK_STATUSBAR(screen->tme_gtk_screen_mouse_statusbar), 309: screen->tme_gtk_screen_mouse_statusbar_cid, 310: status); 311: tme_free(status); 312: 313: /* if the original events mask on the framebuffer event box have 314: never been saved, save them now, and add the mouse events: */ 315: if (screen->tme_gtk_screen_mouse_events_old == 0) { 316: screen->tme_gtk_screen_mouse_events_old 317: = gdk_window_get_events(screen->tme_gtk_screen_event_box->window); 318: gtk_widget_add_events(screen->tme_gtk_screen_event_box, 319: GDK_POINTER_MOTION_MASK 320: | GDK_BUTTON_PRESS_MASK 321: | GDK_BUTTON_RELEASE_MASK); 322: } 323: 324: /* get the current width and height of the framebuffer gtkimage, and 325: halve them to get the warp center: */ 326: gdk_window_get_geometry(screen->tme_gtk_screen_gtkimage->window, 327: &junk, 328: &junk, 329: &screen->tme_gtk_screen_mouse_warp_x, 330: &screen->tme_gtk_screen_mouse_warp_y, 331: &junk); 332: screen->tme_gtk_screen_mouse_warp_x >>= 1; 333: screen->tme_gtk_screen_mouse_warp_y >>= 1; 334: 335: /* warp the pointer to center: */ 336: _tme_gtk_mouse_warp_pointer(screen); 337: 338: /* grab the pointer: */ 339: rc 340: = gdk_pointer_grab(screen->tme_gtk_screen_gtkimage->window, 341: TRUE, 342: GDK_POINTER_MOTION_MASK 343: | GDK_BUTTON_PRESS_MASK 344: | GDK_BUTTON_RELEASE_MASK, 345: screen->tme_gtk_screen_gtkimage->window, 346: display->tme_gtk_display_mouse_cursor, 347: gdk_event_raw->key.time); 348: assert (rc == 0); 349: 350: /* we are now in mouse mode: */ 351: screen->tme_gtk_screen_mouse_keyval 352: = gdk_event_raw->key.keyval; 353: 354: /* unlock the mutex: */ 355: tme_mutex_unlock(&display->tme_gtk_display_mutex); 356: 357: /* stop propagating this event: */ 358: return (TRUE); 359: } 360: 361: /* this turns mouse mode off. it is called with the mutex locked: */ 362: void 363: _tme_gtk_mouse_mode_off(struct tme_gtk_screen *screen, 364: guint32 time) 365: { 366: /* the mouse must be on: */ 367: assert (screen->tme_gtk_screen_mouse_keyval 368: != GDK_VoidSymbol); 369: 370: /* ungrab the pointer: */ 371: gdk_pointer_ungrab(time); 372: 373: /* restore the old events mask on the event box: */ 374: gdk_window_set_events(screen->tme_gtk_screen_event_box->window, 375: screen->tme_gtk_screen_mouse_events_old); 376: 377: /* pop our message off of the statusbar: */ 378: gtk_statusbar_pop(GTK_STATUSBAR(screen->tme_gtk_screen_mouse_statusbar), 379: screen->tme_gtk_screen_mouse_statusbar_cid); 380: 381: /* restore the text on the mouse label: */ 382: gtk_label_set_text(GTK_LABEL(screen->tme_gtk_screen_mouse_label), 383: _("Mouse is off")); 384: 385: /* the mouse is now off: */ 386: screen->tme_gtk_screen_mouse_keyval = GDK_VoidSymbol; 387: } 388: 389: /* this is called when the mouse controls change: */ 390: static int 391: _tme_gtk_mouse_ctrl(struct tme_mouse_connection *conn_mouse, 392: unsigned int ctrl) 393: { 394: struct tme_gtk_display *display; 395: 396: /* recover our data structure: */ 397: display = conn_mouse 398: ->tme_mouse_connection.tme_connection_element->tme_element_private; 399: 400: /* XXX TBD */ 401: abort(); 402: 403: return (TME_OK); 404: } 405: 406: /* this is called to read the mouse: */ 407: static int 408: _tme_gtk_mouse_read(struct tme_mouse_connection *conn_mouse, 409: struct tme_mouse_event *event, 410: unsigned int count) 411: { 412: struct tme_gtk_display *display; 413: int rc; 414: 415: /* recover our data structure: */ 416: display = conn_mouse 417: ->tme_mouse_connection.tme_connection_element->tme_element_private; 418: 419: /* lock the mutex: */ 420: tme_mutex_lock(&display->tme_gtk_display_mutex); 421: 422: /* copy an event out of the mouse buffer: */ 423: rc = tme_mouse_buffer_copyout(display->tme_gtk_display_mouse_buffer, 424: event, 425: count); 426: 427: /* unlock the mutex: */ 428: tme_mutex_unlock(&display->tme_gtk_display_mutex); 429: 430: return (rc); 431: } 432: 433: /* this breaks a mouse connection: */ 434: static int 435: _tme_gtk_mouse_connection_break(struct tme_connection *conn, 436: unsigned int state) 437: { 438: abort(); 439: } 440: 441: /* this makes a new mouse connection: */ 442: static int 443: _tme_gtk_mouse_connection_make(struct tme_connection *conn, 444: unsigned int state) 445: { 446: struct tme_gtk_display *display; 447: 448: /* recover our data structure: */ 449: display = conn->tme_connection_element->tme_element_private; 450: 451: /* both sides must be mouse connections: */ 452: assert(conn->tme_connection_type 453: == TME_CONNECTION_MOUSE); 454: assert(conn->tme_connection_other->tme_connection_type 455: == TME_CONNECTION_MOUSE); 456: 457: /* we are always set up to answer calls across the connection, so we 458: only have to do work when the connection has gone full, namely 459: taking the other side of the connection: */ 460: if (state == TME_CONNECTION_FULL) { 461: 462: /* save our connection: */ 463: tme_mutex_lock(&display->tme_gtk_display_mutex); 464: display->tme_gtk_display_mouse_connection 465: = (struct tme_mouse_connection *) conn->tme_connection_other; 466: tme_mutex_unlock(&display->tme_gtk_display_mutex); 467: } 468: 469: return (TME_OK); 470: } 471: 472: /* this scores a mouse connection: */ 473: static int 474: _tme_gtk_mouse_connection_score(struct tme_connection *conn, 475: unsigned int *_score) 476: { 477: struct tme_mouse_connection *conn_mouse; 478: 479: /* both sides must be mouse connections: */ 480: assert(conn->tme_connection_type == TME_CONNECTION_MOUSE); 481: assert(conn->tme_connection_other->tme_connection_type == TME_CONNECTION_MOUSE); 482: 483: /* the other side cannot be a real mouse: */ 484: conn_mouse 485: = (struct tme_mouse_connection *) conn->tme_connection_other; 486: *_score = (conn_mouse->tme_mouse_connection_read == NULL); 487: return (TME_OK); 488: } 489: 490: /* this makes a new connection side for a GTK mouse: */ 491: int 492: _tme_gtk_mouse_connections_new(struct tme_gtk_display *display, 493: struct tme_connection **_conns) 494: { 495: struct tme_mouse_connection *conn_mouse; 496: struct tme_connection *conn; 497: 498: /* if we don't have a mouse connection yet: */ 499: if (display->tme_gtk_display_mouse_connection == NULL) { 500: 501: /* create our side of a mouse connection: */ 502: conn_mouse = tme_new0(struct tme_mouse_connection, 1); 503: conn = &conn_mouse->tme_mouse_connection; 504: 505: /* fill in the generic connection: */ 506: conn->tme_connection_next = *_conns; 507: conn->tme_connection_type = TME_CONNECTION_MOUSE; 508: conn->tme_connection_score = _tme_gtk_mouse_connection_score; 509: conn->tme_connection_make = _tme_gtk_mouse_connection_make; 510: conn->tme_connection_break = _tme_gtk_mouse_connection_break; 511: 512: /* fill in the mouse connection: */ 513: conn_mouse->tme_mouse_connection_ctrl = _tme_gtk_mouse_ctrl; 514: conn_mouse->tme_mouse_connection_read = _tme_gtk_mouse_read; 515: 516: /* return the connection side possibility: */ 517: *_conns = conn; 518: } 519: 520: /* done: */ 521: return (TME_OK); 522: } 523: 524: /* this attaches the GTK mouse to a new screen: */ 525: void 526: _tme_gtk_mouse_attach(struct tme_gtk_screen *screen) 527: { 528: struct tme_gtk_display *display; 529: GtkWidget *hbox0; 530: GtkWidget *ebox; 531: 532: /* get the display: */ 533: display = screen->tme_gtk_screen_display; 534: 535: /* create the horizontal packing box for the mouse controls: */ 536: hbox0 = gtk_hbox_new(FALSE, 0); 537: 538: /* pack the horizontal packing box into the outer vertical packing box: */ 539: gtk_box_pack_start(GTK_BOX(screen->tme_gtk_screen_vbox0), 540: hbox0, 541: FALSE, FALSE, 0); 542: 543: /* show the horizontal packing box: */ 544: gtk_widget_show(hbox0); 545: 546: /* create the event box for the mouse on label: */ 547: ebox = gtk_event_box_new(); 548: 549: /* pack the event box into the horizontal packing box: */ 550: gtk_box_pack_start(GTK_BOX(hbox0), 551: ebox, 552: FALSE, FALSE, 0); 553: 554: /* set the tip on the event box, which will eventually contain the mouse on label: */ 555: gtk_tooltips_set_tip(GTK_TOOLTIPS(display->tme_gtk_display_tooltips), 556: ebox, 557: "Press a key here to turn the mouse on. The same key " \ 558: "will turn the mouse off.", 559: NULL); 560: 561: /* make sure the event box gets key_press events: */ 562: gtk_widget_add_events(ebox, 563: GDK_KEY_PRESS_MASK); 564: 565: /* set a signal handler for the event box events: */ 566: gtk_signal_connect(GTK_OBJECT(ebox), 567: "event", 568: GTK_SIGNAL_FUNC(_tme_gtk_mouse_ebox_event), 569: screen); 570: 571: /* the event box can focus: */ 572: GTK_WIDGET_SET_FLAGS(ebox, GTK_CAN_FOCUS); 573: 574: /* show the event box: */ 575: gtk_widget_show(ebox); 576: 577: /* create the mouse on label: */ 578: screen->tme_gtk_screen_mouse_label 579: = gtk_label_new(_("Mouse is off")); 580: 581: /* add the mouse on label to the event box: */ 582: gtk_container_add(GTK_CONTAINER(ebox), 583: screen->tme_gtk_screen_mouse_label); 584: 585: /* show the mouse on label: */ 586: gtk_widget_show(screen->tme_gtk_screen_mouse_label); 587: 588: /* create the mouse statusbar: */ 589: screen->tme_gtk_screen_mouse_statusbar 590: = gtk_statusbar_new(); 591: 592: /* pack the mouse statusbar into the horizontal packing box: */ 593: gtk_box_pack_start(GTK_BOX(hbox0), 594: screen->tme_gtk_screen_mouse_statusbar, 595: TRUE, TRUE, 10); 596: 597: /* show the mouse statusbar: */ 598: gtk_widget_show(screen->tme_gtk_screen_mouse_statusbar); 599: 600: /* push an initial message onto the statusbar: */ 601: screen->tme_gtk_screen_mouse_statusbar_cid 602: = gtk_statusbar_get_context_id(GTK_STATUSBAR(screen->tme_gtk_screen_mouse_statusbar), 603: "mouse context"); 604: gtk_statusbar_push(GTK_STATUSBAR(screen->tme_gtk_screen_mouse_statusbar), 605: screen->tme_gtk_screen_mouse_statusbar_cid, 606: _("The Machine Emulator")); 607: 608: /* although the event mask doesn't include these events yet, 609: set a signal handler for the mouse events: */ 610: gtk_signal_connect(GTK_OBJECT(screen->tme_gtk_screen_event_box), 611: "motion_notify_event", 612: GTK_SIGNAL_FUNC(_tme_gtk_mouse_mouse_event), 613: screen); 614: gtk_signal_connect(GTK_OBJECT(screen->tme_gtk_screen_event_box), 615: "button_press_event", 616: GTK_SIGNAL_FUNC(_tme_gtk_mouse_mouse_event), 617: screen); 618: gtk_signal_connect(GTK_OBJECT(screen->tme_gtk_screen_event_box), 619: "button_release_event", 620: GTK_SIGNAL_FUNC(_tme_gtk_mouse_mouse_event), 621: screen); 622: 623: /* mouse mode is off: */ 624: screen->tme_gtk_screen_mouse_keyval = GDK_VoidSymbol; 625: } 626: 627: /* this initializes mouse part of the display: */ 628: void 629: _tme_gtk_mouse_new(struct tme_gtk_display *display) 630: { 631: GdkPixmap *source, *mask; 632: 633: /* we have no mouse connection: */ 634: display->tme_gtk_display_mouse_connection = NULL; 635: 636: /* allocate the mouse buffer: */ 637: display->tme_gtk_display_mouse_buffer 638: = tme_mouse_buffer_new(1024); 639: 640: /* create the mouse cursor: */ 641: source 642: = gdk_bitmap_create_from_data(NULL, 643: _tme_gtk_mouse_cursor_source, 644: TME_GTK_MOUSE_CURSOR_WIDTH, 645: TME_GTK_MOUSE_CURSOR_HEIGHT); 646: mask 647: = gdk_bitmap_create_from_data (NULL, 648: _tme_gtk_mouse_cursor_mask, 649: TME_GTK_MOUSE_CURSOR_WIDTH, 650: TME_GTK_MOUSE_CURSOR_HEIGHT); 651: display->tme_gtk_display_mouse_cursor 652: = gdk_cursor_new_from_pixmap(source, 653: mask, 654: &_tme_gtk_mouse_cursor_color, 655: &_tme_gtk_mouse_cursor_color, 656: 0, 657: 0); 658: gdk_pixmap_unref(source); 659: gdk_pixmap_unref(mask); 660: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.