FLTK logo

[master] 0287024 - Move input method support to Fl_Screen_Driver from Fl_Graphics_Driver

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 ]

[master] 0287024 - Move input method support to Fl_Screen_Driver from Fl_Graphics_Driver "ManoloFLTK" Jun 19, 2022  
 
commit 02870242eea8b729b3dbd6d23eb77372f61c6318
Author:     ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>
AuthorDate: Sun Jun 19 10:23:24 2022 +0200
Commit:     ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>
CommitDate: Sun Jun 19 10:23:24 2022 +0200

    Move input method support to Fl_Screen_Driver from Fl_Graphics_Driver

 FL/Fl_Graphics_Driver.H                            |   4 -
 src/Fl_Graphics_Driver.cxx                         |  15 ---
 src/Fl_Screen_Driver.H                             |   4 +
 src/Fl_Screen_Driver.cxx                           |  11 ++
 src/Fl_win32.cxx                                   |  35 +++++-
 src/Fl_x.cxx                                       | 133 ++++++++++-----------
 src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.H         |   2 +
 src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx       |   8 ++
 src/drivers/GDI/Fl_GDI_Graphics_Driver.H           |   1 -
 src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx         |  37 ------
 src/drivers/Quartz/Fl_Quartz_Graphics_Driver.H     |   2 -
 src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx   |   8 --
 src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H   |   2 -
 src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx |  12 --
 src/drivers/Wayland/Fl_Wayland_Screen_Driver.H     |   2 +
 src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx   |  12 ++
 src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H       |   2 +
 src/drivers/X11/Fl_X11_Screen_Driver.H             |  21 +++-
 src/drivers/X11/Fl_X11_Screen_Driver.cxx           |  96 ++++++++++++++-
 src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H         |   3 -
 src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx       |  85 -------------
 src/fl_font.cxx                                    |   7 +-
 22 files changed, 252 insertions(+), 250 deletions(-)

diff --git FL/Fl_Graphics_Driver.H FL/Fl_Graphics_Driver.H
index 12f6ecc..2898aa5 100644
--- FL/Fl_Graphics_Driver.H
+++ FL/Fl_Graphics_Driver.H
@@ -352,10 +352,6 @@ public:
   virtual float scale_font_for_PostScript(Fl_Font_Descriptor *desc, int s);
   // default implementation may be enough
   virtual float scale_bitmap_for_PostScript();
-  // next 3 are related to X Input Method
-  virtual void set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win);
-  virtual void reset_spot();
-  virtual void set_status(int X, int Y, int W, int H);
   // each platform implements these 3 functions its own way
   virtual void add_rectangle_to_region(Fl_Region r, int x, int y, int w, int h);
   virtual Fl_Region XRectangleRegion(int x, int y, int w, int h);
diff --git src/Fl_Graphics_Driver.cxx src/Fl_Graphics_Driver.cxx
index d0f6638..7575829 100644
--- src/Fl_Graphics_Driver.cxx
+++ src/Fl_Graphics_Driver.cxx
@@ -124,21 +124,6 @@ void Fl_Graphics_Driver::copy_offscreen(int x, int y, int w, int h, Fl_Offscreen
   }
 }
 
-/** see fl_set_spot() */
-void Fl_Graphics_Driver::set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win)
-{
-  // nothing to do, reimplement in driver if needed
-}
-
-void Fl_Graphics_Driver::set_status(int X, int Y, int W, int H) {}
-
-
-/** see fl_reset_spot() */
-void Fl_Graphics_Driver::reset_spot()
-{
-  // nothing to do, reimplement in driver if needed
-}
-
 
 /** Sets the value of the fl_gc global variable when it changes */
 void Fl_Graphics_Driver::global_gc()
diff --git src/Fl_Screen_Driver.H src/Fl_Screen_Driver.H
index 5c08e2a..f7f9277 100644
--- src/Fl_Screen_Driver.H
+++ src/Fl_Screen_Driver.H
@@ -207,6 +207,10 @@ public:
   virtual int clipboard_contains(const char * /*type*/) {return 0;}
   //  implement to support paste-from-clipboard
   virtual void clipboard_notify_change() {}
+  // next 3 are related to Input Methods
+  virtual void set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win);
+  virtual void reset_spot();
+  virtual void set_status(int X, int Y, int W, int H);
 };
 
 #endif // !FL_SCREEN_DRIVER_H
diff --git src/Fl_Screen_Driver.cxx src/Fl_Screen_Driver.cxx
index de925ba..22008da 100644
--- src/Fl_Screen_Driver.cxx
+++ src/Fl_Screen_Driver.cxx
@@ -513,6 +513,17 @@ int Fl_Screen_Driver::parse_color(const char* p, uchar& r, uchar& g, uchar& b)
 
 void Fl_Screen_Driver::default_icons(const Fl_RGB_Image *icons[], int count) {}
 
+
+/** see fl_set_spot() */
+void Fl_Screen_Driver::set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win)
+{}
+
+void Fl_Screen_Driver::set_status(int X, int Y, int W, int H) {}
+
+
+/** see fl_reset_spot() */
+void Fl_Screen_Driver::reset_spot() {}
+
 /**
  \}
  \endcond
diff --git src/Fl_win32.cxx src/Fl_win32.cxx
index 51d122a..6480aab 100644
--- src/Fl_win32.cxx
+++ src/Fl_win32.cxx
@@ -193,13 +193,13 @@ static int get_wsock_mod() {
  */
 static HMODULE s_imm_module = 0;
 typedef BOOL(WINAPI *flTypeImmAssociateContextEx)(HWND, HIMC, DWORD);
