|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.