unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Ted Zlatanov <tzz@lifelogs.com>
To: emacs-devel@gnu.org
Subject: Re: Emacs X/GTK code trouble with Maemo
Date: Wed, 24 Jan 2007 13:56:06 -0500	[thread overview]
Message-ID: <g69veiww8xl.fsf@dhcp-65-162.kendall.corp.akamai.com> (raw)
In-Reply-To: 45B5B638.2070808@swipnet.se

[-- 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

  parent reply	other threads:[~2007-01-24 18:56 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-01-15 20:06 porting and packaging Emacs to a new platform: Maemo Ted Zlatanov
2007-01-22 21:43 ` Emacs X/GTK code trouble with Maemo (was: porting and packaging Emacs to a new platform: Maemo) Ted Zlatanov
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 [this message]
2007-01-24 19:57       ` Ted Zlatanov
2007-01-24 20:10       ` Jan Djärv

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=g69veiww8xl.fsf@dhcp-65-162.kendall.corp.akamai.com \
    --to=tzz@lifelogs.com \
    --cc=emacs-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).