Annotation of tme/host/gtk/gtk-display.c, revision 1.1.1.3

1.1.1.3 ! root        1: /* $Id: gtk-display.c,v 1.4 2010/06/05 14:28:17 fredette Exp $ */
1.1       root        2: 
                      3: /* host/gtk/gtk-display.c - GTK display 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.3 ! root       37: _TME_RCSID("$Id: gtk-display.c,v 1.4 2010/06/05 14:28:17 fredette Exp $");
1.1       root       38: 
                     39: /* includes: */
                     40: #include "gtk-display.h"
                     41: 
                     42: /* macros: */
                     43: 
                     44: /* the GTK display callout function.  it must be called with the mutex locked: */
                     45: void
                     46: _tme_gtk_display_callout(struct tme_gtk_display *display,
                     47:                         int new_callouts)
                     48: {
                     49:   struct tme_keyboard_connection *conn_keyboard;
                     50:   struct tme_mouse_connection *conn_mouse;
                     51:   int callouts, later_callouts;
                     52:   unsigned int ctrl;
                     53:   int rc;
                     54:   
                     55:   /* add in any new callouts: */
                     56:   display->tme_gtk_display_callout_flags |= new_callouts;
                     57: 
                     58:   /* if this function is already running in another thread, simply
                     59:      return now.  the other thread will do our work: */
                     60:   if (display->tme_gtk_display_callout_flags
                     61:       & TME_GTK_DISPLAY_CALLOUT_RUNNING) {
                     62:     return;
                     63:   }
                     64: 
                     65:   /* callouts are now running: */
                     66:   display->tme_gtk_display_callout_flags
                     67:     |= TME_GTK_DISPLAY_CALLOUT_RUNNING;
                     68: 
                     69:   /* assume that we won't need any later callouts: */
                     70:   later_callouts = 0;
                     71: 
                     72:   /* loop while callouts are needed: */
                     73:   for (; ((callouts
                     74:           = display->tme_gtk_display_callout_flags)
                     75:          & TME_GTK_DISPLAY_CALLOUTS_MASK); ) {
                     76: 
                     77:     /* clear the needed callouts: */
                     78:     display->tme_gtk_display_callout_flags
                     79:       = (callouts
                     80:         & ~TME_GTK_DISPLAY_CALLOUTS_MASK);
                     81:     callouts
                     82:       &= TME_GTK_DISPLAY_CALLOUTS_MASK;
                     83: 
                     84:     /* get our keyboard connection: */
                     85:     conn_keyboard = display->tme_gtk_display_keyboard_connection;
                     86: 
                     87:     /* if we need to call out new keyboard control information: */
                     88:     if (callouts & TME_GTK_DISPLAY_CALLOUT_KEYBOARD_CTRL) {
                     89: 
                     90:       /* form the new ctrl: */
                     91:       ctrl = 0;
                     92:       if (!tme_keyboard_buffer_is_empty(display->tme_gtk_display_keyboard_buffer)) {
                     93:        ctrl |= TME_KEYBOARD_CTRL_OK_READ;
                     94:       }
                     95: 
                     96:       /* unlock the mutex: */
                     97:       tme_mutex_unlock(&display->tme_gtk_display_mutex);
                     98:       
                     99:       /* do the callout: */
                    100:       rc = (conn_keyboard != NULL
                    101:            ? ((*conn_keyboard->tme_keyboard_connection_ctrl)
                    102:               (conn_keyboard,
                    103:                ctrl))
                    104:            : TME_OK);
                    105:        
                    106:       /* lock the mutex: */
                    107:       tme_mutex_lock(&display->tme_gtk_display_mutex);
                    108:       
                    109:       /* if the callout was unsuccessful, remember that at some later
                    110:         time this callout should be attempted again: */
                    111:       if (rc != TME_OK) {
                    112:        later_callouts |= TME_GTK_DISPLAY_CALLOUT_KEYBOARD_CTRL;
                    113:       }
                    114:     }
                    115: 
                    116:     /* get our mouse connection: */
                    117:     conn_mouse = display->tme_gtk_display_mouse_connection;
                    118: 
                    119:     /* if we need to call out new mouse control information: */
                    120:     if (callouts & TME_GTK_DISPLAY_CALLOUT_MOUSE_CTRL) {
                    121: 
                    122:       /* form the new ctrl: */
                    123:       ctrl = 0;
                    124:       if (!tme_mouse_buffer_is_empty(display->tme_gtk_display_mouse_buffer)) {
                    125:        ctrl |= TME_MOUSE_CTRL_OK_READ;
                    126:       }
                    127: 
                    128:       /* unlock the mutex: */
                    129:       tme_mutex_unlock(&display->tme_gtk_display_mutex);
                    130:       
                    131:       /* do the callout: */
                    132:       rc = (conn_mouse != NULL
                    133:            ? ((*conn_mouse->tme_mouse_connection_ctrl)
                    134:               (conn_mouse,
                    135:                ctrl))
                    136:            : TME_OK);
                    137:        
                    138:       /* lock the mutex: */
                    139:       tme_mutex_lock(&display->tme_gtk_display_mutex);
                    140:       
                    141:       /* if the callout was unsuccessful, remember that at some later
                    142:         time this callout should be attempted again: */
                    143:       if (rc != TME_OK) {
                    144:        later_callouts |= TME_GTK_DISPLAY_CALLOUT_MOUSE_CTRL;
                    145:       }
                    146:     }
                    147:   }
                    148:   
                    149:   /* put in any later callouts, and clear that callouts are running: */
                    150:   display->tme_gtk_display_callout_flags = later_callouts;
1.1.1.3 ! root      151: 
        !           152:   /* yield to GTK: */
        !           153:   tme_threads_gtk_yield();
1.1       root      154: }
                    155: 
                    156: /* this is a GTK callback for an enter notify event, that has the
                    157:    widget grab focus and then continue normal event processing: */
                    158: gint
                    159: _tme_gtk_display_enter_focus(GtkWidget *widget,
                    160:                             GdkEvent *gdk_event_raw,
                    161:                             gpointer junk)
                    162: {
                    163: 
                    164:   /* grab the focus: */
                    165:   gtk_widget_grab_focus(widget);
                    166: 
                    167:   /* continue normal event processing: */
                    168:   return (FALSE);
                    169: }
                    170: 
