|
|
1.1 ! root 1: /* $Id: gtk-display.c,v 1.2 2003/07/31 01:42:13 fredette Exp $ */ ! 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> ! 37: _TME_RCSID("$Id: gtk-display.c,v 1.2 2003/07/31 01:42:13 fredette Exp $"); ! 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; ! 151: } ! 152: ! 153: /* this is a GTK callback for an enter notify event, that has the ! 154: widget grab focus and then continue normal event processing: */ ! 155: gint ! 156: _tme_gtk_display_enter_focus(GtkWidget *widget, ! 157: GdkEvent *gdk_event_raw, ! 158: gpointer junk) ! 159: { ! 160: ! 161: /* grab the focus: */ ! 162: gtk_widget_grab_focus(widget); ! 163: ! 164: /* continue normal event processing: */ ! 165: return (FALSE); ! 166: } ! 167: ! 168: /* this makes a new connection side for a GTK display: */ ! 169: static int ! 170: _tme_gtk_display_connections_new(struct tme_element *element, ! 171: const char * const *args, ! 172: struct tme_connection **_conns, ! 173: char **_output) ! 174: { ! 175: struct tme_gtk_display *display; ! 176: ! 177: /* recover our data structure: */ ! 178: display = (struct tme_gtk_display *) element->tme_element_private; ! 179: ! 180: /* we never take any arguments: */ ! 181: if (args[1] != NULL) { ! 182: tme_output_append_error(_output, ! 183: "%s %s, ", ! 184: args[1], ! 185: _("unexpected")); ! 186: return (EINVAL); ! 187: } ! 188: ! 189: /* make any new keyboard connections: */ ! 190: _tme_gtk_keyboard_connections_new(display, _conns); ! 191: ! 192: /* make any new mouse connections: */ ! 193: _tme_gtk_mouse_connections_new(display, _conns); ! 194: ! 195: /* make any new screen connections: */ ! 196: _tme_gtk_screen_connections_new(display, _conns); ! 197: ! 198: /* done: */ ! 199: return (TME_OK); ! 200: } ! 201: ! 202: /* the new GTK display function: */ ! 203: TME_ELEMENT_SUB_NEW_DECL(tme_host_gtk,display) { ! 204: struct tme_gtk_display *display; ! 205: int arg_i; ! 206: int usage; ! 207: ! 208: /* check our arguments: */ ! 209: usage = FALSE; ! 210: arg_i = 1; ! 211: for (;;) { ! 212: ! 213: if (0) { ! 214: } ! 215: ! 216: /* if we've run out of arguments: */ ! 217: else if (args[arg_i + 0] == NULL) { ! 218: ! 219: break; ! 220: } ! 221: ! 222: /* otherwise this is a bad argument: */ ! 223: else { ! 224: tme_output_append_error(_output, ! 225: "%s %s", ! 226: args[arg_i], ! 227: _("unexpected")); ! 228: usage = TRUE; ! 229: break; ! 230: } ! 231: } ! 232: ! 233: if (usage) { ! 234: tme_output_append_error(_output, ! 235: "%s %s", ! 236: _("usage:"), ! 237: args[0]); ! 238: return (EINVAL); ! 239: } ! 240: ! 241: /* call gtk_init if we haven't already: */ ! 242: tme_threads_gtk_init(); ! 243: ! 244: /* start our data structure: */ ! 245: display = tme_new0(struct tme_gtk_display, 1); ! 246: display->tme_gtk_display_element = element; ! 247: ! 248: /* create the tooltips group: */ ! 249: display->tme_gtk_display_tooltips = gtk_tooltips_new(); ! 250: ! 251: /* create the keyboard: */ ! 252: _tme_gtk_keyboard_new(display); ! 253: ! 254: /* create the mouse: */ ! 255: _tme_gtk_mouse_new(display); ! 256: ! 257: /* create the first screen: */ ! 258: _tme_gtk_screen_new(display); ! 259: ! 260: /* start the threads: */ ! 261: tme_mutex_init(&display->tme_gtk_display_mutex); ! 262: tme_thread_create((tme_thread_t) _tme_gtk_screen_th_update, display); ! 263: ! 264: /* fill the element: */ ! 265: element->tme_element_private = display; ! 266: element->tme_element_connections_new = _tme_gtk_display_connections_new; ! 267: ! 268: return (TME_OK); ! 269: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.