? 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 +#include +#include + +GtkIMContext *im_context; /* the context for the keyboard input method */ +Atom hildon_com, hildon_utf, hildon_cls; + /* 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 ();