[oe-commits] org.oe.dev mb-applet-inputmanager: apply patch from Phil Blundell to pop up input method on focus
koen commit
openembedded-commits at lists.openembedded.org
Sat Nov 11 13:20:08 UTC 2006
mb-applet-inputmanager: apply patch from Phil Blundell to pop up input method on focus
* requires libgtkinput to be loaded
* see http://www.nabble.com/libgtkinput-t971843.html
* this also brings mbinputmgr-tray.c in sync with o-hand svn rev 1163
Author: koen at openembedded.org
Branch: org.openembedded.dev
Revision: 06d5f378407afd328215f36092ee46fc94696cf2
ViewMTN: http://monotone.openembedded.org/revision.psp?id=06d5f378407afd328215f36092ee46fc94696cf2
Files:
1
packages/matchbox-applet-inputmanager/files
packages/matchbox-applet-inputmanager/files/mbinputmgr-libgtkinput.patch
packages/matchbox-applet-inputmanager/files/mbinputmgr-tray.c
packages/matchbox-applet-inputmanager/files/update-to-svn.diff
packages/matchbox-applet-inputmanager/matchbox-applet-inputmanager_0.6.bb
Diffs:
#
# mt diff -re70382d5e407f3e867cf9fe07a2a0b85eede0819 -r06d5f378407afd328215f36092ee46fc94696cf2
#
#
#
# add_dir "packages/matchbox-applet-inputmanager/files"
#
# add_file "packages/matchbox-applet-inputmanager/files/mbinputmgr-libgtkinput.patch"
# content [6c51831f35fe2bf7262955d439787fce00889177]
#
# add_file "packages/matchbox-applet-inputmanager/files/mbinputmgr-tray.c"
# content [3b581f789193a21efcb4529c8a6880c88b9013af]
#
# add_file "packages/matchbox-applet-inputmanager/files/update-to-svn.diff"
# content [18382c045a110e690421c6dd8b478583eb6f134d]
#
# patch "packages/matchbox-applet-inputmanager/matchbox-applet-inputmanager_0.6.bb"
# from [a8df8864f8d00f995504c2a77f2da9168d8ccb17]
# to [591cdf89b3be6c04c6b13c30f1af898de7af6d6b]
#
============================================================
--- packages/matchbox-applet-inputmanager/files/mbinputmgr-libgtkinput.patch 6c51831f35fe2bf7262955d439787fce00889177
+++ packages/matchbox-applet-inputmanager/files/mbinputmgr-libgtkinput.patch 6c51831f35fe2bf7262955d439787fce00889177
@@ -0,0 +1,350 @@
+Index: mb-applet-input-manager-0.6/mbinputmgr-tray.c
+===================================================================
+--- mb-applet-input-manager-0.6/mbinputmgr-tray.c (revision 1292)
++++ mb-applet-input-manager-0.6/mbinputmgr-tray.c (working copy)
+@@ -32,8 +32,20 @@
+ MBInpmgrState *Inpmgr_state = NULL;
+ Bool ButtonIsDown = False;
+ int ButtonActive;
+-Atom AtomIMActivate;
+
++Atom atoms[2];
++char *atom_names[] =
++ {
++ "_MB_INPUT_REQUEST",
++ "_GPE_INPUT_MANAGER"
++ };
++
++#define _MB_INPUT_REQUEST 0
++#define _GPE_INPUT_MANAGER 1
++
++#define _GPE_INPUT_MANAGER_OPEN 1
++#define _GPE_INPUT_MANAGER_CLOSE 2
++
+ typedef struct ButtonImgs {
+
+ MBPixbufImage *active;
+@@ -41,6 +53,17 @@
+
+ } ButtonImgs;
+
++struct window_record
++{
++ Window w;
++ struct window_record *next;
++};
++
++struct window_record *requests;
++
++Display *dpy;
++Bool auto_enabled;
++
+ void
+ paint_callback ( MBTrayApp *app, Drawable drw )
+ {
+@@ -262,14 +285,190 @@
+ }
+
+ void
++really_close (void)
++{
++ if (requests == NULL && mbinputmgr_method_active (Inpmgr_state) && auto_enabled)
++ {
++ mbinputmgr_toggle_selected_method (Inpmgr_state);
++ auto_enabled = False;
++ }
++}
++
++Bool timer_active;
++struct timeval expires;
++
++Bool
++get_timeout (struct timeval *tv)
++{
++ int sec, usec;
++ struct timeval now;
++
++ if (!timer_active)
++ return False;
++
++ gettimeofday (&now, NULL);
++
++ sec = expires.tv_sec - now.tv_sec;
++ usec = expires.tv_usec - now.tv_usec;
++ if (usec < 0)
++ {
++ sec--;
++ usec += 1000000;
++ }
++
++ if (sec < 0)
++ {
++ /* timer expired */
++ really_close ();
++ timer_active = False;
++ return False;
++ }
++
++ tv->tv_sec = sec;
++ tv->tv_usec = usec;
++
++ return True;
++}
++
++Bool
++process_close_request (Window w)
++{
++ struct window_record *r, *pr = NULL;
++ unsigned long tv;
++
++ for (r = requests; r != NULL && r->w != w; )
++ {
++ pr = r;
++ r = r->next;
++ }
++
++ if (r)
++ {
++ if (pr)
++ pr->next = r->next;
++ else
++ requests = r->next;
++
++ free (r);
++
++ if (requests == NULL && mbinputmgr_method_active (Inpmgr_state) && auto_enabled)
++ {
++ timer_active = True;
++ gettimeofday (&expires, NULL);
++ expires.tv_usec += 100000;
++ if (expires.tv_usec >= 1000000)
++ {
++ expires.tv_sec++;
++ expires.tv_usec -= 1000000;
++ }
++ }
++
++ return True;
++ }
++
++ return False;
++}
++
++int trapped_error_code;
++int (*old_error_handler) (Display *d, XErrorEvent *e);
++
++static int
++error_handler(Display *display,
++ XErrorEvent *error)
++{
++ trapped_error_code = error->error_code;
++ return 0;
++}
++
++static void
++trap_errors(void)
++{
++ trapped_error_code = 0;
++ old_error_handler = XSetErrorHandler(error_handler);
++}
++
++static int
++untrap_errors(void)
++{
++ XSetErrorHandler(old_error_handler);
++ return trapped_error_code;
++}
++
++Bool
++process_open_request (Window w)
++{
++ struct window_record *r;
++
++ for (r = requests; r != NULL && r->w != w; r = r->next)
++ ;
++
++ if (r)
++ return True;
++
++ trap_errors ();
++ XSelectInput (dpy, w, StructureNotifyMask);
++ XSync (dpy, False);
++ if (untrap_errors ())
++ return False;
++
++ r = malloc (sizeof (*r));
++ r->next = requests;
++ r->w = w;
++ requests = r;
++
++ if (!mbinputmgr_method_active(Inpmgr_state))
++ {
++ mbinputmgr_toggle_selected_method (Inpmgr_state);
++ auto_enabled = True;
++ }
++
++ return False;
++}
++
++Bool docked_already;
++
++void
++is_docked (void)
++{
++ Window tray_w;
++
++ tray_w = mb_tray_app_xwin (app);
++
++ if (XGetSelectionOwner (dpy, atoms[_GPE_INPUT_MANAGER]) == None)
++ {
++ XSetSelectionOwner (dpy, atoms[_GPE_INPUT_MANAGER], tray_w, CurrentTime);
++ }
++ else
++ {
++ fprintf (stderr, "Unable to claim _GPE_INPUT_MANAGER selection.\n");
++ }
++}
++
++void
+ xevent_callback (MBTrayApp *app, XEvent *ev)
+ {
+ if (ev->type == ClientMessage)
+ {
+ XClientMessageEvent *cmev = (XClientMessageEvent *)&ev->xconfigure;
+
+- if (cmev->message_type == AtomIMActivate)
++ if (cmev->message_type == atoms[_GPE_INPUT_MANAGER])
+ {
++ switch (cmev->data.l[0])
++ {
++ case _GPE_INPUT_MANAGER_OPEN:
++ process_open_request (cmev->data.l[1]);
++ break;
++ case _GPE_INPUT_MANAGER_CLOSE:
++ process_close_request (cmev->data.l[1]);
++ break;
++ default:
++ fprintf (stderr, "received unknown _GPE_INPUT_MANAGER request %d\n", cmev->data.l[0]);
++ break;
++ }
++ }
++#ifndef DISABLE_OLD_PROTOCOL
++ else if (cmev->message_type == atoms[_MB_INPUT_REQUEST])
++ {
+ /* De Activate */
+ if (cmev->data.l[0] == 0 && mbinputmgr_method_active(Inpmgr_state))
+ mbinputmgr_toggle_selected_method (Inpmgr_state);
+@@ -278,8 +477,20 @@
+ && !mbinputmgr_method_active(Inpmgr_state))
+ mbinputmgr_toggle_selected_method (Inpmgr_state);
+ }
++#endif
+ }
++ else if (ev->type == UnmapNotify)
++ {
++ XUnmapEvent *uev = &ev->xunmap;
+
++ process_close_request (uev->window);
++ }
++ else if (ev->type == ConfigureNotify && !docked_already)
++ {
++ docked_already = TRUE;
++ is_docked ();
++ }
++
+ mb_menu_handle_xevent (PopupMenu, ev);
+ }
+
+@@ -347,11 +558,42 @@
+ free(icon_path);
+ }
+
++static Bool
++get_xevent_timed(Display* dpy, XEvent* event_return, struct timeval *tv)
++{
++ if (tv == NULL)
++ {
++ XNextEvent(dpy, event_return);
++ return True;
++ }
++
++ XFlush(dpy);
++
++ if (XPending(dpy) == 0)
++ {
++ int fd = ConnectionNumber(dpy);
++ fd_set readset;
++ FD_ZERO(&readset);
++ FD_SET(fd, &readset);
++ if (select(fd+1, &readset, NULL, NULL, tv) == 0)
++ {
++ return False;
++ } else {
++ XNextEvent(dpy, event_return);
++ return True;
++ }
++ } else {
++ XNextEvent(dpy, event_return);
++ return True;
++ }
++}
++
+ int
+ main(int argc, char **argv)
+ {
+ int i;
+ MBPixbufImage *app_icon_img = NULL;
++ XEvent xevent;
+
+ app = mb_tray_app_new ( "Input Selector",
+ resize_callback,
+@@ -359,13 +601,13 @@
+ &argc,
+ &argv );
+
++ dpy = mb_tray_app_xdisplay (app);
++
+ Pixbuf = mb_pixbuf_new(mb_tray_app_xdisplay(app),
+ mb_tray_app_xscreen(app));
+
+- AtomIMActivate = XInternAtom(mb_tray_app_xdisplay(app),
+- "_MB_INPUT_REQUEST", False);
++ XInternAtoms (dpy, atom_names, sizeof (atom_names) / sizeof (atom_names[0]), False, atoms);
+
+-
+ PopupMenu = mb_menu_new (mb_tray_app_xdisplay(app),
+ mb_tray_app_xscreen(app));
+
+@@ -399,17 +641,30 @@
+
+ mb_tray_app_set_xevent_callback (app, xevent_callback );
+
++ mb_tray_app_set_xevent_mask (app, SubstructureNotifyMask);
++
+ mb_tray_app_set_button_callback (app, button_callback );
+
+ /* XXX set up dnotify to reload entrys only on _addition_ */
+
++#ifndef DISABLE_OLD_PROTOCOL
+ XSelectInput(mb_tray_app_xdisplay(app),
+ mb_tray_app_xrootwin(app),
+ SubstructureNotifyMask);
++#endif
+
++ /* Not using mb_tray_app_main() to avoid libmb's broken get_xevent_timed() */
++ mb_tray_app_main_init (app);
++ for (;;)
++ {
++ struct timeval tv, *tvp = NULL;
+
+- mb_tray_app_main (app);
++ if (get_timeout (&tv))
++ tvp = &tv;
+
++ if (get_xevent_timed (dpy, &xevent, tvp))
++ mb_tray_handle_xevent (app, &xevent);
++ }
++
+ return 0;
+ }
+-
============================================================
--- packages/matchbox-applet-inputmanager/files/mbinputmgr-tray.c 3b581f789193a21efcb4529c8a6880c88b9013af
+++ packages/matchbox-applet-inputmanager/files/mbinputmgr-tray.c 3b581f789193a21efcb4529c8a6880c88b9013af
@@ -0,0 +1,415 @@
+/*
+ mbinputmgr
+ An inprogress panel app to manager available software input methods
+
+ Copyright (c) 2003 Matthew Allum
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+*/
+
+#include "mbinputmgr.h"
+
+enum {
+ BUTTON_ACTIVATE,
+ BUTTON_MENU,
+};
+
+MBMenu *PopupMenu = NULL;
+MBPixbuf *Pixbuf = NULL;
+MBTrayApp *app;
+int IconDim = 16;
+int IconWidth = 26;
+int TrayDepth = 0; /* width/height dep on orientation */
+int TrayAppLen = 0; /* len of tar app */
+MBInpmgrState *Inpmgr_state = NULL;
+Bool ButtonIsDown = False;
+int ButtonActive;
+Atom AtomIMActivate;
+
+typedef struct ButtonImgs {
+
+ MBPixbufImage *active;
+ MBPixbufImage *inactive;
+
+} ButtonImgs;
+
+void
+paint_callback ( MBTrayApp *app, Drawable drw )
+{
+ int x = 0, y = 0, ax, ay;
+ MBPixbufImage *img_bg = NULL, *img_icon = NULL, *img_selected = NULL;
+ int r = 0x33, g = 0x33, b = 0x33;
+ ButtonImgs *button;
+ int menu_button_offset = 0;
+
+ /* The window has not yet been resized to a what we want */
+ if ( TrayDepth == 0 ) return;
+
+ if (mbinputmgr_method_active(Inpmgr_state))
+ {
+ r = 0xcc, g = 0xcc, b = 0xcc;
+ }
+
+ img_bg = mb_tray_app_get_background (app, Pixbuf);
+
+ if (img_bg == NULL)
+ return;
+
+ button = (ButtonImgs*)Inpmgr_state->MethodSelected->data;
+
+ if (ButtonIsDown)
+ {
+ if (ButtonActive == BUTTON_MENU)
+ {
+ menu_button_offset = 2;
+ img_selected = button->inactive;
+ }
+ else img_selected = button->active;
+ }
+ else
+ {
+ img_selected = button->inactive;
+ }
+
+ /* XXX abort for now if vertical */
+
+ if (mb_tray_app_tray_is_vertical (app))
+ {
+ MBPixbufImage *img_tmp = NULL;
+
+ if (mb_pixbuf_img_get_width(img_bg) != TrayDepth
+ || mb_pixbuf_img_get_height(img_bg) != TrayAppLen)
+ {
+ mb_pixbuf_img_free(Pixbuf, img_bg);
+ return;
+ }
+
+
+ /* GREAT BIG FUCKING HACK -
+ app gets expose on orientation change
+ with mb_tray_app_tray_is_vertical = TRUE,
+ but app->h & app->w not updated via missing configure event.
+ need to figure out a better fix than this !!
+
+ NOTES:
+ - This expose can be basically ignored.
+
+ */
+ if (mb_pixbuf_img_get_width(img_bg) > mb_pixbuf_img_get_height(img_bg))
+ {
+ mb_pixbuf_img_render_to_drawable (Pixbuf, img_bg, drw, 0, 0);
+ mb_pixbuf_img_free(Pixbuf, img_bg);
+ return;
+ }
+
+ img_tmp = mb_pixbuf_img_scale (Pixbuf,
+ img_selected,
+ IconWidth, TrayDepth );
+
+ img_icon = mb_pixbuf_img_transform (Pixbuf, img_tmp,
+ MBPIXBUF_TRANS_ROTATE_90);
+
+ mb_pixbuf_img_copy_composite (Pixbuf, img_bg, img_icon,
+ 0, 0, TrayDepth, IconWidth, 0, 0);
+
+ ax = IconWidth+2 ; ay = 1 + menu_button_offset;
+
+ for (x=4; x>=0; x--)
+ {
+ for (y=0; y < ((x-4)*-2)+1; y++)
+ mb_pixbuf_img_plot_pixel(Pixbuf, img_bg, ay, ax+x+y, 0x33, 0x33, 0x33);
+ ay++;
+ }
+
+ mb_pixbuf_img_free(Pixbuf, img_tmp);
+ }
+ else
+ {
+
+ if (mb_pixbuf_img_get_width(img_bg) != TrayAppLen
+ || mb_pixbuf_img_get_height(img_bg) != TrayDepth)
+ {
+ /* Dont paint till were sized how we want */
+ mb_pixbuf_img_render_to_drawable (Pixbuf, img_bg, drw, 0, 0);
+ mb_pixbuf_img_free(Pixbuf, img_bg);
+ return;
+ }
+
+ img_icon = mb_pixbuf_img_scale (Pixbuf,
+ img_selected,
+ IconWidth, TrayDepth );
+
+ mb_pixbuf_img_copy_composite (Pixbuf, img_bg, img_icon,
+ 0, 0, IconWidth, TrayDepth, 0, 0);
+
+ ax = IconWidth+2; ay = 1 + menu_button_offset;
+
+ for (x=4; x>=0; x--)
+ {
+ for (y=0; y < ((x-4)*-2)+1; y++)
+ mb_pixbuf_img_plot_pixel(Pixbuf, img_bg, ax+x+y, ay, 0x33, 0x33, 0x33);
+ ay++;
+ }
+ }
+
+ mb_pixbuf_img_render_to_drawable (Pixbuf, img_bg, drw, 0, 0);
+
+ /* Free up images */
+
+ mb_pixbuf_img_free( Pixbuf, img_bg );
+ mb_pixbuf_img_free( Pixbuf, img_icon );
+
+}
+
+void
+resize_callback ( MBTrayApp *app, int w, int h )
+{
+ /* Image should be 26/16 + 6 for arrow - should fix to be dynamic */
+
+ IconWidth = 26;
+ TrayAppLen = IconWidth + 12;
+
+ if (mb_tray_app_tray_is_vertical (app))
+ {
+ if (w > 16)
+ {
+ IconWidth = (26 * w)/16;
+ TrayAppLen = IconWidth + 12;
+ }
+
+ TrayDepth = w;
+ mb_tray_app_request_size (app, TrayDepth, TrayAppLen );
+ }
+ else
+ {
+ if (h > 16)
+ {
+ IconWidth = (26 * h)/16;
+ TrayAppLen = IconWidth + 12;
+ }
+
+ TrayDepth = h;
+ mb_tray_app_request_size (app, TrayAppLen, TrayDepth );
+ }
+}
+
+void
+button_callback (MBTrayApp *app, int x, int y, Bool is_released )
+{
+ int abs_x, abs_y;
+
+ if (mb_menu_is_active(PopupMenu))
+ {
+ ButtonIsDown = True;
+
+ if (is_released)
+ {
+ mb_menu_deactivate(PopupMenu);
+ ButtonIsDown = False;
+ }
+
+ ButtonActive = BUTTON_MENU;
+ mb_tray_app_repaint (app);
+ return;
+ }
+
+ if (is_released)
+ {
+ ButtonIsDown = False;
+ if ( (mb_tray_app_tray_is_vertical (app) && y > IconWidth)
+ || (!mb_tray_app_tray_is_vertical (app) && x > IconWidth) )
+ {
+ mb_tray_app_get_absolute_coords (app, &abs_x, &abs_y);
+
+ /* aligned top, position down a little */
+ if (abs_y < 8)
+ {
+ int w, h;
+ mb_menu_get_root_menu_size(PopupMenu, &w, &h);
+ abs_y = h + IconDim + 2;
+ }
+
+ mb_menu_activate(PopupMenu, abs_x, abs_y);
+ ButtonActive = BUTTON_MENU;
+ }
+ else
+ {
+ ButtonActive = BUTTON_ACTIVATE;
+ mbinputmgr_toggle_selected_method (Inpmgr_state);
+ }
+
+ mb_tray_app_repaint (app);
+ }
+ else
+ {
+ if ( (mb_tray_app_tray_is_vertical (app) && y > IconWidth)
+ || (!mb_tray_app_tray_is_vertical (app) && x > IconWidth) )
+ ButtonActive = BUTTON_MENU;
+ else
+ ButtonActive = BUTTON_ACTIVATE;
+
+ ButtonIsDown = True;
+ mb_tray_app_repaint (app);
+ }
+}
+
+void
+xevent_callback (MBTrayApp *app, XEvent *ev)
+{
+ if (ev->type == ClientMessage)
+ {
+ XClientMessageEvent *cmev = (XClientMessageEvent *)&ev->xconfigure;
+
+ if (cmev->message_type == AtomIMActivate)
+ {
+ /* De Activate */
+ if (cmev->data.l[0] == 0 && mbinputmgr_method_active(Inpmgr_state))
+ mbinputmgr_toggle_selected_method (Inpmgr_state);
+ /* Activate */
+ else if (cmev->data.l[0] == 1
+ && !mbinputmgr_method_active(Inpmgr_state))
+ mbinputmgr_toggle_selected_method (Inpmgr_state);
+ }
+ }
+
+ mb_menu_handle_xevent (PopupMenu, ev);
+}
+
+void
+menu_item_activated_callback (MBMenuItem *item_active)
+{
+
+ mb_menu_deactivate(PopupMenu);
+
+ mbinpmgr_change_selected_method (Inpmgr_state,
+ (InputMethod*)mb_menu_item_get_user_data(item_active));
+
+ mb_tray_app_repaint (app);
+}
+
+void
+load_icon (InputMethod *method)
+{
+ int x,y;
+ char *icon_path;
+ ButtonImgs *button%s
>>> DIFF TRUNCATED @ 16K
More information about the Openembedded-commits
mailing list