mirror of
https://github.com/fltk/fltk.git
synced 2026-05-23 15:56:10 +08:00
Move input method support to Fl_Screen_Driver from Fl_Graphics_Driver
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user