[maemo-commits] [maemo-commits] r15001 - in projects/haf/trunk/libsdl1.2: debian src/video/dga src/video/x11

From: subversion at stage.maemo.org subversion at stage.maemo.org
Date: Thu Jan 3 14:59:52 EET 2008
Author: kusalone
Date: 2008-01-03 14:59:43 +0200 (Thu, 03 Jan 2008)
New Revision: 15001

Modified:
   projects/haf/trunk/libsdl1.2/debian/changelog
   projects/haf/trunk/libsdl1.2/src/video/dga/SDL_dgaevents.c
   projects/haf/trunk/libsdl1.2/src/video/x11/SDL_x11events.c
   projects/haf/trunk/libsdl1.2/src/video/x11/SDL_x11video.c
   projects/haf/trunk/libsdl1.2/src/video/x11/SDL_x11video.h
Log:
libsdl1.2: first prototype of experimental XIM utilization inside SDL.


Modified: projects/haf/trunk/libsdl1.2/debian/changelog
===================================================================
--- projects/haf/trunk/libsdl1.2/debian/changelog	2008-01-02 14:18:22 UTC (rev 15000)
+++ projects/haf/trunk/libsdl1.2/debian/changelog	2008-01-03 12:59:43 UTC (rev 15001)
@@ -1,3 +1,11 @@
+libsdl1.2 (1.2.8-24un) unstable; urgency=low
+
+  * UNRELEASED (and possibly (likely) broken)
+  * src/video/x11/: implemented XIC usage to get proper unicode translations
+    for keyboard events.
+
+ -- Kuisma Salonen <kuisma.salonen at nokia.com>  Thu, 27 Dec 2007 11:45:22 +0200
+
 libsdl1.2 (1.2.8-23) unstable; urgency=low
 
   * debian/control: added libxmu-dev back to build dependencies as X backend

Modified: projects/haf/trunk/libsdl1.2/src/video/dga/SDL_dgaevents.c
===================================================================
--- projects/haf/trunk/libsdl1.2/src/video/dga/SDL_dgaevents.c	2008-01-02 14:18:22 UTC (rev 15000)
+++ projects/haf/trunk/libsdl1.2/src/video/dga/SDL_dgaevents.c	2008-01-03 12:59:43 UTC (rev 15001)
@@ -40,7 +40,7 @@
 extern int X11_Pending(Display *display);
 extern void X11_InitKeymap(void);
 extern SDL_keysym *X11_TranslateKey(Display *display, XKeyEvent *xkey,
-				    KeyCode kc, SDL_keysym *keysym);
+				    KeyCode kc, SDL_keysym *keysym, XIC ic);
 
 static int DGA_DispatchEvent(_THIS)
 {
@@ -86,7 +86,7 @@
 		posted = SDL_PrivateKeyboard((xevent.type == KeyPress), 
 					X11_TranslateKey(DGA_Display,
 							 &xkey, xkey.keycode,
-							 &keysym));
+							 &keysym, 0));
 	    }
 	    break;
 

Modified: projects/haf/trunk/libsdl1.2/src/video/x11/SDL_x11events.c
===================================================================
--- projects/haf/trunk/libsdl1.2/src/video/x11/SDL_x11events.c	2008-01-02 14:18:22 UTC (rev 15000)
+++ projects/haf/trunk/libsdl1.2/src/video/x11/SDL_x11events.c	2008-01-03 12:59:43 UTC (rev 15001)
@@ -63,8 +63,10 @@
 static SDLKey ODD_keymap[256];
 static SDLKey MISC_keymap[256];
 SDL_keysym *X11_TranslateKey(Display *display, XKeyEvent *xkey, KeyCode kc,
-			     SDL_keysym *keysym);
+			     SDL_keysym *keysym, XIC ic);
 
+static unsigned short _translate_utf8_keyevent(XIC ic, XKeyPressedEvent *e);
+
 /* Check to see if this is a repeated key.
    (idea shamelessly lifted from GII -- thanks guys! :)
  */
@@ -224,6 +226,9 @@
 #ifdef DEBUG_XEVENTS
 printf("FocusIn!\n");
 #endif
+		if ( SDL_ic != NULL )
+			XSetICFocus(SDL_ic);
+
 		posted = SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS);
 
 		/* Queue entry into fullscreen mode */
@@ -237,6 +242,9 @@
 #ifdef DEBUG_XEVENTS
 printf("FocusOut!\n");
 #endif
+		if ( SDL_ic != NULL )
+			XUnsetICFocus(SDL_ic);
+
 		posted = SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS);
 
 		/* Queue leaving fullscreen mode */
