
  q2 (2003.09.06)
    - XIM support
    - use Mesa on Red Hat Linux 9

diff -Naurw fox-1.0.45.orig/configure fox-1.0.45-cur/configure
--- fox-1.0.45.orig/configure	2003-08-15 07:25:58.000000000 +0900
+++ fox-1.0.45-cur/configure	2003-08-31 19:05:45.000000000 +0900
@@ -7782,7 +7782,7 @@
     GL_TESTS="gltest glviewer"
     if test "x$MESA" = "xHAVE_MESA" ; then
       CXXFLAGS="${CXXFLAGS} -DHAVE_MESA"
-      GL_LIBS="-lMesaGL -lMesaGLU"
+      GL_LIBS="-lOSMesa -lGLU"
     else
       GL_LIBS="-lGL -lGLU"
     fi
diff -Naurw fox-1.0.45.orig/include/FXApp.h fox-1.0.45-cur/include/FXApp.h
--- fox-1.0.45.orig/include/FXApp.h	2002-01-19 07:42:51.000000000 +0900
+++ fox-1.0.45-cur/include/FXApp.h	2003-09-06 19:44:10.000000000 +0900
@@ -318,6 +318,7 @@
   void addRepaint(FXID win,FXint x,FXint y,FXint w,FXint h,FXbool synth=0);
   void removeRepaints(FXID win,FXint x,FXint y,FXint w,FXint h);
   void scrollRepaints(FXID win,FXint dx,FXint dy);
+  void set_focus_to(FXID window, int revert, FXuint time);
 #else
   void leaveWindow(FXWindow *win,FXWindow *anc);
   void enterWindow(FXWindow *win,FXWindow *anc);
@@ -662,4 +663,8 @@
   virtual ~FXApp();
   };
 
+#if !defined(WIN32) && !defined(NO_XIM)
+extern FXWindow* xic_window;
+#endif
+
 #endif
diff -Naurw fox-1.0.45.orig/src/FXApp.cpp fox-1.0.45-cur/src/FXApp.cpp
--- fox-1.0.45.orig/src/FXApp.cpp	2003-06-21 04:38:40.000000000 +0900
+++ fox-1.0.45-cur/src/FXApp.cpp	2003-09-06 19:44:27.000000000 +0900
@@ -790,6 +790,10 @@
     // What's going on
     FXTRACE((100,"%s::openDisplay: opening display.\n",getClassName()));
 #ifndef WIN32
+      // Preparation for XIM
+      if (!XSupportsLocale())
+          setlocale(LC_ALL, "C");
+      XSetLocaleModifiers("");
 
     // Set error handler
     XSetErrorHandler(xerrorhandler);
@@ -847,15 +851,6 @@
 #ifndef NO_XIM
     xic=NULL;
     xim=(void*)XOpenIM((Display*)display,NULL,NULL,NULL);
-    if(xim){
-#ifndef _AIX
-      xic=XCreateIC((XIM)xim,XNInputStyle,XIMPreeditNothing|XIMStatusNothing,XNClientWindow,XDefaultRootWindow((Display*)display),NULL);
-#else
-      // Suggested by Terry Bezue <terryb@nc.rr.com> for AIX
-      xic=XCreateIC((XIM)xim,XNInputStyle,XIMPreeditNothing|XIMStatusNone,XNClientWindow,XDefaultRootWindow((Display*)display),NULL);
-#endif
-      if(xic) XmbResetIC((XIC)xic);
-      }
 #endif
 
     // Window manager communication
@@ -1083,8 +1078,10 @@
     // Destroy input method context
 #ifndef NO_XIM
     if(xim){
-      if(xic) XDestroyIC((XIC)xic);
+        if (xic) 
+            XDestroyIC((XIC) xic);
       XCloseIM((XIM)xim);
+        xim = xic = NULL;
       }
 #endif
 
@@ -1767,7 +1764,7 @@
   XNextEvent((Display*)display,&ev);
 
   // Filter event through input method context, if any
