|
|
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.