File: matchbox-keyboard-gtk-embed.c

package info (click to toggle)
matchbox-keyboard 0.1-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k, lenny
  • size: 716 kB
  • ctags: 394
  • sloc: ansic: 3,301; xml: 1,776; sh: 794; makefile: 49
file content (153 lines) | stat: -rw-r--r-- 3,115 bytes parent folder | download | duplicates (11)
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;
}