@@ -304,7 +312,9 @@
 		posted = SDL_PrivateKeyboard(SDL_PRESSED,
 				X11_TranslateKey(SDL_Display, &xevent.xkey,
 						 xevent.xkey.keycode,
-						 &keysym));
+						 &keysym, SDL_ic));
+		/*keysym.unicode = _translate_utf8_keyevent(SDL_ic,
+							  &xevent.xkey);*/
 	    }
 	    break;
 
@@ -320,7 +330,9 @@
 			posted = SDL_PrivateKeyboard(SDL_RELEASED, 
 				X11_TranslateKey(SDL_Display, &xevent.xkey,
 						 xevent.xkey.keycode,
-						 &keysym));
+						 &keysym, SDL_ic));
+			/*keysym.unicode = _translate_utf8_keyevent(SDL_ic,
+								&xevent.xkey);*/
 		}
 	    }
 	    break;
@@ -621,8 +633,50 @@
 	MISC_keymap[XK_Hyper_R&0xFF] = SDLK_MENU;   /* Windows "Menu" key */
 }
 
+  /* small jinx translation for max 16 bit characters */
+  /* logic specific to max 3 bytes instead of being generic */
+static unsigned short _translate_unicode(unsigned char *utf8)
+{
+	unsigned short ret = 0;
+	int i, cnt;
+
+	if( utf8[0] & 0x80 ) { /* multibyte */
+		  /* TODO: take potential erroreus utf8 into account */
+		for(i = 2; i < 8; i++) {
+			if(!((0x80 >> i) & utf8[0]))
+				break;
+		}
+
+		cnt = i;
+		for(i = 0; i < cnt; i++) {
+			ret |= ((i == cnt - 1)
+	? (((unsigned long)utf8[0] & (0xff >> (cnt + 1))) << (i*6))
+	: (((unsigned long)utf8[cnt-i-1] & 0x3f) << (i*6)));
+		}
+	} else { /* single byte */
+		ret = utf8[0];
+	}
+
+	return ret;
+}
+
+static unsigned short _translate_utf8_keyevent(XIC ic, XKeyPressedEvent *e)
+{
+	unsigned char keybuf[512] = { 0 };
+	Status state;
+
+	if( Xutf8LookupString(ic, e, keybuf, sizeof(keybuf), NULL, &state) ) {
+		if( state == XLookupChars || state == XLookupBoth ) {
+			return _translate_unicode(keybuf);
+		}
+	}
+
+
+	return 0;
+}
+
 SDL_keysym *X11_TranslateKey(Display *display, XKeyEvent *xkey, KeyCode kc,
-			     SDL_keysym *keysym)
+			     SDL_keysym *keysym, XIC ic)
 {
 	KeySym xsym;
 
@@ -707,6 +761,8 @@
 		/* Until we handle the IM protocol, use XLookupString() */
 		unsigned char keybuf[32];
 
+		memset(keybuf, 0, sizeof(keybuf));
+
 #define BROKEN_XFREE86_INTERNATIONAL_KBD
 /* This appears to be a magical flag that is used with AltGr on
    international keyboards to signal alternate key translations.
@@ -719,16 +775,26 @@
 			xkey->state |= (1<<13);
 		}
 #endif
+		if ( ic ) {
+			/*if ( Xutf8LookupString(SDL_ic, &xevent.xkey,
+						(char *)keybuf,
+						sizeof(keybuf), NULL,
+						&state) ) {
+				keysym->unicode = _translate_unicode(keybuf);
+			}*/
+			keysym->unicode = _translate_utf8_keyevent(ic, xkey);
+		} else {
 		/* Look up the translated value for the key event */
-		if ( XLookupString(xkey, (char *)keybuf, sizeof(keybuf),
-							NULL, &state) ) {
+			if ( XLookupString(xkey, (char *)keybuf,
+					   sizeof(keybuf), NULL, &state) ) {
 			/*
 			 * FIXME,: XLookupString() may yield more than one
 			 * character, so we need a mechanism to allow for
 			 * this (perhaps generate null keypress events with
 			 * a unicode value)
 			 */
-			keysym->unicode = keybuf[0];
+				keysym->unicode = keybuf[0];
+			}
 		}
 	}
 	return(keysym);
@@ -895,7 +961,7 @@
 			if(key_vec[i] & (1 << j)) {
 				SDL_keysym sk;
 				KeyCode kc = i << 3 | j;
-				X11_TranslateKey(display, NULL, kc, &sk);
+				X11_TranslateKey(display, NULL, kc, &sk, 0);
 				new_kstate[sk.sym] = SDL_PRESSED;
 				xcode[sk.sym] = kc;
 			}

