|
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 ] | |