1 # include "appFrameConfig.h"
2
3 # include <stdlib.h>
4 # include <stdio.h>
5
6 # include "guiWidgets.h"
7
8 # include <appDebugon.h>
9 # include <uniUtf8.h>
10
11 # ifdef USE_MOTIF
12
13 # include <X11/Xatom.h>
14 # include <X11/keysym.h>
15
appGuiDebugKey(const char * how,XKeyPressedEvent * keyEvent,APP_KEY_VALUE keysym,char * b)16 static void appGuiDebugKey( const char * how,
17 XKeyPressedEvent * keyEvent,
18 APP_KEY_VALUE keysym,
19 char * b )
20 {
21 const char * keyString= XKeysymToString( keysym );
22 int state= keyEvent->state;
23
24 if ( ! keyString )
25 { keyString= "<Unknown>"; }
26
27 appDebug( "KEY: %s (%s%s%s%s%s%s%s%s<Key>%s): ",
28 APP_X11EventNames[keyEvent->type],
29 (state&KEY_SHIFT_MASK)?"Shift":"",
30 (state&KEY_CONTROL_MASK)?"Ctrl":"",
31 (state&LockMask)?"Lock":"",
32 (state&Mod1Mask)?"Mod1":"",
33 (state&Mod2Mask)?"Mod2":"",
34 (state&Mod3Mask)?"Mod3":"",
35 (state&Mod4Mask)?"Mod4":"",
36 (state&Mod5Mask)?"Mod5":"",
37 keyString );
38
39 if ( b && b[0] )
40 { appDebug( "XLookup%s -> \"%s\" (0x%02x)\n", how, b, b[0] ); }
41 else{ appDebug( "XLookup%s -|\n", how ); }
42 }
43
appGuiHandleKeysym(DocumentWidget * dw,char * scratch,APP_KEY_VALUE keysym,int state)44 static void appGuiHandleKeysym( DocumentWidget * dw,
45 char * scratch,
46 APP_KEY_VALUE keysym,
47 int state )
48 {
49 if ( keysym != 0 &&
50 ( keysym & 0xff00 ) != 0xff00 )
51 {
52 int unicode= appKeysymX11ToUnicode( keysym );
53
54 if ( unicode >= 0 )
55 {
56 int step= uniPutUtf8( scratch, unicode );
57 if ( step < 1 )
58 { LLDEB(unicode,step); }
59 else{
60 scratch[step]= '\0';
61 (*dw->dwGotString)( dw->dwOwner, (char *)scratch, step );
62 return;
63 }
64 }
65 }
66
67 (*dw->dwGotKey)( dw->dwOwner, keysym, state );
68
69 return;
70 }
71
APP_EVENT_HANDLER_H(appKeyPressed,w,voiddw,event)72 static APP_EVENT_HANDLER_H( appKeyPressed, w, voiddw, event )
73 {
74 DocumentWidget * dw= (DocumentWidget *)voiddw;
75
76 APP_KEY_VALUE keysym;
77 XKeyPressedEvent * keyEvent= &(event->xkey);
78
79 char scratch[12+1];
80
81 static int debugKeys= 0;
82
83 if ( debugKeys == 0 )
84 {
85 if ( getenv( "TED_DEBUG_KEYS" ) )
86 { debugKeys= 1; }
87 else{ debugKeys= -1; }
88 }
89
90 if ( event->type != KeyPress )
91 { LLDEB(event->type,KeyPress); return; }
92
93 keysym= 0;
94 scratch[0]= '\0';
95
96 if ( dw->dwInputContext )
97 {
98 Status status;
99
100 (void) /* gotString= */ XmbLookupString( dw->dwInputContext, keyEvent,
101 (char *)scratch, sizeof(scratch)- 1,
102 &keysym, &status );
103 switch( status )
104 {
105 case XBufferOverflow:
106 LSDEB(status,"XBufferOverflow"); return;
107 case XLookupNone:
108 LSDEB(status,"XLookupNone"); return;
109 case XLookupChars:
110 LSDEB(status,"XLookupChars"); return;
111 default:
112 LSDEB(status,"default"); return;
113
114 case XLookupKeySym:
115 case XLookupBoth:
116 scratch[0]= '\0';
117 appGuiHandleKeysym( dw, scratch, keysym, keyEvent->state );
118 if ( debugKeys > 0 )
119 {
120 appGuiDebugKey( status==XLookupBoth?"Both":"KeySym",
121 keyEvent, keysym, scratch );
122 }
123 return;
124 }
125 }
126 else{
127 (void) /* gotString= */ XLookupString( keyEvent,
128 (char *)scratch, sizeof(scratch)- 1,
129 &keysym, (XComposeStatus *)0 );
130
131 scratch[0]= '\0';
132 appGuiHandleKeysym( dw, scratch, keysym, keyEvent->state );
133 if ( debugKeys > 0 )
134 { appGuiDebugKey( ":NoIm", keyEvent, keysym, scratch ); }
135
136 return;
137 }
138
139 }
140
141 /************************************************************************/
142 /* */
143 /* Set an old-fashined X11 Input style for accented characters etc. */
144 /* */
145 /************************************************************************/
146
147 static XIMStyle appXimPreferences[]=
148 {
149 XIMPreeditCallbacks,
150 XIMPreeditPosition,
151 XIMPreeditArea,
152 XIMPreeditNothing,
153 XIMStatusCallbacks,
154 XIMStatusArea,
155 XIMStatusNothing,
156 };
157
appDocumentSetInputContext(APP_INPUT_METHOD im,DocumentWidget * dw)158 void appDocumentSetInputContext( APP_INPUT_METHOD im,
159 DocumentWidget * dw )
160 {
161 XtAddEventHandler( dw->dwWidget, KeyPressMask, False,
162 appKeyPressed, (void *)dw );
163
164 if ( im )
165 {
166 XIMStyles * availableStyles= (XIMStyles *)0;
167 XIMStyle supportedStyles;
168 XIMStyle likedStyle;
169 int style;
170
171 XGetIMValues( im,
172 XNQueryInputStyle, &availableStyles,
173 NULL );
174
175 supportedStyles= XIMPreeditArea |
176 XIMPreeditNothing |
177 XIMPreeditNone |
178 XIMStatusArea |
179 XIMStatusNothing |
180 XIMStatusNone ;
181
182 likedStyle= 0;
183 for ( style= 0; style < availableStyles->count_styles; style++ )
184 {
185 XIMStyle foundStyle= availableStyles->supported_styles[style];
186 unsigned j;
187
188 if ( ( supportedStyles & foundStyle ) != foundStyle )
189 { continue; }
190
191 if ( ! likedStyle )
192 { likedStyle= foundStyle; continue; }
193
194 for ( j= 0; j < sizeof(appXimPreferences)/sizeof(XIMStyle); j++ )
195 {
196 if ( ( foundStyle & appXimPreferences[j] ) &&
197 ! ( likedStyle & appXimPreferences[j] ) )
198 { likedStyle= foundStyle; break; }
199 }
200 }
201
202 if ( likedStyle )
203 {
204 dw->dwInputContext= XCreateIC( im,
205 XNClientWindow, XtWindow( dw->dwWidget ),
206 XNInputStyle, likedStyle,
207 /*
208 XNPeeditAttributes, attributeList,
209 XNStatusAttributes, attributeList,
210 */
211 NULL );
212 }
213 else{ dw->dwInputContext= (XIC)0; }
214
215 if ( availableStyles )
216 { XFree( availableStyles ); }
217 }
218 else{ dw->dwInputContext= (XIC)0; }
219
220 return;
221 }
222
223 # endif
224