diff options
| -rw-r--r-- | FL/Fl_Input.H | 168 | ||||
| -rw-r--r-- | documentation/src/events.dox | 24 | ||||
| -rw-r--r-- | src/Fl_compose.cxx | 167 |
3 files changed, 42 insertions, 317 deletions
diff --git a/FL/Fl_Input.H b/FL/Fl_Input.H index 89903a24c..da193849d 100644 --- a/FL/Fl_Input.H +++ b/FL/Fl_Input.H @@ -40,7 +40,11 @@ characters (even 0), and will correctly display any UTF text, using ^X notation for unprintable control characters. It assumes the font can draw any characters of the used scripts, which is true - for standard fonts under MSWindows and Mac OS X.</P> + for standard fonts under MSWindows and Mac OS X. + Characters can be input using the keyboard or the character palette/map. + Character composition is done using using dead keys and/or a compose + key as defined by the operating system. +</P> <CENTER><TABLE border=1 WIDTH=90% summary="Fl_Input keyboard and mouse bindings."> @@ -84,168 +88,8 @@ expected.</TD></TR> <TR><TD><B>Shift+move</B></TD><TD>Move the cursor but also extend the selection.</TD></TR> - - <TR><TD><B>RightCtrl or - <BR>Compose</B></TD><TD> - \anchor Fl_Input_Compose_Character - Start a compose-character - sequence. The next one or two keys typed define the character to - insert (see table that follows.) - - <p>For instance, to type "á" type [compose][a]['] or [compose]['][a]. - - <P>The character "nbsp" (non-breaking space) is typed by using - [compose][space]. - - <P>The single-character sequences may be followed by a space if - necessary to remove ambiguity. For instance, if you really want to - type "ª~" rather than "ã" you must type [compose][a][space][~]. - - <p>The same key may be used to "quote" control characters into the - text. If you need a ^Q character you can get one by typing - [compose][Control+Q]. - - <p>X may have a key on the keyboard - defined as XK_Multi_key. If so this key may be used as well - as the right-hand control key. You can set this up with the program - xmodmap. - - <p>If your keyboard is set to support a foreign language you should - also be able to type "dead key" prefix characters. On X you will - actually be able to see what dead key you typed, and if you then move - the cursor without completing the sequence the accent will remain - inserted. - - <p>Under MSWindows or Mac OS X, character composition is done using - system-defined keystroke series.</TD></TR> </TABLE></CENTER> - - <!-- NEW PAGE --> - <center><table border=1 summary="Character Composition Table"> - <caption align="top">Character Composition Table</caption> - <tr> - <th>Keys</th><th>Char</th> - <th>Keys</th><th>Char</th> - <th>Keys</th><th>Char</th> - <th>Keys</th><th>Char</th> - <th>Keys</th><th>Char</th> - <th>Keys</th><th>Char</th> - - </tr><tr> - <td align=center>sp</td><td align=center><small>nbsp</small></td> - <td align=center>*</td><td align=center>°</td> - <td align=center>` A</td><td align=center>À</td> - <td align=center>D -</td><td align=center>Ð</td> - <td align=center>` a</td><td align=center>à</td> - <td align=center>d -</td><td align=center>ð</td> - </tr><tr> - <td align=center>!</td><td align=center>¡</td> - <td align=center>+ -</td><td align=center>±</td> - <td align=center>' A</td><td align=center>Á</td> - <td align=center>~ N</td><td align=center>Ñ</td> - <td align=center>' a</td><td align=center>á</td> - <td align=center>~ n</td><td align=center>ñ</td> - </tr><tr> - <td align=center>%</td><td align=center>¢</td> - <td align=center>2</td><td align=center>²</td> - <td align=center>A ^</td><td align=center>Â</td> - <td align=center>` O</td><td align=center>Ò</td> - <td align=center>^ a</td><td align=center>â</td> - <td align=center>` o</td><td align=center>ò</td> - </tr><tr> - <td align=center>#</td><td align=center>£</td> - <td align=center>3</td><td align=center>³</td> - <td align=center>~ A</td><td align=center>Ã</td> - <td align=center>' O</td><td align=center>Ó</td> - <td align=center>~ a</td><td align=center>ã</td> - <td align=center>' o</td><td align=center>ó</td> - </tr><tr> - <td align=center>$</td><td align=center>¤</td> - <td align=center>'</td><td align=center>´</td> - <td align=center>: A</td><td align=center>Ä</td> - <td align=center>^ O</td><td align=center>Ô</td> - <td align=center>: a</td><td align=center>ä</td> - <td align=center>^ o</td><td align=center>ô</td> - </tr><tr> - <td align=center>y =</td><td align=center>¥</td> - <td align=center>u</td><td align=center>µ</td> - <td align=center>* A</td><td align=center>Å</td> - <td align=center>~ O</td><td align=center>Õ</td> - <td align=center>* a</td><td align=center>å</td> - <td align=center>~ o</td><td align=center>õ</td> - </tr><tr> - <td align=center>|</td><td align=center>¦</td> - <td align=center>p</td><td align=center>¶</td> - <td align=center>A E</td><td align=center>Æ</td> - <td align=center>: O</td><td align=center>Ö</td> - <td align=center>a e</td><td align=center>æ</td> - <td align=center>: o</td><td align=center>ö</td> - </tr><tr> - <td align=center>&</td><td align=center>§</td> - <td align=center>.</td><td align=center>·</td> - <td align=center>, C</td><td align=center>Ç</td> - <td align=center>x</td><td align=center>×</td> - <td align=center>, c</td><td align=center>ç</td> - <td align=center>- :</td><td align=center>÷</td> - </tr><tr> - <td align=center>:</td><td align=center>¨</td> - <td align=center>,</td><td align=center>¸</td> - <td align=center>E `</td><td align=center>È</td> - <td align=center>O /</td><td align=center>Ø</td> - <td align=center>` e</td><td align=center>è</td> - <td align=center>o /</td><td align=center>ø</td> - </tr><tr> - <td align=center>c</td><td align=center>©</td> - <td align=center>1</td><td align=center>¹</td> - <td align=center>' E</td><td align=center>É</td> - <td align=center>` U</td><td align=center>Ù</td> - <td align=center>' e</td><td align=center>é</td> - <td align=center>` u</td><td align=center>ù</td> - </tr><tr> - <td align=center>a</td><td align=center>ª</td> - <td align=center>o</td><td align=center>º</td> - <td align=center>^ E</td><td align=center>Ê</td> - <td align=center>' U</td><td align=center>Ú</td> - <td align=center>^ e</td><td align=center>ê</td> - <td align=center>' u</td><td align=center>ú</td> - </tr><tr> - <td align=center>< <</td><td align=center>«</td> - <td align=center>> ></td><td align=center>»</td> - <td align=center>: E</td><td align=center>Ë</td> - <td align=center>^ U</td><td align=center>Û</td> - <td align=center>: e</td><td align=center>ë</td> - <td align=center>^ u</td><td align=center>û</td> - </tr><tr> - <td align=center>~</td><td align=center>¬</td> - <td align=center>1 4</td><td align=center>¼</td> - <td align=center>` I</td><td align=center>Ì</td> - <td align=center>: U</td><td align=center>Ü</td> - <td align=center>` i</td><td align=center>ì</td> - <td align=center>: u</td><td align=center>ü</td> - </tr><tr> - <td align=center>-</td><td align=center></td> - <td align=center>1 2</td><td align=center>½</td> - <td align=center>' I</td><td align=center>Í</td> - <td align=center>' Y</td><td align=center>Ý</td> - <td align=center>' i</td><td align=center>í</td> - <td align=center>' y</td><td align=center>ý</td> - </tr><tr> - <td align=center>r</td><td align=center>®</td> - <td align=center>3 4</td><td align=center>¾</td> - <td align=center>^ I</td><td align=center>Î</td> - <td align=center>T H</td><td align=center>Þ</td> - <td align=center>^ i</td><td align=center>î</td> - <td align=center>t h</td><td align=center>þ</td> - </tr><tr> - <td align=center>_</td><td align=center>¯</td> - <td align=center>?</td><td align=center>¿</td> - <td align=center>: I</td><td align=center>Ï</td> - <td align=center>s s</td><td align=center>ß</td> - <td align=center>: i</td><td align=center>ï</td> - <td align=center>: y</td><td align=center>ÿ</td> - </tr> - </table></center> -*/ + */ class FL_EXPORT Fl_Input : public Fl_Input_ { int handle_key(); int shift_position(int p); diff --git a/documentation/src/events.dox b/documentation/src/events.dox index cfb2552db..c142b3319 100644 --- a/documentation/src/events.dox +++ b/documentation/src/events.dox @@ -164,6 +164,7 @@ should return 1. If you return zero then FLTK assumes you ignored the key and will then attempt to send it to a parent widget. If none of them want it, it will change the event into a \p FL_SHORTCUT event. +FL_KEYBOARD events are also generated by the character palette/map. To receive \p FL_KEYBOARD events you must also respond to the \p FL_FOCUS and \p FL_UNFOCUS @@ -171,7 +172,7 @@ events. If you are writing a text-editing widget you may also want to call the Fl::compose() -function to translate individual keystrokes into foreign characters. +function to translate individual keystrokes into characters. \p FL_KEYUP events are sent to the widget that currently has focus. This is not necessarily the same widget @@ -411,21 +412,15 @@ window modal. \section events_compose_characters FLTK Compose-Character Sequences -\todo Does Fltk Compose Character Sequences text need updating - after the addition of UTF-8 handling to FLTK-1.3.x ? - -The foreign-letter compose processing done by the Fl_Input widget's -\ref Fl_Input_Compose_Character "compose" -key handler is provided in a function that you can call if you are +The character composition done by Fl_Input widget +requires that you call the Fl::compose() function if you are writing your own text editor widget. -FLTK uses its own compose processing to allow "preview" of -the partially composed sequence, which is impossible with the -usual "dead key" processing. - -Although currently only characters in the ISO-8859-1 -character set are handled, you should call this in case any -enhancements to the processing are done in the future. The +Currently, all characters made by single key strokes +with or without modifier keys, or by system-defined character +compose sequences (that can involve dead keys or a compose key) can be input. +You should call Fl::compose() in case any +enhancements to this processing are done in the future. The interface has been designed to handle arbitrary UTF-8 encoded text. @@ -434,6 +429,7 @@ The following methods are provided for character composition: \li Fl::compose() \li Fl::compose_reset() +Under Mac OS X, FLTK "previews" partially composed sequences. \htmlonly <hr> diff --git a/src/Fl_compose.cxx b/src/Fl_compose.cxx index 8fc3ef179..b6c47a6cc 100644 --- a/src/Fl_compose.cxx +++ b/src/Fl_compose.cxx @@ -28,40 +28,47 @@ #include <FL/Fl.H> #include <FL/x.H> - -#if !defined(__APPLE__) && !defined(WIN32) - -static const char* const compose_pairs = -//"=E _'f _\"..+ ++^ %%^S< OE ^Z ^''^^\"\"^-*- --~ TM^s> oe ^z:Y" // this is not unicode but CP1252 -" ! % # $ y=| & : c a <<~ - r _ * +-2 3 ' u p . , 1 o >>141234? " // unicode from U+00A0 -"`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" // unicode from U+00C0 -"`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";// unicode from U+00E0 - -#endif - #ifndef FL_DOXYGEN +// at present, this is effectively used by Mac OS X only int Fl::compose_state = 0; #endif -#if defined(__APPLE__) || defined(WIN32) -// under Mac OS X and MS Windows, character composition is handled by the OS +/** Any text editing widget should call this for each FL_KEYBOARD event. + Use of this function is very simple. + + <p>If <i>true</i> is returned, then it has modified the + Fl::event_text() and Fl::event_length() to a set of <i>bytes</i> to + insert (it may be of zero length!). In will also set the "del" + parameter to the number of <i>bytes</i> to the left of the cursor to + delete, this is used to delete the results of the previous call to + Fl::compose(). + + <p>If <i>false</i> is returned, the keys should be treated as function + keys, and del is set to zero. You could insert the text anyways, if + you don't know what else to do. + + <p>Though the current implementation returns immediately, future + versions may take quite awhile, as they may pop up a window or do + other user-interface things to allow characters to be selected. + */ int Fl::compose(int& del) { + // character composition is now handled by the OS del = 0; -#ifdef WIN32 - unsigned char ascii = (unsigned)e_text[0]; - if ((e_state & (FL_ALT|FL_META)) && !(ascii & 128)) return 0; -#elif defined(__APPLE__) +#if defined(__APPLE__) // this stuff is to be treated as a function key if(Fl::e_length == 0 || Fl::e_keysym == FL_Enter || Fl::e_keysym == FL_KP_Enter || - Fl::e_keysym == FL_Tab || Fl::e_keysym == FL_Escape || Fl::e_state&FL_META || Fl::e_state&FL_CTRL ) { + Fl::e_keysym == FL_Tab || Fl::e_keysym == FL_Escape || Fl::e_state&(FL_META | FL_CTRL) ) { return 0; } +#else + unsigned char ascii = (unsigned)e_text[0]; + if ((e_state & (FL_ALT | FL_META)) && !(ascii & 128)) return 0; #endif if(Fl::compose_state) { del = 1; Fl::compose_state = 0; } else { -#ifdef WIN32 +#ifndef __APPLE__ // Only insert non-control characters: if (! (ascii & ~31 && ascii!=127)) { return 0; } #endif @@ -69,128 +76,6 @@ int Fl::compose(int& del) { return 1; } -#else - -/** Any text editing widget should call this for each FL_KEYBOARD event. - Use of this function is very simple. - - <p>If <i>true</i> is returned, then it has modified the - Fl::event_text() and Fl::event_length() to a set of <i>bytes</i> to - insert (it may be of zero length!). In will also set the "del" - parameter to the number of <i>bytes</i> to the left of the cursor to - delete, this is used to delete the results of the previous call to - Fl::compose(). - - <p>If <i>false</i> is returned, the keys should be treated as function - keys, and del is set to zero. You could insert the text anyways, if - you don't know what else to do. - - <p>Though the current implementation returns immediately, future - versions may take quite awhile, as they may pop up a window or do - other user-interface things to allow characters to be selected. -*/ -int Fl::compose(int& del) { - - del = 0; - unsigned char ascii = (unsigned)e_text[0]; - - // Alt+letters are reserved for shortcuts. But alt+foreign letters - // has to be allowed, because some key layouts require alt to be held - // down in order to type them... - // - // OSX users sometimes need to hold down ALT for keys, so we only check - // for META on OSX... - if ((e_state & (FL_ALT|FL_META)) && !(ascii & 128)) return 0; - - if (compose_state == 1) { // after the compose key - if ( // do not get distracted by any modifier keys - e_keysym==FL_Shift_L|| - e_keysym==FL_Shift_R || - e_keysym==FL_Alt_L || - e_keysym==FL_Alt_R || - e_keysym==FL_Meta_L || - e_keysym==FL_Meta_R || - e_keysym==FL_Control_R || - e_keysym==FL_Control_L || - e_keysym==FL_Menu - ) return 0; - - if (ascii == ' ') { // space turns into nbsp - int len = fl_utf8encode(0xA0, e_text); - e_text[len] = '\0'; - e_length = len; - compose_state = 0; - return 1; - } else if (ascii < ' ' || ascii == 127) { - compose_state = 0; - return 0; - } - - // see if it is either character of any pair: - for (const char *p = compose_pairs; *p; p += 2) - if (p[0] == ascii || p[1] == ascii) { - if (p[1] == ' ') { - int len = fl_utf8encode((p-compose_pairs)/2+0xA0, e_text); - e_text[len] = '\0'; - e_length = len; - } - - compose_state = ascii; - return 1; - } - - if (e_length) { // compose key also "quotes" control characters - compose_state = 0; - return 1; - } - - } else if (compose_state) { // second character of compose - - char c1 = char(compose_state); // retrieve first character - // now search for the pair in either order: - for (const char *p = compose_pairs; *p; p += 2) { - if ( (p[0] == ascii && p[1] == c1) || (p[1] == ascii && p[0] == c1)) { - int len = fl_utf8encode((p-compose_pairs)/2+0xA0, e_text); - e_text[len] = '\0'; - e_length = len; - del = 1; // delete the old character and insert new one - compose_state = 0; - return 1; - } - } - - } - - int i = e_keysym; - - // See if they type the compose prefix key: - if (i == FL_Control_R || i == 0xff20/* Multi-Key */) { - compose_state = 1; - return 1; - } - - // See if they typed a dead key. This gets it into the same state as - // typing prefix+accent: - if (i >= 0xfe50 && i <= 0xfe5b) { - ascii = e_text[0]; - for (const char *p = compose_pairs; *p; p += 2) - if (p[0] == ascii || - (p[1] == ' ' && (p - compose_pairs) / 2 + 0xA0 == ascii)) { - compose_state = p[0]; - return 1; - } - compose_state = 0; - return 1; - } - - // Only insert non-control characters: - if (e_length && (ascii & ~31 && ascii!=127)) {compose_state = 0; return 1;} - - return 0; -} - -#endif // __APPLE__ || WIN32 - // // End of "$Id$" // |
