32
// MRS: Uncomment the following define to get the original (pre-1.1.2)
33
// dead key support code. The original code apparently did not
34
// work on Belgian keyboards.
37
//#define OLD_DEAD_KEY_CODE
42
static const char* const compose_pairs =
43
" ! % # $ y=| & : c a <<~ - r _ * +-2 3 ' u p . , 1 o >>141234? "//00A0 ...
44
"`A'A^A~A:A*AAE,C`E'E^E:E`I'I^I:I-D~N`O'O^O~O:Ox O/`U'U^U:U'YTHss" //00C0 ...
45
"`a'a^a~a:a*aae,c`e'e^e:e`i'i^i:i-d~n`o'o^o~o:o-:o/`u'u^u:u'yth:y";//00E0 ...
49
static const char* const compose_pairs =
50
"=E _'f _\"..+ ++^ %%^S< OE ^Z ^''^^\"\"^-*- --~ TM^s> oe ^z:Y"
51
" ! % # $ y=| & : c a <<~ - r _ * +-2 3 ' u p . , 1 o >>141234? "
52
"`A'A^A~A:A*AAE,C`E'E^E:E`I'I^I:I-D~N`O'O^O~O:Ox O/`U'U^U:U'YTHss"
53
"`a'a^a~a:a*aae,c`e'e^e:e`i'i^i:i-d~n`o'o^o~o:o-:o/`u'u^u:u'yth:y";
57
#if !defined(WIN32) && defined(OLD_DEAD_KEY_CODE) // X only
58
// X dead-key lookup table. This turns a dead-key keysym into the
59
// first of two characters for one of the compose sequences. These
60
// keysyms start at 0xFE50.
61
// Win32 handles the dead keys before FLTK can see them. This is
62
// unfortunate, because you don't get the preview effect.
63
static char dead_keys[] = {
65
'\'', // XK_dead_acute
66
'^', // XK_dead_circumflex
68
'_', // XK_dead_macron
70
'.', // XK_dead_abovedot
71
':', // XK_dead_diaeresis
72
'*', // XK_dead_abovering
73
0, // XK_dead_doubleacute
75
',' // XK_dead_cedilla
76
// 0, // XK_dead_ogonek
78
// 0, // XK_dead_voiced_sound
79
// 0, // XK_dead_semivoiced_sound
80
// 0 // XK_dead_belowdot
82
#endif // !WIN32 && OLD_DEAD_KEY_CODE
85
32
int Fl::compose_state = 0;
35
#if !defined(WIN32) && !defined(__APPLE__)
88
39
/** Any text editing widget should call this for each FL_KEYBOARD event.
89
Use of this function is very simple.
91
<p>If <i>true</i> is returned, then it has modified the
92
Fl::event_text() and Fl::event_length() to a set of <i>bytes</i> to
93
insert (it may be of zero length!). In will also set the "del"
94
parameter to the number of <i>bytes</i> to the left of the cursor to
95
delete, this is used to delete the results of the previous call to
98
<p>If <i>false</i> is returned, the keys should be treated as function
99
keys, and del is set to zero. You could insert the text anyways, if
100
you don't know what else to do.
102
<p>Though the current implementation returns immediately, future
103
versions may take quite awhile, as they may pop up a window or do
104
other user-interface things to allow characters to be selected.
40
Use of this function is very simple.
42
<p>If <i>true</i> is returned, then it has modified the
43
Fl::event_text() and Fl::event_length() to a set of <i>bytes</i> to
44
insert (it may be of zero length!). In will also set the "del"
45
parameter to the number of <i>bytes</i> to the left of the cursor to
46
delete, this is used to delete the results of the previous call to
49
<p>If <i>false</i> is returned, the keys should be treated as function
50
keys, and del is set to zero. You could insert the text anyways, if
51
you don't know what else to do.
53
<p>Though the current implementation returns immediately, future
54
versions may take quite awhile, as they may pop up a window or do
55
other user-interface things to allow characters to be selected.
106
57
int Fl::compose(int& del) {
58
// character composition is now handled by the OS
109
unsigned char ascii = (unsigned)e_text[0];
111
// Alt+letters are reserved for shortcuts. But alt+foreign letters
112
// has to be allowed, because some key layouts require alt to be held
113
// down in order to type them...
115
// OSX users sometimes need to hold down ALT for keys, so we only check
116
// for META on OSX...
118
if ((e_state & FL_META) && !(ascii & 128)) return 0;
120
if ((e_state & (FL_ALT|FL_META)) && !(ascii & 128)) return 0;
123
if (compose_state == 1) { // after the compose key
124
if ( // do not get distracted by any modifier keys
125
e_keysym==FL_Shift_L||
126
e_keysym==FL_Shift_R ||
127
e_keysym==FL_Alt_L ||
128
e_keysym==FL_Alt_R ||
129
e_keysym==FL_Meta_L ||
130
e_keysym==FL_Meta_R ||
131
e_keysym==FL_Control_R ||
132
e_keysym==FL_Control_L ||
136
if (ascii == ' ') { // space turns into nbsp
138
int len = fl_utf8encode(0xCA, e_text);
142
int len = fl_utf8encode(0xA0, e_text);
148
} else if (ascii < ' ' || ascii == 127) {
153
// see if it is either character of any pair:
154
for (const char *p = compose_pairs; *p; p += 2)
155
if (p[0] == ascii || p[1] == ascii) {
157
int len = fl_utf8encode((p-compose_pairs)/2+0xA0, e_text);
162
compose_state = ascii;
166
if (e_length) { // compose key also "quotes" control characters
171
} else if (compose_state) { // second character of compose
173
char c1 = char(compose_state); // retrieve first character
175
if ( (c1==0x60 && ascii==0xab) || (c1==0x27 && ascii==0x60)) {
187
// now search for the pair in either order:
188
for (const char *p = compose_pairs; *p; p += 2) {
189
if (p[0] == ascii && p[1] == c1 || p[1] == ascii && p[0] == c1) {
190
int len = fl_utf8encode((p-compose_pairs)/2+0xA0, e_text);
193
del = 1; // delete the old character and insert new one
203
// See if they type the compose prefix key:
204
if (i == FL_Control_R || i == 0xff20/* Multi-Key */) {
210
#elif (defined __APPLE__)
211
if (e_state & 0x40000000) {
213
compose_state = ascii;
215
compose_state = compose_pairs[(ascii-0x80)*2];
219
// See if they typed a dead key. This gets it into the same state as
220
// typing prefix+accent:
221
if (i >= 0xfe50 && i <= 0xfe5b) {
222
# ifdef OLD_DEAD_KEY_CODE
223
ascii = dead_keys[i-0xfe50];
224
for (const char *p = compose_pairs; *p; p += 2)
226
compose_state = ascii;
231
for (const char *p = compose_pairs; *p; p += 2)
233
(p[1] == ' ' && (p - compose_pairs) / 2 + 0xA0 == ascii)) {
234
compose_state = p[0];
237
# endif // OLD_DEAD_KEY_CODE
243
// Only insert non-control characters:
244
if (e_length && (ascii & ~31 && ascii!=127)) {compose_state = 0; return 1;}
60
#if defined(__APPLE__)
61
// this stuff is to be treated as a function key
62
if(Fl::e_length == 0 || Fl::e_keysym == FL_Enter || Fl::e_keysym == FL_KP_Enter ||
63
Fl::e_keysym == FL_Tab || Fl::e_keysym == FL_Escape || Fl::e_state&(FL_META | FL_CTRL) ) {
67
unsigned char ascii = (unsigned)e_text[0];
68
if ((e_state & (FL_ALT | FL_META)) && !(ascii & 128)) return 0;
70
unsigned char ascii = (unsigned)e_text[0];
71
if ((e_state & (FL_ALT | FL_META | FL_CTRL)) && !(ascii & 128)) return 0;
73
if(Fl::compose_state) {
74
del = Fl::compose_state;
75
Fl::compose_state = 0;
78
// Only insert non-control characters:
79
if (! (ascii & ~31 && ascii!=127)) { return 0; }
86
If the user moves the cursor, be sure to call Fl::compose_reset().
87
The next call to Fl::compose() will start out in an initial state. In
88
particular it will not set "del" to non-zero. This call is very fast
89
so it is ok to call it many times and in many places.
91
void Fl::compose_reset()
93
Fl::compose_state = 0;
94
#if !defined(WIN32) && !defined(__APPLE__)
95
if (fl_xim_ic) XmbResetIC(fl_xim_ic);
100
// End of "$Id: Fl_compose.cxx 8626 2011-04-27 11:21:57Z manolo $"