Real Unicode support for X11. Based on updated version of this patch:
authorRyan C. Gordon <icculus@icculus.org>
Mon, 21 Nov 2005 00:16:34 +0000
changeset 11789867f3d86e44
parent 1177 e967ab22e6fd
child 1179 abb4267e7028
Real Unicode support for X11. Based on updated version of this patch:
http://lists.arabeyes.org/archives/developer/2004/June/msg00160.html

--ryan.
BUGS
src/video/x11/SDL_x11events.c
src/video/x11/SDL_x11events_c.h
src/video/x11/SDL_x11sym.h
src/video/x11/SDL_x11video.c
src/video/x11/SDL_x11video.h
     1.1 --- a/BUGS	Sun Nov 20 23:59:26 2005 +0000
     1.2 +++ b/BUGS	Mon Nov 21 00:16:34 2005 +0000
     1.3 @@ -15,6 +15,7 @@
     1.4  	It requires handling of keyboard mapping events and using the XIM
     1.5  	input translation extension.  I will implement it as requested.
     1.6  	Latin-1 keyboard input works fine.
     1.7 +	(UPDATE 04/06/2004: this bug is now fixed)
     1.8  
     1.9  	The keyboard modifiers are not set to the correct state on startup.
    1.10  
    1.11 @@ -100,7 +101,8 @@
    1.12  	It requires handling of keyboard mapping events and using the XIM
    1.13  	input translation extension.  I will implement it as requested.
    1.14  	Latin-1 keyboard input works fine.
    1.15 -
    1.16 +	(UPDATE 04/06/2004: this bug is now fixed but needs testing)
    1.17 +	
    1.18  	The keyboard modifiers are not set to the correct state on startup.
    1.19  
    1.20  Solaris:
    1.21 @@ -110,7 +112,8 @@
    1.22  	It requires handling of keyboard mapping events and using the XIM
    1.23  	input translation extension.  I will implement it as requested.
    1.24  	Latin-1 keyboard input works fine.
    1.25 -
    1.26 +	(UPDATE 04/06/2004: this bug is now fixed but needs testing)
    1.27 +	
    1.28  	The keyboard modifiers are not set to the correct state on startup.
    1.29  
    1.30  IRIX:
    1.31 @@ -122,7 +125,8 @@
    1.32  	It requires handling of keyboard mapping events and using the XIM
    1.33  	input translation extension.  I will implement it as requested.
    1.34  	Latin-1 keyboard input works fine.
    1.35 -
    1.36 +	(UPDATE 04/06/2004: this bug is now fixed but needs testing)
    1.37 +	
    1.38  	The keyboard modifiers are not set to the correct state on startup.
    1.39  
    1.40  EPOC:
    1.41 @@ -148,7 +152,8 @@
    1.42  	It requires handling of keyboard mapping events and using the XIM
    1.43  	input translation extension.  I will implement it as requested.
    1.44  	Latin-1 keyboard input works fine.
    1.45 -
    1.46 +	(UPDATE 04/06/2004: this bug is now fixed but needs testing)
    1.47 +	
    1.48  	The keyboard modifiers are not set to the correct state on startup.
    1.49  
    1.50  OSF/Tru64:  -= NOT YET SUPPORTED =-
    1.51 @@ -160,7 +165,8 @@
    1.52  	It requires handling of keyboard mapping events and using the XIM
    1.53  	input translation extension.  I will implement it as requested.
    1.54  	Latin-1 keyboard input works fine.
    1.55 -
    1.56 +	(UPDATE 04/06/2004: this bug is now fixed but needs testing)
    1.57 +	
    1.58  	The keyboard modifiers are not set to the correct state on startup.
    1.59  
    1.60  AIX:  -= NOT YET SUPPORTED =-
    1.61 @@ -176,7 +182,8 @@
    1.62  	It requires handling of keyboard mapping events and using the XIM
    1.63  	input translation extension.  I will implement it as requested.
    1.64  	Latin-1 keyboard input works fine.
    1.65 -
    1.66 +	(UPDATE 04/06/2004: this bug is now fixed but needs testing)
    1.67 +	
    1.68  	The keyboard modifiers are not set to the correct state on startup.
    1.69  
    1.70  	The AIX port was done by Carsten.Griwodz@KOM.tu-darmstadt.de
     2.1 --- a/src/video/x11/SDL_x11events.c	Sun Nov 20 23:59:26 2005 +0000
     2.2 +++ b/src/video/x11/SDL_x11events.c	Mon Nov 21 00:16:34 2005 +0000
     2.3 @@ -62,7 +62,7 @@
     2.4  /* The translation tables from an X11 keysym to a SDL keysym */
     2.5  static SDLKey ODD_keymap[256];
     2.6  static SDLKey MISC_keymap[256];
     2.7 -SDL_keysym *X11_TranslateKey(Display *display, XKeyEvent *xkey, KeyCode kc,
     2.8 +SDL_keysym *X11_TranslateKey(Display *display, XIC ic, XKeyEvent *xkey, KeyCode kc,
     2.9  			     SDL_keysym *keysym);
    2.10  
    2.11  /* Check to see if this is a repeated key.
    2.12 @@ -241,7 +241,7 @@
    2.13  #ifdef DEBUG_XEVENTS
    2.14  printf("KeymapNotify!\n");
    2.15  #endif
    2.16 -		X11_SetKeyboardState(SDL_Display, xevent.xkeymap.key_vector);
    2.17 +		X11_SetKeyboardState(SDL_Display, SDL_IC,  xevent.xkeymap.key_vector);
    2.18  	    }
    2.19  	    break;
    2.20  
    2.21 @@ -293,7 +293,7 @@
    2.22  printf("KeyPress (X11 keycode = 0x%X)\n", xevent.xkey.keycode);
    2.23  #endif
    2.24  		posted = SDL_PrivateKeyboard(SDL_PRESSED,
    2.25 -				X11_TranslateKey(SDL_Display, &xevent.xkey,
    2.26 +				X11_TranslateKey(SDL_Display, SDL_IC, &xevent.xkey,
    2.27  						 xevent.xkey.keycode,
    2.28  						 &keysym));
    2.29  	    }
    2.30 @@ -309,7 +309,7 @@
    2.31  		/* Check to see if this is a repeated key */
    2.32  		if ( ! X11_KeyRepeat(SDL_Display, &xevent) ) {
    2.33  			posted = SDL_PrivateKeyboard(SDL_RELEASED, 
    2.34 -				X11_TranslateKey(SDL_Display, &xevent.xkey,
    2.35 +				X11_TranslateKey(SDL_Display, SDL_IC,  &xevent.xkey,
    2.36  						 xevent.xkey.keycode,
    2.37  						 &keysym));
    2.38  		}
    2.39 @@ -612,7 +612,128 @@
    2.40  	MISC_keymap[XK_Hyper_R&0xFF] = SDLK_MENU;   /* Windows "Menu" key */
    2.41  }
    2.42  
    2.43 -SDL_keysym *X11_TranslateKey(Display *display, XKeyEvent *xkey, KeyCode kc,
    2.44 +#ifdef X_HAVE_UTF8_STRING
    2.45 +Uint32 Utf8ToUcs4(const char * utf8)
    2.46 +{
    2.47 +	Uint32 c;
    2.48 +	int i = 1;
    2.49 +	int noOctets = 0;
    2.50 +	int firstOctetMask = 0;
    2.51 +	unsigned char firstOctet = utf8[0];
    2.52 +	if (firstOctet < 0x80) {
    2.53 +		/*
    2.54 +		  Characters in the range:
    2.55 +		    00000000 to 01111111 (ASCII Range)
    2.56 +		  are stored in one octet:
    2.57 +		    0xxxxxxx (The same as its ASCII representation)
    2.58 +		  The least 6 significant bits of the first octet is the most 6 significant nonzero bits
    2.59 +		  of the UCS4 representation.
    2.60 +		*/
    2.61 +		noOctets = 1;
    2.62 +		firstOctetMask = 0x7F;  /* 0(1111111) - The most significant bit is ignored */
    2.63 +	} else if ((firstOctet & 0xE0) /* get the most 3 significant bits by AND'ing with 11100000 */
    2.64 +	              == 0xC0 ) {  /* see if those 3 bits are 110. If so, the char is in this range */
    2.65 +		/*
    2.66 +		  Characters in the range:
    2.67 +		    00000000 10000000 to 00000111 11111111
    2.68 +		  are stored in two octets:
    2.69 +		    110xxxxx 10xxxxxx
    2.70 +		  The least 5 significant bits of the first octet is the most 5 significant nonzero bits
    2.71 +		  of the UCS4 representation.
    2.72 +		*/
    2.73 +		noOctets = 2;
    2.74 +		firstOctetMask = 0x1F;  /* 000(11111) - The most 3 significant bits are ignored */
    2.75 +	} else if ((firstOctet & 0xF0) /* get the most 4 significant bits by AND'ing with 11110000 */
    2.76 +	              == 0xE0) {  /* see if those 4 bits are 1110. If so, the char is in this range */
    2.77 +		/*
    2.78 +		  Characters in the range:
    2.79 +		    00001000 00000000 to 11111111 11111111
    2.80 +		  are stored in three octets:
    2.81 +		    1110xxxx 10xxxxxx 10xxxxxx
    2.82 +		  The least 4 significant bits of the first octet is the most 4 significant nonzero bits
    2.83 +		  of the UCS4 representation.
    2.84 +		*/
    2.85 +		noOctets = 3;
    2.86 +		firstOctetMask = 0x0F; /* 0000(1111) - The most 4 significant bits are ignored */
    2.87 +	} else if ((firstOctet & 0xF8) /* get the most 5 significant bits by AND'ing with 11111000 */
    2.88 +	              == 0xF0) {  /* see if those 5 bits are 11110. If so, the char is in this range */
    2.89 +		/*
    2.90 +		  Characters in the range:
    2.91 +		    00000001 00000000 00000000 to 00011111 11111111 11111111
    2.92 +		  are stored in four octets:
    2.93 +		    11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
    2.94 +		  The least 3 significant bits of the first octet is the most 3 significant nonzero bits
    2.95 +		  of the UCS4 representation.
    2.96 +		*/
    2.97 +		noOctets = 4;
    2.98 +		firstOctetMask = 0x07; /* 11110(111) - The most 5 significant bits are ignored */
    2.99 +	} else if ((firstOctet & 0xFC) /* get the most 6 significant bits by AND'ing with 11111100 */
   2.100 +	              == 0xF8) { /* see if those 6 bits are 111110. If so, the char is in this range */
   2.101 +		/*
   2.102 +		  Characters in the range:
   2.103 +		    00000000 00100000 00000000 00000000 to
   2.104 +		    00000011 11111111 11111111 11111111
   2.105 +		  are stored in five octets:
   2.106 +		    111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
   2.107 +		  The least 2 significant bits of the first octet is the most 2 significant nonzero bits
   2.108 +		  of the UCS4 representation.
   2.109 +		*/
   2.110 +		noOctets = 5;
   2.111 +		firstOctetMask = 0x03; /* 111110(11) - The most 6 significant bits are ignored */
   2.112 +	} else if ((firstOctet & 0xFE) /* get the most 7 significant bits by AND'ing with 11111110 */
   2.113 +	              == 0xFC) { /* see if those 7 bits are 1111110. If so, the char is in this range */
   2.114 +		/*
   2.115 +		  Characters in the range:
   2.116 +		    00000100 00000000 00000000 00000000 to
   2.117 +		    01111111 11111111 11111111 11111111
   2.118 +		  are stored in six octets:
   2.119 +		    1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
   2.120 +		  The least significant bit of the first octet is the most significant nonzero bit
   2.121 +		  of the UCS4 representation.
   2.122 +		*/
   2.123 +		noOctets = 6;
   2.124 +		firstOctetMask = 0x01; /* 1111110(1) - The most 7 significant bits are ignored */
   2.125 +	} else
   2.126 +		return 0;  /* The given chunk is not a valid UTF-8 encoded Unicode character */
   2.127 +	
   2.128 +	/*
   2.129 +	  The least noOctets significant bits of the first octet is the most 2 significant nonzero bits
   2.130 +	  of the UCS4 representation.
   2.131 +	  The first 6 bits of the UCS4 representation is the least 8-noOctets-1 significant bits of
   2.132 +	  firstOctet if the character is not ASCII. If so, it's the least 7 significant bits of firstOctet.
   2.133 +	  This done by AND'ing firstOctet with its mask to trim the bits used for identifying the
   2.134 +	  number of continuing octets (if any) and leave only the free bits (the x's)
   2.135 +	  Sample:
   2.136 +	  1-octet:    0xxxxxxx  &  01111111 = 0xxxxxxx
   2.137 +	  2-octets:  110xxxxx  &  00011111 = 000xxxxx
   2.138 +	*/
   2.139 +	c = firstOctet & firstOctetMask;
   2.140 +	
   2.141 +	/* Now, start filling c.ucs4 with the bits from the continuing octets from utf8. */
   2.142 +	for (i = 1; i < noOctets; i++) {
   2.143 +		/* A valid continuing octet is of the form 10xxxxxx */
   2.144 +		if ((utf8[i] & 0xC0) /* get the most 2 significant bits by AND'ing with 11000000 */
   2.145 +		    != 0x80) /* see if those 2 bits are 10. If not, the is a malformed sequence. */
   2.146 +			/*The given chunk is a partial sequence at the end of a string that could
   2.147 +			   begin a valid character */
   2.148 +			return 0;
   2.149 +		
   2.150 +		/* Make room for the next 6-bits */
   2.151 +		c <<= 6;
   2.152 +		
   2.153 +		/*
   2.154 +		  Take only the least 6 significance bits of the current octet (utf8[i]) and fill the created room
   2.155 +		  of c.ucs4 with them.
   2.156 +		  This done by AND'ing utf8[i] with 00111111 and the OR'ing the result with c.ucs4.
   2.157 +		*/
   2.158 +		c |= utf8[i] & 0x3F;
   2.159 +	}
   2.160 +	return c;
   2.161 +}
   2.162 +#endif
   2.163 +
   2.164 +
   2.165 +SDL_keysym *X11_TranslateKey(Display *display, XIC ic, XKeyEvent *xkey, KeyCode kc,
   2.166  			     SDL_keysym *keysym)
   2.167  {
   2.168  	KeySym xsym;
   2.169 @@ -695,8 +816,7 @@
   2.170  	keysym->unicode = 0;
   2.171  	if ( SDL_TranslateUNICODE && xkey ) {
   2.172  		static XComposeStatus state;
   2.173 -		/* Until we handle the IM protocol, use XLookupString() */
   2.174 -		unsigned char keybuf[32];
   2.175 +
   2.176  
   2.177  #define BROKEN_XFREE86_INTERNATIONAL_KBD
   2.178  /* This appears to be a magical flag that is used with AltGr on
   2.179 @@ -711,15 +831,31 @@
   2.180  		}
   2.181  #endif
   2.182  		/* Look up the translated value for the key event */
   2.183 -		if ( pXLookupString(xkey, (char *)keybuf, sizeof(keybuf),
   2.184 -							NULL, &state) ) {
   2.185 -			/*
   2.186 -			 * FIXME,: XLookupString() may yield more than one
   2.187 -			 * character, so we need a mechanism to allow for
   2.188 -			 * this (perhaps generate null keypress events with
   2.189 -			 * a unicode value)
   2.190 -			 */
   2.191 -			keysym->unicode = keybuf[0];
   2.192 +
   2.193 +		/* if there is no connection with the IM server, use the regular method */
   2.194 +		if (ic == NULL) {
   2.195 +			unsigned char keybuf[32];
   2.196 +
   2.197 +			if ( pXLookupString(xkey, (char *)keybuf, sizeof(keybuf),
   2.198 +								NULL, &state) ) {
   2.199 +				/*
   2.200 +				* FIXME,: XLookupString() may yield more than one
   2.201 +				* character, so we need a mechanism to allow for
   2.202 +				* this (perhaps generate null keypress events with
   2.203 +				* a unicode value)
   2.204 +				*/
   2.205 +				keysym->unicode = keybuf[0];
   2.206 +			}
   2.207 +		} else {  /* else, use the IM protocol */
   2.208 +			#ifdef X_HAVE_UTF8_STRING
   2.209 +			/* A UTF-8 character can be at most 6 bytes */
   2.210 +			unsigned char keybuf[6];
   2.211 +			pXSetICFocus(ic);
   2.212 +			if ( pXutf8LookupString(ic, (XKeyPressedEvent *)xkey, (char *)keybuf, sizeof(keybuf),
   2.213 +			                                    NULL, (Status *)&state) )
   2.214 +				keysym->unicode = Utf8ToUcs4(keybuf);
   2.215 +			pXUnsetICFocus(ic);
   2.216 +			#endif
   2.217  		}
   2.218  	}
   2.219  	return(keysym);
   2.220 @@ -832,12 +968,13 @@
   2.221  	return(unicode);
   2.222  }
   2.223  
   2.224 +
   2.225  /*
   2.226   * Called when focus is regained, to read the keyboard state and generate
   2.227   * synthetic keypress/release events.
   2.228   * key_vec is a bit vector of keycodes (256 bits)
   2.229   */
   2.230 -void X11_SetKeyboardState(Display *display, const char *key_vec)
   2.231 +void X11_SetKeyboardState(Display *display, XIC ic, const char *key_vec)
   2.232  {
   2.233  	char keys_return[32];
   2.234  	int i;
   2.235 @@ -886,7 +1023,7 @@
   2.236  			if(key_vec[i] & (1 << j)) {
   2.237  				SDL_keysym sk;
   2.238  				KeyCode kc = i << 3 | j;
   2.239 -				X11_TranslateKey(display, NULL, kc, &sk);
   2.240 +				X11_TranslateKey(display, ic, NULL, kc, &sk);
   2.241  				new_kstate[sk.sym] = SDL_PRESSED;
   2.242  				xcode[sk.sym] = kc;
   2.243  			}
     3.1 --- a/src/video/x11/SDL_x11events_c.h	Sun Nov 20 23:59:26 2005 +0000
     3.2 +++ b/src/video/x11/SDL_x11events_c.h	Mon Nov 21 00:16:34 2005 +0000
     3.3 @@ -30,5 +30,5 @@
     3.4  /* Functions to be exported */
     3.5  extern void X11_InitOSKeymap(_THIS);
     3.6  extern void X11_PumpEvents(_THIS);
     3.7 -extern void X11_SetKeyboardState(Display *display, const char *key_vec);
     3.8 +extern void X11_SetKeyboardState(Display *display, XIC ic, const char *key_vec);
     3.9  
     4.1 --- a/src/video/x11/SDL_x11sym.h	Sun Nov 20 23:59:26 2005 +0000
     4.2 +++ b/src/video/x11/SDL_x11sym.h	Mon Nov 21 00:16:34 2005 +0000
     4.3 @@ -114,6 +114,13 @@
     4.4  SDL_X11_SYM(int,XextRemoveDisplay,(XExtensionInfo*,Display*))
     4.5  #ifdef X_HAVE_UTF8_STRING
     4.6  SDL_X11_SYM(int,Xutf8TextListToTextProperty,(Display*,char**,int,XICCEncodingStyle,XTextProperty*))
     4.7 +SDL_X11_SYM(int,Xutf8LookupString,(XIC,XKeyPressedEvent*,char*,int,KeySym*,Status*))
     4.8 +SDL_X11_SYM(XIC,XCreateIC,(XIM, ...))
     4.9 +SDL_X11_SYM(void,XDestroyIC,(XIC))
    4.10 +SDL_X11_SYM(void,XSetICFocus,(XIC))
    4.11 +SDL_X11_SYM(void,XUnsetICFocus,(XIC))
    4.12 +SDL_X11_SYM(XIM,XOpenIM,(Display*,struct _XrmHashBucketRec*,char*,char*))
    4.13 +SDL_X11_SYM(Status,XCloseIM,(XIM))
    4.14  #endif
    4.15  SDL_X11_SYM(void,_XEatData,(Display*,unsigned long))
    4.16  SDL_X11_SYM(void,_XFlush,(Display*))
     5.1 --- a/src/video/x11/SDL_x11video.c	Sun Nov 20 23:59:26 2005 +0000
     5.2 +++ b/src/video/x11/SDL_x11video.c	Mon Nov 21 00:16:34 2005 +0000
     5.3 @@ -349,6 +349,7 @@
     5.4  		 FocusChangeMask | KeyPressMask | KeyReleaseMask
     5.5  		 | PropertyChangeMask | StructureNotifyMask | KeymapStateMask);
     5.6  
     5.7 +    char * savedclassname = 0;
     5.8      /* Set the class hints so we can get an icon (AfterStep) */
     5.9      {
    5.10  	XClassHint *classhints;
    5.11 @@ -358,6 +359,7 @@
    5.12              if ( ! classname ) {
    5.13                  classname = "SDL_App";
    5.14              }
    5.15 +	    savedclassname = strdup(classname);
    5.16  	    classhints->res_name = classname;
    5.17  	    classhints->res_class = classname;
    5.18  	    pXSetClassHint(SDL_Display, WMwindow, classhints);
    5.19 @@ -365,6 +367,33 @@
    5.20  	}
    5.21      }
    5.22  
    5.23 +    /* Setup the communication with the IM server */
    5.24 +    SDL_IM = NULL;
    5.25 +    SDL_IC = NULL;
    5.26 +
    5.27 +    #ifdef X_HAVE_UTF8_STRING
    5.28 +    SDL_IM = pXOpenIM(SDL_Display, NULL, savedclassname, savedclassname);
    5.29 +    if (SDL_IM == NULL) {
    5.30 +	SDL_SetError("no input method could be opened");
    5.31 +    } else {
    5.32 +	SDL_IC = pXCreateIC(SDL_IM,
    5.33 +			XNClientWindow, WMwindow,
    5.34 +			XNFocusWindow, WMwindow,
    5.35 +			XNInputStyle, XIMPreeditNothing  | XIMStatusNothing,
    5.36 +			XNResourceName, savedclassname,
    5.37 +			XNResourceClass, savedclassname,
    5.38 +			NULL);
    5.39 +	if (SDL_IC == NULL) {
    5.40 +		SDL_SetError("no input context could be created");
    5.41 +		pXCloseIM(SDL_IM);
    5.42 +		SDL_IM = NULL;
    5.43 +	}
    5.44 +    }
    5.45 +    #endif
    5.46 +
    5.47 +    free(savedclassname);
    5.48 +
    5.49 +
    5.50      /* Allow the window to be deleted by the window manager */
    5.51      WM_DELETE_WINDOW = pXInternAtom(SDL_Display, "WM_DELETE_WINDOW", False);
    5.52      pXSetWMProtocols(SDL_Display, WMwindow, &WM_DELETE_WINDOW, 1);
    5.53 @@ -808,7 +837,6 @@
    5.54  					| ButtonPressMask | ButtonReleaseMask
    5.55  					| PointerMotionMask | ExposureMask ));
    5.56  	}
    5.57 -
    5.58  	/* Create the graphics context here, once we have a window */
    5.59  	if ( flags & SDL_OPENGL ) {
    5.60  		if ( X11_GL_CreateContext(this) < 0 ) {
    5.61 @@ -854,7 +882,7 @@
    5.62  	}
    5.63  
    5.64  	/* Update the internal keyboard state */
    5.65 -	X11_SetKeyboardState(SDL_Display, NULL);
    5.66 +	X11_SetKeyboardState(SDL_Display, SDL_IC, NULL);
    5.67  
    5.68  	/* When the window is first mapped, ignore non-modifier keys */
    5.69  	{
    5.70 @@ -892,6 +920,7 @@
    5.71  			screen->flags &= ~SDL_FULLSCREEN;
    5.72  		}
    5.73  	}
    5.74 +	
    5.75  	return(0);
    5.76  }
    5.77  
    5.78 @@ -1231,6 +1260,18 @@
    5.79  		/* Flush any delayed updates */
    5.80  		pXSync(GFX_Display, False);
    5.81  
    5.82 +		/* Close the connection with the IM server */
    5.83 +		#ifdef X_HAVE_UTF8_STRING
    5.84 +		if (SDL_IC == NULL) {
    5.85 +			pXDestroyIC(SDL_IC);
    5.86 +			SDL_IC = NULL;
    5.87 +		}
    5.88 +		if (SDL_IM == NULL) {
    5.89 +			pXCloseIM(SDL_IM);
    5.90 +			SDL_IM = NULL;
    5.91 +		}
    5.92 +		#endif
    5.93 +
    5.94  		/* Start shutting down the windows */
    5.95  		X11_DestroyImage(this, this->screen);
    5.96  		X11_DestroyWindow(this, this->screen);
     6.1 --- a/src/video/x11/SDL_x11video.h	Sun Nov 20 23:59:26 2005 +0000
     6.2 +++ b/src/video/x11/SDL_x11video.h	Mon Nov 21 00:16:34 2005 +0000
     6.3 @@ -62,6 +62,8 @@
     6.4      Window SDL_Window;		/* Shared by both displays (no X security?) */
     6.5      Atom WM_DELETE_WINDOW;	/* "close-window" protocol atom */
     6.6      WMcursor *BlankCursor;	/* The invisible cursor */
     6.7 +    XIM X11_IM;		/* Used to communicate with the input method (IM) server */
     6.8 +    XIC X11_IC;		/* Used for retaining the state, properties, and semantics of communication with                                                  the input method (IM) server */
     6.9  
    6.10      char *SDL_windowid;		/* Flag: true if we have been passed a window */
    6.11  
    6.12 @@ -147,15 +149,15 @@
    6.13  #define SDL_Display		(this->hidden->X11_Display)
    6.14  #define GFX_Display		(this->hidden->GFX_Display)
    6.15  #define SDL_Screen		DefaultScreen(this->hidden->X11_Display)
    6.16 -
    6.17  #define SDL_Visual		(this->hidden->vis)
    6.18 -
    6.19  #define SDL_Root		RootWindow(SDL_Display, SDL_Screen)
    6.20  #define WMwindow		(this->hidden->WMwindow)
    6.21  #define FSwindow		(this->hidden->FSwindow)
    6.22  #define SDL_Window		(this->hidden->SDL_Window)
    6.23  #define WM_DELETE_WINDOW	(this->hidden->WM_DELETE_WINDOW)
    6.24  #define SDL_BlankCursor		(this->hidden->BlankCursor)
    6.25 +#define SDL_IM		(this->hidden->X11_IM)
    6.26 +#define SDL_IC		(this->hidden->X11_IC)
    6.27  #define SDL_windowid		(this->hidden->SDL_windowid)
    6.28  #define using_dga		(this->hidden->using_dga)
    6.29  #define use_mitshm		(this->hidden->use_mitshm)
    6.30 @@ -186,7 +188,6 @@
    6.31  #define gamma_saved		(this->hidden->gamma_saved)
    6.32  #define gamma_changed		(this->hidden->gamma_changed)
    6.33  #define SDL_iconcolors		(this->hidden->iconcolors)
    6.34 -
    6.35  /* Some versions of XFree86 have bugs - detect if this is one of them */
    6.36  #define BUGGY_XFREE86(condition, buggy_version) \
    6.37  ((strcmp(ServerVendor(SDL_Display), "The XFree86 Project, Inc") == 0) && \