-  if(xim && XFilterEvent(&ev,XDefaultRootWindow((Display*)display))) return FALSE;
+    if (XFilterEvent(&ev, None)) return FALSE;
 
   // Save expose events for later...
   if(ev.xany.type==Expose || ev.xany.type==GraphicsExpose){
@@ -1883,7 +1880,8 @@
 // Dispatch event to widget
 FXbool FXApp::dispatchEvent(FXRawEvent& ev){
   FXWindow *window;
-  char      buf[20];
+    char* buf = NULL;
+    int buflen;
   KeySym    sym;
   Atom      answer;
   XEvent    se;
@@ -1922,28 +1920,38 @@
         event.root_y=ev.xkey.y_root;
         event.state=ev.xkey.state&~(Button4Mask|Button5Mask);     // Exclude wheel buttons
 
-        // Translate to keysym
-        n=XLookupString(&ev.xkey,buf,sizeof(buf),&sym,NULL);
-        event.code=sym;
-
-        // Translate to string on KeyPress
-        if(ev.xkey.type==KeyPress){
+        buflen = 20;
+        buf = (char*) malloc(buflen);
 #ifndef NO_XIM
           if(xic){
             Status s;
-            n=XmbLookupString((XIC)xic,(XKeyPressedEvent*)&ev.xkey.type,buf,sizeof(buf),&sym,&s);
+            n = XmbLookupString((XIC) xic, &ev.xkey, buf, buflen, &sym, &s);
+            if (s == XBufferOverflow) {
+                free(buf);
+                buflen = n + 1;
+                buf = (char*) malloc(buflen);
+                n = XmbLookupString((XIC) xic, &ev.xkey, buf, buflen, &sym, &s);
+            }
             if(s!=XLookupChars && s!=XLookupBoth) n=0;
             }
+        else {
+            n = XLookupString(&ev.xkey, buf, buflen, &sym, NULL);
+        }
+        event.code = sym;
+#else
+        n = XLookupString(&ev.xkey, buf, buflen, &sym, NULL);
+        event.code = sym;
 #endif
 
+        if(ev.xkey.type==KeyPress) {
           // Replace text string
           event.text.replace(0,1000,buf,n);
           }
-
-        // Clear string on KeyRelease
         else{
+            // Clear string on KeyRelease
           event.text.clear();
           }
+        free(buf); buf = NULL;
 
         // Fix modifier state
         if(ev.xkey.type==KeyPress){
@@ -2258,8 +2266,9 @@
             if(invocation && invocation->window && invocation->window->id()) ev.xclient.window=invocation->window->id();
             // Assign focus to innermost modal dialog, even when trying to focus
             // on another window; these other windows are dead to inputs anyway.
-            // XSetInputFocus causes a spurious BadMatch error; we ignore this in xerrorhandler
-            XSetInputFocus((Display*)display,ev.xclient.window,RevertToParent,ev.xclient.data.l[1]);
+            // XSetInputFocus causes a spurious BadMatch error; we ignore this in
+            // xerrorhandler
+            set_focus_to(ev.xclient.window, RevertToParent, ev.xclient.data.l[1]);
             }
           }
 
@@ -2948,7 +2957,7 @@
 #if defined(__BCPLUSPLUS__) || defined(__BORLANDC__)
   setlocale(LC_CTYPE,"C");  // Locale support broken under Borland C++ 5.5
 #else
-  setlocale(LC_CTYPE,"");
+    setlocale(LC_ALL, "");
 #endif
 
   // Try locate display
@@ -4556,3 +4565,29 @@
   // Do this last
   app=NULL;
   }
+
+
+#ifndef WIN32
+#ifndef NO_XIM
+FXWindow* xic_window = NULL;
+#endif
+
+void FXApp::set_focus_to(FXID window, int revert, FXuint time)
+{
+    XSetInputFocus((Display*) display, window, RevertToPointerRoot, CurrentTime);
+#ifndef NO_XIM
+  if (xim && xic) {
+    FXWindow* w = findWindowWithId(window);
+    while (w && w->getParent()) w = w->getParent();
+    if (w && xic_window != w) {
+      XSetICValues((XIC) xic, XNClientWindow, w->id(),
+                   XNFocusWindow, window, NULL);
+      xic_window = w;
+    }
+    else
+      XSetICValues((XIC) xic, XNFocusWindow, window, NULL);
+    XSetICFocus((XIC)  xic);
+  }
+#endif
+}
+#endif
diff -Naurw fox-1.0.45.orig/src/FXTopWindow.cpp fox-1.0.45-cur/src/FXTopWindow.cpp
--- fox-1.0.45.orig/src/FXTopWindow.cpp	2002-08-08 13:42:04.000000000 +0900
+++ fox-1.0.45-cur/src/FXTopWindow.cpp	2003-09-06 18:35:06.000000000 +0900
@@ -219,6 +219,39 @@
 
       // Set hints
       XSetWMNormalHints(DISPLAY(getApp()),xid,&size);
+
+#ifndef NO_XIM
+        // Create XIC
+        if (getApp()->xim && !getApp()->xic) {
+            static const XIMStyle candidate[] = {
+                (XIMPreeditNothing | XIMStatusNothing),
+                (XIMPreeditNothing | XIMStatusNone),
+                0 };
+            
+            XIMStyle style_selected = 0;
+            XIMStyles* im_styles;
+            XGetIMValues((XIM) getApp()->xim, XNQueryInputStyle, &im_styles, NULL);
+            for (int i = 0; candidate[i]; i++) {
+                for (int j = 0; j < im_styles->count_styles; j++) {
+                    if ((candidate[i] & im_styles->supported_styles[j]) == candidate[i]) {
+                        style_selected = im_styles->supported_styles[j];
+                        goto l1;
+                    }
+                }
+            }
+        l1:
+            XFree(im_styles);
+            if (style_selected) {
+                FXWindow* client = getApp()->mainWindow ? getApp()->mainWindow : this;
+                getApp()->xic = XCreateIC((XIM) getApp()->xim,
+                                          XNInputStyle, style_selected,
+                                          XNClientWindow, client->id(),
+                                          NULL);
+                xic_window = client;
+            }
+            if (getApp()->xic) XmbResetIC((XIC) getApp()->xic);
+        }
+#endif
 #endif
 
       // Set title
@@ -248,7 +281,7 @@
   FXShell::setFocus();
   if(xid){
 #ifndef WIN32
-    XSetInputFocus(DISPLAY(getApp()),xid,RevertToPointerRoot,CurrentTime);
+    getApp()->set_focus_to(xid, RevertToPointerRoot, CurrentTime);
 #else
     SetFocus((HWND)xid);
 #endif
@@ -268,7 +301,8 @@
     if(win==xid){
       if(getOwner() && getOwner()->id()){
         FXTRACE((100,"back to owner\n"));
-        XSetInputFocus(DISPLAY(getApp()),getOwner()->id(),RevertToPointerRoot,CurrentTime);
+        getApp()->set_focus_to(getOwner()->id(), RevertToPointerRoot,
+                               CurrentTime);
         }
       else{
         FXTRACE((100,"back to NULL\n"));
diff -Naurw fox-1.0.45.orig/src/FXWindow.cpp fox-1.0.45-cur/src/FXWindow.cpp
--- fox-1.0.45.orig/src/FXWindow.cpp	2003-06-16 00:23:02.000000000 +0900
+++ fox-1.0.45-cur/src/FXWindow.cpp	2003-08-31 19:05:45.000000000 +0900
@@ -2130,6 +2130,15 @@
     }
   }
 
+#if !defined(WIN32) && !defined(NO_XIM)
+static unsigned int get_im_event_mask(void* im, void* ic)
+{
+    static unsigned int im_event_mask = 0;
+    if (im && ic && !im_event_mask)
+        XGetICValues((XIC) ic, XNFilterEvents, &im_event_mask, NULL);
+    return im_event_mask;
+}
+#endif
 
 // Enable the window
 void FXWindow::enable(){
@@ -2137,7 +2146,12 @@
     flags|=FLAG_ENABLED;
     if(xid){
 #ifndef WIN32
+#ifndef NO_XIM
+        FXuint events = BASIC_EVENT_MASK | ENABLED_EVENT_MASK |
+                        get_im_event_mask(getApp()->xim, getApp()->xic);
+#else
       FXuint events=BASIC_EVENT_MASK|ENABLED_EVENT_MASK;
+#endif
       if(flags&FLAG_SHELL) events|=SHELL_EVENT_MASK;
       XSelectInput(DISPLAY(getApp()),xid,events);
 #else
@@ -2155,7 +2169,11 @@
     flags&=~FLAG_ENABLED;
     if(xid){
 #ifndef WIN32
+#ifndef NO_XIM
+        FXuint events = BASIC_EVENT_MASK | get_im_event_mask(getApp()->xim, getApp()->xic);
+#else
       FXuint events=BASIC_EVENT_MASK;
+#endif
       if(flags&FLAG_SHELL) events|=SHELL_EVENT_MASK;
       XSelectInput(DISPLAY(getApp()),xid,events);
       if(getApp()->mouseGrabWindow==this){
