diff options
| author | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2022-06-19 10:23:24 +0200 |
|---|---|---|
| committer | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2022-06-19 10:23:24 +0200 |
| commit | 02870242eea8b729b3dbd6d23eb77372f61c6318 (patch) | |
| tree | 1c754a9b01c71b3e68aa795469c30b6c32074e17 /src/drivers/X11 | |
| parent | 232743c3a5d903be813f6c4445f3f96bab25cae0 (diff) | |
Move input method support to Fl_Screen_Driver from Fl_Graphics_Driver
Diffstat (limited to 'src/drivers/X11')
| -rw-r--r-- | src/drivers/X11/Fl_X11_Screen_Driver.H | 21 | ||||
| -rw-r--r-- | src/drivers/X11/Fl_X11_Screen_Driver.cxx | 96 |
2 files changed, 113 insertions, 4 deletions
diff --git a/src/drivers/X11/Fl_X11_Screen_Driver.H b/src/drivers/X11/Fl_X11_Screen_Driver.H index 4b877c937..ead653078 100644 --- a/src/drivers/X11/Fl_X11_Screen_Driver.H +++ b/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 a/src/drivers/X11/Fl_X11_Screen_Driver.cxx b/src/drivers/X11/Fl_X11_Screen_Driver.cxx index 3c942d654..b1a62b29e 100644 --- a/src/drivers/X11/Fl_X11_Screen_Driver.cxx +++ b/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) |
