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

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

unix.superglobalmegacorp.com

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