1.1.1.2   root      171: /* this creates a menu of radio buttons: */
                    172: GtkWidget *
                    173: _tme_gtk_display_menu_radio(void *state,
                    174:                            tme_gtk_display_menu_items_t menu_items)
                    175: {
                    176:   GtkWidget *menu;
                    177:   GSList *menu_group;
                    178:   struct tme_gtk_display_menu_item menu_item_buffer;
                    179:   GtkSignalFunc menu_func;
                    180:   GtkWidget *menu_item;
                    181: 
                    182:   /* create the menu: */
                    183:   menu = gtk_menu_new();
                    184: 
                    185:   /* create the menu items: */
                    186:   menu_group = NULL;
                    187:   for (menu_item_buffer.tme_gtk_display_menu_item_which = 0;
                    188:        ;
                    189:        menu_item_buffer.tme_gtk_display_menu_item_which++) {
                    190:     menu_func = (*menu_items)(state, &menu_item_buffer);
                    191:     if (menu_func == GTK_SIGNAL_FUNC(NULL)) {
                    192:       break;
                    193:     }
                    194:     menu_item
                    195:       = gtk_radio_menu_item_new_with_label(menu_group,
                    196:                                           menu_item_buffer.tme_gtk_display_menu_item_string);
                    197:     if (menu_item_buffer.tme_gtk_display_menu_item_widget != NULL) {
                    198:       *menu_item_buffer.tme_gtk_display_menu_item_widget = menu_item;
                    199:     }
                    200:     menu_group
                    201:       = gtk_radio_menu_item_group(GTK_RADIO_MENU_ITEM(menu_item));
                    202:     gtk_signal_connect(GTK_OBJECT(menu_item), 
                    203:                       "activate",
                    204:                       menu_func,
                    205:                       (gpointer) state);
                    206:     gtk_menu_append(GTK_MENU(menu), menu_item);
                    207:     gtk_widget_show(menu_item);
                    208:   }
                    209: 
                    210:   /* return the menu: */
                    211:   return (menu);
                    212: }
                    213: 
