1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
#include <gtk/gtk.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
GtkWidget *m_layout;
static const char *m_kbd_path = "/usr/local/bin/matchbox-keyboard";
static const char *m_kbd_str;
static guint m_kbd_xid;
static guint m_kbd_pid;
void
cleanup_children(int s)
{
kill(-getpid(), 15); /* kill every one in our process group */
exit(0);
}
void
install_signal_handlers(void)
{
signal (SIGCHLD, SIG_IGN); /* kernel can deal with zombies */
signal (SIGINT, cleanup_children);
signal (SIGQUIT, cleanup_children);
signal (SIGTERM, cleanup_children);
}
unsigned long
launch_keyboard(void)
{
int i = 0, fd[2];
int stdout_pipe[2];
int stdin_pipe[2];
char buf[256], c;
size_t n;
unsigned long result;
printf("Launching keyboard from: %s\r\n",m_kbd_path);
pipe (stdout_pipe);
pipe (stdin_pipe);
switch (fork ())
{
case 0:
{
/* Close the Child process' STDOUT */
close(1);
dup(stdout_pipe[1]);
close(stdout_pipe[0]);
close(stdout_pipe[1]);
execlp ("/bin/sh", "sh", "-c", "matchbox-keyboard --xid", NULL);
}
case -1:
perror ("### Failed to launch 'matchbox-keyboard --xid', is it installed? ### ");
exit(1);
}
/* Parent */
/* Close the write end of STDOUT */
close(stdout_pipe[1]);
/* FIXME: This could be a little safer... */
do
{
n = read(stdout_pipe[0], &c, 1);
if (n == 0 || c == '\n')
break;
buf[i++] = c;
}
while (i < 256);
buf[i] = '\0';
result = atol (buf);
close(stdout_pipe[0]);
return result;
}
void widget_destroy( GtkWidget *widget,
gpointer data )
{
gtk_widget_destroy(widget);
gtk_widget_destroy(m_layout);
gtk_main_quit ();
}
int main(int argc, char **argv)
{
GtkWidget *window, *button, *textview, *vbox;
GtkWidget *socket, *plug, *socket_box;
unsigned long kb_xid;
gtk_init (&argc, &argv);
install_signal_handlers();
kb_xid = launch_keyboard();
if (!kb_xid)
{
perror ("### 'matchbox-keyboard --xid', failed to return valid window ID. ### ");
exit(-1);
}
/* Window */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size (GTK_WINDOW (window), 640, 480);
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
g_signal_connect (G_OBJECT (window), "destroy",
G_CALLBACK (widget_destroy), NULL);
/* Container and textview */
vbox = gtk_vbox_new(FALSE, 5);
gtk_container_add (GTK_CONTAINER (window), vbox);
textview = gtk_text_view_new();
gtk_box_pack_start (GTK_BOX(vbox), textview, TRUE, TRUE, 2);
/* Socket ( XEMBED ) stuff */
socket_box = gtk_event_box_new ();
gtk_widget_show (socket_box);
socket = gtk_socket_new ();
gtk_container_add (GTK_CONTAINER (socket_box), socket);
gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET(socket_box), TRUE, TRUE, 0);
gtk_socket_add_id(GTK_SOCKET(socket), kb_xid);
/* FIXME: handle "plug-added" & "plug-removed" signals for socket */
gtk_widget_show_all (window);
gtk_main ();
return 0;
}
|