main.c 5.78 KB
Newer Older
Elliot Lee's avatar
Elliot Lee committed
1 2 3 4 5
/* Gnome panel: Initialization routines
 * (C) 1997 the Free Software Foundation
 *
 * Authors: Federico Mena
 *          Miguel de Icaza
6
 *          George Lebl
Elliot Lee's avatar
Elliot Lee committed
7 8
 */

9
#include <config.h>
Elliot Lee's avatar
Elliot Lee committed
10
#include <string.h>
11
#include <signal.h>
12
#include <sys/wait.h>
Arturo Espinosa's avatar
Arturo Espinosa committed
13
#include <gnome.h>
Elliot Lee's avatar
Elliot Lee committed
14

15
#include "panel-include.h"
16

17 18 19 20 21
extern int config_sync_timeout;
extern GList *applets_to_sync;
extern int panels_to_sync;
extern int globals_to_sync;
extern int need_complete_save;
22

23 24
extern GArray *applets;
extern int applet_count;
25

26 27
extern char *panel_cfg_path;
extern char *old_panel_cfg_path;
28

29
GtkTooltips *panel_tooltips = NULL;
30

31
GnomeClient *client = NULL;
Elliot Lee's avatar
Elliot Lee committed
32

33
/*a list of started extern applet child processes*/
34
extern GList * children;
35

36
/* True if parsing determined that all the work is already done.  */
George Lebl's avatar
George Lebl committed
37
int just_exit = 0;
38

39
/* The security cookie */
40
char *cookie = NULL;
41

42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
/* These are the arguments that our application supports.  */
static struct argp_option arguments[] =
{
#define DISCARD_KEY -1
  { "discard-session", DISCARD_KEY, N_("ID"), 0, N_("Discard session"), 1 },
  { NULL, 0, NULL, 0, NULL, 0 }
};

/* Forward declaration of the function that gets called when one of
   our arguments is recognized.  */
static error_t parse_an_arg (int key, char *arg, struct argp_state *state);

/* This structure defines our parser.  It can be used to specify some
   options for how our parsing function should be called.  */
static struct argp parser =
{
58 59 60 61 62 63 64 65 66
	arguments,			/* Options.  */
	parse_an_arg,			/* The parser function.  */
	NULL,				/* Some docs.  */
	NULL,				/* Some more docs.  */
	NULL,				/* Child arguments -- gnome_init fills
					   this in for us.  */
	NULL,				/* Help filter.  */
	NULL				/* Translation domain; for the app it
					   can always be NULL.  */
67 68 69 70 71 72 73
};

/*I guess this should be called after we load up, but the problem is
  we never know when all the applets are going to finish loading and
  we don't want to clean the file before they load up, so now we
  only call it on the discard cmdline argument*/
void
George Lebl's avatar
George Lebl committed
74
discard_session (char *id)
75
{
George Lebl's avatar
George Lebl committed
76
	char *sess;
77

78 79
	/*FIXME: hmm this won't work ... there needs to be a clean_dir*/
	sess = g_copy_strings ("/panel.d/Session-", id, NULL);
80
	gnome_config_clean_file (sess);
81 82
	g_free (sess);

83
	gnome_config_sync ();
84

85
	return;
86 87
}

88
	
89 90 91
static error_t
parse_an_arg (int key, char *arg, struct argp_state *state)
{
92
	if (key == DISCARD_KEY) {
93
		gnome_client_disable_master_connection ();
94 95 96 97 98 99 100
		discard_session (arg);
		just_exit = 1;
		return 0;
	}

	/* We didn't recognize it.  */
	return ARGP_ERR_UNKNOWN;
101 102
}

103 104 105 106 107 108 109 110 111 112 113
void
sigchld_handler(int type)
{
	GList *list;
	pid_t pid = waitpid(0,NULL,WNOHANG);

	if(pid <= 0)
		return;

	for(list=children;list!=NULL;list=g_list_next(list)) {
		AppletChild *child=list->data;
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
		AppletInfo *info;
		if(child->pid != pid)
			continue;
		info = get_applet_info(child->applet_id);
		if(info && !info->widget) {
			Extern *ext = info->data;
			if(ext && ext->ior) {
				int i;
				AppletInfo *in;
				for(i=0,in=(AppletInfo *)applets->data;
				    i<applet_count;
				    i++,in++) {
					Extern *e;
					if(in->type != APPLET_EXTERN &&
					   in->type != APPLET_EXTERN_PENDING &&
					   in->type != APPLET_EXTERN_RESERVED)
						continue;
					e = in->data;

					if(e && e->ior &&
					   strcmp(ext->ior,e->ior)==0)
						panel_clean_applet(in->applet_id);
136
				}
137
			}
138
		}
139 140 141 142
		exec_queue_done(child->applet_id);

		g_free(child);
		children=g_list_remove_link(children,list);
143
		g_list_free(list);
144
		return;
145 146
	}
}
147

