Annotation of tme/host/gtk/gtk-mouse.c, revision 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.