|
|
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.