/* * xmim - X MeeGo Input Method bridge * Copyright (c) 2012 Javier S. Pedro * * Portions from the Smart Common Input Method * Copyright (c) 2002-2005 James Su * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA */ #include #include #include #include #include #include "meego/meego-im-connector.h" #include "ximserver.h" #include "xmim.h" Display *x_dpy; Window x_win; XIM x_im; XIC x_ic; char * opt_display = NULL; gint64 opt_xephyr = 0; static GMainLoop *main_loop; static MeegoImConnector *m_connector; static GIOChannel *x_chan; static int x_watch; static GOptionEntry entries[] = { { "display", 'd', 0, G_OPTION_ARG_STRING, &opt_display, "X11 display to use", "DISPLAY" }, { "xephyr", 'x', 0, G_OPTION_ARG_INT64, &opt_xephyr, "Xephyr mode", "XEPHYR_WINDOW_ID" }, { NULL } }; static gboolean x_watch_cb(GIOChannel *source, GIOCondition condition, gpointer data) { XEvent e; while (XPending(x_dpy)) { XNextEvent(x_dpy, &e); if (XFilterEvent(&e, None)) { continue; } } return TRUE; } static Window create_im_window() { int scr = DefaultScreen(x_dpy); Window win = XCreateSimpleWindow(x_dpy, DefaultRootWindow(x_dpy), -1, -1, 1, 1, 0, 0, BlackPixel(x_dpy, scr)); XSetWindowAttributes attrs; unsigned long attrmask; attrs.override_redirect = True; attrmask = CWOverrideRedirect; XChangeWindowAttributes(x_dpy, win, attrmask, &attrs); XSelectInput(x_dpy, win, KeyPressMask | KeyReleaseMask | StructureNotifyMask); XMapWindow(x_dpy, win); return win; } int main(int argc, char *argv[]) { GError *error = NULL; GOptionContext *context; setlocale(LC_ALL, ""); g_type_init(); context = g_option_context_new("- X11 <-> Meego Input Method bridge daemon"); g_option_context_add_main_entries(context, entries, NULL); if (!g_option_context_parse(context, &argc, &argv, &error)) { g_printerr("option parsing failed: %s\n", error->message); return EXIT_FAILURE; } main_loop = g_main_loop_new(NULL, TRUE); XSetLocaleModifiers(""); // We will open the default IM as a "slave" x_dpy = XOpenDisplay(opt_display); if (!x_dpy) { g_critical("Cannot open X display"); return EXIT_FAILURE; } x_chan = g_io_channel_unix_new(ConnectionNumber(x_dpy)); x_watch = g_io_add_watch(x_chan, G_IO_IN | G_IO_ERR, x_watch_cb, NULL); g_warn_if_fail(XSupportsLocale()); // Open the slave input method x_im = XOpenIM(x_dpy, NULL, NULL, NULL); g_warn_if_fail(x_im); // Create the IM server window x_win = create_im_window(); g_warn_if_fail(x_win != None); // Create the slave input context x_ic = XCreateIC(x_im, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, NULL); g_warn_if_fail(x_ic); m_connector = meego_im_connector_get_singleton(); g_warn_if_fail(m_connector); xims_open(); XFlush(x_dpy); // Flush X11 queue before blocking in the event loop g_main_loop_run(main_loop); xims_close(); g_source_remove(x_watch); g_io_channel_unref(x_chan); XDestroyIC(x_ic); XCloseIM(x_im); XCloseDisplay(x_dpy); return EXIT_SUCCESS; }