Modified: projects/haf/trunk/libsdl1.2/src/video/x11/SDL_x11video.c
===================================================================
--- projects/haf/trunk/libsdl1.2/src/video/x11/SDL_x11video.c	2008-01-02 14:18:22 UTC (rev 15000)
+++ projects/haf/trunk/libsdl1.2/src/video/x11/SDL_x11video.c	2008-01-03 12:59:43 UTC (rev 15001)
@@ -362,18 +362,30 @@
     /* Set the class hints so we can get an icon (AfterStep) */
     {
 	XClassHint *classhints;
+	char *classname = getenv("SDL_VIDEO_X11_WMCLASS");
+	if ( ! classname ) {
+	    classname = "SDL_App";
+	}
 	classhints = XAllocClassHint();
 	if(classhints != NULL) {
-            char *classname = getenv("SDL_VIDEO_X11_WMCLASS");
-            if ( ! classname ) {
-                classname = "SDL_App";
-            }
 	    classhints->res_name = classname;
 	    classhints->res_class = classname;
 	    XSetClassHint(SDL_Display, WMwindow, classhints);
             XSetClassHint(SDL_Display, FSwindow, classhints);
 	    XFree(classhints);
 	}
+
+	if( SDL_im != NULL ) {
+		SDL_ic = XCreateIC(SDL_im,
+			XNClientWindow, WMwindow,
+			XNFocusWindow, WMwindow,
+			XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
+			XNResourceName, classname,
+			XNResourceClass, classname,
+			NULL);
+		if( SDL_ic != NULL )
+			XSetICFocus(SDL_ic);
+	}
     }
 
     /* Allow the window to be deleted by the window manager */
@@ -384,11 +396,15 @@
 static int X11_VideoInit(_THIS, SDL_PixelFormat *vformat)
 {
 	char *display;
+	char *classname;
 	int i;
 
 	/* Open the X11 display */
 	display = NULL;		/* Get it from DISPLAY environment variable */
 
+	SDL_im = NULL;
+	SDL_ic = NULL;
+
 	if ( (strncmp(XDisplayName(display), ":", 1) == 0) ||
 	     (strncmp(XDisplayName(display), "unix:", 5) == 0) ) {
 		local_X11 = 1;
@@ -423,6 +439,12 @@
 	/* use default screen (from $DISPLAY) */
 	SDL_Screen = DefaultScreen(SDL_Display);
 
+	classname = getenv("SDL_VIDEO_X11_WMCLASS");
+	if ( ! classname ) {
+		classname = "SDL_App";
+	}
+	SDL_im = XOpenIM(SDL_Display, NULL, classname, classname);
+
 #ifndef NO_SHARED_MEMORY
 	/* Check for MIT shared memory extension */
 	use_mitshm = 0;
@@ -1243,6 +1265,16 @@
 		/* Flush any delayed updates */
 		XSync(GFX_Display, False);
 
+		if ( SDL_ic != NULL ) {
+			XUnsetICFocus(SDL_ic);
+			XDestroyIC(SDL_ic);
+			SDL_ic = NULL;
+		}
+		if ( SDL_im != NULL ) {
+			XCloseIM(SDL_im);
+			SDL_im = NULL;
+		}
+
 		/* Start shutting down the windows */
 		X11_DestroyImage(this, this->screen);
 		X11_DestroyWindow(this, this->screen);

Modified: projects/haf/trunk/libsdl1.2/src/video/x11/SDL_x11video.h
===================================================================
--- projects/haf/trunk/libsdl1.2/src/video/x11/SDL_x11video.h	2008-01-02 14:18:22 UTC (rev 15000)
+++ projects/haf/trunk/libsdl1.2/src/video/x11/SDL_x11video.h	2008-01-03 12:59:43 UTC (rev 15001)
@@ -68,6 +68,9 @@
 
     char *SDL_windowid;		/* Flag: true if we have been passed a window */
 
+    XIM SDL_im;
+    XIC SDL_ic;
+
     /* Direct Graphics Access extension information */
     int using_dga;
 
@@ -157,6 +160,8 @@
 #define WMwindow		(this->hidden->WMwindow)
 #define FSwindow		(this->hidden->FSwindow)
 #define SDL_Window		(this->hidden->SDL_Window)
+#define SDL_im			(this->hidden->SDL_im)
+#define SDL_ic			(this->hidden->SDL_ic)
 #define WM_DELETE_WINDOW	(this->hidden->WM_DELETE_WINDOW)
 #define SDL_BlankCursor		(this->hidden->BlankCursor)
 #define SDL_windowid		(this->hidden->SDL_windowid)


More information about the maemo-commits mailing list