* Re: Emacs X/GTK code trouble with Maemo
2007-01-23 7:16 ` Emacs X/GTK code trouble with Maemo Jan Djärv
2007-01-23 16:31 ` Ted Zlatanov
@ 2007-01-24 18:56 ` Ted Zlatanov
2007-01-24 19:57 ` Ted Zlatanov
2007-01-24 20:10 ` Jan Djärv
1 sibling, 2 replies; 7+ messages in thread
From: Ted Zlatanov @ 2007-01-24 18:56 UTC (permalink / raw)
To: emacs-devel
[-- Attachment #1: Type: text/plain, Size: 910 bytes --]
Jan,
I just wanted to ask how to obtain the GDK window for a frame. Right
now I'm using:
GdkWindow *gdkWindow;
im_context = gtk_im_multicontext_new();
gdkWindow = gdk_window_foreign_new(FRAME_X_WINDOW(frame));
gtk_im_context_set_client_window(im_context, gdkWindow); /* we need the frame's GDK window */
hildon_gtk_im_context_show(im_context);
xassert (im_content != NULL);
to set the IM context for a "fake" GDK window around the frame's X
window. I'd like to get the real GDK window, the one used for
drawing. If we don't use a GDK window, when should I create the fake
one mentioned above? Right now, I'm doing it on FocusIn events in
src/xterm.c:x_focus_changed(), which I'm sure is the wrong place.
I looked at all the macros in frame.h, but couldn't find what I
needed.
The current patch (very preliminary) is attached if you or anyone else
have the time to look at it.
Thanks
Ted
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: xterm.patch --]
[-- Type: text/x-diff, Size: 15446 bytes --]
? xterm.patch
Index: xterm.c
===================================================================
RCS file: /sources/emacs/emacs/src/xterm.c,v
retrieving revision 1.936
diff -u -r1.936 xterm.c
--- xterm.c 10 Dec 2006 23:32:00 -0000 1.936
+++ xterm.c 24 Jan 2007 18:53:59 -0000
@@ -164,6 +164,13 @@
int use_xim = 0; /* configure --without-xim */
#endif
+#include <hildon-widgets/hildon-program.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtk.h>
+
+GtkIMContext *im_context; /* the context for the keyboard input method */
+Atom hildon_com, hildon_utf, hildon_cls;
+
\f
/* Non-nil means Emacs uses toolkit scroll bars. */
@@ -3177,7 +3184,7 @@
struct frame *frame;
{
struct frame *old_focus = dpyinfo->x_focus_frame;
-
+
if (frame != dpyinfo->x_focus_frame)
{
/* Set this before calling other routines, so that they see
@@ -3216,6 +3223,7 @@
struct frame *frame;
struct input_event *bufp;
{
+ GdkWindow *gdkWindow;
if (type == FocusIn)
{
if (dpyinfo->x_focus_event_frame != frame)
@@ -3240,6 +3248,11 @@
if (FRAME_XIC (frame))
XSetICFocus (FRAME_XIC (frame));
#endif
+ im_context = gtk_im_multicontext_new();
+ gdkWindow = gdk_window_foreign_new(FRAME_X_WINDOW(frame));
+ gtk_im_context_set_client_window(im_context, gdkWindow); /* we need the frame's GDK window */
+ hildon_gtk_im_context_show(im_context);
+ xassert (im_content != NULL);
}
else if (type == FocusOut)
{
@@ -3255,6 +3268,9 @@
if (FRAME_XIC (frame))
XUnsetICFocus (FRAME_XIC (frame));
#endif
+ hildon_gtk_im_context_hide(im_context);
+ gtk_im_context_reset(im_context);
+ g_object_unref(im_context);
}
}
@@ -5691,25 +5707,91 @@
inev.ie.kind = NO_EVENT;
inev.ie.arg = Qnil;
+ hildon_com = XInternAtom(dpyinfo->display, "_HILDON_IM_COM", TRUE);
+ hildon_utf = XInternAtom(dpyinfo->display, "_HILDON_IM_INSERT_UTF8", TRUE);
+ hildon_cls = XInternAtom(dpyinfo->display, "_HILDON_IM_CLOSE", TRUE);
+
switch (event.type)
{
case ClientMessage:
{
- if (event.xclient.message_type
- == dpyinfo->Xatom_wm_protocols
- && event.xclient.format == 32)
- {
- if (event.xclient.data.l[0]
- == dpyinfo->Xatom_wm_take_focus)
- {
- /* Use x_any_window_to_frame because this
- could be the shell widget window
- if the frame has no title bar. */
- f = x_any_window_to_frame (dpyinfo, event.xclient.window);
+ if (event.xclient.message_type == hildon_cls) /* keyboard closed */
+ {
+ printf ("Got hildon_cls event\n");
+ if (NULL != im_context)
+ {
+ hildon_gtk_im_context_hide(im_context);
+ gtk_im_context_reset(im_context);
+ g_object_unref(im_context);
+ im_context = NULL;
+ }
+ }
+ else if (event.xclient.message_type == hildon_utf) /* keyboard input */
+ {
+ printf ("Got hildon_utf event\n");
+ XEvent kev = event; /* create new event */
+ KeySym sym = XStringToKeysym(&event.xclient.data.b[4]); /* read the key */
+
+ if (!sym) sym = event.xclient.data.b[4]; /* fall back to input */
+
+ kev.type = KeyPress; /* keyboard event */
+ kev.xkey.root = event.xclient.window;
+ kev.xkey.subwindow = None;
+ kev.xkey.time = CurrentTime;
+ kev.xkey.x = kev.xkey.y = kev.xkey.x_root = kev.xkey.y_root = 1;
+ kev.xkey.same_screen = TRUE;
+ kev.xkey.keycode = XKeysymToKeycode(dpyinfo->display, sym); /* convert to key code */
+
+ if (isupper(event.xclient.data.b[4])) /* upper case letter? */
+ kev.xkey.state = ShiftMask; /* yes: we need shift */
+ else
+ kev.xkey.state = 0;
+
+ XSendEvent(dpyinfo->display, event.xclient.window, TRUE, KeyPressMask, &kev);
+
+ kev.type = KeyRelease; /* key release event */
+ XSendEvent(dpyinfo->display, event.xclient.window, TRUE, KeyReleaseMask, &kev);
+ }
+ else if (event.xclient.message_type == hildon_com)/* special key/event */
+ {
+ printf ("Got hildon_com event\n");
+ switch (event.xclient.data.b[4])
+ {
+ case 0: /* return / enter */
+ /* send XK_Return (or handle specially) */
+ break;
+ case 1: /* tab */
+ /* send XK_Tab (or handle specially) */
+ break;
+ case 2: /* backspace */
+ /* send XK_BackSpace (or handle specially) */
+ break;
+ case 4: /* state change */
+ break;
+ case 7: /* special char */
+ break;
+ default:
+ printf("Unknown IM event data %d\n",
+ (int) event.xclient.data.b[4]);
+ }
+ }
+ else
+ {
+ if (event.xclient.message_type
+ == dpyinfo->Xatom_wm_protocols
+ && event.xclient.format == 32)
+ {
+ if (event.xclient.data.l[0]
+ == dpyinfo->Xatom_wm_take_focus)
+ {
+ /* Use x_any_window_to_frame because this
+ could be the shell widget window
+ if the frame has no title bar. */
+ f = x_any_window_to_frame (dpyinfo, event.xclient.window);
#ifdef HAVE_X_I18N
- /* Not quite sure this is needed -pd */
- if (f && FRAME_XIC (f))
- XSetICFocus (FRAME_XIC (f));
+ /* Not quite sure this is needed -pd */
+ if (f && FRAME_XIC (f))
+ XSetICFocus (FRAME_XIC (f));
#endif
#if 0 /* Emacs sets WM hints whose `input' field is `true'. This
instructs the WM to set the input focus automatically for
@@ -5724,147 +5806,148 @@
below can generate additional FocusIn events which confuse
Emacs. */
- /* Since we set WM_TAKE_FOCUS, we must call
- XSetInputFocus explicitly. But not if f is null,
- since that might be an event for a deleted frame. */
- if (f)
- {
- Display *d = event.xclient.display;
- /* Catch and ignore errors, in case window has been
- iconified by a window manager such as GWM. */
- x_catch_errors (d);
- XSetInputFocus (d, event.xclient.window,
- /* The ICCCM says this is
- the only valid choice. */
- RevertToParent,
- event.xclient.data.l[1]);
- /* This is needed to detect the error
- if there is an error. */
- XSync (d, False);
- x_uncatch_errors ();
- }
- /* Not certain about handling scroll bars here */
+ /* Since we set WM_TAKE_FOCUS, we must call
+ XSetInputFocus explicitly. But not if f is null,
+ since that might be an event for a deleted frame. */
+ if (f)
+ {
+ Display *d = event.xclient.display;
+ /* Catch and ignore errors, in case window has been
+ iconified by a window manager such as GWM. */
+ x_catch_errors (d);
+ XSetInputFocus (d, event.xclient.window,
+ /* The ICCCM says this is
+ the only valid choice. */
+ RevertToParent,
+ event.xclient.data.l[1]);
+ /* This is needed to detect the error
+ if there is an error. */
+ XSync (d, False);
+ x_uncatch_errors ();
+ }
+ /* Not certain about handling scroll bars here */
#endif /* 0 */
- goto done;
- }
+ goto done;
+ }
- if (event.xclient.data.l[0]
- == dpyinfo->Xatom_wm_save_yourself)
- {
- /* Save state modify the WM_COMMAND property to
- something which can reinstate us. This notifies
- the session manager, who's looking for such a
- PropertyNotify. Can restart processing when
- a keyboard or mouse event arrives. */
- /* If we have a session manager, don't set this.
- KDE will then start two Emacsen, one for the
- session manager and one for this. */
+ if (event.xclient.data.l[0]
+ == dpyinfo->Xatom_wm_save_yourself)
+ {
+ /* Save state modify the WM_COMMAND property to
+ something which can reinstate us. This notifies
+ the session manager, who's looking for such a
+ PropertyNotify. Can restart processing when
+ a keyboard or mouse event arrives. */
+ /* If we have a session manager, don't set this.
+ KDE will then start two Emacsen, one for the
+ session manager and one for this. */
#ifdef HAVE_X_SM
- if (! x_session_have_connection ())
+ if (! x_session_have_connection ())
#endif
- {
- f = x_top_window_to_frame (dpyinfo,
- event.xclient.window);
- /* This is just so we only give real data once
- for a single Emacs process. */
- if (f == SELECTED_FRAME ())
- XSetCommand (FRAME_X_DISPLAY (f),
- event.xclient.window,
- initial_argv, initial_argc);
- else if (f)
- XSetCommand (FRAME_X_DISPLAY (f),
- event.xclient.window,
- 0, 0);
- }
- goto done;
- }
+ {
+ f = x_top_window_to_frame (dpyinfo,
+ event.xclient.window);
+ /* This is just so we only give real data once
+ for a single Emacs process. */
+ if (f == SELECTED_FRAME ())
+ XSetCommand (FRAME_X_DISPLAY (f),
+ event.xclient.window,
+ initial_argv, initial_argc);
+ else if (f)
+ XSetCommand (FRAME_X_DISPLAY (f),
+ event.xclient.window,
+ 0, 0);
+ }
+ goto done;
+ }
- if (event.xclient.data.l[0]
- == dpyinfo->Xatom_wm_delete_window)
- {
- f = x_any_window_to_frame (dpyinfo,
- event.xclient.window);
- if (!f)
- goto OTHER; /* May be a dialog that is to be removed */
+ if (event.xclient.data.l[0]
+ == dpyinfo->Xatom_wm_delete_window)
+ {
+ f = x_any_window_to_frame (dpyinfo,
+ event.xclient.window);
+ if (!f)
+ goto OTHER; /* May be a dialog that is to be removed */
+
+ inev.ie.kind = DELETE_WINDOW_EVENT;
+ XSETFRAME (inev.ie.frame_or_window, f);
+ goto done;
+ }
- inev.ie.kind = DELETE_WINDOW_EVENT;
- XSETFRAME (inev.ie.frame_or_window, f);
goto done;
- }
-
- goto done;
- }
+ }
- if (event.xclient.message_type
- == dpyinfo->Xatom_wm_configure_denied)
- {
- goto done;
- }
+ if (event.xclient.message_type
+ == dpyinfo->Xatom_wm_configure_denied)
+ {
+ goto done;
+ }
- if (event.xclient.message_type
- == dpyinfo->Xatom_wm_window_moved)
- {
- int new_x, new_y;
- f = x_window_to_frame (dpyinfo, event.xclient.window);
+ if (event.xclient.message_type
+ == dpyinfo->Xatom_wm_window_moved)
+ {
+ int new_x, new_y;
+ f = x_window_to_frame (dpyinfo, event.xclient.window);
- new_x = event.xclient.data.s[0];
- new_y = event.xclient.data.s[1];
+ new_x = event.xclient.data.s[0];
+ new_y = event.xclient.data.s[1];
- if (f)
- {
- f->left_pos = new_x;
- f->top_pos = new_y;
- }
- goto done;
- }
+ if (f)
+ {
+ f->left_pos = new_x;
+ f->top_pos = new_y;
+ }
+ goto done;
+ }
#ifdef HACK_EDITRES
- if (event.xclient.message_type
- == dpyinfo->Xatom_editres)
- {
- f = x_any_window_to_frame (dpyinfo, event.xclient.window);
- if (f)
- _XEditResCheckMessages (f->output_data.x->widget, NULL,
- &event, NULL);
- goto done;
- }
+ if (event.xclient.message_type
+ == dpyinfo->Xatom_editres)
+ {
+ f = x_any_window_to_frame (dpyinfo, event.xclient.window);
+ if (f)
+ _XEditResCheckMessages (f->output_data.x->widget, NULL,
+ &event, NULL);
+ goto done;
+ }
#endif /* HACK_EDITRES */
- if ((event.xclient.message_type
- == dpyinfo->Xatom_DONE)
- || (event.xclient.message_type
- == dpyinfo->Xatom_PAGE))
- {
- /* Ghostview job completed. Kill it. We could
- reply with "Next" if we received "Page", but we
- currently never do because we are interested in
- images, only, which should have 1 page. */
- Pixmap pixmap = (Pixmap) event.xclient.data.l[1];
- f = x_window_to_frame (dpyinfo, event.xclient.window);
- if (!f)
- goto OTHER;
- x_kill_gs_process (pixmap, f);
- expose_frame (f, 0, 0, 0, 0);
- goto done;
- }
+ if ((event.xclient.message_type
+ == dpyinfo->Xatom_DONE)
+ || (event.xclient.message_type
+ == dpyinfo->Xatom_PAGE))
+ {
+ /* Ghostview job completed. Kill it. We could
+ reply with "Next" if we received "Page", but we
+ currently never do because we are interested in
+ images, only, which should have 1 page. */
+ Pixmap pixmap = (Pixmap) event.xclient.data.l[1];
+ f = x_window_to_frame (dpyinfo, event.xclient.window);
+ if (!f)
+ goto OTHER;
+ x_kill_gs_process (pixmap, f);
+ expose_frame (f, 0, 0, 0, 0);
+ goto done;
+ }
#ifdef USE_TOOLKIT_SCROLL_BARS
- /* Scroll bar callbacks send a ClientMessage from which
- we construct an input_event. */
- if (event.xclient.message_type
- == dpyinfo->Xatom_Scrollbar)
- {
- x_scroll_bar_to_input_event (&event, &inev.ie);
- *finish = X_EVENT_GOTO_OUT;
- goto done;
- }
+ /* Scroll bar callbacks send a ClientMessage from which
+ we construct an input_event. */
+ if (event.xclient.message_type
+ == dpyinfo->Xatom_Scrollbar)
+ {
+ x_scroll_bar_to_input_event (&event, &inev.ie);
+ *finish = X_EVENT_GOTO_OUT;
+ goto done;
+ }
#endif /* USE_TOOLKIT_SCROLL_BARS */
- f = x_any_window_to_frame (dpyinfo, event.xclient.window);
- if (!f)
- goto OTHER;
- if (x_handle_dnd_message (f, &event.xclient, dpyinfo, &inev.ie))
- *finish = X_EVENT_DROP;
+ f = x_any_window_to_frame (dpyinfo, event.xclient.window);
+ if (!f)
+ goto OTHER;
+ if (x_handle_dnd_message (f, &event.xclient, dpyinfo, &inev.ie))
+ *finish = X_EVENT_DROP;
+ }
}
break;
@@ -10434,8 +10517,11 @@
XSetLocaleModifiers ("");
#endif
+ HildonProgram *program;
gtk_init (&argc, &argv2);
+ program = HILDON_PROGRAM(hildon_program_get_instance());
+
/* gtk_init does set_locale. We must fix locale after calling it. */
fixup_locale ();
xg_initialize ();
[-- Attachment #3: Type: text/plain, Size: 142 bytes --]
_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-devel
^ permalink raw reply [flat|nested] 7+ messages in thread