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