diff options
22 files changed, 252 insertions, 250 deletions
diff --git a/FL/Fl_Graphics_Driver.H b/FL/Fl_Graphics_Driver.H index 12f6ecc2c..2898aa527 100644 --- a/FL/Fl_Graphics_Driver.H +++ b/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 a/src/Fl_Graphics_Driver.cxx b/src/Fl_Graphics_Driver.cxx index d0f663877..7575829dc 100644 --- a/src/Fl_Graphics_Driver.cxx +++ b/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 a/src/Fl_Screen_Driver.H b/src/Fl_Screen_Driver.H index 5c08e2af1..f7f927758 100644 --- a/src/Fl_Screen_Driver.H +++ b/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 a/src/Fl_Screen_Driver.cxx b/src/Fl_Screen_Driver.cxx index de925baa5..22008dae2 100644 --- a/src/Fl_Screen_Driver.cxx +++ b/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 a/src/Fl_win32.cxx b/src/Fl_win32.cxx index 51d122aeb..6480aabd4 100644 --- a/src/Fl_win32.cxx +++ b/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 a/src/Fl_x.cxx b/src/Fl_x.cxx index b2fd15d27..67f82af9a 100644 --- a/src/Fl_x.cxx +++ b/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 a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.H b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.H index 74e1a8123..a2303d0be 100644 --- a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.H +++ b/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 a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx index 33f92a6db..01c3b0f95 100644 --- a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx +++ b/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 a/src/drivers/GDI/Fl_GDI_Graphics_Driver.H b/src/drivers/GDI/Fl_GDI_Graphics_Driver.H index c916fc65e..49ad98e21 100644 --- a/src/drivers/GDI/Fl_GDI_Graphics_Driver.H +++ b/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 a/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx b/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx index 0bdc53ffe..87adc44f0 100644 --- a/src/drivers/GDI/Fl_GDI_Graphics_Driver.cxx +++ b/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 a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.H b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.H index a62fae898..b073d633a 100644 --- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.H +++ b/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 a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx index ee9542c21..b50309438 100644 --- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx +++ b/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 a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H index 1a15312ad..a87a59878 100644 --- a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H +++ b/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 a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx index 8ed03f47e..7e7e1f0d7 100644 --- a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx +++ b/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 a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.H b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.H index 6af144fab..c24cad238 100644 --- a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.H +++ b/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 a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx index 4a1cd1bc4..81f6b9258 100644 --- a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx +++ b/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 a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H b/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H index 6754396ff..a2c7719bf 100644 --- a/src/drivers/WinAPI/Fl_WinAPI_Screen_Driver.H +++ b/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 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) diff --git a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H index e22d10691..9e3c44dce 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.H +++ b/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 a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx b/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx index 8a9380486..13a67f428 100644 --- a/src/drivers/Xlib/Fl_Xlib_Graphics_Driver.cxx +++ b/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 a/src/fl_font.cxx b/src/fl_font.cxx index df7df43d7..423c49ab9 100644 --- a/src/fl_font.cxx +++ b/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); } |
