Mercurial > hg > xemacs-beta
comparison src/gpmevent.c @ 793:e38acbeb1cae
[xemacs-hg @ 2002-03-29 04:46:17 by ben]
lots o' fixes
etc/ChangeLog: New file.
Separated out all entries for etc/ into their own ChangeLog.
Includes entries for the following files:
etc/BABYL, etc/BETA, etc/CHARSETS, etc/DISTRIB, etc/Emacs.ad,
etc/FTP, etc/GNUS-NEWS, etc/GOATS, etc/HELLO, etc/INSTALL,
etc/MACHINES, etc/MAILINGLISTS, etc/MSDOS, etc/MYTHOLOGY, etc/NEWS,
etc/OXYMORONS, etc/PACKAGES, etc/README, etc/TUTORIAL,
etc/TUTORIAL.de, etc/TUTORIAL.ja, etc/TUTORIAL.ko, etc/TUTORIAL.se,
etc/aliases.ksh, etc/altrasoft-logo.xpm, etc/check_cygwin_setup.sh,
etc/custom/example-themes/europe-theme.el,
etc/custom/example-themes/ex-custom-file,
etc/custom/example-themes/example-theme.el, etc/e/eterm.ti,
etc/edt-user.doc, etc/enriched.doc, etc/etags.1, etc/gnuserv.1,
etc/gnuserv.README, etc/package-index.LATEST.gpg,
etc/package-index.LATEST.pgp, etc/photos/jan.png, etc/recycle.xpm,
etc/refcard.tex, etc/sample.Xdefaults, etc/sample.emacs,
etc/sgml/CATALOG, etc/sgml/HTML32.dtd, etc/skk/SKK.tut.E,
etc/smilies/Face_ase.xbm, etc/smilies/Face_ase2.xbm,
etc/smilies/Face_ase3.xbm, etc/smilies/Face_smile.xbm,
etc/smilies/Face_weep.xbm, etc/sounds, etc/toolbar,
etc/toolbar/workshop-cap-up.xpm, etc/xemacs-ja.1, etc/xemacs.1,
etc/yow.lines, etc\BETA, etc\NEWS, etc\README, etc\TUTORIAL,
etc\TUTORIAL.de, etc\check_cygwin_setup.sh, etc\sample.init.el,
etc\unicode\README, etc\unicode\mule-ucs\*, etc\unicode\other\*
unicode/unicode-consortium/8859-16.TXT: New file.
mule/english.el: Define this charset now, since a bug was fixed that formerly
prevented it.
mule/ethio-util.el: Fix compile errors involving Unicode `characters', which should be
integers.
Makefile.in.in: Always include gui.c, to fix compile error when TTY-only.
EmacsFrame.c, abbrev.c, alloc.c, buffer.c, buffer.h, bytecode.c, bytecode.h, callint.c, callproc.c, casetab.c, casetab.h, charset.h, chartab.c, chartab.h, cmds.c, console-msw.c, console-msw.h, console-tty.c, console-x.c, console-x.h, console.c, console.h, data.c, database.c, device-gtk.c, device-msw.c, device-x.c, device.c, device.h, dialog-msw.c, doc.c, doprnt.c, dumper.c, dynarr.c, editfns.c, eldap.c, eldap.h, elhash.c, elhash.h, emacs.c, eval.c, event-Xt.c, event-gtk.c, event-msw.c, event-stream.c, event-tty.c, event-unixoid.c, events.c, events.h, extents.c, extents.h, faces.c, faces.h, file-coding.c, file-coding.h, fileio.c, filelock.c, fns.c, frame-gtk.c, frame-msw.c, frame-tty.c, frame-x.c, frame.c, frame.h, free-hook.c, general-slots.h, glyphs-eimage.c, glyphs-gtk.c, glyphs-msw.c, glyphs-widget.c, glyphs-x.c, glyphs.c, glyphs.h, gpmevent.c, gtk-xemacs.c, gui-msw.c, gui-x.c, gui-x.h, gui.c, gui.h, gutter.c, gutter.h, indent.c, input-method-xlib.c, insdel.c, keymap.c, keymap.h, lisp-disunion.h, lisp-union.h, lisp.h, lread.c, lrecord.h, lstream.c, lstream.h, marker.c, menubar-gtk.c, menubar-msw.c, menubar-x.c, menubar.c, minibuf.c, mule-canna.c, mule-ccl.c, mule-charset.c, mule-wnnfns.c, native-gtk-toolbar.c, objects-msw.c, objects-tty.c, objects-x.c, objects.c, objects.h, opaque.c, opaque.h, postgresql.c, postgresql.h, print.c, process-unix.c, process.c, process.h, rangetab.c, rangetab.h, redisplay-gtk.c, redisplay-msw.c, redisplay-output.c, redisplay-tty.c, redisplay-x.c, redisplay.c, scrollbar-gtk.c, scrollbar-msw.c, scrollbar-x.c, scrollbar.c, scrollbar.h, search.c, select-gtk.c, select-x.c, sound.c, specifier.c, specifier.h, strftime.c, symbols.c, symeval.h, syntax.h, text.c, text.h, toolbar-common.c, toolbar-msw.c, toolbar.c, toolbar.h, tooltalk.c, tooltalk.h, ui-gtk.c, ui-gtk.h, undo.c, vm-limit.c, window.c, window.h: Eliminate XSETFOO. Replace all usages with wrap_foo().
Make symbol->name a Lisp_Object, not Lisp_String *. Eliminate
nearly all uses of Lisp_String * in favor of Lisp_Object, and
correct macros so most of them favor Lisp_Object.
Create new error-behavior ERROR_ME_DEBUG_WARN -- output warnings,
but at level `debug' (usually ignored). Use it when instantiating
specifiers, so problems can be debugged. Move
log-warning-minimum-level into C so that we can optimize
ERROR_ME_DEBUG_WARN.
Fix warning levels consistent with new definitions.
Add default_ and parent fields to char table; not yet implemented.
New fun Dynarr_verify(); use for further error checking on Dynarrs.
Rearrange code at top of lisp.h in conjunction with dynarr changes.
Fix eifree(). Use Eistrings in various places
(format_event_object(), where_is_to_char(), and callers thereof)
to avoid fixed-size strings buffers. New fun write_eistring().
Reindent and fix GPM code to follow standards.
Set default MS Windows font to Lucida Console (same size as
Courier New but less interline spacing, so more lines fit).
Increase default frame size on Windows to 50 lines. (If that's too
big for the workspace, the frame will be shrunk as necessary.)
Fix problem with text files with no newlines (). (Change
`convert-eol' coding system to use `nil' for autodetect,
consistent with make-coding-system.)
Correct compile warnings in vm-limit.c.
Fix handling of reverse-direction charsets to avoid errors when
opening (e.g.) mule-ucs/lisp/reldata/uiso8859-6.el.
Recode some object printing methods to use write_fmt_string()
instead of a fixed buffer and sprintf.
Turn on display of png comments as warnings (level `info'), now
that they're unobtrusive.
Revamped the sound documentation.
Fixed bug in redisplay w.r.t. hscroll/truncation/continuation
glyphs causing jumping up and down of the lines, since they're
bigger than the line size. (It was seen most obviously when
there's a horizontal scroll bar, e.g. do C-h a glyph or something
like that.) The problem was that the glyph-contrib-p setting on
glyphs was ignored even if it was set properly, which it wasn't
until now.
author | ben |
---|---|
date | Fri, 29 Mar 2002 04:49:13 +0000 |
parents | fdefd0186b75 |
children | 2b6fa2618f76 |
comparison
equal
deleted
inserted
replaced
792:4e83fdb13eb9 | 793:e38acbeb1cae |
---|---|
1 /* GPM (General purpose mouse) functions | 1 /* GPM (General purpose mouse) functions |
2 Copyright (C) 1997 William M. Perry <wmperry@gnu.org> | 2 Copyright (C) 1997 William M. Perry <wmperry@gnu.org> |
3 Copyright (C) 1999 Free Software Foundation, Inc. | 3 Copyright (C) 1999 Free Software Foundation, Inc. |
4 | 4 Copyright (C) 2002 Ben Wing. |
5 This file is part of XEmacs. | 5 |
6 | 6 This file is part of XEmacs. |
7 XEmacs is free software; you can redistribute it and/or modify it | 7 |
8 under the terms of the GNU General Public License as published by the | 8 XEmacs is free software; you can redistribute it and/or modify it |
9 Free Software Foundation; either version 2, or (at your option) any | 9 under the terms of the GNU General Public License as published by the |
10 later version. | 10 Free Software Foundation; either version 2, or (at your option) any |
11 | 11 later version. |
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT | 12 |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 13 XEmacs is distributed in the hope that it will be useful, but WITHOUT |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | 14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
15 for more details. | 15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
16 | 16 for more details. |
17 You should have received a copy of the GNU General Public License | 17 |
18 along with XEmacs; see the file COPYING. If not, write to | 18 You should have received a copy of the GNU General Public License |
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 19 along with XEmacs; see the file COPYING. If not, write to |
20 Boston, MA 02111-1307, USA. */ | 20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
21 Boston, MA 02111-1307, USA. */ | |
21 | 22 |
22 /* Synched up with: Not in FSF. */ | 23 /* Synched up with: Not in FSF. */ |
23 | 24 |
24 /* Authors: William Perry */ | 25 /* Authors: William Perry */ |
25 | 26 |
26 #include <config.h> | 27 #include <config.h> |
27 #include "lisp.h" | 28 #include "lisp.h" |
29 | |
30 #include "commands.h" | |
31 #include "console-tty.h" | |
28 #include "console.h" | 32 #include "console.h" |
29 #include "console-tty.h" | |
30 #include "device.h" | 33 #include "device.h" |
31 #include "events.h" | 34 #include "events.h" |
35 #include "lstream.h" | |
36 #include "process.h" | |
32 #include "sysdep.h" | 37 #include "sysdep.h" |
33 #include "commands.h" | 38 |
34 #include "lstream.h" | |
35 #include "sysproc.h" /* for MAXDESC */ | 39 #include "sysproc.h" /* for MAXDESC */ |
36 #include "process.h" | |
37 | 40 |
38 #ifdef HAVE_GPM | 41 #ifdef HAVE_GPM |
39 #include "gpmevent.h" | 42 #include "gpmevent.h" |
40 #include <gpm.h> | 43 #include <gpm.h> |
41 | 44 |
50 static void (*orig_next_event_cb) (Lisp_Event *); | 53 static void (*orig_next_event_cb) (Lisp_Event *); |
51 | 54 |
52 static Lisp_Object gpm_event_queue; | 55 static Lisp_Object gpm_event_queue; |
53 static Lisp_Object gpm_event_queue_tail; | 56 static Lisp_Object gpm_event_queue_tail; |
54 | 57 |
55 struct __gpm_state { | 58 struct __gpm_state |
56 int gpm_tried; | 59 { |
57 int gpm_flag; | 60 int gpm_tried; |
58 void *gpm_stack; | 61 int gpm_flag; |
62 void *gpm_stack; | |
59 }; | 63 }; |
60 | 64 |
61 static struct __gpm_state gpm_state_information[MAXDESC]; | 65 static struct __gpm_state gpm_state_information[MAXDESC]; |
62 | 66 |
63 static void | 67 static void |
64 store_gpm_state (int fd) | 68 store_gpm_state (int fd) |
65 { | 69 { |
66 gpm_state_information[fd].gpm_tried = gpm_tried; | 70 gpm_state_information[fd].gpm_tried = gpm_tried; |
67 gpm_state_information[fd].gpm_flag = gpm_flag; | 71 gpm_state_information[fd].gpm_flag = gpm_flag; |
68 gpm_state_information[fd].gpm_stack = gpm_stack; | 72 gpm_state_information[fd].gpm_stack = gpm_stack; |
69 } | 73 } |
70 | 74 |
71 static void | 75 static void |
72 restore_gpm_state (int fd) | 76 restore_gpm_state (int fd) |
73 { | 77 { |
74 gpm_tried = gpm_state_information[fd].gpm_tried; | 78 gpm_tried = gpm_state_information[fd].gpm_tried; |
75 gpm_flag = gpm_state_information[fd].gpm_flag; | 79 gpm_flag = gpm_state_information[fd].gpm_flag; |
76 gpm_stack = gpm_state_information[fd].gpm_stack; | 80 gpm_stack = gpm_state_information[fd].gpm_stack; |
77 gpm_consolefd = gpm_fd = fd; | 81 gpm_consolefd = gpm_fd = fd; |
78 } | 82 } |
79 | 83 |
80 static void | 84 static void |
81 clear_gpm_state (int fd) | 85 clear_gpm_state (int fd) |
82 { | 86 { |
83 if (fd >= 0) | 87 if (fd >= 0) |
84 { | 88 memset (&gpm_state_information[fd], '\0', sizeof (struct __gpm_state)); |
85 memset(&gpm_state_information[fd], '\0', sizeof(struct __gpm_state)); | 89 gpm_tried = gpm_flag = 1; |
86 } | 90 gpm_fd = gpm_consolefd = -1; |
87 gpm_tried = gpm_flag = 1; | 91 gpm_stack = NULL; |
88 gpm_fd = gpm_consolefd = -1; | |
89 gpm_stack = NULL; | |
90 } | 92 } |
91 | 93 |
92 static int | 94 static int |
93 get_process_infd (Lisp_Process *p) | 95 get_process_infd (Lisp_Process *p) |
94 { | 96 { |
102 Run GPM_GetEvent(). | 104 Run GPM_GetEvent(). |
103 This function is the process handler for the GPM connection. | 105 This function is the process handler for the GPM connection. |
104 */ | 106 */ |
105 (process, string)) | 107 (process, string)) |
106 { | 108 { |
107 Gpm_Event ev; | 109 Gpm_Event ev; |
108 int modifiers = 0; | 110 int modifiers = 0; |
109 int button = 1; | 111 int button = 1; |
110 Lisp_Object fake_event = Qnil; | 112 Lisp_Object fake_event = Qnil; |
111 Lisp_Event *event = NULL; | 113 Lisp_Event *event = NULL; |
112 struct gcpro gcpro1; | 114 struct gcpro gcpro1; |
113 static int num_events; | 115 static int num_events; |
114 | 116 |
115 CHECK_PROCESS (process); | 117 CHECK_PROCESS (process); |
116 | 118 |
117 restore_gpm_state (get_process_infd (XPROCESS (process))); | 119 restore_gpm_state (get_process_infd (XPROCESS (process))); |
118 | 120 |
119 if (!Gpm_GetEvent(&ev)) | 121 if (!Gpm_GetEvent (&ev)) |
120 { | 122 { |
121 warn_when_safe (Qnil, Qcritical, "Gpm_GetEvent failed - %d", gpm_fd); | 123 warn_when_safe (Qnil, Qerror, |
122 return(Qzero); | 124 "Gpm_GetEvent failed - %d", gpm_fd); |
123 } | 125 return (Qzero); |
124 | 126 } |
125 GCPRO1(fake_event); | 127 |
126 | 128 GCPRO1 (fake_event); |
127 num_events++; | 129 |
128 | 130 num_events++; |
129 fake_event = Fmake_event (Qnil, Qnil); | 131 |
130 event = XEVENT(fake_event); | 132 fake_event = Fmake_event (Qnil, Qnil); |
131 | 133 event = XEVENT (fake_event); |
132 event->timestamp = 0; | 134 |
133 event->channel = Fselected_frame (Qnil); /* CONSOLE_SELECTED_FRAME (con); */ | 135 event->timestamp = 0; |
134 | 136 event->channel = Fselected_frame (Qnil); /* CONSOLE_SELECTED_FRAME (con); */ |
135 /* Whow, wouldn't named defines be NICE!?!?! */ | 137 |
136 modifiers = 0; | 138 /* Whow, wouldn't named defines be NICE!?!?! */ |
137 | 139 modifiers = 0; |
138 if (ev.modifiers & 1) modifiers |= XEMACS_MOD_SHIFT; | 140 |
139 if (ev.modifiers & 2) modifiers |= XEMACS_MOD_META; | 141 if (ev.modifiers & 1) modifiers |= XEMACS_MOD_SHIFT; |
140 if (ev.modifiers & 4) modifiers |= XEMACS_MOD_CONTROL; | 142 if (ev.modifiers & 2) modifiers |= XEMACS_MOD_META; |
141 if (ev.modifiers & 8) modifiers |= XEMACS_MOD_META; | 143 if (ev.modifiers & 4) modifiers |= XEMACS_MOD_CONTROL; |
142 | 144 if (ev.modifiers & 8) modifiers |= XEMACS_MOD_META; |
143 if (ev.buttons & GPM_B_LEFT) | 145 |
144 { | 146 if (ev.buttons & GPM_B_LEFT) |
145 button = 1; | 147 button = 1; |
146 } | 148 else if (ev.buttons & GPM_B_MIDDLE) |
147 else if (ev.buttons & GPM_B_MIDDLE) | 149 button = 2; |
148 { | 150 else if (ev.buttons & GPM_B_RIGHT) |
149 button = 2; | 151 button = 3; |
150 } | 152 |
151 else if (ev.buttons & GPM_B_RIGHT) | 153 switch (GPM_BARE_EVENTS (ev.type)) |
152 { | 154 { |
153 button = 3; | 155 case GPM_DOWN: |
154 } | 156 case GPM_UP: |
155 | 157 event->event_type = |
156 switch (GPM_BARE_EVENTS(ev.type)) { | 158 (ev.type & GPM_DOWN) ? button_press_event : button_release_event; |
157 case GPM_DOWN: | 159 event->event.button.x = ev.x; |
158 case GPM_UP: | 160 event->event.button.y = ev.y; |
159 event->event_type = | 161 event->event.button.button = button; |
160 (ev.type & GPM_DOWN) ? button_press_event : button_release_event; | 162 event->event.button.modifiers = modifiers; |
161 event->event.button.x = ev.x; | 163 break; |
162 event->event.button.y = ev.y; | 164 case GPM_MOVE: |
163 event->event.button.button = button; | 165 case GPM_DRAG: |
164 event->event.button.modifiers = modifiers; | 166 event->event_type = pointer_motion_event; |
165 break; | 167 event->event.motion.x = ev.x; |
166 case GPM_MOVE: | 168 event->event.motion.y = ev.y; |
167 case GPM_DRAG: | 169 event->event.motion.modifiers = modifiers; |
168 event->event_type = pointer_motion_event; | 170 default: |
169 event->event.motion.x = ev.x; | 171 /* This will never happen */ |
170 event->event.motion.y = ev.y; | 172 break; |
171 event->event.motion.modifiers = modifiers; | 173 } |
172 default: | 174 |
173 /* This will never happen */ | 175 /* Handle the event */ |
174 break; | 176 enqueue_event (fake_event, &gpm_event_queue, &gpm_event_queue_tail); |
175 } | 177 |
176 | 178 UNGCPRO; |
177 /* Handle the event */ | 179 |
178 enqueue_event (fake_event, &gpm_event_queue, &gpm_event_queue_tail); | 180 return (Qzero); |
179 | |
180 UNGCPRO; | |
181 | |
182 return (Qzero); | |
183 } | 181 } |
184 | 182 |
185 static void turn_off_gpm (char *process_name) | 183 static void turn_off_gpm (char *process_name) |
186 { | 184 { |
187 Lisp_Object process = Fget_process (build_string (process_name)); | 185 Lisp_Object process = Fget_process (build_string (process_name)); |
188 int fd = -1; | 186 int fd = -1; |
189 | 187 |
190 if (NILP (process)) | 188 if (NILP (process)) |
191 { | 189 /* Something happened to our GPM process - fail silently */ |
192 /* Something happened to our GPM process - fail silently */ | 190 return; |
193 return; | 191 |
194 } | 192 fd = get_process_infd (XPROCESS (process)); |
195 | 193 |
196 fd = get_process_infd (XPROCESS (process)); | 194 restore_gpm_state (fd); |
197 | 195 |
198 restore_gpm_state (fd); | 196 Gpm_Close(); |
199 | 197 |
200 Gpm_Close(); | 198 clear_gpm_state (fd); |
201 | 199 |
202 clear_gpm_state (fd); | 200 Fdelete_process (build_string (process_name)); |
203 | |
204 Fdelete_process (build_string (process_name)); | |
205 } | 201 } |
206 | 202 |
207 #ifdef TIOCLINUX | 203 #ifdef TIOCLINUX |
208 static Lisp_Object | 204 static Lisp_Object |
209 tty_get_foreign_selection (Lisp_Object selection_symbol, Lisp_Object target_type) | 205 tty_get_foreign_selection (Lisp_Object selection_symbol, |
210 { | 206 Lisp_Object target_type) |
211 /* This function can GC */ | 207 { |
212 struct device *d = decode_device (Qnil); | 208 /* This function can GC */ |
213 int fd = DEVICE_INFD (d); | 209 struct device *d = decode_device (Qnil); |
214 char c = 3; | 210 int fd = DEVICE_INFD (d); |
215 Lisp_Object output_stream = Qnil; | 211 char c = 3; |
216 Lisp_Object terminal_stream = Qnil ; | 212 Lisp_Object output_stream = Qnil; |
217 Lisp_Object output_string = Qnil; | 213 Lisp_Object terminal_stream = Qnil; |
218 struct gcpro gcpro1,gcpro2,gcpro3; | 214 Lisp_Object output_string = Qnil; |
219 | 215 struct gcpro gcpro1,gcpro2,gcpro3; |
220 GCPRO3(output_stream,terminal_stream,output_string); | 216 |
221 | 217 GCPRO3(output_stream,terminal_stream,output_string); |
222 /* The ioctl() to paste actually puts things in the input queue of | 218 |
223 ** the virtual console, so we need to trap that data, since we are | 219 /* The ioctl() to paste actually puts things in the input queue of |
224 ** supposed to return the actual string selection from this | 220 ** the virtual console, so we need to trap that data, since we are |
225 ** function. | 221 ** supposed to return the actual string selection from this |
226 */ | 222 ** function. |
227 | 223 */ |
228 /* I really hate doing this, but it doesn't seem to cause any | 224 |
229 ** problems, and it makes the Lstream_read stuff further down | 225 /* I really hate doing this, but it doesn't seem to cause any |
230 ** error out correctly instead of trying to indefinitely read from | 226 ** problems, and it makes the Lstream_read stuff further down |
231 ** the console. | 227 ** error out correctly instead of trying to indefinitely read from |
232 ** | 228 ** the console. |
233 ** There is no set_descriptor_blocking() function call, but in my | 229 ** |
234 ** testing under linux, it has not proved fatal to leave the | 230 ** There is no set_descriptor_blocking() function call, but in my |
235 ** descriptor in non-blocking mode. | 231 ** testing under linux, it has not proved fatal to leave the |
236 ** | 232 ** descriptor in non-blocking mode. |
237 ** William Perry Nov 5, 1999 | 233 ** |
238 */ | 234 ** William Perry Nov 5, 1999 |
239 set_descriptor_non_blocking (fd); | 235 */ |
240 | 236 set_descriptor_non_blocking (fd); |
241 /* We need two streams, one for reading from the selected device, | 237 |
242 ** and one to write the data into. There is no writable version | 238 /* We need two streams, one for reading from the selected device, |
243 ** of the lisp-string lstream, so we make do with a resizing | 239 ** and one to write the data into. There is no writable version |
244 ** buffer stream, and make a string out of it after we are | 240 ** of the lisp-string lstream, so we make do with a resizing |
245 ** done. | 241 ** buffer stream, and make a string out of it after we are |
246 */ | 242 ** done. |
247 output_stream = make_resizing_buffer_output_stream (); | 243 */ |
248 terminal_stream = make_filedesc_input_stream (fd, 0, -1, LSTR_BLOCKED_OK); | 244 output_stream = make_resizing_buffer_output_stream (); |
249 output_string = Qnil; | 245 terminal_stream = make_filedesc_input_stream (fd, 0, -1, LSTR_BLOCKED_OK); |
250 | 246 output_string = Qnil; |
251 /* #### We should arguably use a specbind() and an unwind routine here, | 247 |
252 ** #### but I don't care that much right now. | 248 /* #### We should arguably use a specbind() and an unwind routine here, |
253 */ | 249 ** #### but I don't care that much right now. |
254 if (NILP (output_stream) || NILP (terminal_stream)) | 250 */ |
251 if (NILP (output_stream) || NILP (terminal_stream)) | |
252 /* Should we signal an error here? */ | |
253 goto out; | |
254 | |
255 if (ioctl (fd, TIOCLINUX, &c) < 0) | |
256 { | |
257 /* Could not get the selection - eek */ | |
258 UNGCPRO; | |
259 return (Qnil); | |
260 } | |
261 | |
262 while (1) | |
263 { | |
264 Intbyte tempbuf[1024]; /* some random amount */ | |
265 Bytecount i; | |
266 Bytecount size_in_bytes = | |
267 Lstream_read (XLSTREAM (terminal_stream), | |
268 tempbuf, sizeof (tempbuf)); | |
269 | |
270 if (size_in_bytes <= 0) | |
271 /* end of the stream */ | |
272 break; | |
273 | |
274 /* convert CR->LF */ | |
275 for (i = 0; i < size_in_bytes; i++) | |
255 { | 276 { |
256 /* Should we signal an error here? */ | 277 if (tempbuf[i] == '\r') |
257 goto out; | 278 tempbuf[i] = '\n'; |
258 } | 279 } |
259 | 280 |
260 if (ioctl (fd, TIOCLINUX, &c) < 0) | 281 Lstream_write (XLSTREAM (output_stream), tempbuf, size_in_bytes); |
261 { | 282 } |
262 /* Could not get the selection - eek */ | 283 |
263 UNGCPRO; | 284 Lstream_flush (XLSTREAM (output_stream)); |
264 return (Qnil); | 285 |
265 } | 286 output_string = |
266 | 287 make_string (resizing_buffer_stream_ptr (XLSTREAM (output_stream)), |
267 while (1) | 288 Lstream_byte_count (XLSTREAM (output_stream))); |
268 { | 289 |
269 Intbyte tempbuf[1024]; /* some random amount */ | 290 Lstream_delete (XLSTREAM (output_stream)); |
270 Bytecount i; | 291 Lstream_delete (XLSTREAM (terminal_stream)); |
271 Bytecount size_in_bytes = | |
272 Lstream_read (XLSTREAM (terminal_stream), | |
273 tempbuf, sizeof (tempbuf)); | |
274 | |
275 if (size_in_bytes <= 0) | |
276 { | |
277 /* end of the stream */ | |
278 break; | |
279 } | |
280 | |
281 /* convert CR->LF */ | |
282 for (i = 0; i < size_in_bytes; i++) | |
283 { | |
284 if (tempbuf[i] == '\r') | |
285 { | |
286 tempbuf[i] = '\n'; | |
287 } | |
288 } | |
289 | |
290 Lstream_write (XLSTREAM (output_stream), tempbuf, size_in_bytes); | |
291 } | |
292 | |
293 Lstream_flush (XLSTREAM (output_stream)); | |
294 | |
295 output_string = make_string (resizing_buffer_stream_ptr (XLSTREAM (output_stream)), | |
296 Lstream_byte_count (XLSTREAM (output_stream))); | |
297 | |
298 Lstream_delete (XLSTREAM (output_stream)); | |
299 Lstream_delete (XLSTREAM (terminal_stream)); | |
300 | 292 |
301 out: | 293 out: |
302 UNGCPRO; | 294 UNGCPRO; |
303 return (output_string); | 295 return (output_string); |
304 } | 296 } |
305 | 297 |
306 static Lisp_Object | 298 static Lisp_Object |
307 tty_selection_exists_p (Lisp_Object selection, Lisp_Object selection_type) | 299 tty_selection_exists_p (Lisp_Object selection, Lisp_Object selection_type) |
308 { | 300 { |
309 return (Qt); | 301 return (Qt); |
310 } | 302 } |
311 #endif /* TIOCLINUX */ | 303 #endif /* TIOCLINUX */ |
312 | 304 |
313 #if 0 | 305 #if 0 |
314 static Lisp_Object | 306 static Lisp_Object |
315 tty_own_selection (Lisp_Object selection_name, Lisp_Object selection_value, | 307 tty_own_selection (Lisp_Object selection_name, Lisp_Object selection_value, |
316 Lisp_Object how_to_add, Lisp_Object selection_type) | 308 Lisp_Object how_to_add, Lisp_Object selection_type) |
317 { | 309 { |
318 /* There is no way to do this cleanly - the GPM selection | 310 /* There is no way to do this cleanly - the GPM selection |
319 ** 'protocol' (actually the TIOCLINUX ioctl) requires a start and | 311 ** 'protocol' (actually the TIOCLINUX ioctl) requires a start and |
320 ** end position on the _screen_, not a string to stick in there. | 312 ** end position on the _screen_, not a string to stick in there. |
321 ** Lame. | 313 ** Lame. |
322 ** | 314 ** |
323 ** William Perry Nov 4, 1999 | 315 ** William Perry Nov 4, 1999 |
324 */ | 316 */ |
325 } | 317 } |
326 #endif | 318 #endif |
327 | 319 |
328 /* This function appears to work once in a blue moon. I'm not sure | 320 /* This function appears to work once in a blue moon. I'm not sure |
329 ** exactly why either. *sigh* | 321 ** exactly why either. *sigh* |
330 ** | 322 ** |
331 ** William Perry Nov 4, 1999 | 323 ** William Perry Nov 4, 1999 |
332 ** | 324 ** |
333 ** Apparently, this is the way (mouse-position) is supposed to work, | 325 ** Apparently, this is the way (mouse-position) is supposed to work, |
334 ** and I was just expecting something else. (mouse-pixel-position) | 326 ** and I was just expecting something else. (mouse-pixel-position) |
335 ** works just fine. | 327 ** works just fine. |
336 ** | 328 ** |
337 ** William Perry Nov 7, 1999 | 329 ** William Perry Nov 7, 1999 |
338 */ | 330 */ |
339 static int | 331 static int |
340 tty_get_mouse_position (struct device *d, Lisp_Object *frame, int *x, int *y) | 332 tty_get_mouse_position (struct device *d, Lisp_Object *frame, int *x, int *y) |
341 { | 333 { |
342 Gpm_Event ev; | 334 Gpm_Event ev; |
343 int num_buttons; | 335 int num_buttons; |
344 | 336 |
345 memset(&ev,'\0',sizeof(ev)); | 337 memset(&ev,'\0',sizeof(ev)); |
346 | 338 |
347 num_buttons = Gpm_GetSnapshot(&ev); | 339 num_buttons = Gpm_GetSnapshot(&ev); |
348 | 340 |
349 if (!num_buttons) | 341 if (!num_buttons) |
350 { | 342 /* This means there are events pending... */ |
351 /* This means there are events pending... */ | 343 |
352 | 344 /* #### In theory, we should drain the events pending, stick |
353 /* #### In theory, we should drain the events pending, stick | 345 ** #### them in the queue, and return the mouse position |
354 ** #### them in the queue, and return the mouse position | 346 ** #### anyway. |
355 ** #### anyway. | 347 */ |
356 */ | 348 return (-1); |
357 return(-1); | 349 *x = ev.x; |
358 } | 350 *y = ev.y; |
359 *x = ev.x; | 351 *frame = DEVICE_SELECTED_FRAME (d); |
360 *y = ev.y; | 352 return (1); |
361 *frame = DEVICE_SELECTED_FRAME (d); | |
362 return (1); | |
363 } | 353 } |
364 | 354 |
365 static void | 355 static void |
366 tty_set_mouse_position (struct window *w, int x, int y) | 356 tty_set_mouse_position (struct window *w, int x, int y) |
367 { | 357 { |
368 /* | 358 /* |
369 #### I couldn't find any GPM functions that set the mouse position. | 359 #### I couldn't find any GPM functions that set the mouse position. |
370 #### Mr. Perry had left this function empty; that must be why. | 360 #### Mr. Perry had left this function empty; that must be why. |
371 #### karlheg | 361 #### karlheg |
372 */ | 362 */ |
373 } | 363 } |
374 | 364 |
375 static int gpm_event_pending_p (int user_p) | 365 static int gpm_event_pending_p (int user_p) |
376 { | 366 { |
377 Lisp_Object event; | 367 Lisp_Object event; |
378 | 368 |
379 EVENT_CHAIN_LOOP (event, gpm_event_queue) | 369 EVENT_CHAIN_LOOP (event, gpm_event_queue) |
370 { | |
371 if (!user_p || command_event_p (event)) | |
372 return (1); | |
373 } | |
374 return (orig_event_pending_p (user_p)); | |
375 } | |
376 | |
377 static void gpm_next_event_cb (Lisp_Event *event) | |
378 { | |
379 /* #### It would be nice to preserve some sort of ordering of the | |
380 ** #### different types of events, but that would be quite a bit | |
381 ** #### of work, and would more than likely break the abstraction | |
382 ** #### between the other event loops and this one. | |
383 */ | |
384 | |
385 if (!NILP (gpm_event_queue)) | |
386 { | |
387 Lisp_Object queued_event = | |
388 dequeue_event (&gpm_event_queue, &gpm_event_queue_tail); | |
389 *event = *(XEVENT (queued_event)); | |
390 | |
391 if (event->event_type == pointer_motion_event) | |
380 { | 392 { |
381 if (!user_p || command_event_p (event)) | 393 struct device *d = decode_device (event->channel); |
382 { | 394 int fd = DEVICE_INFD (d); |
383 return (1); | 395 |
384 } | 396 /* Ok, now this is just freaky. Bear with me though. |
397 ** | |
398 ** If you run gnuclient and attach to a XEmacs running in | |
399 ** X or on another TTY, the mouse cursor does not get | |
400 ** drawn correctly. This is because the ioctl() fails | |
401 ** with EPERM because the TTY specified is not our | |
402 ** controlling terminal. If you are the superuser, it | |
403 ** will work just spiffy. The appropriate source file (at | |
404 ** least in linux 2.2.x) is | |
405 ** .../linux/drivers/char/console.c in the function | |
406 ** tioclinux(). The following bit of code is brutal to | |
407 ** us: | |
408 ** | |
409 ** if (current->tty != tty && !suser()) | |
410 ** return -EPERM; | |
411 ** | |
412 ** I even tried setting us as a process leader, removing | |
413 ** our controlling terminal, and then using the TIOCSCTTY | |
414 ** to set up a new controlling terminal, all with no luck. | |
415 ** | |
416 ** What is even weirder is if you run XEmacs in a VC, and | |
417 ** attach to it from another VC with gnuclient, go back to | |
418 ** the original VC and hit a key, the mouse pointer | |
419 ** displays (in BOTH VCs), until you hit a key in the | |
420 ** second VC, after which it does not display in EITHER | |
421 ** VC. Bizarre, no? | |
422 ** | |
423 ** All I can say is thank god Linux comes with source code | |
424 ** or I would have been completely confused. Well, ok, | |
425 ** I'm still completely confused. I don't see why they | |
426 ** don't just check the permissions on the device | |
427 ** (actually, if you have enough access to it to get the | |
428 ** console's file descriptor, you should be able to do | |
429 ** with it as you wish, but maybe that is just me). | |
430 ** | |
431 ** William M. Perry - Nov 9, 1999 | |
432 */ | |
433 | |
434 Gpm_DrawPointer (event->event.motion.x,event->event.motion.y, fd); | |
385 } | 435 } |
386 return (orig_event_pending_p (user_p)); | 436 |
387 } | 437 return; |
388 | 438 } |
389 static void gpm_next_event_cb (Lisp_Event *event) | 439 |
390 { | 440 orig_next_event_cb (event); |
391 /* #### It would be nice to preserve some sort of ordering of the | |
392 ** #### different types of events, but that would be quite a bit | |
393 ** #### of work, and would more than likely break the abstraction | |
394 ** #### between the other event loops and this one. | |
395 */ | |
396 | |
397 if (!NILP (gpm_event_queue)) | |
398 { | |
399 Lisp_Object queued_event = dequeue_event (&gpm_event_queue, &gpm_event_queue_tail); | |
400 *event = *(XEVENT (queued_event)); | |
401 | |
402 if (event->event_type == pointer_motion_event) | |
403 { | |
404 struct device *d = decode_device (event->channel); | |
405 int fd = DEVICE_INFD (d); | |
406 | |
407 /* Ok, now this is just freaky. Bear with me though. | |
408 ** | |
409 ** If you run gnuclient and attach to a XEmacs running in | |
410 ** X or on another TTY, the mouse cursor does not get | |
411 ** drawn correctly. This is because the ioctl() fails | |
412 ** with EPERM because the TTY specified is not our | |
413 ** controlling terminal. If you are the superuser, it | |
414 ** will work just spiffy. The appropriate source file (at | |
415 ** least in linux 2.2.x) is | |
416 ** .../linux/drivers/char/console.c in the function | |
417 ** tioclinux(). The following bit of code is brutal to | |
418 ** us: | |
419 ** | |
420 ** if (current->tty != tty && !suser()) | |
421 ** return -EPERM; | |
422 ** | |
423 ** I even tried setting us as a process leader, removing | |
424 ** our controlling terminal, and then using the TIOCSCTTY | |
425 ** to set up a new controlling terminal, all with no luck. | |
426 ** | |
427 ** What is even weirder is if you run XEmacs in a VC, and | |
428 ** attach to it from another VC with gnuclient, go back to | |
429 ** the original VC and hit a key, the mouse pointer | |
430 ** displays (in BOTH VCs), until you hit a key in the | |
431 ** second VC, after which it does not display in EITHER | |
432 ** VC. Bizarre, no? | |
433 ** | |
434 ** All I can say is thank god Linux comes with source code | |
435 ** or I would have been completely confused. Well, ok, | |
436 ** I'm still completely confused. I don't see why they | |
437 ** don't just check the permissions on the device | |
438 ** (actually, if you have enough access to it to get the | |
439 ** console's file descriptor, you should be able to do | |
440 ** with it as you wish, but maybe that is just me). | |
441 ** | |
442 ** William M. Perry - Nov 9, 1999 | |
443 */ | |
444 | |
445 Gpm_DrawPointer (event->event.motion.x,event->event.motion.y, fd); | |
446 } | |
447 | |
448 return; | |
449 } | |
450 | |
451 orig_next_event_cb (event); | |
452 } | 441 } |
453 | 442 |
454 static void hook_event_callbacks_once (void) | 443 static void hook_event_callbacks_once (void) |
455 { | 444 { |
456 static int hooker; | 445 static int hooker; |
457 | 446 |
458 if (!hooker) | 447 if (!hooker) |
459 { | 448 { |
460 orig_event_pending_p = event_stream->event_pending_p; | 449 orig_event_pending_p = event_stream->event_pending_p; |
461 orig_next_event_cb = event_stream->next_event_cb; | 450 orig_next_event_cb = event_stream->next_event_cb; |
462 event_stream->event_pending_p = gpm_event_pending_p; | 451 event_stream->event_pending_p = gpm_event_pending_p; |
463 event_stream->next_event_cb = gpm_next_event_cb; | 452 event_stream->next_event_cb = gpm_next_event_cb; |
464 hooker = 1; | 453 hooker = 1; |
465 } | 454 } |
466 } | 455 } |
467 | 456 |
468 static void hook_console_methods_once (void) | 457 static void hook_console_methods_once (void) |
469 { | 458 { |
470 static int hooker; | 459 static int hooker; |
471 | 460 |
472 if (!hooker) | 461 if (!hooker) |
473 { | 462 { |
474 /* Install the mouse position methods for the TTY console type */ | 463 /* Install the mouse position methods for the TTY console type */ |
475 CONSOLE_HAS_METHOD (tty, get_mouse_position); | 464 CONSOLE_HAS_METHOD (tty, get_mouse_position); |
476 CONSOLE_HAS_METHOD (tty, set_mouse_position); | 465 CONSOLE_HAS_METHOD (tty, set_mouse_position); |
477 CONSOLE_HAS_METHOD (tty, get_foreign_selection); | 466 CONSOLE_HAS_METHOD (tty, get_foreign_selection); |
478 CONSOLE_HAS_METHOD (tty, selection_exists_p); | 467 CONSOLE_HAS_METHOD (tty, selection_exists_p); |
479 #if 0 | 468 #if 0 |
480 CONSOLE_HAS_METHOD (tty, own_selection); | 469 CONSOLE_HAS_METHOD (tty, own_selection); |
481 #endif | 470 #endif |
482 } | 471 } |
483 } | 472 } |
484 | 473 |
485 DEFUN ("gpm-enabled-p", Fgpm_enabled_p, 0, 1, 0, /* | 474 DEFUN ("gpm-enabled-p", Fgpm_enabled_p, 0, 1, 0, /* |
486 Return non-nil if GPM mouse support is currently enabled on DEVICE. | 475 Return non-nil if GPM mouse support is currently enabled on DEVICE. |
487 */ | 476 */ |
488 (device)) | 477 (device)) |
489 { | 478 { |
490 char *console_name = ttyname (DEVICE_INFD (decode_device (device))); | 479 char *console_name = ttyname (DEVICE_INFD (decode_device (device))); |
491 char process_name[1024]; | 480 char process_name[1024]; |
492 Lisp_Object proc; | 481 Lisp_Object proc; |
493 | 482 |
494 if (!console_name) | 483 if (!console_name) |
495 { | 484 return (Qnil); |
496 return (Qnil); | 485 |
497 } | 486 memset (process_name, '\0', sizeof(process_name)); |
498 | 487 snprintf (process_name, sizeof(process_name) - 1, "gpm for %s", |
499 memset (process_name, '\0', sizeof(process_name)); | 488 console_name); |
500 snprintf (process_name, sizeof(process_name) - 1, "gpm for %s", console_name); | 489 |
501 | 490 proc = Fget_process (build_string (process_name)); |
502 proc = Fget_process (build_string (process_name)); | 491 |
503 | 492 if (NILP (proc)) |
504 if (NILP (proc)) | 493 return (Qnil); |
505 { | 494 |
506 return (Qnil); | 495 if (1) /* (PROCESS_LIVE_P (proc)) */ |
507 } | 496 return (Qt); |
508 | 497 return (Qnil); |
509 if (1) /* (PROCESS_LIVE_P (proc)) */ | |
510 { | |
511 return (Qt); | |
512 } | |
513 return (Qnil); | |
514 } | 498 } |
515 | 499 |
516 DEFUN ("gpm-enable", Fgpm_enable, 0, 2, 0, /* | 500 DEFUN ("gpm-enable", Fgpm_enable, 0, 2, 0, /* |
517 Toggle accepting of GPM mouse events. | 501 Toggle accepting of GPM mouse events. |
518 */ | 502 */ |
519 (device, arg)) | 503 (device, arg)) |
520 { | 504 { |
521 Gpm_Connect conn; | 505 Gpm_Connect conn; |
522 int rval; | 506 int rval; |
523 Lisp_Object gpm_process; | 507 Lisp_Object gpm_process; |
524 Lisp_Object gpm_filter; | 508 Lisp_Object gpm_filter; |
525 struct device *d = decode_device (device); | 509 struct device *d = decode_device (device); |
526 int fd = DEVICE_INFD (d); | 510 int fd = DEVICE_INFD (d); |
527 char *console_name = ttyname (fd); | 511 char *console_name = ttyname (fd); |
528 char process_name[1024]; | 512 char process_name[1024]; |
529 | 513 |
530 hook_event_callbacks_once (); | 514 hook_event_callbacks_once (); |
531 hook_console_methods_once (); | 515 hook_console_methods_once (); |
532 | 516 |
533 if (noninteractive) | 517 if (noninteractive) |
518 invalid_operation ("Can't connect to GPM in batch mode", Qunbound); | |
519 | |
520 if (!console_name) | |
521 /* Something seriously wrong here... */ | |
522 return (Qnil); | |
523 | |
524 memset (process_name, '\0', sizeof(process_name)); | |
525 snprintf (process_name, sizeof(process_name) - 1, "gpm for %s", | |
526 console_name); | |
527 | |
528 if (NILP (arg)) | |
529 { | |
530 turn_off_gpm (process_name); | |
531 return (Qnil); | |
532 } | |
533 | |
534 /* DANGER DANGER. | |
535 ** Though shalt not call (gpm-enable t) after we have already | |
536 ** started, or stuff blows up. | |
537 */ | |
538 if (!NILP (Fgpm_enabled_p (device))) | |
539 invalid_operation ("GPM already enabled for this console", Qunbound); | |
540 | |
541 conn.eventMask = GPM_DOWN|GPM_UP|GPM_MOVE|GPM_DRAG; | |
542 conn.defaultMask = GPM_MOVE; | |
543 conn.minMod = 0; | |
544 conn.maxMod = ((1 << KG_SHIFT) | (1 << KG_ALT) | (1 << KG_CTRL)); | |
545 | |
546 /* Reset some silly static variables so that multiple Gpm_Open() | |
547 ** calls have even a slight chance of working | |
548 */ | |
549 gpm_tried = 0; | |
550 gpm_flag = 0; | |
551 gpm_stack = NULL; | |
552 | |
553 /* Make sure Gpm_Open() does ioctl() on the correct | |
554 ** descriptor, or it can get the wrong terminal sizes, etc. | |
555 */ | |
556 gpm_consolefd = fd; | |
557 | |
558 /* We have to pass the virtual console manually, otherwise if you | |
559 ** use 'gnuclient -nw' to connect to an XEmacs that is running in | |
560 ** X, Gpm_Open() tries to use ttyname(0 | 1 | 2) to find out which | |
561 ** console you are using, which is of course not correct for the | |
562 ** new tty device. | |
563 */ | |
564 if (strncmp (console_name, "/dev/tty", 8) || !isdigit (console_name[8])) | |
565 /* Urk, something really wrong */ | |
566 return (Qnil); | |
567 | |
568 rval = Gpm_Open (&conn, atoi (console_name + 8)); | |
569 | |
570 switch (rval) | |
571 { | |
572 case -1: /* General failure */ | |
573 break; | |
574 case -2: /* We are running under an XTerm */ | |
575 Gpm_Close(); | |
576 break; | |
577 default: | |
578 /* Is this really necessary? */ | |
579 set_descriptor_non_blocking (gpm_fd); | |
580 store_gpm_state (gpm_fd); | |
581 gpm_process = | |
582 connect_to_file_descriptor (build_string (process_name), Qnil, | |
583 make_int (gpm_fd), | |
584 make_int (gpm_fd)); | |
585 | |
586 if (!NILP (gpm_process)) | |
534 { | 587 { |
535 invalid_operation ("Can't connect to GPM in batch mode.", Qunbound); | 588 rval = 0; |
589 Fprocess_kill_without_query (gpm_process, Qnil); | |
590 gpm_filter = wrap_subr (&SFreceive_gpm_event); | |
591 set_process_filter (gpm_process, gpm_filter, 1); | |
592 | |
593 /* Keep track of the device for later */ | |
594 /* Fput (gpm_process, intern ("gpm-device"), device); */ | |
536 } | 595 } |
537 | 596 else |
538 if (!console_name) | |
539 { | 597 { |
540 /* Something seriously wrong here... */ | 598 Gpm_Close (); |
541 return (Qnil); | 599 rval = -1; |
542 } | 600 } |
543 | 601 } |
544 memset (process_name, '\0', sizeof(process_name)); | 602 |
545 snprintf (process_name, sizeof(process_name) - 1, "gpm for %s", console_name); | 603 return (rval ? Qnil : Qt); |
546 | |
547 if (NILP (arg)) | |
548 { | |
549 turn_off_gpm (process_name); | |
550 return (Qnil); | |
551 } | |
552 | |
553 /* DANGER DANGER. | |
554 ** Though shalt not call (gpm-enable t) after we have already | |
555 ** started, or stuff blows up. | |
556 */ | |
557 if (!NILP (Fgpm_enabled_p (device))) | |
558 { | |
559 invalid_operation ("GPM already enabled for this console.", Qunbound); | |
560 } | |
561 | |
562 conn.eventMask = GPM_DOWN|GPM_UP|GPM_MOVE|GPM_DRAG; | |
563 conn.defaultMask = GPM_MOVE; | |
564 conn.minMod = 0; | |
565 conn.maxMod = ((1<<KG_SHIFT)|(1<<KG_ALT)|(1<<KG_CTRL)); | |
566 | |
567 /* Reset some silly static variables so that multiple Gpm_Open() | |
568 ** calls have even a slight chance of working | |
569 */ | |
570 gpm_tried = 0; | |
571 gpm_flag = 0; | |
572 gpm_stack = NULL; | |
573 | |
574 /* Make sure Gpm_Open() does ioctl() on the correct | |
575 ** descriptor, or it can get the wrong terminal sizes, etc. | |
576 */ | |
577 gpm_consolefd = fd; | |
578 | |
579 /* We have to pass the virtual console manually, otherwise if you | |
580 ** use 'gnuclient -nw' to connect to an XEmacs that is running in | |
581 ** X, Gpm_Open() tries to use ttyname(0 | 1 | 2) to find out which | |
582 ** console you are using, which is of course not correct for the | |
583 ** new tty device. | |
584 */ | |
585 if (strncmp (console_name, "/dev/tty",8) || !isdigit (console_name[8])) | |
586 { | |
587 /* Urk, something really wrong */ | |
588 return (Qnil); | |
589 } | |
590 | |
591 rval = Gpm_Open (&conn, atoi(console_name + 8)); | |
592 | |
593 switch (rval) { | |
594 case -1: /* General failure */ | |
595 break; | |
596 case -2: /* We are running under an XTerm */ | |
597 Gpm_Close(); | |
598 break; | |
599 default: | |
600 /* Is this really necessary? */ | |
601 set_descriptor_non_blocking (gpm_fd); | |
602 store_gpm_state (gpm_fd); | |
603 gpm_process = connect_to_file_descriptor (build_string (process_name), Qnil, | |
604 make_int (gpm_fd), | |
605 make_int (gpm_fd)); | |
606 | |
607 if (!NILP (gpm_process)) | |
608 { | |
609 rval = 0; | |
610 Fprocess_kill_without_query (gpm_process, Qnil); | |
611 XSETSUBR (gpm_filter, &SFreceive_gpm_event); | |
612 set_process_filter (gpm_process, gpm_filter, 1); | |
613 | |
614 /* Keep track of the device for later */ | |
615 /* Fput (gpm_process, intern ("gpm-device"), device); */ | |
616 } | |
617 else | |
618 { | |
619 Gpm_Close(); | |
620 rval = -1; | |
621 } | |
622 } | |
623 | |
624 return(rval ? Qnil : Qt); | |
625 } | 604 } |
626 | 605 |
627 void vars_of_gpmevent (void) | 606 void vars_of_gpmevent (void) |
628 { | 607 { |
629 gpm_event_queue = Qnil; | 608 gpm_event_queue = Qnil; |
630 gpm_event_queue_tail = Qnil; | 609 gpm_event_queue_tail = Qnil; |
631 staticpro (&gpm_event_queue); | 610 staticpro (&gpm_event_queue); |
632 staticpro (&gpm_event_queue_tail); | 611 staticpro (&gpm_event_queue_tail); |
633 dump_add_root_object (&gpm_event_queue); | 612 dump_add_root_object (&gpm_event_queue); |
634 dump_add_root_object (&gpm_event_queue_tail); | 613 dump_add_root_object (&gpm_event_queue_tail); |
635 } | 614 } |
636 | 615 |
637 void syms_of_gpmevent (void) | 616 void syms_of_gpmevent (void) |
638 { | 617 { |
639 DEFSUBR (Freceive_gpm_event); | 618 DEFSUBR (Freceive_gpm_event); |
640 DEFSUBR (Fgpm_enable); | 619 DEFSUBR (Fgpm_enable); |
641 DEFSUBR (Fgpm_enabled_p); | 620 DEFSUBR (Fgpm_enabled_p); |
642 } | 621 } |
643 | 622 |
644 #endif /* HAVE_GPM */ | 623 #endif /* HAVE_GPM */ |