1.1       root      214: /* this makes a new connection side for a GTK display: */
                    215: static int
                    216: _tme_gtk_display_connections_new(struct tme_element *element, 
                    217:                                 const char * const *args, 
                    218:                                 struct tme_connection **_conns,
                    219:                                 char **_output)
                    220: {
                    221:   struct tme_gtk_display *display;
                    222: 
                    223:   /* recover our data structure: */
                    224:   display = (struct tme_gtk_display *) element->tme_element_private;
                    225: 
                    226:   /* we never take any arguments: */
                    227:   if (args[1] != NULL) {
                    228:     tme_output_append_error(_output,
                    229:                            "%s %s, ",
                    230:                            args[1],
                    231:                            _("unexpected"));
                    232:     return (EINVAL);
                    233:   }
                    234: 
                    235:   /* make any new keyboard connections: */
                    236:   _tme_gtk_keyboard_connections_new(display, _conns);
                    237: 
                    238:   /* make any new mouse connections: */
                    239:   _tme_gtk_mouse_connections_new(display, _conns);
                    240: 
                    241:   /* make any new screen connections: */
                    242:   _tme_gtk_screen_connections_new(display, _conns);
                    243: 
                    244:   /* done: */
                    245:   return (TME_OK);
                    246: }
                    247: 
                    248: /* the new GTK display function: */
                    249: TME_ELEMENT_SUB_NEW_DECL(tme_host_gtk,display) {
                    250:   struct tme_gtk_display *display;
                    251:   int arg_i;
                    252:   int usage;
                    253:   
                    254:   /* check our arguments: */
                    255:   usage = FALSE;
                    256:   arg_i = 1;
                    257:   for (;;) {
                    258: 
                    259:     if (0) {
                    260:     }
                    261: 
                    262:     /* if we've run out of arguments: */
                    263:     else if (args[arg_i + 0] == NULL) {
                    264: 
                    265:       break;
                    266:     }
                    267: 
                    268:     /* otherwise this is a bad argument: */
                    269:     else {
                    270:       tme_output_append_error(_output,
                    271:                              "%s %s", 
                    272:                              args[arg_i],
                    273:                              _("unexpected"));
                    274:       usage = TRUE;
                    275:       break;
                    276:     }
                    277:   }
                    278: 
                    279:   if (usage) {
                    280:     tme_output_append_error(_output,
                    281:                            "%s %s",
                    282:                            _("usage:"),
                    283:                            args[0]);
                    284:     return (EINVAL);
                    285:   }
                    286: 
                    287:   /* call gtk_init if we haven't already: */
                    288:   tme_threads_gtk_init();
                    289: 
                    290:   /* start our data structure: */
                    291:   display = tme_new0(struct tme_gtk_display, 1);
                    292:   display->tme_gtk_display_element = element;
                    293: 
                    294:   /* create the tooltips group: */
                    295:   display->tme_gtk_display_tooltips = gtk_tooltips_new();
                    296: 
                    297:   /* create the keyboard: */
                    298:   _tme_gtk_keyboard_new(display);
                    299: 
                    300:   /* create the mouse: */
                    301:   _tme_gtk_mouse_new(display);
                    302: 
                    303:   /* create the first screen: */
                    304:   _tme_gtk_screen_new(display);
                    305: 
                    306:   /* start the threads: */
                    307:   tme_mutex_init(&display->tme_gtk_display_mutex);
                    308:   tme_thread_create((tme_thread_t) _tme_gtk_screen_th_update, display);
                    309: 
                    310:   /* fill the element: */
                    311:   element->tme_element_private = display;
                    312:   element->tme_element_connections_new = _tme_gtk_display_connections_new;
                    313: 
                    314:   return (TME_OK);
                    315: }

unix.superglobalmegacorp.com

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