Move input method support to Fl_Screen_Driver from Fl_Graphics_Driver

This commit is contained in:
ManoloFLTK
2022-06-19 10:23:24 +02:00
parent 232743c3a5
commit 02870242ee
22 changed files with 252 additions and 250 deletions
-4
View File
@@ -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);
-15
View File
@@ -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()
+4
View File
@@ -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
+11
View File
@@ -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
+31 -4
View File
@@ -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) {
+63 -70
View File
@@ -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);
@@ -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_;
};
@@ -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();
}
-1
View File
@@ -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);
@@ -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;
@@ -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 {
@@ -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();
}
@@ -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);
};
@@ -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;
@@ -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();
};
@@ -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;
}
@@ -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);
};
+19 -2
View File
@@ -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);
};
+94 -2
View File
@@ -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)
@@ -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
@@ -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);
+4 -3
View File
@@ -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);
}