Annotation of tme/host/gtk/gtk-mouse.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.