source: trunk/third/sawfish/capplet/sawmill-capplet.c @ 17367

Revision 17367, 7.7 KB checked in by ghudson, 23 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r17366, which included commits to RCS files with non-trunk default branches.
Line 
1/* sawmill-capplet.c -- embed sawmill-ui in the gnome control center
2   $Id: sawmill-capplet.c,v 1.1.1.2 2002-03-20 05:00:26 ghudson Exp $
3
4   Copyright (C) 1999 John Harper <john@dcs.warwick.ac.uk>
5
6   This file is part of sawmill.
7
8   sawmill is free software; you can redistribute it and/or modify it
9   under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2, or (at your option)
11   any later version.
12
13   sawmill is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with sawmill; see the file COPYING.   If not, write to
20   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
21
22/* this was initially based on mouse-properties.c */
23
24#ifdef HAVE_CONFIG_H
25#include <config.h>
26#endif
27
28#include "../build.h"
29#include "../src/libclient.h"
30
31#include <stdio.h>
32#include <signal.h>
33#include <errno.h>
34
35#ifdef HAVE_UNISTD_H
36#include <unistd.h>
37#endif
38#if HAVE_SYS_WAIT_H
39# include <sys/wait.h>
40#endif
41
42#include <capplet-widget.h>
43#include <gdk/gdkx.h>
44
45static GtkWidget *ui_socket;
46static GtkWidget *capplet;
47
48static int ui_pid;
49static int ui_stdin[2];
50static int ui_stdout[2];
51static guint ui_handler_id;
52
53static char *group;
54static gboolean no_flatten = FALSE;
55
56
57/* communicating with sawfish-ui */
58
59#define X_IO(op, fd, buf, len)                          \
60        char *buf__ = (char *)buf;                      \
61        int todo__ = len;                               \
62        while(todo__ > 0) {                             \
63            int this__ = op (fd, buf__, todo__);        \
64            if(this__ < 0) {                            \
65                if (errno != EINTR)                     \
66                    return -1;                          \
67            }                                           \
68            else if(this__ == 0)                        \
69                break;                                  \
70            else {                                      \
71                todo__ -= this__;                       \
72                buf__ += this__;                        \
73            }                                           \
74        }                                               \
75        return len - todo__;
76
77static int
78x_write (int fd, void *buf, size_t len)
79{
80    X_IO (write, fd, buf, len);
81}
82
83static int
84x_read (int fd, void *buf, size_t len)
85{
86    X_IO (read, fd, buf, len);
87}
88
89static int
90ui_command (char *str)
91{
92    if (ui_pid != 0)
93    {
94        u_char ret;
95        x_write (ui_stdin[1], str, strlen(str));
96        x_read (ui_stdout[0], &ret, 1);
97        return ret;
98    }
99    else
100        return 0;
101}
102
103static void
104display_error (const char *message)
105{
106    GtkWidget *label;
107
108    if (ui_handler_id != 0)
109    {
110        gtk_input_remove (ui_handler_id);
111        ui_handler_id = 0;
112    }
113
114    if (ui_pid != 0  && waitpid (ui_pid, 0, WNOHANG) == ui_pid)
115    {
116        ui_pid = 0;
117    }
118
119    if (ui_socket != 0)
120    {
121        gtk_container_remove (GTK_CONTAINER (capplet), ui_socket);
122        gtk_object_destroy (GTK_OBJECT (ui_socket));
123        ui_socket = 0;
124    }
125
126    label = gtk_label_new (_("The applet encountered an error"));
127    gtk_container_add (GTK_CONTAINER (capplet), label);
128    gtk_widget_show (label);
129}
130
131static void
132ui_output_callback (gpointer data, gint fd, GdkInputCondition cond)
133{
134    char out;
135    int bytes_read;
136
137    bytes_read = x_read (ui_stdout[0], &out, 1);
138    if (bytes_read == 1)
139    {
140        switch (out)
141        {
142        case 'c':
143            capplet_widget_state_changed (CAPPLET_WIDGET (capplet), TRUE);
144            break;
145
146        case 'g':                       /* group doesn't exist */
147            display_error (_("That group doesn't exist"));
148        }
149    }
150    else
151    {
152        /* EOF or error of some sort */
153
154        display_error (_("The applet encountered an error"));
155    }
156}
157
158
159/* capplet button callbacks */
160
161static void
162sawmill_help (void)
163{
164}
165
166static void
167sawmill_apply (void)
168{
169    ui_command("apply\n");
170}
171
172static void
173sawmill_revert (void)
174{
175    ui_command ("revert\n");
176}
177
178static void
179sawmill_ok (void)
180{
181    gtk_container_remove (GTK_CONTAINER (capplet), ui_socket);
182    ui_command ("ok\n");
183}
184
185static void
186sawmill_cancel (void)
187{
188    gtk_container_remove (GTK_CONTAINER (capplet), ui_socket);
189    ui_command ("cancel\n");
190}
191
192
193/* initialisation */
194
195/* returns non-zero if sawfish is running */
196static gint
197sawmill_running_p (void)
198{
199    int ret = client_open (0);  /* 0 == $DISPLAY */
200    if (ret == 0)
201        client_close ();
202    return (ret == 0);
203}
204
205static void
206sawmill_setup (void)
207{
208    capplet = capplet_widget_new ();
209
210    if (!sawmill_running_p ())
211    {
212        GtkWidget *label = gtk_label_new (_("Sawfish isn't running"));
213        gtk_container_add (GTK_CONTAINER (capplet), label);
214        return;
215    }
216
217    gtk_signal_connect (GTK_OBJECT (capplet), "help",
218                        GTK_SIGNAL_FUNC (sawmill_help), NULL);
219    gtk_signal_connect (GTK_OBJECT (capplet), "try",
220                        GTK_SIGNAL_FUNC (sawmill_apply), NULL);
221    gtk_signal_connect (GTK_OBJECT (capplet), "revert",
222                        GTK_SIGNAL_FUNC (sawmill_revert), NULL);
223    gtk_signal_connect (GTK_OBJECT (capplet), "ok",
224                        GTK_SIGNAL_FUNC (sawmill_ok), NULL);
225    gtk_signal_connect (GTK_OBJECT (capplet), "cancel",
226                        GTK_SIGNAL_FUNC (sawmill_cancel), NULL);
227
228    ui_socket = gtk_socket_new ();
229    gtk_container_add (GTK_CONTAINER (capplet), ui_socket);
230
231    /* show this here so the widget gets realized */
232    gtk_widget_show_all (capplet);
233
234    /* now fork the sawmill-ui script */
235    pipe (ui_stdin);
236    pipe (ui_stdout);
237    switch (ui_pid = fork ())
238    {
239        char buf[64];
240        char *argv[10];
241        int i;
242
243    case -1:
244        exit (5);
245
246    case 0:                             /* child */
247        dup2 (ui_stdin[0], 0);
248        dup2 (ui_stdout[1], 1);
249        close (ui_stdin[0]);
250        close (ui_stdin[1]);
251        close (ui_stdout[0]);
252        close (ui_stdout[1]);
253        sprintf (buf, "%ld", (long)GDK_WINDOW_XWINDOW (ui_socket->window));
254        i = 0;
255        argv[i++] = "sawfish-ui";
256        if (!no_flatten)
257            argv[i++] = "--flatten";
258        else
259            argv[i++] = "--single-level";
260        argv[i++] = "--socket-id";
261        argv[i++] = buf;
262        if (group != 0)
263        {
264            argv[i++] = "--group";
265            argv[i++] = group;
266        }
267        argv[i++] = 0;
268        execvp (argv[0], argv);
269        exit (10);
270
271    default:                            /* parent */
272        close (ui_stdin[0]);
273        close (ui_stdout[1]);
274        ui_handler_id = gdk_input_add (ui_stdout[0], GDK_INPUT_READ,
275                                       (GdkInputFunction)
276                                       ui_output_callback, 0);
277    }
278}
279
280
281/* entry point */
282
283int
284main (int argc, char **argv)
285{
286    GnomeClient *client = NULL;
287    GnomeClientFlags flags;
288    gchar *session_args[3];
289    int token, init_results;
290
291    static struct poptOption options[] = {
292        { "sawmill-group", 0, POPT_ARG_STRING, &group,
293          0, "Sawfish customization group", "GROUP" },
294        { "sawfish-group", 0, POPT_ARG_STRING, &group,
295          0, "Sawfish customization group", "GROUP" },
296        { "sawfish-no-flatten", 0, POPT_ARG_NONE, &no_flatten,
297          0, "Don't flatten group trees", 0 },
298        { 0, 0, 0, 0, 0 }
299    };
300
301#if 0
302    bindtextdomain (PACKAGE, GNOMELOCALEDIR);
303    textdomain (PACKAGE);
304#endif
305
306    init_results = gnome_capplet_init("sawfish-properties", SAWFISH_VERSION,
307                                      argc, argv, options, 0, NULL);
308
309    if (init_results < 0) {
310        g_warning ("an initialization error occurred while "
311                   "starting 'sawfish-properties-capplet'.\n"
312                   "aborting...\n");
313        exit (1);
314    }
315
316    client = gnome_master_client ();
317    flags = gnome_client_get_flags(client);
318
319#if 0
320    /* XXX I copied this from mouse-properties.c, but the
321       XXX GNOME_SAWFISH_PROPERTIES root property just grows
322       XXX each time the capplet is started... */
323
324    if (flags & GNOME_CLIENT_IS_CONNECTED) {
325        token = gnome_startup_acquire_token("GNOME_SAWFISH_PROPERTIES",
326                                            gnome_client_get_id(client));
327
328        if (token) {
329            session_args[0] = argv[0];
330            session_args[1] = "--init-session-settings";
331            session_args[2] = NULL;
332            gnome_client_set_priority (client, 20);
333            gnome_client_set_restart_style (client, GNOME_RESTART_ANYWAY);
334            gnome_client_set_restart_command (client, 2, session_args);
335        }
336        else
337            gnome_client_set_restart_style (client, GNOME_RESTART_NEVER);
338
339        gnome_client_flush (client);
340    }
341    else
342        token = 1;
343#endif
344
345    if (init_results != 1) {
346        sawmill_setup ();
347        gtk_widget_show_all (capplet);
348        capplet_gtk_main ();
349        if (ui_pid != 0)
350            waitpid (ui_pid, 0, 0);
351    }
352    return 0;
353}
Note: See TracBrowser for help on using the repository browser.