1268
|
1 /* Shared event code between X and GTK -- include file.
|
|
2 Copyright (C) 1991-5, 1997 Free Software Foundation, Inc.
|
|
3 Copyright (C) 1995 Sun Microsystems, Inc.
|
|
4 Copyright (C) 1996, 2001, 2002, 2003 Ben Wing.
|
|
5
|
|
6 This file is part of XEmacs.
|
|
7
|
|
8 XEmacs is free software; you can redistribute it and/or modify it
|
|
9 under the terms of the GNU General Public License as published by the
|
|
10 Free Software Foundation; either version 2, or (at your option) any
|
|
11 later version.
|
|
12
|
|
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT
|
|
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
16 for more details.
|
|
17
|
|
18 You should have received a copy of the GNU General Public License
|
|
19 along with XEmacs; see the file COPYING. If not, write to
|
|
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
21 Boston, MA 02111-1307, USA. */
|
|
22
|
|
23 /* Synched up with: Not in FSF. */
|
|
24
|
|
25 /* For some code it's reasonable to have only one copy and conditionalize
|
|
26 at run-time. For other code it isn't. #### Perhaps all code should be
|
|
27 included here, not in event-xlike.c. However, event-xlike.c is always
|
|
28 X-specific, whereas the following code isn't, in the GTK case. */
|
|
29
|
2828
|
30 EXFUN (Funicode_to_char, 2); /* In unicode.c. */
|
|
31
|
1268
|
32 static int
|
|
33 #ifdef THIS_IS_GTK
|
|
34 emacs_gtk_event_pending_p (int how_many)
|
|
35 #else
|
|
36 emacs_Xt_event_pending_p (int how_many)
|
|
37 #endif
|
|
38 {
|
|
39 Lisp_Object event;
|
|
40 int tick_count_val;
|
|
41
|
|
42 /* If `how_many' is 0, then this function returns whether there are any
|
|
43 X, timeout, or fd events pending (that is, whether
|
|
44 emacs_Xt_next_event() would return immediately without blocking).
|
|
45
|
|
46 If `how_many' is > 0, then this function returns whether there are
|
|
47 that many *user generated* events available (keyboard, mouse click,
|
|
48 etc.). This also implies that emacs_Xt_next_event() would not block.
|
|
49 */
|
|
50
|
|
51 /* This function used to simply check whether there were any X events (or
|
|
52 if user_p was 1, it iterated over all the pending X events using
|
|
53 XCheckIfEvent(), looking for keystrokes and button events). That
|
|
54 worked in the old cheesoid event loop, which didn't go through
|
|
55 XtAppDispatchEvent(), but it doesn't work any more -- X events may not
|
|
56 result in anything. For example, a button press in a blank part of
|
|
57 the menubar appears as an X event but will not result in any Emacs
|
|
58 events (a button press that activates the menubar results in an Emacs
|
|
59 event through the stop_next_event mechanism).
|
|
60
|
|
61 The only accurate way of determining whether these X events translate
|
|
62 into Emacs events is to go ahead and dispatch them until there's
|
|
63 something on the dispatch queue. */
|
|
64
|
|
65 if (!how_many)
|
|
66 {
|
|
67 /* We're being asked for *ALL* events, not just user events. */
|
|
68
|
|
69 /* (1) Any pending events in the dispatch queue? */
|
|
70 if (!NILP (dispatch_event_queue))
|
|
71 return 1;
|
|
72
|
|
73 /* (2) Any TTY or process input available?
|
|
74
|
|
75 Note that formerly we just checked the value of XtAppPending() to
|
|
76 determine if there was file-desc input. This doesn't work any
|
|
77 more with the signal_event_pipe; XtAppPending() will says "yes" in
|
|
78 this case but there isn't really any input. So instead we keep
|
|
79 track of the file descriptors, and call select() ourselves.
|
|
80 Another way of fixing this problem is for the signal_event_pipe to
|
|
81 generate actual input in the form of an identity eval event or
|
|
82 something. (#### maybe this actually happens?) */
|
|
83
|
|
84 if (poll_fds_for_input (non_fake_input_wait_mask))
|
|
85 return 1;
|
|
86
|
|
87 #ifndef THIS_IS_GTK
|
|
88 /* (3) Any timeout input available? */
|
|
89 if (XtAppPending (Xt_app_con) & XtIMTimer)
|
|
90 return 1;
|
|
91 #else
|
|
92 /* #### Is there any way to do this in Gtk? I don't think there
|
|
93 is a 'peek' for events */
|
|
94 #endif
|
|
95 }
|
|
96 else
|
|
97 {
|
|
98 /* HOW_MANY > 0 */
|
|
99 EVENT_CHAIN_LOOP (event, dispatch_event_queue)
|
|
100 {
|
|
101 if (command_event_p (event))
|
|
102 {
|
|
103 how_many--;
|
|
104 if (how_many <= 0)
|
|
105 return 1;
|
|
106 }
|
|
107 }
|
|
108 }
|
|
109
|
|
110 /* XtAppPending() can be super-slow, esp. over a network connection.
|
|
111 Quantify results have indicated that in some cases the call to
|
|
112 detect_input_pending() completely dominates the running time of
|
|
113 redisplay(). Fortunately, in a SIGIO world we can more quickly
|
|
114 determine whether there are any X events: if an event has happened
|
|
115 since the last time we checked, then a SIGIO will have happened. On a
|
|
116 machine with broken SIGIO, we'll still be in an OK state --
|
|
117 quit_check_signal_tick_count will get ticked at least every 1/4
|
|
118 second, so we'll be no more than that much behind reality. (In general
|
|
119 it's OK if we erroneously report no input pending when input is
|
|
120 actually pending() -- preemption is just a bit less efficient, that's
|
|
121 all. It's bad bad bad if you err the other way -- you've promised
|
|
122 that `next-event' won't block but it actually will, and some action
|
|
123 might get delayed until the next time you hit a key.)
|
|
124 */
|
|
125
|
|
126 if (!in_modal_loop)
|
|
127 {
|
|
128 /* quit_check_signal_tick_count is volatile so try to avoid race
|
|
129 conditions by using a temporary variable */
|
|
130 tick_count_val = quit_check_signal_tick_count;
|
|
131 if (last_quit_check_signal_tick_count != tick_count_val
|
|
132 #if !defined (THIS_IS_GTK) && (!defined (SIGIO) || defined (CYGWIN))
|
|
133 || (XtIMXEvent & XtAppPending (Xt_app_con))
|
|
134 #endif
|
|
135 )
|
|
136 {
|
|
137 last_quit_check_signal_tick_count = tick_count_val;
|
|
138
|
|
139 /* We need to drain the entire queue now -- if we only drain part of
|
|
140 it, we may later on end up with events actually pending but
|
|
141 detect_input_pending() returning false because there wasn't
|
|
142 another SIGIO. */
|
|
143 event_stream_drain_queue ();
|
|
144
|
|
145 if (!how_many)
|
|
146 return !NILP (dispatch_event_queue);
|
|
147
|
|
148 EVENT_CHAIN_LOOP (event, dispatch_event_queue)
|
|
149 {
|
|
150 if (command_event_p (event))
|
|
151 {
|
|
152 how_many--;
|
|
153 if (how_many <= 0)
|
|
154 return 1;
|
|
155 }
|
|
156 }
|
|
157
|
|
158 return 0;
|
|
159 }
|
|
160 }
|
|
161
|
|
162 return 0;
|
|
163 }
|
2828
|
164
|
|
165 #if defined(THIS_IS_X) || !defined(__GDK_KEYS_H__)
|
|
166
|
|
167 /* Use an appropriate map to Unicode within x_keysym_to_character. Arguments
|
|
168 are evaluated multiple times.
|
|
169
|
|
170 Breaks if an X11 keysym maps to zero in Unicode. */
|
|
171
|
|
172 #define USE_UNICODE_MAP(keysym, map) \
|
|
173 if (keysym >= FIRST_KNOWN_##map \
|
|
174 && (keysym < (FIRST_KNOWN_##map + countof(map))) \
|
|
175 && map[keysym - FIRST_KNOWN_##map ]) do \
|
|
176 { \
|
|
177 keysym -= FIRST_KNOWN_##map ; \
|
|
178 return Funicode_to_char(make_int(map[keysym]), Qnil); \
|
|
179 } while (0)
|
|
180
|
|
181 /* Maps to Unicode for X11 KeySyms, where we don't have a direct internal
|
|
182 mapping based on a Mule character set, or whatever. Taken from Markus
|
|
183 Kuhn's X11.keysyms--if you're ever comparing with that file, note the
|
|
184 sequences of KeySyms often leave out entries, so you'll have to fill them
|
|
185 in. Doesn't include support for Hangul, which it should, if the X11
|
|
186 Hangul keysyms have ever been used anywhere.
|
|
187
|
|
188 I'm not #ifdef'ing this based on wheter MULE is defined, because it's a
|
|
189 matter of 324 bytes in a stripped executable, and I want the
|
|
190 testing. :-P */
|
|
191
|
|
192 static UINT_16_BIT const TECHNICAL[] =
|
|
193 {
|
|
194 0x23B7, /* #x08A1 LEFT RADICAL Technical */
|
|
195
|
|
196 #define FIRST_KNOWN_TECHNICAL 0x8A1
|
|
197
|
|
198 0x0, /* #x08A2 TOP LEFT RADICAL Technical */
|
|
199 0x0, /* #x08A3 HORIZONTAL CONNECTOR Technical */
|
|
200 0x2320, /* #x08A4 TOP INTEGRAL Technical */
|
|
201 0x2321, /* #x08A5 BOTTOM INTEGRAL Technical */
|
|
202 0x0, /* #x08A6 VERTICAL CONNECTOR Technical */
|
|
203 0x23A1, /* #x08A7 TOP LEFT SQUARE BRACKET Technical */
|
|
204 0x23A3, /* #x08A8 BOTTOM LEFT SQUARE BRACKET Technical */
|
|
205 0x23A4, /* #x08A9 TOP RIGHT SQUARE BRACKET Technical */
|
|
206 0x23A6, /* #x08AA BOTTOM RIGHT SQUARE BRACKET Technical */
|
|
207 0x239B, /* #x08AB TOP LEFT PARENTHESIS Technical */
|
|
208 0x239D, /* #x08AC BOTTOM LEFT PARENTHESIS Technical */
|
|
209 0x239E, /* #x08AD TOP RIGHT PARENTHESIS Technical */
|
|
210 0x23A0, /* #x08AE BOTTOM RIGHT PARENTHESIS Technical */
|
|
211 0x23A8, /* #x08AF LEFT MIDDLE CURLY BRACE Technical */
|
|
212 0x23AC, /* #x08B0 RIGHT MIDDLE CURLY BRACE Technical */
|
|
213 0x0, /* #x08B1 TOP LEFT SUMMATION Technical */
|
|
214 0x0, /* #x08B2 BOTTOM LEFT SUMMATION Technical */
|
|
215 0x0, /* #x08B3 TOP VERTICAL SUMMATION CONNECTOR Technical */
|
|
216 0x0, /* #x08B4 BOTTOM VERTICAL SUMMATION CONNECTOR Technical */
|
|
217 0x0, /* #x08B5 TOP RIGHT SUMMATION Technical */
|
|
218 0x0, /* #x08B6 BOTTOM RIGHT SUMMATION Technical */
|
|
219 0x0, /* #x08B7 RIGHT MIDDLE SUMMATION Technical */
|
|
220 0x0, /* #x08B8 */
|
|
221 0x0, /* #x08B9 */
|
|
222 0x0, /* #x08BA */
|
|
223 0x0, /* #x08BB */
|
|
224 0x2264, /* #x08BC LESS THAN OR EQUAL SIGN Technical */
|
|
225 0x2260, /* #x08BD NOT EQUAL SIGN Technical */
|
|
226 0x2265, /* #x08BE GREATER THAN OR EQUAL SIGN Technical */
|
|
227 0x222B, /* #x08BF INTEGRAL Technical */
|
|
228 0x2234, /* #x08C0 THEREFORE Technical */
|
|
229 0x221D, /* #x08C1 VARIATION, PROPORTIONAL TO Technical */
|
|
230 0x221E, /* #x08C2 INFINITY Technical */
|
|
231 0x0, /* #x08C3 */
|
|
232 0x0, /* #x08C4 */
|
|
233 0x2207, /* #x08C5 NABLA, DEL Technical */
|
|
234 0x0, /* #x08C6 */
|
|
235 0x0, /* #x08C7 */
|
|
236 0x223C, /* #x08C8 IS APPROXIMATE TO Technical */
|
|
237 0x2243, /* #x08C9 SIMILAR OR EQUAL TO Technical */
|
|
238 0x0, /* #x08CA */
|
|
239 0x0, /* #x08CB */
|
|
240 0x0, /* #x08CC */
|
|
241 0x21D4, /* #x08CD IF AND ONLY IF Technical */
|
|
242 0x21D2, /* #x08CE IMPLIES Technical */
|
|
243 0x2261, /* #x08CF IDENTICAL TO Technical */
|
|
244 0x0, /* #x08D0 */
|
|
245 0x0, /* #x08D1 */
|
|
246 0x0, /* #x08D2 */
|
|
247 0x0, /* #x08D3 */
|
|
248 0x0, /* #x08D4 */
|
|
249 0x0, /* #x08D5 */
|
|
250 0x221A, /* #x08D6 RADICAL Technical */
|
|
251 0x0, /* #x08D7 */
|
|
252 0x0, /* #x08D8 */
|
|
253 0x0, /* #x08D9 */
|
|
254 0x2282, /* #x08DA IS INCLUDED IN Technical */
|
|
255 0x2283, /* #x08DB INCLUDES Technical */
|
|
256 0x2229, /* #x08DC INTERSECTION Technical */
|
|
257 0x222A, /* #x08DD UNION Technical */
|
|
258 0x2227, /* #x08DE LOGICAL AND Technical */
|
|
259 0x2228, /* #x08DF LOGICAL OR Technical */
|
|
260 0x0, /* #x08E0 */
|
|
261 0x0, /* #x08E1 */
|
|
262 0x0, /* #x08E2 */
|
|
263 0x0, /* #x08E3 */
|
|
264 0x0, /* #x08E4 */
|
|
265 0x0, /* #x08E5 */
|
|
266 0x0, /* #x08E6 */
|
|
267 0x0, /* #x08E7 */
|
|
268 0x0, /* #x08E8 */
|
|
269 0x0, /* #x08E9 */
|
|
270 0x0, /* #x08Ea */
|
|
271 0x0, /* #x08Eb */
|
|
272 0x0, /* #x08Ec */
|
|
273 0x0, /* #x08Ed */
|
|
274 0x0, /* #x08Ee */
|
|
275 0x2202, /* #x08EF PARTIAL DERIVATIVE Technical */
|
|
276 0x0, /* #x08F0 */
|
|
277 0x0, /* #x08F1 */
|
|
278 0x0, /* #x08F2 */
|
|
279 0x0, /* #x08F3 */
|
|
280 0x0, /* #x08F4 */
|
|
281 0x0, /* #x08F5 */
|
|
282 0x0192, /* #x08F6 FUNCTION Technical */
|
|
283 0x0, /* #x08F7 */
|
|
284 0x0, /* #x08F8 */
|
|
285 0x0, /* #x08F9 */
|
|
286 0x0, /* #x08FA */
|
|
287 0x2190, /* #x08FB LEFT ARROW Technical */
|
|
288 0x2191, /* #x08FC UPWARD ARROW Technical */
|
|
289 0x2192, /* #x08FD RIGHT ARROW Technical */
|
|
290 0x2193, /* #x08FE DOWNWARD ARROW Technical */
|
|
291 };
|
|
292
|
|
293 static UINT_16_BIT const SPECIAL[] =
|
|
294 {
|
|
295 0x25C6, /* #x09E0 SOLID DIAMOND Special */
|
|
296
|
|
297 #define FIRST_KNOWN_SPECIAL 0x9E0
|
|
298
|
|
299 0x2592, /* #x09E1 CHECKERBOARD Special */
|
|
300 0x2409, /* #x09E2 ``HT'' Special */
|
|
301 0x240C, /* #x09E3 ``FF'' Special */
|
|
302 0x240D, /* #x09E4 ``CR'' Special */
|
|
303 0x240A, /* #x09E5 ``LF'' Special */
|
|
304 0x0, /* #x09E6 */
|
|
305 0x0, /* #x09E7 */
|
|
306 0x2424, /* #x09E8 ``NL'' Special */
|
|
307 0x240B, /* #x09E9 ``VT'' Special */
|
|
308 0x2518, /* #x09EA LOWER-RIGHT CORNER Special */
|
|
309 0x2510, /* #x09EB UPPER-RIGHT CORNER Special */
|
|
310 0x250C, /* #x09EC UPPER-LEFT CORNER Special */
|
|
311 0x2514, /* #x09ED LOWER-LEFT CORNER Special */
|
|
312 0x253C, /* #x09EE CROSSING-LINES Special */
|
|
313 0x23BA, /* #x09EF HORIZONTAL LINE, SCAN 1 Special */
|
|
314 0x23BB, /* #x09F0 HORIZONTAL LINE, SCAN 3 Special */
|
|
315 0x2500, /* #x09F1 HORIZONTAL LINE, SCAN 5 Special */
|
|
316 0x23BC, /* #x09F2 HORIZONTAL LINE, SCAN 7 Special */
|
|
317 0x23BD, /* #x09F3 HORIZONTAL LINE, SCAN 9 Special */
|
|
318 0x251C, /* #x09F4 LEFT ``T'' Special */
|
|
319 0x2524, /* #x09F5 RIGHT ``T'' Special */
|
|
320 0x2534, /* #x09F6 BOTTOM ``T'' Special */
|
|
321 0x252C, /* #x09F7 TOP ``T'' Special */
|
|
322 0x2502 /* #x09F8 VERTICAL BAR Special */
|
|
323 };
|
|
324
|
|
325 static UINT_16_BIT const PUBLISHING[] =
|
|
326 {
|
|
327 0x2003, /* #x0AA1 EM SPACE Publish */
|
|
328
|
|
329 #define FIRST_KNOWN_PUBLISHING 0xAA1
|
|
330
|
|
331 0x2002, /* #x0AA2 EN SPACE Publish */
|
|
332 0x2004, /* #x0AA3 3/EM SPACE Publish */
|
|
333 0x2005, /* #x0AA4 4/EM SPACE Publish */
|
|
334 0x2007, /* #x0AA5 DIGIT SPACE Publish */
|
|
335 0x2008, /* #x0AA6 PUNCTUATION SPACE Publish */
|
|
336 0x2009, /* #x0AA7 THIN SPACE Publish */
|
|
337 0x200A, /* #x0AA8 HAIR SPACE Publish */
|
|
338 0x2014, /* #x0AA9 EM DASH Publish */
|
|
339 0x2013, /* #x0AAA EN DASH Publish */
|
|
340 0x0, /* #x0AAB */
|
|
341 0x0, /* #x0AAC SIGNIFICANT BLANK SYMBOL Publish */
|
|
342 0x0, /* #x0AAD */
|
|
343 0x2026, /* #x0AAE ELLIPSIS Publish */
|
|
344 0x2025, /* #x0AAF DOUBLE BASELINE DOT Publish */
|
|
345 0x2153, /* #x0AB0 VULGAR FRACTION ONE THIRD Publish */
|
|
346 0x2154, /* #x0AB1 VULGAR FRACTION TWO THIRDS Publish */
|
|
347 0x2155, /* #x0AB2 VULGAR FRACTION ONE FIFTH Publish */
|
|
348 0x2156, /* #x0AB3 VULGAR FRACTION TWO FIFTHS Publish */
|
|
349 0x2157, /* #x0AB4 VULGAR FRACTION THREE FIFTHS Publish */
|
|
350 0x2158, /* #x0AB5 VULGAR FRACTION FOUR FIFTHS Publish */
|
|
351 0x2159, /* #x0AB6 VULGAR FRACTION ONE SIXTH Publish */
|
|
352 0x215A, /* #x0AB7 VULGAR FRACTION FIVE SIXTHS Publish */
|
|
353 0x2105, /* #x0AB8 CARE OF Publish */
|
|
354 0x0, /* #x0AB9 */
|
|
355 0x0, /* #x0ABA */
|
|
356 0x2012, /* #x0ABB FIGURE DASH Publish */
|
|
357 0x0, /* #x0ABC LEFT ANGLE BRACKET Publish */
|
|
358 0x0, /* #x0ABD DECIMAL POINT Publish */
|
|
359 0x0, /* #x0ABE RIGHT ANGLE BRACKET Publish */
|
|
360 0x0, /* #x0ABF MARKER Publish */
|
|
361 0x0, /* #x0AC0 */
|
|
362 0x0, /* #x0AC1 */
|
|
363 0x0, /* #x0AC2 */
|
|
364 0x215B, /* #x0AC3 VULGAR FRACTION ONE EIGHTH Publish */
|
|
365 0x215C, /* #x0AC4 VULGAR FRACTION THREE EIGHTHS Publish */
|
|
366 0x215D, /* #x0AC5 VULGAR FRACTION FIVE EIGHTHS Publish */
|
|
367 0x215E, /* #x0AC6 VULGAR FRACTION SEVEN EIGHTHS Publish */
|
|
368 0x0, /* #x0AC7 */
|
|
369 0x0, /* #x0AC8 */
|
|
370 0x2122, /* #x0AC9 TRADEMARK SIGN Publish */
|
|
371 0x0, /* #x0ACA SIGNATURE MARK Publish */
|
|
372 0x0, /* #x0ACB TRADEMARK SIGN IN CIRCLE Publish */
|
|
373 0x0, /* #x0ACC LEFT OPEN TRIANGLE Publish */
|
|
374 0x0, /* #x0ACD RIGHT OPEN TRIANGLE Publish */
|
|
375 0x0, /* #x0ACE EM OPEN CIRCLE Publish */
|
|
376 0x0, /* #x0ACF EM OPEN RECTANGLE Publish */
|
|
377 0x2018, /* #x0AD0 LEFT SINGLE QUOTATION MARK Publish */
|
|
378 0x2019, /* #x0AD1 RIGHT SINGLE QUOTATION MARK Publish */
|
|
379 0x201C, /* #x0AD2 LEFT DOUBLE QUOTATION MARK Publish */
|
|
380 0x201D, /* #x0AD3 RIGHT DOUBLE QUOTATION MARK Publish */
|
|
381 0x211E, /* #x0AD4 PRESCRIPTION, TAKE, RECIPE Publish */
|
|
382 0x0, /* #x0AD5 */
|
|
383 0x2032, /* #x0AD6 MINUTES Publish */
|
|
384 0x2033, /* #x0AD7 SECONDS Publish */
|
|
385 0x0, /* #x0AD8 */
|
|
386 0x271D, /* #x0AD9 LATIN CROSS Publish */
|
|
387 0x0, /* #x0ADA HEXAGRAM Publish */
|
|
388 0x0, /* #x0ADB FILLED RECTANGLE BULLET Publish */
|
|
389 0x0, /* #x0ADC FILLED LEFT TRIANGLE BULLET Publish */
|
|
390 0x0, /* #x0ADD FILLED RIGHT TRIANGLE BULLET Publish */
|
|
391 0x0, /* #x0ADE EM FILLED CIRCLE Publish */
|
|
392 0x0, /* #x0ADF EM FILLED RECTANGLE Publish */
|
|
393 0x0, /* #x0AE0 EN OPEN CIRCLE BULLET Publish */
|
|
394 0x0, /* #x0AE1 EN OPEN SQUARE BULLET Publish */
|
|
395 0x0, /* #x0AE2 OPEN RECTANGULAR BULLET Publish */
|
|
396 0x0, /* #x0AE3 OPEN TRIANGULAR BULLET UP Publish */
|
|
397 0x0, /* #x0AE4 OPEN TRIANGULAR BULLET DOWN Publish */
|
|
398 0x0, /* #x0AE5 OPEN STAR Publish */
|
|
399 0x0, /* #x0AE6 EN FILLED CIRCLE BULLET Publish */
|
|
400 0x0, /* #x0AE7 EN FILLED SQUARE BULLET Publish */
|
|
401 0x0, /* #x0AE8 FILLED TRIANGULAR BULLET UP Publish */
|
|
402 0x0, /* #x0AE9 FILLED TRIANGULAR BULLET DOWN Publish */
|
|
403 0x0, /* #x0AEA LEFT POINTER Publish */
|
|
404 0x0, /* #x0AEB RIGHT POINTER Publish */
|
|
405 0x2663, /* #x0AEC CLUB Publish */
|
|
406 0x2666, /* #x0AED DIAMOND Publish */
|
|
407 0x2665, /* #x0AEE HEART Publish */
|
|
408 0x0, /* #x0AEF */
|
|
409 0x2720, /* #x0AF0 MALTESE CROSS Publish */
|
|
410 0x2020, /* #x0AF1 DAGGER Publish */
|
|
411 0x2021, /* #x0AF2 DOUBLE DAGGER Publish */
|
|
412 0x2713, /* #x0AF3 CHECK MARK, TICK Publish */
|
|
413 0x2717, /* #x0AF4 BALLOT CROSS Publish */
|
|
414 0x266F, /* #x0AF5 MUSICAL SHARP Publish */
|
|
415 0x266D, /* #x0AF6 MUSICAL FLAT Publish */
|
|
416 0x2642, /* #x0AF7 MALE SYMBOL Publish */
|
|
417 0x2640, /* #x0AF8 FEMALE SYMBOL Publish */
|
|
418 0x260E, /* #x0AF9 TELEPHONE SYMBOL Publish */
|
|
419 0x2315, /* #x0AFA TELEPHONE RECORDER SYMBOL Publish */
|
|
420 0x2117, /* #x0AFB PHONOGRAPH COPYRIGHT SIGN Publish */
|
|
421 0x2038, /* #x0AFC CARET Publish */
|
|
422 0x201A, /* #x0AFD SINGLE LOW QUOTATION MARK Publish */
|
|
423 0x201E, /* #x0AFE DOUBLE LOW QUOTATION MARK Publish */
|
|
424 };
|
|
425
|
|
426 static UINT_16_BIT const APL[] =
|
|
427 {
|
|
428 0x22A5, /* #x0BC2 DOWN TACK APL */
|
|
429 #define FIRST_KNOWN_APL 0xBC2
|
|
430 0x0, /* #x0BC3 UP SHOE (CAP) APL */
|
|
431 0x230A, /* #x0BC4 DOWN STILE APL */
|
|
432 0x0, /* #x0BC5 */
|
|
433 0x0, /* #x0BC6 UNDERBAR APL */
|
|
434 0x0, /* #x0BC7 */
|
|
435 0x0, /* #x0BC8 */
|
|
436 0x0, /* #x0BC9 */
|
|
437 0x2218, /* #x0BCA JOT APL */
|
|
438 0x0, /* #x0BCB */
|
|
439 0x2395, /* #x0BCC QUAD APL */
|
|
440 0x0, /* #x0BCD */
|
|
441 0x22A4, /* #x0BCE UP TACK APL */
|
|
442 0x25CB, /* #x0BCF CIRCLE APL */
|
|
443 0x0, /* #x0BD0 */
|
|
444 0x0, /* #x0BD1 */
|
|
445 0x0, /* #x0BD2 */
|
|
446 0x2308, /* #x0BD3 UP STILE APL */
|
|
447 0x0, /* #x0BD4 */
|
|
448 0x0, /* #x0BD5 */
|
|
449 0x0, /* #x0BD6 DOWN SHOE (CUP) APL */
|
|
450 0x0, /* #x0BD7 */
|
|
451 0x0, /* #x0BD8 RIGHT SHOE APL */
|
|
452 0x0, /* #x0BD9 */
|
|
453 0x0, /* #x0BDA LEFT SHOE APL */
|
|
454 0x0, /* #x0BDB */
|
|
455 0x0, /* #x0BDC */
|
|
456 0x22A2, /* #x0BDC LEFT TACK APL */
|
|
457 0x0, /* #x0BDE */
|
|
458 0x0, /* #x0BDF */
|
|
459 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, /* 0x0BB0--0x0BBB */
|
|
460 0x0, 0x0, 0x0, 0x0,
|
|
461 0x22A3, /* #x0BFC RIGHT TACK APL */
|
|
462 };
|
|
463
|
|
464 /* For every key on the keyboard that has a known character correspondence,
|
|
465 we define the character-of-keysym property of its XEmacs keysym, and make
|
|
466 the default binding for the key be self-insert-command.
|
|
467
|
|
468 The following magic is based on intimate knowledge of some of
|
|
469 X11/keysymdef.h. The keysym mappings defined by X11 are based on the
|
|
470 iso8859 standards, except for Cyrillic and Greek.
|
|
471
|
|
472 In a non-Mule world, a user can still have a multi-lingual editor, by
|
|
473 doing (set-face-font "...-iso8859-2" (current-buffer)) for all their
|
|
474 Latin-2 buffers, etc. and the X11 keysyms corresponding to characters in
|
|
475 those character sets will still do the right thing (because of the
|
|
476 make_char (code + 0x80) non-Mule case below.) Of course, X11 keysyms in
|
|
477 other character sets will not do the right thing, because XEmacs won't
|
|
478 support the right thing.
|
|
479
|
|
480 This code is also called when a command lookup is about to fail, and the
|
|
481 X11 platform code has worked out that it previously wasn't aware the
|
|
482 keysym of that command could be generated by the user's keyboard; in that
|
|
483 case, we bind its XEmacs keysym to self-insert-command if it has a
|
|
484 character correspondence we know about, and tell the general event code
|
|
485 that we've done so, so it can try the lookup again.
|
|
486
|
|
487 Called from the GTK code because GTK 1 has no defined way of doing the
|
|
488 same thing, and this works for it on X11. It should be moved back into
|
|
489 event-Xt.c when and if the GTK port moves to GTK 2. */
|
|
490
|
|
491 #ifndef THIS_IS_GTK
|
|
492 static Lisp_Object
|
|
493 x_keysym_to_character(KeySym keysym)
|
|
494 #else
|
|
495 Lisp_Object
|
|
496 gtk_keysym_to_character(guint keysym)
|
|
497 #endif
|
|
498 {
|
|
499 Lisp_Object charset = Qzero;
|
|
500 int code = 0;
|
|
501
|
|
502 /* Markus Kuhn's spec says keysyms in the range #x01000100 to #x0110FFFF
|
|
503 and only those should correspond directly to Unicode code points, in
|
|
504 the range #x100-#x10FFFF; actual implementations can have the Latin 1
|
|
505 code points do the same thing with keysyms
|
|
506 #x010000A0-#x01000100. */
|
|
507
|
|
508 if (keysym >= 0x010000A0 && keysym <= 0x0110FFFF)
|
|
509 return Funicode_to_char (make_int(keysym & 0xffffff), Qnil);
|
|
510
|
|
511 if ((keysym & 0xff) < 0xa0)
|
|
512 return Qnil;
|
|
513
|
|
514 switch (keysym >> 8)
|
|
515 {
|
|
516
|
|
517 #define USE_CHARSET(var,cs) \
|
|
518 ((var) = charset_by_leading_byte (LEADING_BYTE_##cs))
|
|
519
|
|
520 case 0: /* ASCII + Latin1 */
|
|
521 USE_CHARSET (charset, LATIN_ISO8859_1);
|
|
522 code = keysym & 0x7f;
|
|
523 break;
|
|
524 case 1: /* Latin2 */
|
|
525 USE_CHARSET (charset, LATIN_ISO8859_2);
|
|
526 code = keysym & 0x7f;
|
|
527 break;
|
|
528 case 2: /* Latin3 */
|
|
529 USE_CHARSET (charset, LATIN_ISO8859_3);
|
|
530 code = keysym & 0x7f;
|
|
531 break;
|
|
532 case 3: /* Latin4 */
|
|
533 USE_CHARSET (charset, LATIN_ISO8859_4);
|
|
534 code = keysym & 0x7f;
|
|
535 break;
|
|
536 case 4: /* Katakana */
|
|
537 USE_CHARSET (charset, KATAKANA_JISX0201);
|
|
538 if ((keysym & 0xff) > 0xa0)
|
|
539 code = keysym & 0x7f;
|
|
540 break;
|
|
541 case 5: /* Arabic */
|
|
542 USE_CHARSET (charset, ARABIC_ISO8859_6);
|
|
543 code = keysym & 0x7f;
|
|
544 break;
|
|
545 case 6: /* Cyrillic */
|
|
546 {
|
|
547 static UExtbyte const cyrillic[] = /* 0x20 - 0x7f */
|
|
548 {0x00, 0x72, 0x73, 0x71, 0x74, 0x75, 0x76, 0x77,
|
|
549 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x00, 0x7e, 0x7f,
|
|
550 0x70, 0x22, 0x23, 0x21, 0x24, 0x25, 0x26, 0x27,
|
|
551 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x00, 0x2e, 0x2f,
|
|
552 0x6e, 0x50, 0x51, 0x66, 0x54, 0x55, 0x64, 0x53,
|
|
553 0x65, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e,
|
|
554 0x5f, 0x6f, 0x60, 0x61, 0x62, 0x63, 0x56, 0x52,
|
|
555 0x6c, 0x6b, 0x57, 0x68, 0x6d, 0x69, 0x67, 0x6a,
|
|
556 0x4e, 0x30, 0x31, 0x46, 0x34, 0x35, 0x44, 0x33,
|
|
557 0x45, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
|
|
558 0x3f, 0x4f, 0x40, 0x41, 0x42, 0x43, 0x36, 0x32,
|
|
559 0x4c, 0x4b, 0x37, 0x48, 0x4d, 0x49, 0x47, 0x4a};
|
|
560 USE_CHARSET (charset, CYRILLIC_ISO8859_5);
|
|
561 code = cyrillic[(keysym & 0x7f) - 0x20];
|
|
562 break;
|
|
563 }
|
|
564 case 7: /* Greek */
|
|
565 {
|
|
566 static UExtbyte const greek[] = /* 0x20 - 0x7f */
|
|
567 {0x00, 0x36, 0x38, 0x39, 0x3a, 0x5a, 0x00, 0x3c,
|
|
568 0x3e, 0x5b, 0x00, 0x3f, 0x00, 0x00, 0x35, 0x2f,
|
|
569 0x00, 0x5c, 0x5d, 0x5e, 0x5f, 0x7a, 0x40, 0x7c,
|
|
570 0x7d, 0x7b, 0x60, 0x7e, 0x00, 0x00, 0x00, 0x00,
|
|
571 0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
|
|
572 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
|
573 0x50, 0x51, 0x53, 0x00, 0x54, 0x55, 0x56, 0x57,
|
|
574 0x58, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
575 0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
|
|
576 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
|
577 0x70, 0x71, 0x73, 0x72, 0x74, 0x75, 0x76, 0x77,
|
|
578 0x78, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
|
579 USE_CHARSET (charset, GREEK_ISO8859_7);
|
|
580 code = greek[(keysym & 0x7f) - 0x20];
|
|
581 break;
|
|
582 }
|
|
583 case 8:
|
|
584 USE_UNICODE_MAP(keysym, TECHNICAL);
|
|
585 break;
|
|
586 case 9:
|
|
587 USE_UNICODE_MAP(keysym, SPECIAL);
|
|
588 break;
|
|
589 case 10:
|
|
590 USE_UNICODE_MAP(keysym, PUBLISHING);
|
|
591 break;
|
|
592 case 11:
|
|
593 USE_UNICODE_MAP(keysym, APL);
|
|
594 break;
|
|
595 case 12: /* Hebrew */
|
|
596 USE_CHARSET (charset, HEBREW_ISO8859_8);
|
|
597 code = keysym & 0x7f;
|
|
598 break;
|
|
599 case 13: /* Thai */
|
|
600 /* #### This needs to deal with character composition.
|
|
601 Are you sure we can't leave it to the X server? */
|
|
602 USE_CHARSET (charset, THAI_TIS620);
|
|
603 code = keysym & 0x7f;
|
|
604 break;
|
|
605 case 14: /* Korean Hangul. Would like some information on whether this
|
|
606 is worth doing--there don't appear to be any Korean keyboard
|
|
607 layouts in the XKB data files. */
|
|
608 break;
|
|
609
|
|
610 case 19: /* Latin 9 - ISO8859-15. */
|
|
611 USE_CHARSET (charset, LATIN_ISO8859_15);
|
|
612 code = keysym & 0x7f;
|
|
613 break;
|
|
614 case 32: /* Currency. The lower sixteen bits of these keysyms happily
|
|
615 correspond exactly to the Unicode code points of the
|
|
616 associated characters */
|
|
617 return Funicode_to_char(make_int(keysym & 0xffff), Qnil);
|
|
618 break;
|
|
619 default:
|
|
620 break;
|
|
621 }
|
|
622
|
|
623 if (code == 0)
|
|
624 return Qnil;
|
|
625
|
|
626 #ifdef MULE
|
|
627 return make_char (make_ichar (charset, code, 0));
|
|
628 #else
|
|
629 return make_char (code + 0x80);
|
|
630 #endif
|
|
631 }
|
|
632
|
|
633 #endif /* defined(THIS_IS_X) || !defined(__GDK_KEYS_H__) */
|