George Lebl's avatar
George Lebl committed
148
static int
149 150
try_config_sync(gpointer data)
{
151
	panel_config_sync();
152 153 154
	return TRUE;
}

Elliot Lee's avatar
Elliot Lee committed
155 156 157 158

int
main(int argc, char **argv)
{
159
	char buf[256];
160 161
	struct sigaction sa;
	
162 163
	panel_cfg_path = g_strdup("/panel.d/default/");
	old_panel_cfg_path = g_strdup("/panel.d/default/");
164

165
	bindtextdomain(PACKAGE, GNOMELOCALEDIR);
166
	textdomain(PACKAGE);
Elliot Lee's avatar
Elliot Lee committed
167

168 169 170 171
	sigemptyset (&sa.sa_mask);
	sa.sa_handler = sigchld_handler;
	sa.sa_flags   = 0;
	sigaction (SIGCHLD, &sa, NULL);
172

173 174 175 176
	panel_corba_register_arguments ();

	gnome_init("panel", &parser, argc, argv, 0, NULL);

177 178
	/* Setup the cookie */
	cookie = create_cookie ();
179 180
	g_snprintf(buf,256,"/panel/Secret/cookie-DISPLAY-%s",getenv("DISPLAY"));
	gnome_config_private_set_string (buf, cookie);
181 182 183 184
	gnome_config_sync();
	
	panel_corba_gtk_init();

185 186
	if (just_exit)
		return 0;
187

188 189 190
	client= gnome_master_client ();

	gtk_signal_connect (GTK_OBJECT (client), "save_yourself",
191 192
			    GTK_SIGNAL_FUNC (panel_session_save), NULL);
	gtk_object_set_data(GTK_OBJECT(client),"argv0",g_strdup(argv[0]));
193 194 195
	gtk_signal_connect (GTK_OBJECT (client), "die",
			    GTK_SIGNAL_FUNC (panel_session_die), NULL);

196
	if (GNOME_CLIENT_CONNECTED (client)) {
George Lebl's avatar
George Lebl committed
197
		char *session_id;
198

199 200 201 202 203 204 205 206 207
		if (gnome_cloned_client ())
		  {
		    /* This client has been resumed or is a clone of
                       another panel (i.e. gnome_cloned_client !=
                       NULL).  */
		    session_id= gnome_client_get_id (gnome_cloned_client ());
		  }
		else
		  session_id= NULL;
208

209 210
		if(session_id) {
			g_free(old_panel_cfg_path);
211
			old_panel_cfg_path = g_copy_strings("/panel.d/Session-",
212 213 214
							    session_id,"/",
							    NULL);
		}
215
		puts("connected to session manager");
216
	}
217

218 219 220 221
	/* Tell session manager how to run us.  */
	gnome_client_set_clone_command (client, 1, argv);
	gnome_client_set_restart_command (client, 1, argv);

222
	applets = g_array_new(FALSE);
223
	applet_count = 0;
224

George Lebl's avatar
George Lebl committed
225
	panel_tooltips = gtk_tooltips_new();
226 227 228

	/*set the globals*/
	load_up_globals();
229
	
230 231 232 233
	init_user_panels();

	init_user_applets();

234
	/*add forbidden lists to ALL panels*/
235
	g_list_foreach(panels,(GFunc)panel_widget_add_forbidden,NULL);
236 237 238

	/*this will make the drawers be hidden for closed panels etc ...*/
	send_state_change();
239 240 241 242
	
	/*attempt to sync the config every 10 seconds, only if a change was
	  indicated though*/
	config_sync_timeout = gtk_timeout_add(10*1000,try_config_sync,NULL);
243
	
Arturo Espinosa's avatar
Arturo Espinosa committed
244
	/* I use the glue code to avoid making this a C++ file */
245
	panel_corba_gtk_main ("IDL:GNOME/Panel:1.0");
Tom Tromey's avatar
Tom Tromey committed
246

Elliot Lee's avatar
Elliot Lee committed
247 248
	return 0;
}