1 /* This is the interface to the GPM mouse under Linux */
2 /* Copyright (c) 1992, 1998 John E. Davis
3 * This file is part of JED editor library source.
4 *
5 * You may distribute this file under the terms the GNU General Public
6 * License. See the file COPYING for more information.
7 */
8 #include "config.h"
9 #include "jed-feat.h"
10
11 #include <stdio.h>
12 #include <signal.h>
13 #include <slang.h>
14
15 #include <gpm.h>
16
17 #include "jdmacros.h"
18
19 #include "buffer.h"
20 #include "sysdep.h"
21 #include "keymap.h"
22 #include "misc.h"
23 #include "paste.h"
24 #include "screen.h"
25 #include "ledit.h"
26 #include "ins.h"
27 #include "display.h"
28 #include "hooks.h"
29 #include "kanji.h"
30
31 #define MOD_SHIFT 1
32 #define MOD_CTRL 4
33
34 static int Mouse_Showing;
35 static int MouseX, MouseY;
36 static int Suspend_Mouse_Events;
37
38 #if 0
39 /* This is needed to get the link to work with gpm. */
40 int wgetch (void)
41 {
42 return 0;
43 }
44 int *stdscr;
45 #endif
46
draw_mouse(void)47 static void draw_mouse (void)
48 {
49 Gpm_Event event;
50
51 if (MouseX < 1)
52 MouseX = 1;
53 else if (MouseX >= Jed_Num_Screen_Cols)
54 MouseX = Jed_Num_Screen_Cols;
55
56 if (MouseY < 1)
57 MouseY = 1;
58 else if (MouseY >= Jed_Num_Screen_Rows)
59 MouseY = Jed_Num_Screen_Rows;
60
61 event.x = MouseX;
62 event.y = MouseY;
63
64 GPM_DRAWPOINTER(&event);
65 Mouse_Showing = 1;
66 }
67
68
mouse_handler_2(void)69 static int mouse_handler_2 (void)
70 {
71 int b = 0, nbuttons;
72 Gpm_Event event;
73 unsigned char buf[3];
74 JMouse_Type jm;
75
76 if (Gpm_GetEvent (&event) <= 0) return -1;
77 if (Suspend_Mouse_Events)
78 {
79 if (Suspend_Mouse_Events == -1)
80 Suspend_Mouse_Events = 0;
81 return -1;
82 }
83
84 MouseX += event.dx;
85 MouseY += event.dy;
86
87 draw_mouse ();
88
89 if (event.type & GPM_MOVE) return 0;
90
91 nbuttons = 0;
92 if (event.buttons & GPM_B_LEFT)
93 {
94 b = JMOUSE_BUTTON_1;
95 nbuttons++;
96 }
97 if (event.buttons & GPM_B_MIDDLE)
98 {
99 b = JMOUSE_BUTTON_2;
100 nbuttons++;
101 }
102 if (event.buttons & GPM_B_RIGHT)
103 {
104 b = JMOUSE_BUTTON_3;
105 nbuttons++;
106 }
107
108 if (nbuttons != 1) return 0;
109
110 jm.button = b;
111
112 if ((event.type & GPM_DOUBLE)
113 && (event.type & GPM_DOWN)) jm.type = JMOUSE_DOUBLE_CLICK;
114 else if ((event.type & GPM_TRIPLE)
115 && (event.type & GPM_DOWN)) jm.type = JMOUSE_TRIPLE_CLICK;
116 else if (event.type & GPM_DRAG) jm.type = JMOUSE_DRAG;
117 else if (event.type & GPM_DOWN) jm.type = JMOUSE_DOWN;
118 else if (event.type & GPM_UP) jm.type = JMOUSE_UP;
119 else return 0;
120
121 if (event.modifiers & MOD_SHIFT)
122 {
123 jm.state = JMOUSE_SHIFT;
124 }
125 else if (event.modifiers & MOD_CTRL)
126 {
127 jm.state = JMOUSE_CTRL;
128 }
129 else jm.state = 0;
130
131 jm.x = MouseX;
132 jm.y = MouseY;
133
134 b = jed_mouse_add_event (&jm);
135 if (b == -1) return 0;
136
137 buf[0] = 27; buf[1] = 0; buf[2] = (char) b;
138 ungetkey_string ((char *)buf, 3);
139 return 1;
140 }
141
142
143 static int Warp_Pending;
close_update(void)144 static void close_update (void)
145 {
146 if (Warp_Pending || Mouse_Showing)
147 {
148 if (Warp_Pending)
149 {
150 MouseX = Screen_Col;
151 MouseY = Screen_Row;
152 }
153 draw_mouse ();
154 Warp_Pending = 0;
155 }
156 else Mouse_Showing = 0;
157 }
158
warp_pointer(void)159 static void warp_pointer (void)
160 {
161 Warp_Pending = 1;
162 }
163
164 static char *CutBuffer;
165 static int CutBuffer_Len;
166
insert_cutbuffer(void)167 static int insert_cutbuffer (void)
168 {
169 CHECK_READ_ONLY
170 if (CutBuffer == NULL) return 0;
171 if (CutBuffer_Len) ins_chars ((unsigned char *) CutBuffer, CutBuffer_Len);
172 return CutBuffer_Len;
173 }
174
region_to_cutbuffer(void)175 static void region_to_cutbuffer (void)
176 {
177 int nbytes;
178
179 if (CutBuffer != NULL)
180 {
181 SLfree (CutBuffer);
182 }
183
184 CutBuffer = make_buffer_substring(&nbytes);
185 CutBuffer_Len = nbytes;
186 }
187
close_mouse(void)188 static void close_mouse (void)
189 {
190 JMouse_Hide_Mouse_Hook = NULL;
191 X_Update_Close_Hook = NULL;
192
193 if (JMouse_Event_Hook == NULL) return;
194 JMouse_Event_Hook = NULL;
195
196 Gpm_Close ();
197 }
198
disable_mouse(void)199 static void disable_mouse (void)
200 {
201 reset_tty (); /* closes mouse */
202 X_Open_Mouse_Hook = NULL;
203 X_Close_Mouse_Hook = NULL;
204 init_tty ();
205 }
206
207 static SLang_Intrin_Fun_Type gpm_mouse_table[] =
208 {
209 MAKE_INTRINSIC("x_warp_pointer", warp_pointer, VOID_TYPE, 0),
210 MAKE_INTRINSIC("x_insert_cutbuffer", insert_cutbuffer, INT_TYPE, 0),
211 /* Prototype: Integer x_insert_cut_buffer ();
212 * Inserts cutbuffer into the current buffer and returns the number
213 * of characters inserted.
214 */
215 MAKE_INTRINSIC("x_copy_region_to_cutbuffer", region_to_cutbuffer, VOID_TYPE, 0),
216 /* Prototype: Void x_copy_region_to_cutbuffer();
217 */
218 MAKE_INTRINSIC("gpm_disable_mouse", disable_mouse, VOID_TYPE, 0),
219 SLANG_END_TABLE
220 };
221
hide_mouse(int show)222 static void hide_mouse (int show)
223 {
224 Mouse_Showing = show;
225 }
226
open_mouse(void)227 static int open_mouse (void)
228 {
229 static int not_first_time;
230 Gpm_Connect conn;
231 char *term;
232 SLSig_Fun_Type *sigtstp_fun;
233 int status;
234
235 /* Unbelievable. If we are running in an Xterm, gpm will turn on mouse
236 * reporting. Nice huh? NOT!!!
237 */
238 term = getenv ("TERM");
239 if ((term != NULL)
240 && (!strncmp (term, "xterm", 5) && !strncmp(term, "kterm", 5)))
241 return -1;
242
243 /* Another libgpm annoyance. gpm installs a signal handler for SIGTSTP.
244 * I am going to un-install it.
245 */
246 sigtstp_fun = SLsignal (SIGTSTP, (SLSig_Fun_Type *)SIG_DFL);
247
248 conn.eventMask = ~0;
249 conn.defaultMask = 0;
250 conn.maxMod = MOD_CTRL | MOD_SHIFT;
251 conn.minMod = 0;
252
253 Mouse_Showing = 0;
254 Suspend_Mouse_Events = -1;
255 MouseX = Jed_Num_Screen_Cols / 2;
256 MouseY = Jed_Num_Screen_Rows / 2;
257
258 status = Gpm_Open (&conn, 0);
259 /* Uninstall the gpm signal handler */
260 (void) SLsignal (SIGTSTP, sigtstp_fun);
261
262 if (status == -1)
263 return -1;
264
265 if (not_first_time == 0)
266 {
267 if (-1 == SLadd_intrin_fun_table (gpm_mouse_table, "MOUSE"))
268 return -1;
269
270 not_first_time = 1;
271 }
272
273 JMouse_Event_Hook = mouse_handler_2;
274 X_Update_Close_Hook = close_update;
275 JMouse_Hide_Mouse_Hook = hide_mouse;
276 return gpm_fd;
277 }
278
279
280 int (*X_Open_Mouse_Hook)(void) = open_mouse;
281 void (*X_Close_Mouse_Hook)(void) = close_mouse;
282
283
284