FLTK logo

[Library] r4778 - trunk/src/x11

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 All Forums  |  Back to fltk.commit  ]
 
Previous Message ]Next Message ]

[Library] r4778 - trunk/src/x11 fltk-dev Jan 31, 2006  
 
Author: spitzak
Date: 2006-01-31 04:25:04 -0500 (Tue, 31 Jan 2006)
New Revision: 4778

Modified:
   trunk/src/x11/run.cxx
Log:
Updates the shift state on X right after any shift keys, so the GUI can
preview the current shift state. Makes it match Windows and OS/X.

Attempt to clean up the XIM code. For my simple system this works, hope
I did not break the asian input.


Modified: trunk/src/x11/run.cxx
===================================================================
--- trunk/src/x11/run.cxx	2006-01-27 06:47:27 UTC (rev 4777)
+++ trunk/src/x11/run.cxx	2006-01-31 09:25:04 UTC (rev 4778)
@@ -104,118 +104,106 @@
 
 static void fl_new_ic()
 {
-  XVaNestedList preedit_attr;
-  XVaNestedList status_attr;
-  char          **missing_list;
-  int           missing_count;
-  char          *def_string;
-  int predit = 0;
-  int sarea = 0;
-  XIMStyles* xim_styles = NULL;
-
+  // Give up if this failed earlier:
   if (!fl_xim_im)
-      return;
+    return;
 
+  if (fl_xim_ic)
+    XDestroyIC(fl_xim_ic);
+  fl_xim_ic = NULL;
+
   if (!fl_xim_fs) {
+    char          **missing_list;
+    int           missing_count;
+    char          *def_string;
     fl_xim_fs = XCreateFontSet(xdisplay,
 			       "-misc-fixed-medium-r-normal--14-*",
 			       &missing_list, &missing_count, &def_string);
   }
 
-  XPoint	spot;
-  spot.x = 0;
-  spot.y = 0;
-  preedit_attr = XVaCreateNestedList(0,
-				     XNSpotLocation, &spot,
-				     XNFontSet, fl_xim_fs, NULL);
-  status_attr = XVaCreateNestedList(0,
-				    XNAreaNeeded, &status_area,
-				    XNFontSet, fl_xim_fs, NULL);
+  XIMStyles* xim_styles = NULL;
+  if (XGetIMValues(fl_xim_im, XNQueryInputStyle,
+		   &xim_styles, NULL, NULL) ||
+      !xim_styles || !xim_styles->count_styles) {
+    warning("No XIM style found\n");
+    XCloseIM(fl_xim_im);
+    fl_xim_im = NULL;
+    return;
+  }
 
-  if (!XGetIMValues (fl_xim_im, XNQueryInputStyle,
-		     &xim_styles, NULL, NULL)) {
-    int i;
-    XIMStyle *style;
-    for (i = 0, style = xim_styles->supported_styles;
-	 i < xim_styles->count_styles; i++, style++) {
-      if (*style == (XIMPreeditPosition | XIMStatusArea)) {
-	sarea = 1;
-	predit = 1;
-      } else if (*style == (XIMPreeditPosition | XIMStatusNothing)) {
-	predit = 1;
-      }
+  bool predit = false;
+  bool sarea = false;
+  for (int i = 0; i < xim_styles->count_styles; ++i) {
+    XIMStyle* style = xim_styles->supported_styles+i;
+    if (*style == (XIMPreeditPosition | XIMStatusArea)) {
+      sarea = true;
+      predit = true;
+    } else if (*style == (XIMPreeditPosition | XIMStatusNothing)) {
+      predit = true;
     }
   }
   XFree(xim_styles);
 
-  if (fl_xim_ic)
-    XDestroyIC(fl_xim_ic);
-  fl_xim_ic = NULL;
-  if (sarea)
-    fl_xim_ic = XCreateIC(fl_xim_im,
-			  XNInputStyle, (XIMPreeditPosition | XIMStatusArea),
-			  XNPreeditAttributes, preedit_attr,
-			  XNStatusAttributes, status_attr,
-			  NULL);
+  if (predit) {
+    XPoint	spot;
+    spot.x = 0;
+    spot.y = 0;
+    XVaNestedList preedit_attr =
+      XVaCreateNestedList(0,
+			  XNSpotLocation, &spot,
+			  XNFontSet, fl_xim_fs, NULL);
 
-  if (!fl_xim_ic && predit)
-    fl_xim_ic = XCreateIC(fl_xim_im,
-			  XNInputStyle,(XIMPreeditPosition | XIMStatusNothing),
-			  XNPreeditAttributes, preedit_attr,
-			  NULL);
+    if (sarea) {
+      XVaNestedList status_attr =
+	XVaCreateNestedList(0,
+			    XNAreaNeeded, &status_area,
+			    XNFontSet, fl_xim_fs, NULL);
+      fl_xim_ic = XCreateIC(fl_xim_im,
+			    XNInputStyle, (XIMPreeditPosition | XIMStatusArea),
+			    XNPreeditAttributes, preedit_attr,
+			    XNStatusAttributes, status_attr,
+			    NULL);
+      XFree(status_attr);
+    }
+    if (!fl_xim_ic)
+      fl_xim_ic = XCreateIC(fl_xim_im,
+			    XNInputStyle,XIMPreeditPosition | XIMStatusNothing,
+			    XNPreeditAttributes, preedit_attr,
+			    NULL);
+    XFree(preedit_attr);
+    if (fl_xim_ic) {
+      fl_is_over_the_spot = 1;
+      XVaNestedList status_attr;
+      status_attr = XVaCreateNestedList(0, XNAreaNeeded, &status_area, NULL);
+      if (status_area.height != 0)
+	XGetICValues(fl_xim_ic, XNStatusAttributes, status_attr, NULL);
+      XFree(status_attr);
+      return;
+    }
+  }
 
-  XFree(preedit_attr);
-  XFree(status_attr);
-
+  // create a non-preedit one:
+  fl_is_over_the_spot = 0;
+  fl_xim_ic = XCreateIC(fl_xim_im,
+			XNInputStyle, (XIMPreeditNothing | XIMStatusNothing),
+			NULL);
   if (!fl_xim_ic) {
-    fl_is_over_the_spot = 0;
-    fl_xim_ic = XCreateIC(fl_xim_im,
-			  XNInputStyle, (XIMPreeditNothing | XIMStatusNothing),
-			  NULL);
-  } else {
-    fl_is_over_the_spot = 1;
-    XVaNestedList status_attr;
-    status_attr = XVaCreateNestedList(0, XNAreaNeeded, &status_area, NULL);
-    if (status_area.height != 0)
-      XGetICValues(fl_xim_ic, XNStatusAttributes, status_attr, NULL);
-    XFree(status_attr);
+    warning("XCreateIC() failed\n");
+    XCloseIM(fl_xim_im);
+    fl_xim_im = NULL;
   }
 }
 
 static void fl_init_xim()
 {
-  XIMStyles *xim_styles;
   if (!xdisplay) return;
   if (fl_xim_im) return;
 
   XSetLocaleModifiers("");
   fl_xim_im = XOpenIM(xdisplay, NULL, NULL, NULL);
-  xim_styles = NULL;
-  fl_xim_ic = NULL;
 
-  if (fl_xim_im) {
-    XGetIMValues (fl_xim_im, XNQueryInputStyle,
-		  &xim_styles, NULL, NULL);
-  } else {
+  if (!fl_xim_im)
     warning("XOpenIM() failed\n");
-    return;
-  }
-
-  if (xim_styles && xim_styles->count_styles) {
-    fl_new_ic();
-  } else {
-    warning("No XIM style found\n");
-    XCloseIM(fl_xim_im);
-    fl_xim_im = NULL;
-    return;
-  }
-
-  if (!fl_xim_ic) {
-    warning("XCreateIC() failed\n");
-    XCloseIM(fl_xim_im);
-    XFree(xim_styles);
-    fl_xim_im = NULL;
-  }
 }
 
 void fl_set_spot(fltk::Font *f, Widget *w, int x, int y)
@@ -231,7 +219,6 @@
   static Widget *spotw = NULL;
   static XPoint	spot, spot_set;
   static Color background_orig, textcolor_orig;
-  XFontSet fs = NULL;
 
   if (!fl_xim_ic || !fl_is_over_the_spot) return;
   if (w != spotw) {
@@ -247,15 +234,14 @@
     spotf = f;
     if (f) {
       fnt = f->system_name();
-      if (fnt)
-	fs = XCreateFontSet(xdisplay, fnt, &missing_list,
-			    &missing_count, &def_string);
-      else
-	return;
-      if (fs) {
-	XFreeFontSet(xdisplay, fl_xim_fs);
-	fl_xim_fs = fs;
-	change = 1;
+      if (fnt) {
+	XFontSet fs = XCreateFontSet(xdisplay, fnt, &missing_list,
+				     &missing_count, &def_string);
+	if (fs) {
+	  XFreeFontSet(xdisplay, fl_xim_fs);
+	  fl_xim_fs = fs;
+	  change = 1;
+	}
       }
     } else {
       change = 1;
@@ -299,8 +285,6 @@
   }
 }
 
-static XWindow xim_win = 0; // which window we set xim to last
-
 #else // !USE_XIM
 void fl_set_spot(fltk::Font *f, Widget *w, int x, int y) {}
 #endif
@@ -1406,28 +1390,28 @@
 
   case FocusIn:
 #if USE_XIM
-    if (xim_win != xevent.xclient.window) {
-      xim_win = xevent.xclient.window;
-      if (fl_xim_ic)
-	XDestroyIC(fl_xim_ic);
-      fl_xim_ic = NULL;
-      fl_new_ic();
-      if (fl_xim_ic)
-	XSetICValues(fl_xim_ic,
-		     XNClientWindow, xim_win,
-		     NULL);
+    // For some reason, always destroying & recreating seems to help this work:
+    /*if (!fl_xim_ic)*/ fl_new_ic();
+    if (fl_xim_ic) {
+      XSetICValues(fl_xim_ic,
+		   XNClientWindow, xevent.xclient.window,
+		   NULL);
+      XSetICFocus(fl_xim_ic);
     }
-    if (fl_xim_ic) XSetICFocus(fl_xim_ic);
 #endif
     xfocus = window;
     if (window) {fix_focus(); return true;}
     break;
 
   case FocusOut:
+    if (window && window == xfocus) {
+      xfocus = 0;
+      fix_focus();
 #if USE_XIM
-    if (fl_xim_ic) XUnsetICFocus(fl_xim_ic);
+      if (fl_xim_ic && !focus()) XUnsetICFocus(fl_xim_ic);
 #endif
-    if (window && window == xfocus) {xfocus = 0; fix_focus(); return true;}
+      return true;
+    }
     break;
 
   case KeyPress: {
@@ -1475,11 +1459,11 @@
     NO_XIM:
 #endif
       len = XLookupString(&(xevent.xkey), buffer, buffer_len-1, &keysym, 0);
-      // Make ctrl+dash produce ^_ like it used to:
-      if (xevent.xbutton.state&4 && keysym == '-') buffer[0] = 0x1f;
 #if USE_XIM
     }
 #endif
+    // Make ctrl+dash produce ^_ like it used to:
+    if (len==1 && xevent.xbutton.state&4 && keysym == '-') buffer[0] = 0x1f;
     buffer[len] = 0;
     e_text = buffer;
     e_length = len;
@@ -1554,30 +1538,52 @@
 #endif
       }
     } else {
-      // WHY, OH WHY, do they keep changing the Alt + Meta keys!
-      // Detect all the assignments I have seen and try to map them
-      // back. And now some of them are not setting the shift flags,
-      // so I have to kludge that as well...
+      // Update shift flags to show the results *after* the key. If
+      // this is wrong, the next event will fix them to really what
+      // the X server has.
+      // Also detect the many different assignments that have been done
+      // to the Alt, Meta, and Menu keys. As new arrangments are
+      // discovered they will be added here. Some of the assignments
+      // set the shift keys, some do not.
       switch (keysym) {
+
       case F0Key+13: // F13, wtf? Use this only if F14 does not exist
 	if (XKeysymToKeycode(xdisplay, F0Key+14)) break;
 	// otherwise fall through
       case 0xffeb: // XK_Super_L
 	keysym = LeftMetaKey;
-	break;
+	if (event==KEY) extra_state |= META; else extra_state &= ~META;
+	goto GET_STATE;
+
       case 0xffec: // XK_Super_R
-	keysym = RightMetaKey;
-	break;
       case 0xff20: // XK_Multi_key
 	keysym = RightMetaKey;
-	if (event==KEY) extra_state |= META;
-	else extra_state &= ~META;
-	break;
+	if (event==KEY) extra_state |= META; else extra_state &= ~META;
+	goto GET_STATE;
+
       case 0xff7e: // XK_Mode_switch
 	keysym = RightAltKey;
-	if (event==KEY) extra_state |= ALT;
-	else extra_state &= ~ALT;
-	break;
+	if (event==KEY) extra_state |= ALT; else extra_state &= ~ALT;
+	goto GET_STATE;
+
+      case LeftShiftKey:
+      case RightShiftKey:
+      case LeftCtrlKey:
+      case RightCtrlKey:
+      case CapsLockKey:
+      case LeftMetaKey:
+      case RightMetaKey:
+      case LeftAltKey:
+      case RightAltKey:
+      case NumLockKey:
+      case ScrollLockKey:
+      GET_STATE: {
+	XWindow root = RootWindow(xdisplay, xscreen);
+	XWindow c; int mx,my,cx,cy; unsigned int mask;
+	XQueryPointer(xdisplay,root,&root,&c,&mx,&my,&cx,&cy,&mask);
+	e_state = (mask<<16) | extra_state;
+	break;}
+
       }
     }
     e_keysym = int(keysym);

Direct Link to Message ]
 
     
Previous Message ]Next Message ]
 
 

Comments are owned by the poster. All other content is copyright 1998-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.