-flTypeImmAssociateContextEx flImmAssociateContextEx = 0;
+static flTypeImmAssociateContextEx flImmAssociateContextEx = 0;
 typedef HIMC(WINAPI *flTypeImmGetContext)(HWND);
-flTypeImmGetContext flImmGetContext = 0;
+static flTypeImmGetContext flImmGetContext = 0;
 typedef BOOL(WINAPI *flTypeImmSetCompositionWindow)(HIMC, LPCOMPOSITIONFORM);
-flTypeImmSetCompositionWindow flImmSetCompositionWindow = 0;
+static flTypeImmSetCompositionWindow flImmSetCompositionWindow = 0;
 typedef BOOL(WINAPI *flTypeImmReleaseContext)(HWND, HIMC);
-flTypeImmReleaseContext flImmReleaseContext = 0;
+static flTypeImmReleaseContext flImmReleaseContext = 0;
 
 static void get_imm_module() {
   s_imm_module = LoadLibrary("IMM32.DLL");
@@ -655,6 +655,33 @@ void Fl_WinAPI_Screen_Driver::disable_im() {
   im_enabled = 0;
 }
 
+void Fl_WinAPI_Screen_Driver::set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win)
+{
+  if (!win) return;
+  Fl_Window* tw = win->top_window();
+
+  if (!tw->shown())
+    return;
+
+  HIMC himc = flImmGetContext(fl_xid(tw));
+
+  if (himc) {
+    COMPOSITIONFORM cfs;
+    float s = Fl_Graphics_Driver::default_driver().scale();
+    cfs.dwStyle = CFS_POINT;
+    cfs.ptCurrentPos.x = int(X * s);
+    cfs.ptCurrentPos.y = int(Y * s) - int(tw->labelsize() * s);
+    // Attempt to have temporary text entered by input method use scaled font.
+    // Does good, but still not always effective.
+    Fl_GDI_Font_Descriptor *desc = (Fl_GDI_Font_Descriptor*)Fl_Graphics_Driver::default_driver().font_descriptor();
+    if (desc) SelectObject((HDC)Fl_Graphics_Driver::default_driver().gc(), desc->fid);
+    MapWindowPoints(fl_xid(win), fl_xid(tw), &cfs.ptCurrentPos, 1);
+    flImmSetCompositionWindow(himc, &cfs);
+    flImmReleaseContext(fl_xid(tw), himc);
+  }
+}
+
+
 ////////////////////////////////////////////////////////////////
 
 int Fl_WinAPI_Screen_Driver::get_mouse_unscaled(int &mx, int &my) {
diff --git src/Fl_x.cxx src/Fl_x.cxx
index b2fd15d..67f82af 100644
--- src/Fl_x.cxx
+++ src/Fl_x.cxx
@@ -153,10 +153,6 @@ Window fl_message_window = 0;
 int fl_screen;
 XVisualInfo *fl_visual;
 Colormap fl_colormap;
-static XIM fl_xim_im = 0;
-XIC fl_xim_ic = 0;
-Window fl_xim_win = 0;
-char fl_is_over_the_spot = 0;
 static XRectangle status_area;
 
 static Atom WM_DELETE_WINDOW;
@@ -321,7 +317,7 @@ extern "C" {
 
 extern char *fl_get_font_xfld(int fnum, int size);
 
-static void fl_new_ic()
+void Fl_X11_Screen_Driver::new_ic()
 {
   XVaNestedList preedit_attr = NULL;
   XVaNestedList status_attr = NULL;
@@ -366,7 +362,7 @@ static void fl_new_ic()
                                     XNAreaNeeded, &status_area,
                                     XNFontSet, fs, NULL);
 
-  if (!XGetIMValues(fl_xim_im, XNQueryInputStyle,
+  if (!XGetIMValues(xim_im, XNQueryInputStyle,
                     &xim_styles, NULL, NULL)) {
     int i;
     XIMStyle *style;
@@ -383,65 +379,66 @@ static void fl_new_ic()
   XFree(xim_styles);
 
   if (sarea) {
-    fl_xim_ic = XCreateIC(fl_xim_im,
+    xim_ic = XCreateIC(xim_im,
                           XNInputStyle, (XIMPreeditPosition | XIMStatusArea),
                           XNPreeditAttributes, preedit_attr,
                           XNStatusAttributes, status_attr,
                           NULL);
   }
 
-  if (!fl_xim_ic && predit) {
-    fl_xim_ic = XCreateIC(fl_xim_im,
+  if (!xim_ic && predit) {
+    xim_ic = XCreateIC(xim_im,
                           XNInputStyle, (XIMPreeditPosition | XIMStatusNothing),
                           XNPreeditAttributes, preedit_attr,
                           NULL);
   }
   XFree(preedit_attr);
   XFree(status_attr);
-  if (!fl_xim_ic) {
-    fl_is_over_the_spot = 0;
-    fl_xim_ic = XCreateIC(fl_xim_im,
+  if (!xim_ic) {
+    Fl_X11_Screen_Driver::fl_is_over_the_spot = 0;
+    xim_ic = XCreateIC(xim_im,
                           XNInputStyle, (XIMPreeditNothing | XIMStatusNothing),
                           NULL);
   } else {
-    fl_is_over_the_spot = 1;
+    Fl_X11_Screen_Driver::fl_is_over_the_spot = 1;
     status_attr = XVaCreateNestedList(0, XNAreaNeeded, &status_area, NULL);
 
-    XGetICValues(fl_xim_ic, XNStatusAttributes, status_attr, NULL);
+    XGetICValues(xim_ic, XNStatusAttributes, status_attr, NULL);
     XFree(status_attr);
   }
 }
 
 
-void Fl_Xlib_Graphics_Driver::set_status(int x, int y, int w, int h)
+void Fl_X11_Screen_Driver::set_status(int x, int y, int w, int h)
 {
   XVaNestedList status_attr;
   status_area.x = x;
   status_area.y = y;
   status_area.width = w;
   status_area.height = h;
-  if (!fl_xim_ic) return;
+  if (!xim_ic) return;
   status_attr = XVaCreateNestedList(0, XNArea, &status_area, NULL);
 
-  XSetICValues(fl_xim_ic, XNStatusAttributes, status_attr, NULL);
+  XSetICValues(xim_ic, XNStatusAttributes, status_attr, NULL);
   XFree(status_attr);
 }
 
-static void fl_init_xim() {
+
+void Fl_X11_Screen_Driver::init_xim() {
   static int xim_warning = 2;
   if (xim_warning > 0) xim_warning--;
 
   //XIMStyle *style;
   XIMStyles *xim_styles;
   if (!fl_display) return;
-  if (fl_xim_im) return;
+  if (xim_im) return;
 
-  fl_xim_im = XOpenIM(fl_display, NULL, NULL, NULL);
+  xim_im = XOpenIM(fl_display, NULL, NULL, NULL);
   xim_styles = NULL;
-  fl_xim_ic = NULL;
+  xim_ic = NULL;
 
-  if (fl_xim_im) {
-    XGetIMValues (fl_xim_im, XNQueryInputStyle,
+  if (xim_im) {
+    XGetIMValues (xim_im, XNQueryInputStyle,
                   &xim_styles, NULL, NULL);
   } else {
     if (xim_warning)
@@ -452,61 +449,57 @@ static void fl_init_xim() {
   }
 
   if (xim_styles && xim_styles->count_styles) {
-    fl_new_ic();
+    Fl_X11_Screen_Driver::new_ic();
    } else {
      if (xim_warning)
        Fl::warning("No XIM style found");
-     XCloseIM(fl_xim_im);
-     fl_xim_im = NULL;
+     XCloseIM(xim_im);
+     xim_im = NULL;
      // if xim_styles is allocated, free it now
      if (xim_styles) XFree(xim_styles);
      return;
   }
-  if (!fl_xim_ic) {
+  if (!xim_ic) {
     if (xim_warning)
       Fl::warning("XCreateIC() failed");
-    XCloseIM(fl_xim_im);
-    fl_xim_im = NULL;
+    XCloseIM(xim_im);
+    xim_im = NULL;
   }
   // if xim_styles is still allocated, free it now
   if(xim_styles) XFree(xim_styles);
 }
 
-void fl_xim_deactivate(void);
-
-extern XRectangle fl_spot;
-extern int fl_spotf;
-extern int fl_spots;
 
-void fl_xim_activate(Window xid) {
-  if (!fl_xim_im)
+void Fl_X11_Screen_Driver::xim_activate(Window xid) {
+  if (!xim_im)
     return;
 
   // If the focused window has changed, then use the brute force method
   // of completely recreating the input context.
-  if (fl_xim_win != xid) {
-    fl_xim_deactivate();
+  if (xim_win != xid) {
+    xim_deactivate();
 
-    fl_new_ic();
-    fl_xim_win = xid;
+    Fl_X11_Screen_Driver::new_ic();
+    xim_win = xid;
 
-    XSetICValues(fl_xim_ic,
-                 XNFocusWindow, fl_xim_win,
-                 XNClientWindow, fl_xim_win,
+    XSetICValues(xim_ic,
+                 XNFocusWindow, xim_win,
+                 XNClientWindow, xim_win,
                  NULL);
   }
-
-  fl_set_spot(fl_spotf, fl_spots, fl_spot.x, fl_spot.y, fl_spot.width, fl_spot.height);
+  
+  Fl_X11_Screen_Driver *driver = (Fl_X11_Screen_Driver*)Fl::screen_driver();
+  driver->set_spot(fl_spotf, fl_spots, fl_spot.x, fl_spot.y, fl_spot.width, fl_spot.height, NULL);
 }
 
-void fl_xim_deactivate(void) {
-  if (!fl_xim_ic)
+void Fl_X11_Screen_Driver::xim_deactivate(void) {
+  if (!xim_ic)
     return;
 
-  XDestroyIC(fl_xim_ic);
-  fl_xim_ic = NULL;
+  XDestroyIC(xim_ic);
+  xim_ic = NULL;
 
-  fl_xim_win = 0;
+  xim_win = 0;
 }
 
 void Fl_X11_Screen_Driver::enable_im() {
@@ -514,15 +507,15 @@ void Fl_X11_Screen_Driver::enable_im() {
 
   win = Fl::first_window();
   if (win && win->shown()) {
-    fl_xim_activate(fl_xid(win));
-    XSetICFocus(fl_xim_ic);
+    xim_activate(fl_xid(win));
+    XSetICFocus(xim_ic);
   } else {
-    fl_new_ic();
+    new_ic();
   }
 }
 
 void Fl_X11_Screen_Driver::disable_im() {
-  fl_xim_deactivate();
+  xim_deactivate();
 }
 
 void Fl_X11_Screen_Driver::open_display_platform() {
@@ -607,7 +600,7 @@ void open_display_i(Display* d) {
   templt.visualid = XVisualIDFromVisual(DefaultVisual(d, fl_screen));
   fl_visual = XGetVisualInfo(d, VisualIDMask, &templt, &num);
   fl_colormap = DefaultColormap(d, fl_screen);
-  fl_init_xim();
+  Fl_X11_Screen_Driver::init_xim();
 
 #if !USE_COLORMAP
   Fl::visual(FL_RGB);
@@ -1186,26 +1179,26 @@ int fl_handle(const XEvent& thisevent)
   fl_xevent = &thisevent;
   Window xid = xevent.xany.window;
 
-  if (fl_xim_ic && xevent.type == DestroyNotify &&
-        xid != fl_xim_win && !fl_find(xid))
+  if (Fl_X11_Screen_Driver::xim_ic && xevent.type == DestroyNotify &&
+        xid != Fl_X11_Screen_Driver::xim_win && !fl_find(xid))
   {
     XIM xim_im;
     xim_im = XOpenIM(fl_display, NULL, NULL, NULL);
     if (!xim_im) {
       /*  XIM server has crashed */
       XSetLocaleModifiers("");
-      fl_xim_im = NULL;
-      fl_init_xim();
+      Fl_X11_Screen_Driver::xim_im = NULL;
+      Fl_X11_Screen_Driver::init_xim();
     } else {
       XCloseIM(xim_im); // see STR 2185 for comment
     }
     return 0;
   }
 
-  if (fl_xim_ic && (xevent.type == FocusIn))
-    fl_xim_activate(xid);
+  if (Fl_X11_Screen_Driver::xim_ic && (xevent.type == FocusIn))
+    Fl_X11_Screen_Driver::xim_activate(xid);
 
-  if (fl_xim_ic && XFilterEvent((XEvent *)&xevent, 0))
+  if (Fl_X11_Screen_Driver::xim_ic && XFilterEvent((XEvent *)&xevent, 0))
       return(1);
 
 #if USE_XRANDR
@@ -1616,7 +1609,7 @@ int fl_handle(const XEvent& thisevent)
     return 1;
 
   case FocusIn:
-    if (fl_xim_ic) XSetICFocus(fl_xim_ic);
+    if (Fl_X11_Screen_Driver::xim_ic) XSetICFocus(Fl_X11_Screen_Driver::xim_ic);
     event = FL_FOCUS;
     // If the user has toggled from another application to this one,
     // then it's a good time to check for clipboard changes.
@@ -1624,7 +1617,7 @@ int fl_handle(const XEvent& thisevent)
     break;
 
   case FocusOut:
-    if (fl_xim_ic) XUnsetICFocus(fl_xim_ic);
+    if (Fl_X11_Screen_Driver::xim_ic) XUnsetICFocus(Fl_X11_Screen_Driver::xim_ic);
     event = FL_UNFOCUS;
     break;
 
@@ -1644,15 +1637,15 @@ int fl_handle(const XEvent& thisevent)
       event = FL_KEYDOWN;
 
       int len;
-      if (fl_xim_ic) {
+      if (Fl_X11_Screen_Driver::xim_ic) {
         Status status;
-        len = XUtf8LookupString(fl_xim_ic, (XKeyPressedEvent *)&xevent.xkey,
+        len = XUtf8LookupString(Fl_X11_Screen_Driver::xim_ic, (XKeyPressedEvent *)&xevent.xkey,
                              kp_buffer, kp_buffer_len, &keysym, &status);
 
         while (status == XBufferOverflow && kp_buffer_len < 50000) {
           kp_buffer_len = kp_buffer_len * 5 + 1;
           kp_buffer = (char*)realloc(kp_buffer, kp_buffer_len);
-          len = XUtf8LookupString(fl_xim_ic, (XKeyPressedEvent *)&xevent.xkey,
+          len = XUtf8LookupString(Fl_X11_Screen_Driver::xim_ic, (XKeyPressedEvent *)&xevent.xkey,
                              kp_buffer, kp_buffer_len, &keysym, &status);
         }
         keysym = fl_KeycodeToKeysym(fl_display, keycode, 0);
@@ -1925,8 +1918,8 @@ int fl_handle(const XEvent& thisevent)
 #endif // FLTK_CONSOLIDATE_MOTION
     in_a_window = true;
     { XIMStyles *xim_styles = NULL;
-      if(!fl_xim_im || XGetIMValues(fl_xim_im, XNQueryInputStyle, &xim_styles, NULL, NULL)) {
-        fl_init_xim();
+      if(!Fl_X11_Screen_Driver::xim_im || XGetIMValues(Fl_X11_Screen_Driver::xim_im, XNQueryInputStyle, &xim_styles, NULL, NULL)) {
+        Fl_X11_Screen_Driver::init_xim();
       }
       if (xim_styles) XFree(xim_styles);
     }
@@ -2063,7 +2056,7 @@ void Fl_X11_Window_Driver::resize(int X,int Y,int W,int H) {
     if (shown()) {pWindow->redraw();}
   } else {
     x(X); y(Y);
-    if (fl_xim_win && Fl::focus()) {
+    if (Fl_X11_Screen_Driver::xim_win && Fl::focus()) {
       // Force the Input Method auxiliary window to move too.
       Fl::focus()->handle(FL_FOCUS);
       fl_set_spot(fl_font(), fl_size(), Fl::focus()->x(), Fl::focus()->y() + fl_size(), Fl::focus()->w(), Fl::focus()->h(), NULL);
diff --git src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.H src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.H
index 74e1a81..a2303d0 100644
--- src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.H
+++ src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.H
@@ -100,6 +100,8 @@ public:
   virtual void copy(const char *stuff, int len, int clipboard, const char *type);
   virtual void paste(Fl_Widget &receiver, int clipboard, const char *type);
   virtual int clipboard_contains(const char *type);
+  virtual void set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win);
+  virtual void reset_spot();
 private:
   float scale_;
 };
diff --git src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx
index 33f92a6..01c3b0f 100644
--- src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx
+++ src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx
@@ -381,3 +381,11 @@ Fl_RGB_Image *Fl_Cocoa_Screen_Driver::read_win_rectangle(int X, int Y, int w, in
   rgb->alloc_array = 1;
   return rgb;
 }
+
+void Fl_Cocoa_Screen_Driver::set_spot(int /*font*/, int size, int X, int Y, int /*W*/, int /*H*/, Fl_Window* /*win*/) {
+  Fl_Cocoa_Screen_Driver::insertion_point_location(X, Y, size);
+}
+
+void Fl_Cocoa_Screen_Driver::reset_spot() {
+  Fl_Cocoa_Screen_Driver::reset_marked_text();
+}
diff --git src/drivers/GDI/Fl_GDI_Graphics_Driver.H src/drivers/GDI/Fl_GDI_Graphics_Driver.H
index c916fc6..49ad98e 100644
--- src/drivers/GDI/Fl_GDI_Graphics_Driver.H
+++ src/drivers/GDI/Fl_GDI_Graphics_Driver.H
@@ -143,7 +143,6 @@ protected:
   void color(uchar r, uchar g, uchar b);
   void set_color(Fl_Color i, unsigned int c);
   void free_color(Fl_Color i, int overlay);
-  void set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win);
   virtual Fl_Font set_fonts(const char *name);
   virtual int get_font_sizes(Fl_Font fnum, int*& sizep);
   virtual const char* get_font_name(Fl_Font fnum, int* ap);
diff --git src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx
index 0bdc53f..87adc44 100644
--- src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx
+++ src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx
@@ -245,43 +245,6 @@ void Fl_GDI_Graphics_Driver::XDestroyRegion(Fl_Region r) {
 }
 
 
-typedef BOOL(WINAPI* flTypeImmAssociateContextEx)(HWND, HIMC, DWORD);
-extern flTypeImmAssociateContextEx flImmAssociateContextEx;
-typedef HIMC(WINAPI* flTypeImmGetContext)(HWND);
-extern flTypeImmGetContext flImmGetContext;
-typedef BOOL(WINAPI* flTypeImmSetCompositionWindow)(HIMC, LPCOMPOSITIONFORM);
-extern flTypeImmSetCompositionWindow flImmSetCompositionWindow;
-typedef BOOL(WINAPI* flTypeImmReleaseContext)(HWND, HIMC);
-extern flTypeImmReleaseContext flImmReleaseContext;
-
-
-void Fl_GDI_Graphics_Driver::set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win)
-{
-  if (!win) return;
-  Fl_Window* tw = win->top_window();
-
-  if (!tw->shown())
-    return;
-
-  HIMC himc = flImmGetContext(fl_xid(tw));
-
-  if (himc) {
-    COMPOSITIONFORM cfs;
-    float s = scale();
-    cfs.dwStyle = CFS_POINT;
-    cfs.ptCurrentPos.x = int(X * s);
-    cfs.ptCurrentPos.y = int(Y * s) - int(tw->labelsize() * s);
-    // Attempt to have temporary text entered by input method use scaled font.
-    // Does good, but still not always effective.
-    Fl_GDI_Font_Descriptor *desc = (Fl_GDI_Font_Descriptor*)font_descriptor();
-    if (desc) SelectObject((HDC)gc(), desc->fid);
-    MapWindowPoints(fl_xid(win), fl_xid(tw), &cfs.ptCurrentPos, 1);
-    flImmSetCompositionWindow(himc, &cfs);
-    flImmReleaseContext(fl_xid(tw), himc);
-  }
-}
-
-
 void Fl_GDI_Graphics_Driver::scale(float f) {
   if (f != scale()) {
     size_ = 0;
diff --git src/drivers/Quartz/Fl_Quartz_Graphics_Driver.H src/drivers/Quartz/Fl_Quartz_Graphics_Driver.H
index a62fae8..b073d63 100644
--- src/drivers/Quartz/Fl_Quartz_Graphics_Driver.H
+++ src/drivers/Quartz/Fl_Quartz_Graphics_Driver.H
@@ -173,8 +173,6 @@ protected:
   virtual void restore_scale(float);
   virtual void antialias(int state);
   virtual int antialias();
-  virtual void set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win);
-  virtual void reset_spot();
 };
 
 class Fl_Quartz_Printer_Graphics_Driver : public Fl_Quartz_Graphics_Driver {
diff --git src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx
index ee9542c..b503094 100644
--- src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx
+++ src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx
@@ -174,11 +174,3 @@ void Fl_Quartz_Graphics_Driver::restore_scale(float s) {
     CGContextScaleCTM(gc_, s, s);
   }
 }
-
-void Fl_Quartz_Graphics_Driver::set_spot(int /*font*/, int size, int X, int Y, int /*W*/, int /*H*/, Fl_Window* /*win*/) {
-  Fl_Cocoa_Screen_Driver::insertion_point_location(X, Y, size);
-}
-
-void Fl_Quartz_Graphics_Driver::reset_spot() {
-  Fl_Cocoa_Screen_Driver::reset_marked_text();
-}
diff --git src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H
index 1a15312..a87a598 100644
--- src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H
+++ src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H
@@ -81,8 +81,6 @@ public:
   static void buffer_release(struct wld_window *window);
   static void buffer_commit(struct wld_window *window);
   static void cairo_init(struct fl_wld_buffer *buffer, int width, int height, int stride, cairo_format_t format);
-  void set_spot(int font, int height, int x, int y, int w, int h, Fl_Window *win);
-  void reset_spot();
   virtual void *gc();
   virtual void gc(void *gc);
 };
diff --git src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx
index 8ed03f4..7e7e1f0 100644
--- src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx
+++ src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx
@@ -144,18 +144,6 @@ void Fl_Wayland_Graphics_Driver::set_color(Fl_Color i, unsigned c) {
 }
 
 
-void Fl_Wayland_Graphics_Driver::set_spot(int font, int height, int x, int y, int w, int h, Fl_Window *win) {
-  Fl_Wayland_Screen_Driver::insertion_point_location(x, y, height);
-}
-
-
-void Fl_Wayland_Graphics_Driver::reset_spot() {
-  Fl::compose_state = 0;
-  Fl_Wayland_Screen_Driver::next_marked_length = 0;
-  Fl_Wayland_Screen_Driver::insertion_point_location_is_valid = false;
-}
-
-
 void Fl_Wayland_Graphics_Driver::copy_offscreen(int x, int y, int w, int h, Fl_Offscreen osrc, int srcx, int srcy) {
   // draw portion srcx,srcy,w,h of osrc to position x,y (top-left) of the graphics driver's surface
   int height = osrc->data_size / osrc->stride;
diff --git src/drivers/Wayland/Fl_Wayland_Screen_Driver.H src/drivers/Wayland/Fl_Wayland_Screen_Driver.H
index 6af144f..c24cad2 100644
--- src/drivers/Wayland/Fl_Wayland_Screen_Driver.H
+++ src/drivers/Wayland/Fl_Wayland_Screen_Driver.H
@@ -170,6 +170,8 @@ public:
   static bool own_output(struct wl_output *output);
   typedef enum {unspecified, MUTTER, WESTON, KDE} compositor_name;
   static compositor_name compositor; // identifies the used Wayland compositor
+  void set_spot(int font, int height, int x, int y, int w, int h, Fl_Window *win);
+  void reset_spot();
 };
 
 
diff --git src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx
index 4a1cd1b..81f6b92 100644
--- src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx
+++ src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx
@@ -1429,3 +1429,15 @@ int Fl_Wayland_Screen_Driver::get_mouse(int &xx, int &yy) {
   yy = yy/s;
   return snum;
 }
+
+
+void Fl_Wayland_Screen_Driver::set_spot(int font, int height, int x, int y, int w, int h, Fl_Window *win) {
+  Fl_Wayland_Screen_Driver::insertion_point_location(x, y, height);
+}
+
+
+void Fl_Wayland_Screen_Driver::reset_spot() {
+  Fl::compose_state = 0;
+  Fl_Wayland_Screen_Driver::next_marked_length = 0;
+  Fl_Wayland_Screen_Driver::insertion_point_location_is_valid = false;
+}
diff --git src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H
index 6754396..a2c7719 100644
--- src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H
+++ src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H
@@ -92,6 +92,8 @@ public:
   virtual int clipboard_contains(const char *type);
   // this one is implemented in Fl_win32.cxx
   virtual void clipboard_notify_change();
+  // this one is implemented in Fl_win32.cxx
+  void set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win);
 };
 
 
diff --git src/drivers/X11/Fl_X11_Screen_Driver.H src/drivers/X11/Fl_X11_Screen_Driver.H
index 4b877c9..ead6530 100644
--- src/drivers/X11/Fl_X11_Screen_Driver.H
+++ src/drivers/X11/Fl_X11_Screen_Driver.H
@@ -25,6 +25,7 @@
 
 #include <config.h>
 #include "../../Fl_Screen_Driver.H"
+#include <X11/Xlib.h>
 
 
 class Fl_Window;
@@ -87,8 +88,7 @@ public:
   virtual int text_display_can_leak() const;
   virtual Fl_RGB_Image *read_win_rectangle(int X, int Y, int w, int h, Fl_Window *win, bool may_capture_subwins, bool *did_capture_subwins);
   virtual int get_mouse(int &x, int &y);
-  virtual void enable_im();
-  virtual void disable_im();
+
   virtual void open_display_platform();
   virtual void close_display();
   // --- compute dimensions of an Fl_Offscreen
@@ -102,6 +102,23 @@ public:
   virtual int clipboard_contains(const char *type);
   // this one is in Fl_x.cxx
   virtual void clipboard_notify_change();
+  // for support of input methods
+  static char fl_is_over_the_spot;
+  static XRectangle fl_spot;
+  static int fl_spotf;
+  static int fl_spots;
+  static XIM xim_im;
+  static XIC xim_ic;
+  static Window xim_win;
+  static void new_ic();
+  static void xim_activate(Window xid);
+  static void xim_deactivate(void);
+  static void init_xim();
+  virtual void enable_im();
+  virtual void disable_im();
+  virtual void set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win);
+  virtual void reset_spot();
+  virtual void set_status(int X, int Y, int W, int H);
 };
 
 
diff --git src/drivers/X11/Fl_X11_Screen_Driver.cxx src/drivers/X11/Fl_X11_Screen_Driver.cxx
index 3c942d6..b1a62b2 100644
--- src/drivers/X11/Fl_X11_Screen_Driver.cxx
+++ src/drivers/X11/Fl_X11_Screen_Driver.cxx
@@ -49,7 +49,6 @@
 #endif // DEBUG
 
 extern Atom fl_NET_WORKAREA;
-extern XIC fl_xim_ic; // in Fl_x.cxx
 
 // these are set by Fl::args() and override any system colors: from Fl_get_system_colors.cxx
 extern const char *fl_fg;
@@ -58,6 +57,18 @@ extern const char *fl_bg2;
 // end of extern additions workaround
 
 
+XIM Fl_X11_Screen_Driver::xim_im = 0;
+
+XIC Fl_X11_Screen_Driver::xim_ic = 0;
+
+int Fl_X11_Screen_Driver::fl_spotf = -1;
+int Fl_X11_Screen_Driver::fl_spots = -1;
+XRectangle Fl_X11_Screen_Driver::fl_spot;
+char Fl_X11_Screen_Driver::fl_is_over_the_spot = 0;
+
+Window Fl_X11_Screen_Driver::xim_win = 0;
+
+
 void Fl_X11_Screen_Driver::display(const char *d)
 {
   if (d) setenv("DISPLAY", d, 1);
@@ -486,7 +497,7 @@ int Fl_X11_Screen_Driver::compose(int& del) {
 void Fl_X11_Screen_Driver::compose_reset()
 {
   Fl::compose_state = 0;
-  if (fl_xim_ic) XmbResetIC(fl_xim_ic);
+  if (xim_ic) XmbResetIC(xim_ic);
 }
 
 int Fl_X11_Screen_Driver::text_display_can_leak() const {
@@ -976,6 +987,87 @@ void Fl_X11_Screen_Driver::offscreen_size(Fl_Offscreen off, int &width, int &hei
   height = (int)h;
 }
 
+
+void Fl_X11_Screen_Driver::reset_spot(void)
+{
+  fl_spot.x = -1;
+  fl_spot.y = -1;
+  //if (xim_ic) XUnsetICFocus(xim_ic);
+}
+
+
+void Fl_X11_Screen_Driver::set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win)
+{
+  int change = 0;
+  XVaNestedList preedit_attr;
+  static XFontSet fs = NULL;
+  char **missing_list;
+  int missing_count;
+  char *def_string;
+  char *fnt = NULL;
+  bool must_free_fnt =true;
+
+  static XIC ic = NULL;
+
+  if (!xim_ic || !fl_is_over_the_spot) return;
+  if (Fl::focus()) { // handle case when text widget is inside subwindow
+    Fl_Window *focuswin = Fl::focus()->window();
+    while (focuswin && focuswin->parent()) {
+      X += focuswin->x(); Y += focuswin->y();
+      focuswin = focuswin->window();
+    }
+  }
+  //XSetICFocus(xim_ic);
+  if (X != fl_spot.x || Y != fl_spot.y) {
+    fl_spot.x = X;
+    fl_spot.y = Y;
+    fl_spot.height = H;
+    fl_spot.width = W;
+    change = 1;
+  }
+  if (font != fl_spotf || size != fl_spots) {
+    fl_spotf = font;
+    fl_spots = size;
+    change = 1;
+    if (fs) {
+      XFreeFontSet(fl_display, fs);
+    }
+#if USE_XFT
+
+#if defined(__GNUC__)
+    // FIXME: warning XFT support here
+#endif /*__GNUC__*/
+
+    fnt = NULL; // fl_get_font_xfld(font, size);
+    if (!fnt) {fnt = (char*)"-misc-fixed-*";must_free_fnt=false;}
+    fs = XCreateFontSet(fl_display, fnt, &missing_list,
+                        &missing_count, &def_string);
+#else
+    fnt = fl_get_font_xfld(font, size);
+    if (!fnt) {fnt = (char*)"-misc-fixed-*";must_free_fnt=false;}
+    fs = XCreateFontSet(fl_display, fnt, &missing_list,
+                        &missing_count, &def_string);
+#endif
+  }
+  if (xim_ic != ic) {
+    ic = xim_ic;
+    change = 1;
+  }
+
+  if (fnt && must_free_fnt) free(fnt);
+  if (!change) return;
+
+  float s = Fl_Graphics_Driver::default_driver().scale();
+  XRectangle fl_spot_unscaled = { short(fl_spot.x * s), short(fl_spot.y * s),
+    (unsigned short)(fl_spot.width * s), (unsigned short)(fl_spot.height * s) };
+  preedit_attr = XVaCreateNestedList(0,
+                                     XNSpotLocation, &fl_spot_unscaled,
+                                     XNFontSet, fs, NULL);
+  XSetICValues(xim_ic, XNPreeditAttributes, preedit_attr, NULL);
+  XFree(preedit_attr);
+}
+
+
 #if USE_XFT
 //NOTICE: returns -1 if x,y is not in any screen
 int Fl_X11_Screen_Driver::screen_num_unscaled(int x, int y)
diff --git src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H
index e22d106..9e3c44d 100644
--- src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H
+++ src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H
@@ -205,9 +205,6 @@ protected:
   void color(uchar r, uchar g, uchar b);
   virtual float scale_font_for_PostScript(Fl_Font_Descriptor *desc, int s);
   virtual float scale_bitmap_for_PostScript();
-  virtual void set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win);
-  virtual void reset_spot();
-  virtual void set_status(int X, int Y, int W, int H);
   virtual const char* get_font_name(Fl_Font fnum, int* ap);
   virtual int get_font_sizes(Fl_Font fnum, int*& sizep);
 #if !USE_XFT
diff --git src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx
index 8a93804..13a67f4 100644
--- src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx
+++ src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx
@@ -24,8 +24,6 @@
 #include <string.h>
 #include <stdlib.h>
 
-extern XIC fl_xim_ic;
-extern char fl_is_over_the_spot;
 #if !USE_XFT
 extern char *fl_get_font_xfld(int fnum, int size);
 #endif
@@ -100,89 +98,6 @@ void Fl_Xlib_Graphics_Driver::fixloop() {  // remove equal points from closed pa
   while (n>2 && short_point[n-1].x == short_point[0].x && short_point[n-1].y == short_point[0].y) n--;
 }
 
-// FIXME: should be members of Fl_Xlib_Graphics_Driver
-XRectangle fl_spot;
-int fl_spotf = -1;
-int fl_spots = -1;
-
-void Fl_Xlib_Graphics_Driver::reset_spot(void)
-{
-  fl_spot.x = -1;
-  fl_spot.y = -1;
-  //if (fl_xim_ic) XUnsetICFocus(fl_xim_ic);
-}
-
-void Fl_Xlib_Graphics_Driver::set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win)
-{
-  int change = 0;
-  XVaNestedList preedit_attr;
-  static XFontSet fs = NULL;
-  char **missing_list;
-  int missing_count;
-  char *def_string;
-  char *fnt = NULL;
-  bool must_free_fnt =true;
-
-  static XIC ic = NULL;
-
-  if (!fl_xim_ic || !fl_is_over_the_spot) return;
-  if (Fl::focus()) { // handle case when text widget is inside subwindow
-    Fl_Window *focuswin = Fl::focus()->window();
-    while (focuswin && focuswin->parent()) {
-      X += focuswin->x(); Y += focuswin->y();
-      focuswin = focuswin->window();
-    }
-  }
-  //XSetICFocus(fl_xim_ic);
-  if (X != fl_spot.x || Y != fl_spot.y) {
-    fl_spot.x = X;
-    fl_spot.y = Y;
-    fl_spot.height = H;
-    fl_spot.width = W;
-    change = 1;
-  }
-  if (font != fl_spotf || size != fl_spots) {
-    fl_spotf = font;
-    fl_spots = size;
-    change = 1;
-    if (fs) {
-      XFreeFontSet(fl_display, fs);
-    }
-#if USE_XFT
-
-#if defined(__GNUC__)
-    // FIXME: warning XFT support here
-#endif /*__GNUC__*/
-
-    fnt = NULL; // fl_get_font_xfld(font, size);
-    if (!fnt) {fnt = (char*)"-misc-fixed-*";must_free_fnt=false;}
-    fs = XCreateFontSet(fl_display, fnt, &missing_list,
-                        &missing_count, &def_string);
-#else
-    fnt = fl_get_font_xfld(font, size);
-    if (!fnt) {fnt = (char*)"-misc-fixed-*";must_free_fnt=false;}
-    fs = XCreateFontSet(fl_display, fnt, &missing_list,
-                        &missing_count, &def_string);
-#endif
-  }
-  if (fl_xim_ic != ic) {
-    ic = fl_xim_ic;
-    change = 1;
-  }
-
-  if (fnt && must_free_fnt) free(fnt);
-  if (!change) return;
-
-  float s = scale();
-  XRectangle fl_spot_unscaled = { short(fl_spot.x * s), short(fl_spot.y * s),
-    (unsigned short)(fl_spot.width * s), (unsigned short)(fl_spot.height * s) };
-  preedit_attr = XVaCreateNestedList(0,
-                                     XNSpotLocation, &fl_spot_unscaled,
-                                     XNFontSet, fs, NULL);
-  XSetICValues(fl_xim_ic, XNPreeditAttributes, preedit_attr, NULL);
-  XFree(preedit_attr);
-}
-
 #if !USE_XFT
 unsigned Fl_Xlib_Graphics_Driver::font_desc_size() {
   return (unsigned)sizeof(Fl_Xlib_Fontdesc);
diff --git src/fl_font.cxx src/fl_font.cxx
index df7df43..423c49a 100644
--- src/fl_font.cxx
+++ src/fl_font.cxx
@@ -18,6 +18,7 @@
 // Select fonts from the FLTK font table.
 #include "flstring.h"
 #include <FL/fl_draw.H>
+#include "Fl_Screen_Driver.H"
 
 // -----------------------------------------------------------------------------
 // all driver code is now in drivers/XXX/Fl_XXX_Graphics_Driver_xyz.cxx
@@ -51,15 +52,15 @@ void fl_draw(const char* str, int l, float x, float y) {
 
 void fl_set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win)
 {
-  Fl_Graphics_Driver::default_driver().set_spot(font, size, X, Y, W, H, win);
+  Fl::screen_driver()->set_spot(font, size, X, Y, W, H, win);
 }
 
 void fl_reset_spot()
 {
-  Fl_Graphics_Driver::default_driver().reset_spot();
+  Fl::screen_driver()->reset_spot();
 }
 
 void fl_set_status(int X, int Y, int W, int H)
 {
-  Fl_Graphics_Driver::default_driver().set_status(X, Y, W, H);
+  Fl::screen_driver()->set_status(X, Y, W, H);
 }
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'.