extern.c 48.5 KB
Newer Older
1
/* Gnome panel: extern applet functions
2 3
 * (C) 1997,1998,1999,2000 the Free Software Foundation
 * (C) 2000 Eazel, Inc.
4 5 6 7 8 9
 *
 * Authors:  George Lebl
 *           Federico Mena
 *           Miguel de Icaza
 */

10 11 12
#include "config.h"
#include <gnome.h>

13 14 15 16 17
#include <gdk/gdkx.h>
#include <string.h>
#include <signal.h>

#include "panel-include.h"
18
#include "gnome-panel.h"
19
#include "gnome-run.h"
20 21 22 23 24 25

#define APPLET_EVENT_MASK (GDK_BUTTON_PRESS_MASK |		\
			   GDK_BUTTON_RELEASE_MASK |		\
			   GDK_POINTER_MOTION_MASK |		\
			   GDK_POINTER_MOTION_HINT_MASK)

26 27
#define pg_return_if_fail(evp,x) {if(!(x)) { g_warning("file %s: line %d: Corba Exception: type = %d exid = %s\n", __FILE__, __LINE__, (evp)->_major, (evp)->_repo_id); return; }}
#define pg_return_val_if_fail(evp,x,y) {if(!(x)) { g_warning("file %s: line %d: Corba Exception: type = %d exid = %s\n", __FILE__, __LINE__, (evp)->_major, (evp)->_repo_id); return y;}}
28

29 30 31 32
extern GSList *panels;

extern GSList *applets;
extern GSList *applets_last;
33 34
extern int applet_count;

35
extern int config_sync_timeout;
36
extern int applets_to_sync;
37 38 39
extern int panels_to_sync;
extern int need_complete_save;

40 41 42 43 44 45 46
extern GtkTooltips *panel_tooltips;

extern GlobalConfig global_config;

extern char *panel_cfg_path;
extern char *old_panel_cfg_path;

47
extern int ss_cur_applet;
48
extern gboolean ss_done_save;
49
extern GtkWidget* ss_timeout_dlg;
50
extern gushort ss_cookie;
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
/* Launching applets into other things then the panel */

typedef struct {
	char *goad_id;
	GNOME_PanelAppletBooter booter;
} OutsideExtern;

static GSList *outside_externs = NULL;

static void
push_outside_extern (const char *goad_id,
		     const GNOME_PanelAppletBooter booter,
		     CORBA_Environment *ev)
{
	OutsideExtern *oe;

	g_return_if_fail (goad_id != NULL);
	g_return_if_fail (booter != CORBA_OBJECT_NIL);

	oe = g_new0 (OutsideExtern, 1);

	oe->goad_id = g_strdup (goad_id);
	oe->booter = CORBA_Object_duplicate (booter, ev);

	outside_externs = g_slist_prepend (outside_externs, oe);
}

static GNOME_PanelAppletBooter
pop_outside_extern (const char *goad_id)
{
	GSList *li;

	g_return_val_if_fail (goad_id != NULL, CORBA_OBJECT_NIL);

	for (li = outside_externs; li != NULL; li = li->next) {
		OutsideExtern *oe = li->data;

		if (strcmp (oe->goad_id, goad_id) == 0) {
			GNOME_PanelAppletBooter booter = oe->booter;
			g_free (oe->goad_id);
			oe->goad_id = NULL;
			g_free (oe);
			return booter;
		}
	}
	return CORBA_OBJECT_NIL;
}

100 101 102 103 104 105 106 107
/********************* CORBA Stuff *******************/

CORBA_ORB orb = NULL;
CORBA_Environment ev;
PortableServer_POA thepoa;

/***Panel stuff***/
static GNOME_PanelSpot
108 109 110 111 112 113 114
s_panel_add_applet (PortableServer_Servant servant,
		    const GNOME_Applet panel_applet,
		    const CORBA_char *goad_id,
		    CORBA_char ** cfgpath,
		    CORBA_char ** globcfgpath,
		    CORBA_unsigned_long* wid,
		    CORBA_Environment *ev);
115 116

static GNOME_PanelSpot
117 118 119 120 121 122 123 124 125
s_panel_add_applet_full (PortableServer_Servant servant,
			 const GNOME_Applet panel_applet,
			 const CORBA_char *goad_id,
			 const CORBA_short panel,
			 const CORBA_short pos,
			 CORBA_char ** cfgpath,
			 CORBA_char ** globcfgpath,
			 CORBA_unsigned_long* wid,
			 CORBA_Environment *ev);
126 127

static void
128
s_panel_quit(PortableServer_Servant servant, CORBA_Environment *ev);
129 130

static CORBA_boolean
131
s_panel_get_in_drag(PortableServer_Servant servant, CORBA_Environment *ev);
132

133
static GNOME_StatusSpot
134
s_panel_add_status(PortableServer_Servant servant,
135 136
		   CORBA_unsigned_long* wid,
		   CORBA_Environment *ev);
137

138
static void
139
s_panel_notice_config_changes(PortableServer_Servant servant,
140 141
			      CORBA_Environment *ev);

142

143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
/** Panel2 additions **/
void s_panel_suggest_sync (PortableServer_Servant _servant,
			   CORBA_Environment * ev);
void s_panel_add_launcher (PortableServer_Servant _servant,
			   const CORBA_char * launcher_desktop,
			   const CORBA_short panel,
			   const CORBA_short pos,
			   CORBA_Environment * ev);
void s_panel_ask_about_launcher (PortableServer_Servant _servant,
				 const CORBA_char * exec_string,
				 const CORBA_short panel,
				 const CORBA_short pos,
				 CORBA_Environment * ev);
void s_panel_add_launcher_from_info (PortableServer_Servant _servant,
				     const CORBA_char * name,
				     const CORBA_char * comment,
				     const CORBA_char * exec,
				     const CORBA_char * icon,
				     const CORBA_short panel,
				     const CORBA_short pos,
				     CORBA_Environment * ev);
void s_panel_add_launcher_from_info_url (PortableServer_Servant _servant,
					 const CORBA_char * name,
					 const CORBA_char * comment,
					 const CORBA_char * url,
					 const CORBA_char * icon,
					 const CORBA_short panel,
					 const CORBA_short pos,
					 CORBA_Environment * ev);
void s_panel_run_box (PortableServer_Servant _servant,
		      const CORBA_char * initial_string,
		      CORBA_Environment * ev);
void s_panel_main_menu (PortableServer_Servant _servant,
			CORBA_Environment * ev);
177 178 179 180
void s_panel_launch_an_applet (PortableServer_Servant _servant,
			       const CORBA_char * goad_id,
			       const GNOME_PanelSpot spot,
			       CORBA_Environment * ev);
181

182 183 184
/*** PanelSpot stuff ***/

static CORBA_char *
185
s_panelspot_get_tooltip(PortableServer_Servant servant,
186 187 188
			CORBA_Environment *ev);

static void
189 190
s_panelspot_set_tooltip(PortableServer_Servant servant,
			const CORBA_char *val,
191 192 193
			CORBA_Environment *ev);

static CORBA_short
194
s_panelspot_get_parent_panel(PortableServer_Servant servant,
195 196 197
			     CORBA_Environment *ev);

static CORBA_short
198
s_panelspot_get_spot_pos(PortableServer_Servant servant,
199 200 201
			 CORBA_Environment *ev);

static GNOME_Panel_OrientType
202
s_panelspot_get_parent_orient(PortableServer_Servant servant,
203 204
			      CORBA_Environment *ev);

205 206
static CORBA_short
s_panelspot_get_parent_size(PortableServer_Servant servant,
207 208
			    CORBA_Environment *ev);

209
static CORBA_short
210
s_panelspot_get_free_space(PortableServer_Servant servant,
211 212
			   CORBA_Environment *ev);

213
static CORBA_boolean
214
s_panelspot_get_send_position(PortableServer_Servant servant,
215 216
			      CORBA_Environment *ev);
static void
217
s_panelspot_set_send_position(PortableServer_Servant servant,
218 219 220
			      CORBA_boolean,
			      CORBA_Environment *ev);

221
static CORBA_boolean
222
s_panelspot_get_send_draw(PortableServer_Servant servant,
223 224
			  CORBA_Environment *ev);
static void
225
s_panelspot_set_send_draw(PortableServer_Servant servant,
226 227 228 229
			  CORBA_boolean,
			  CORBA_Environment *ev);

static GNOME_Panel_RgbImage *
230
s_panelspot_get_rgb_background(PortableServer_Servant servant,
231 232
			       CORBA_Environment *ev);

233
static void
234
s_panelspot_register_us(PortableServer_Servant servant,
235 236 237
		     CORBA_Environment *ev);

static void
238
s_panelspot_unregister_us(PortableServer_Servant servant,
239 240 241
		       CORBA_Environment *ev);

static void
242
s_panelspot_abort_load(PortableServer_Servant servant,
243 244 245
		       CORBA_Environment *ev);

static void
246
s_panelspot_show_menu(PortableServer_Servant servant,
247 248 249
		      CORBA_Environment *ev);

static void
250
s_panelspot_drag_start(PortableServer_Servant servant,
251 252 253
		       CORBA_Environment *ev);

static void
254
s_panelspot_drag_stop(PortableServer_Servant servant,
255 256 257
		      CORBA_Environment *ev);

static void
258 259 260 261
s_panelspot_add_callback(PortableServer_Servant servant,
			 const CORBA_char *callback_name,
			 const CORBA_char *stock_item,
			 const CORBA_char *menuitem_text,
262 263 264
			 CORBA_Environment *ev);

static void
265 266
s_panelspot_remove_callback(PortableServer_Servant servant,
			    const CORBA_char *callback_name,
267
			    CORBA_Environment *ev);
268
static void
269 270 271
s_panelspot_callback_set_sensitive(PortableServer_Servant servant,
				   const CORBA_char *callback_name,
				   const CORBA_boolean sensitive,
272
				   CORBA_Environment *ev);
273 274

static void
275
s_panelspot_sync_config(PortableServer_Servant servant,
276 277
			CORBA_Environment *ev);

278
static void
279
s_panelspot_done_session_save(PortableServer_Servant servant,
280
			      CORBA_boolean ret,
281
			      CORBA_unsigned_long cookie,
282 283
			      CORBA_Environment *ev);

284 285 286 287 288 289 290
/*** StatusSpot stuff ***/

static void
s_statusspot_remove(POA_GNOME_StatusSpot *servant,
		    CORBA_Environment *ev);


291
static PortableServer_ServantBase__epv panel_base_epv = {
292 293 294
	NULL, /* _private */
	NULL, /* finalize */
	NULL  /* use base default_POA function */
295 296 297
};

static POA_GNOME_Panel__epv panel_epv = {
298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
	NULL, /* private data */
	s_panel_add_applet,
	s_panel_add_applet_full,
	s_panel_quit,
	s_panel_get_in_drag,
	s_panel_add_status,
	s_panel_notice_config_changes
};

static POA_GNOME_Panel2__epv panel2_epv = {
	NULL, /* private data */
	s_panel_suggest_sync,
	s_panel_add_launcher,
	s_panel_ask_about_launcher,
	s_panel_add_launcher_from_info,
	s_panel_add_launcher_from_info_url,
	s_panel_run_box,
315 316
	s_panel_main_menu,
	s_panel_launch_an_applet
317
};
318 319 320

static POA_GNOME_Panel2__vepv panel_vepv = { &panel_base_epv, &panel_epv, &panel2_epv };
static POA_GNOME_Panel2 panel_servant = { NULL, &panel_vepv };
321 322 323 324 325


static PortableServer_ServantBase__epv panelspot_base_epv = {
  NULL, /* _private */
  NULL, /* finalize */
326
  NULL  /* use base default_POA function */
327 328 329 330
};

static POA_GNOME_PanelSpot__epv panelspot_epv = {
  NULL, /* private data */
331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353
  s_panelspot_get_tooltip,
  s_panelspot_set_tooltip,
  s_panelspot_get_parent_panel,
  s_panelspot_get_spot_pos,
  s_panelspot_get_parent_orient,
  s_panelspot_get_parent_size,
  s_panelspot_get_free_space,
  s_panelspot_get_send_position,
  s_panelspot_set_send_position,
  s_panelspot_get_send_draw,
  s_panelspot_set_send_draw,
  s_panelspot_get_rgb_background,
  s_panelspot_register_us,
  s_panelspot_unregister_us,
  s_panelspot_abort_load,
  s_panelspot_show_menu,
  s_panelspot_drag_start,
  s_panelspot_drag_stop,
  s_panelspot_add_callback,
  s_panelspot_remove_callback,
  s_panelspot_callback_set_sensitive,
  s_panelspot_sync_config,
  s_panelspot_done_session_save
354 355 356
};
static POA_GNOME_PanelSpot__vepv panelspot_vepv = { &panelspot_base_epv, &panelspot_epv };

357 358 359
static PortableServer_ServantBase__epv statusspot_base_epv = {
  NULL, /* _private */
  NULL, /* finalize */
360
  NULL  /* use base default_POA function */
361 362 363 364 365 366 367 368
};

static POA_GNOME_StatusSpot__epv statusspot_epv = {
  NULL, /* private data */
  (gpointer)&s_statusspot_remove
};
static POA_GNOME_StatusSpot__vepv statusspot_vepv = { &statusspot_base_epv, &statusspot_epv };

369
/********************* NON-CORBA Stuff *******************/
370 371

static void
372
extern_start_new_goad_id(Extern *e)
373
{
374
        CORBA_Environment ev;
375 376 377
	CORBA_exception_init(&ev);
	CORBA_Object_release(goad_server_activate_with_id(NULL, e->goad_id, GOAD_ACTIVATE_NEW_ONLY|GOAD_ACTIVATE_ASYNC, NULL),&ev);
	CORBA_exception_free(&ev);
378 379
}

380
Extern *
381 382 383 384 385 386
extern_ref (Extern *ext)
{
	ext->refcount++;
	return ext;
}

387
void
388 389 390 391 392 393 394
extern_unref (Extern *ext)
{
	ext->refcount--;
	if (ext->refcount == 0)
		g_free (ext);
}

395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443
typedef struct {
	char *goad_id;
	char *cfgpath;
	int pos;
	int panel;
} ReloadCallbackData;

static void
destroy_reload_callback_data (gpointer data)
{
	ReloadCallbackData *d = data;

	g_free (d->goad_id);
	d->goad_id = NULL;
	g_free (d->cfgpath);
	d->cfgpath = NULL;

	g_free (d);
}

static void
reload_applet_callback (GtkWidget *w, int button, gpointer data)
{
	PanelWidget *panel;
	ReloadCallbackData *d = data;

	/* unless the button was YES, just do nothing */
	if (button != 0) {
		return;
	}

	/*select the nth panel*/
	g_assert (panels != NULL);
	panel = g_slist_nth_data (panels, d->panel);
	if (panel == NULL)
		panel = panels->data;

	load_extern_applet (d->goad_id, d->cfgpath, panel,
			    d->pos, TRUE /*exactpos*/, FALSE /*queue*/);
}

void
extern_before_remove (Extern *ext)
{
	char *s;
	const char *id ="";
	GtkWidget *dlg;
	ReloadCallbackData *d;

444 445
	if (ext->clean_remove ||
	    ext->didnt_want_save)
446 447 448 449 450 451 452 453 454 455 456 457 458 459
		return;

	id = ext->goad_id != NULL ? ext->goad_id : "";

	/* a hack, but useful to users */
	if (strcmp (id, "deskguide_applet") == 0) {
		id = _("Deskguide (the desktop pager)");
	} else if (strcmp (id, "tasklist_applet") == 0) {
		id = _("Tasklist");
	} else if (strcmp (id, "battery_applet") == 0) {
		id = _("The Battery");
	}

	s = g_strdup_printf (_("%s applet appears to have "
460 461
			       "died unexpectedly.\n\n"
			       "Reload this applet?\n\n"
462
			       "(If you choose not to reload it at "
463
			       "this time you can always add it from\n"
464
			       "the \"Applets\" submenu in the main "
465
			       "menu.)"), id);
466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509

	dlg = gnome_message_box_new (s, GNOME_MESSAGE_BOX_QUESTION,
				     _("Reload"),
				     GNOME_STOCK_BUTTON_CANCEL,
				     NULL);
	gnome_dialog_set_close (GNOME_DIALOG (dlg),
				TRUE /* click_closes */);
	gtk_window_set_wmclass (GTK_WINDOW (dlg),
				"applet_crashed", "Panel");

	g_free (s);

	d = g_new0 (ReloadCallbackData, 1);
	d->goad_id = g_strdup (ext->goad_id);
	d->cfgpath = g_strdup (ext->cfg);

	if (ext->info->widget != NULL) {
		AppletData *ad;
		ad = gtk_object_get_data (GTK_OBJECT (ext->info->widget),
					  PANEL_APPLET_DATA);
		d->pos = ad->pos;
		d->panel = g_slist_index (panels,
					  ext->info->widget->parent);
		if (d->panel < 0)
			d->panel = 0;
	} else {
		d->panel = 0;
		d->pos = 0;
	}

	gtk_signal_connect_full
		(GTK_OBJECT (dlg), "clicked",
		 GTK_SIGNAL_FUNC (reload_applet_callback),
		 NULL,
		 d,
		 destroy_reload_callback_data,
		 FALSE /*object*/,
		 FALSE /*after*/);

	gtk_widget_show (dlg);

	ext->clean_remove = TRUE;
}

510
void
511
extern_clean (Extern *ext)
512
{
513
	CORBA_Environment ev;
514
	PortableServer_ObjectId *id;
515
	CORBA_exception_init (&ev);
516

517 518 519 520 521
	/* to catch any weird cases, we won't be able to at the position here
	 * though so it will go to 0,0 */
	extern_before_remove (ext);

	g_free (ext->goad_id);
522 523
	ext->goad_id = NULL;

524
	g_free (ext->cfg);
525
	ext->cfg = NULL;
526

527
	CORBA_Object_release (ext->pspot, &ev);
528
	ext->pspot = NULL;
529
	CORBA_Object_release (ext->applet, &ev);
530
	ext->applet = NULL;
531 532
	id = PortableServer_POA_servant_to_id (thepoa, ext, &ev);
	PortableServer_POA_deactivate_object (thepoa, id, &ev);
533
	CORBA_free (id);
534
	POA_GNOME_PanelSpot__fini ((PortableServer_Servant) ext, &ev);
535
	
536 537
	if (ext->send_draw_timeout != 0) {
		gtk_timeout_remove (ext->send_draw_timeout);
538 539
		ext->send_draw_timeout = 0;
	}
540 541
	if (ext->send_draw_idle != 0) {
		gtk_idle_remove (ext->send_draw_idle);
542 543
		ext->send_draw_idle = 0;
	}
544

545
	extern_unref (ext);
546

547
	CORBA_exception_free (&ev);
548 549
}

550
static void
551
extern_socket_destroy(GtkWidget *w, gpointer data)
552
{
553
	GtkSocket *socket = GTK_SOCKET(w);
554
	Extern *ext = data;
555

556 557
	if (socket->same_app &&
	    socket->plug_window != NULL) {
558 559 560
		GtkWidget *plug_widget;
		gdk_window_get_user_data (socket->plug_window,
					  (gpointer *)&plug_widget);
561
		if(plug_widget != NULL) {
562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578
			/* XXX: hackaround to broken gtkplug/gtksocket!!!
			   KILL all references to ourselves on the plug
			   and all our references to the plug and then
			   destroy it.*/
			GtkWidget *toplevel = gtk_widget_get_toplevel (w);
			if (toplevel && GTK_IS_WINDOW (toplevel))
				gtk_window_remove_embedded_xid (GTK_WINDOW (toplevel), 
								GDK_WINDOW_XWINDOW (socket->plug_window));

			socket->plug_window = NULL;
			socket->same_app = FALSE;
			GTK_PLUG(plug_widget)->socket_window = NULL;
			GTK_PLUG(plug_widget)->same_app = FALSE;
			gtk_widget_destroy(plug_widget);
		}
	}

579 580 581 582 583
	if (ext->ebox != NULL)
		gtk_widget_destroy(ext->ebox);
	ext->ebox = NULL;

	extern_unref (ext);
584 585
}

586 587 588 589 590 591 592 593 594 595
/*static void
sal(GtkWidget *applet, GtkAllocation *alloc)
{
	printf("SOCKET req:   %dx%d\nSOCKET alloc: %dx%d\n",
	       applet->requisition.width,
	       applet->requisition.height,
	       applet->allocation.width,
	       applet->allocation.height);
}*/

596 597 598 599 600 601 602

static void
send_position_change(Extern *ext)
{
	/*ingore this until we get an ior*/
	if(ext->applet) {
		int x=0,y=0;
603 604
		GtkWidget *wid=ext->ebox;
		
605 606 607 608 609 610 611 612 613 614 615 616 617
		CORBA_Environment ev;
		CORBA_exception_init(&ev);
		/*go the the toplevel panel widget*/
		for(;;) {
			if(!GTK_WIDGET_NO_WINDOW(wid)) {
				x += wid->allocation.x;
				y += wid->allocation.y;
			}
			if(wid->parent)
				wid = wid->parent;
			else
				break;
		}
618
		GNOME_Applet_change_position(ext->applet, x, y, &ev);
619
		if(ev._major)
620 621
			panel_clean_applet (ext->info);
		CORBA_exception_free (&ev);
622 623 624
	}
}

625
static void
626
ebox_size_allocate (GtkWidget *applet, GtkAllocation *alloc, Extern *ext)
627
{
628 629
	if (ext->send_position)
		send_position_change (ext);
630 631 632
}

static void
633
socket_size_allocate (GtkWidget *applet, GtkAllocation *alloc)
634
{
635 636 637 638 639
	
	GtkRequisition req;

	gtk_widget_get_child_requisition (applet, &req);

640 641 642 643 644 645 646
	/* This hack must be here.  The problem is that since it is a two
	 * widget deep hierarchy, an applet that shrink will not cause the
	 * panel to allocate less space.  Such as a tasklist in dynamic
	 * mode.  Since applets always get their requisition, then if they
	 * are ever allocated more, that means we can have the panel resize
	 * them to their preferred size.  Here applet->parent is the
	 * PanelWidget actually. */
647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666
	if (req.width > 0 &&
	    req.height > 0 &&
	    (alloc->width > req.width ||
	     alloc->height > req.height))
		gtk_widget_queue_resize (applet->parent);

}

static void
socket_set_loading (GtkWidget *socket, PanelWidget *panel)
{
	static gboolean tried_loading = FALSE;
	static GdkPixbuf *pb = NULL;
	int size;

	/* sanity */
	if (socket == NULL ||
	    socket->window == NULL)
		return;

667
	size = panel->sz < 14 ? panel->sz : 14;
668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720

	if ( ! tried_loading) {
		char *file;
		file = gnome_pixmap_file ("gnome-unknown.png");

		if (file != NULL) {
			pb = gdk_pixbuf_new_from_file (file);

			g_free (file);
		}
	}
	tried_loading = TRUE;

	if (pb != NULL) {
		GdkPixmap *pm;
		GdkPixbuf *scaled;

		if (gdk_pixbuf_get_width (pb) != size ||
		    gdk_pixbuf_get_height (pb) != size) {
			scaled = gdk_pixbuf_scale_simple (pb, size, size,
							  GDK_INTERP_BILINEAR);
		} else {
			scaled = gdk_pixbuf_ref (pb);
		}


		pm = NULL;
		gdk_pixbuf_render_pixmap_and_mask (scaled, &pm, NULL, 127);

		gdk_pixbuf_unref (scaled);

		if (pm != NULL) {
			gdk_window_set_back_pixmap (socket->window, pm, FALSE);

			gdk_pixmap_unref (pm);
		}
	}
}

static void
socket_unset_loading (GtkWidget *socket)
{
	/* sanity */
	if (socket == NULL)
		return;

	/* sanity */
	if (socket->parent != NULL)
		gtk_widget_queue_resize (socket->parent);

	/* sanity */
	if (socket->window != NULL)
		gdk_window_set_back_pixmap (socket->window, NULL, FALSE);
721 722 723 724 725 726 727 728

	/* sanity */
	if (socket->parent != NULL) {
		gtk_widget_set_usize (socket->parent, -1, -1);
		gtk_signal_connect_after
			(GTK_OBJECT (socket),"size_allocate",
			 GTK_SIGNAL_FUNC (socket_size_allocate), NULL);
	}
729 730
}

731 732 733 734 735
/*note that type should be APPLET_EXTERN_RESERVED or APPLET_EXTERN_PENDING
  only*/
static CORBA_unsigned_long
reserve_applet_spot (Extern *ext, PanelWidget *panel, int pos,
		     AppletType type)
736
{
737
	int size;
738
	GtkWidget *socket;
739

740 741 742 743 744
	ext->ebox = gtk_event_box_new();
	gtk_widget_set_events(ext->ebox, (gtk_widget_get_events(ext->ebox) |
					  APPLET_EVENT_MASK) &
			      ~( GDK_POINTER_MOTION_MASK |
				 GDK_POINTER_MOTION_HINT_MASK));
745

746
	size = panel->sz < 14 ? panel->sz : 14;
747

748
	gtk_widget_set_usize (ext->ebox, size, size);
749

750 751 752
	gtk_signal_connect_after (GTK_OBJECT (ext->ebox),"size_allocate",
				  GTK_SIGNAL_FUNC (ebox_size_allocate),
				  ext);
753

754
	socket = gtk_socket_new();
755

756 757 758 759 760
	if(!socket) {
		g_warning("Can't create a socket");
		return 0;
	}

761
	/* here for debugging purposes */
762 763 764
	/*gtk_signal_connect_after(GTK_OBJECT(socket),"size_allocate",
				 GTK_SIGNAL_FUNC(sal),NULL);*/

765
	gtk_container_add(GTK_CONTAINER(ext->ebox), socket);
766

767
	gtk_widget_show_all (ext->ebox);
768 769 770 771
	
	/*we save the obj in the id field of the appletinfo and the 
	  path in the path field */
	ext->info = NULL;
772 773 774
	if(!register_toy(ext->ebox,
			 ext, (GDestroyNotify)extern_clean,
			 panel, pos, ext->exactpos, type)) {
775 776
		/* the ebox is destroyed in register_toy */
		ext->ebox = NULL;
777
		g_warning(_("Couldn't add applet"));
778 779 780
		return 0;
	}
	ext->info = applets_last->data;
781

782 783 784
	gtk_signal_connect(GTK_OBJECT (socket), "destroy",
			   GTK_SIGNAL_FUNC (extern_socket_destroy),
			   extern_ref (ext));
785 786 787
	
	if(!GTK_WIDGET_REALIZED(socket))
		gtk_widget_realize(socket);
788

789 790
	socket_set_loading (socket, panel);

791
	return GDK_WINDOW_XWINDOW(socket->window);
792 793
}

794 795 796 797 798 799 800 801 802
/* Note exactpos may NOT be changed */
static PanelWidget *
get_us_position (const int panel, const int pos, const char *goad_id, int *newpos,
		 gboolean *exactpos)
{
	PanelWidget *pw = NULL;

	*newpos = pos;

803 804 805 806 807 808
	/* Sanity? can this ever happen? */
	if (goad_id == NULL) {
		g_warning ("get_us_position: goad_id == NULL, bad bad");
		goad_id = "foo";
	}

809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852
	if (panel < 0 || pos < 0) {
		char *key = g_strdup_printf ("%sApplet_Position_Memory/%s/",
					     PANEL_CONFIG_PATH,
					     goad_id);
		gnome_config_push_prefix (key);
		g_free (key);

		if (pos < 0)
			*newpos = gnome_config_get_int ("position=-1");
		if (panel < 0) {
			guint32 unique_id = gnome_config_get_int ("panel_unique_id=0");
			if (unique_id != 0) {
				pw = panel_widget_get_by_id (unique_id);
			}
			if (pw == NULL) {
				*newpos = -1;
			}
		}

		gnome_config_pop_prefix ();
	}

	if (pw == NULL && panel < 0)
		pw = panels->data;

	if (*newpos < 0)
		*newpos = 0;
	else if (exactpos != NULL)
		 *exactpos = TRUE;

	if (pw == NULL) {
		/*select the nth panel*/
		GSList *node = g_slist_nth (panels, panel);
		if (node == NULL)
			node = panels;
		/* There's always at least one */
		g_assert (node != NULL);
		pw = node->data;
	}

	return pw;
}


853
void
854 855 856
load_extern_applet (const char *goad_id, const char *cfgpath,
		    PanelWidget *panel, int pos, gboolean exactpos,
		    gboolean queue)
857
{
858
	char *cfg;
859 860
	Extern *ext;
	POA_GNOME_PanelSpot *panelspot_servant;
861

862
	if (string_empty (cfgpath))
863 864
		cfg = g_strconcat (PANEL_CONFIG_PATH,
				   "Applet_Dummy/", NULL);
865 866
	else
		/*we will free this lateer*/
867 868 869
		cfg = g_strdup (cfgpath);

	ext = g_new0 (Extern, 1);
870
	ext->refcount = 1;
871
	ext->started = FALSE;
872
	ext->exactpos = exactpos;
873
	ext->send_position = FALSE;
874
	ext->send_draw = FALSE;
875
	ext->orient = -1;
876

877 878 879 880
	/* don't know until first save, but FALSE since
	 * we assume it will want to. */
	ext->didnt_want_save = FALSE;

881 882 883
	/* not until we are properly added */
	ext->clean_remove = TRUE;

884
	ext->send_draw_timeout = 0;
885
	ext->send_draw_idle = 0;
886
	ext->send_draw_queued = FALSE;
887

888

889 890 891
	panelspot_servant = (POA_GNOME_PanelSpot *)ext;
	panelspot_servant->_private = NULL;
	panelspot_servant->vepv = &panelspot_vepv;
892

893 894 895
	POA_GNOME_PanelSpot__init(panelspot_servant, &ev);
	
	CORBA_free(PortableServer_POA_activate_object(thepoa, panelspot_servant, &ev));
896
	pg_return_if_fail(&ev, ev._major == CORBA_NO_EXCEPTION);
897

898 899 900
	ext->pspot = CORBA_OBJECT_NIL; /*will be filled in during add_applet*/
	ext->applet = CORBA_OBJECT_NIL;
	ext->goad_id = g_strdup(goad_id);
901
	ext->cfg = cfg;
902

903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920
	if (panel == NULL || pos < 0) {
		if (panel != NULL) {
			gboolean exactpos;
			/* We have a panel */
			PanelWidget *pw = get_us_position (-1, pos, goad_id,
							   &pos, &exactpos);
			/* only use this position if
			 * pw and panel are the same */
			if (pw != panel)
				pos = 0;
			else
				ext->exactpos = exactpos;
		} else /* panel == NULL && pos < 0 */ {
			panel = get_us_position (-1, -1, goad_id, &pos,
						 &ext->exactpos);
		}
	}

921
	if(reserve_applet_spot (ext, panel, pos, APPLET_EXTERN_PENDING)==0) {
922 923
		g_warning(_("Whoops! for some reason we can't add "
			    "to the panel"));
924 925 926
		extern_clean(ext);
		return;
	}
927

928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948
	if(!queue) {
		extern_start_new_goad_id(ext);
		ext->started = TRUE;
	}
}

void
load_queued_externs(void)
{
	GSList *li;
	for(li=applets;li!=NULL;li=g_slist_next(li)) {
		AppletInfo *info = li->data;
		if(info->type == APPLET_EXTERN_PENDING ||
		   info->type == APPLET_EXTERN_RESERVED) {
			Extern *ext = info->data;
			if(!ext->started) {
				extern_start_new_goad_id(ext);
				ext->started = TRUE;
			}
		}
	}
949
}
950

951
/********************* CORBA Stuff *******************/
952

953

954
static GNOME_PanelSpot
955 956 957 958 959 960 961
s_panel_add_applet (PortableServer_Servant servant,
		    const GNOME_Applet panel_applet,
		    const CORBA_char *goad_id,
		    CORBA_char ** cfgpath,
		    CORBA_char ** globcfgpath,
		    CORBA_unsigned_long* wid,
		    CORBA_Environment *ev)
962
{
963
	return s_panel_add_applet_full (servant, panel_applet, goad_id, -1, -1,
964
					cfgpath, globcfgpath, wid, ev);
965 966
}

967
static GNOME_PanelSpot
968 969 970 971 972 973 974 975 976
s_panel_add_applet_full (PortableServer_Servant servant,
			 const GNOME_Applet panel_applet,
			 const CORBA_char *goad_id,
			 const CORBA_short panel,
			 const CORBA_short pos,
			 CORBA_char ** cfgpath,
			 CORBA_char ** globcfgpath,
			 CORBA_unsigned_long* wid,
			 CORBA_Environment *ev)
977
{
978 979
	PanelWidget *pw;
	int newpos;
980
	GSList *li;
981
	Extern *ext;
982 983
	POA_GNOME_PanelSpot *panelspot_servant;
	GNOME_PanelSpot acc;
984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005
	GNOME_PanelAppletBooter booter;

	booter = pop_outside_extern (goad_id);
	if (booter != CORBA_OBJECT_NIL) {
		/* yeah, we do dump the panel and pos, since they
		 * really don't make any sesnse, and aren't really
		 * used anywhere in the first place */
		acc = GNOME_PanelAppletBooter_add_applet (booter,
							  panel_applet,
							  goad_id,
							  cfgpath,
							  globcfgpath,
							  wid,
							  ev);

		/* if we succeeded, then all fine and dandy, otherwise
		 * this thing was some stale thingie, so just ignore it
		 * and launch us into the panel.  This way we're always
		 * getting the applet, even if the booter crashed or we
		 * had a stale one around */
		if (ev->_major == CORBA_NO_EXCEPTION)
			return acc;
1006 1007 1008 1009

		/* recycle the exception */
		CORBA_exception_free (ev);
		CORBA_exception_init (ev);
1010
	}
1011
	
1012
	for (li = applets; li != NULL; li = li->next) {
1013
		AppletInfo *info = li->data;
1014
		if (info && info->type == APPLET_EXTERN_PENDING) {
1015 1016
			Extern *ext = info->data;
			g_assert(ext);
1017
			g_assert(ext->info == info);
1018 1019
			g_assert(ext->goad_id != NULL);
			if (strcmp(ext->goad_id, goad_id)==0) {
1020 1021
				/*we started this and already reserved a spot
				  for it, including the socket widget*/
1022 1023
				GtkWidget *socket =
					GTK_BIN(info->widget)->child;
1024 1025 1026 1027
				if(!socket) {
					g_warning(_("No socket was created"));
					return CORBA_OBJECT_NIL;
				}
1028

1029 1030
				ext->applet = CORBA_Object_duplicate(panel_applet, ev);
				*cfgpath = CORBA_string_dup(ext->cfg);
1031

1032
				*globcfgpath = CORBA_string_dup(PANEL_CONFIG_PATH);
1033
				info->type = APPLET_EXTERN_RESERVED;
1034
				*wid = GDK_WINDOW_XWINDOW(socket->window);
1035
#ifdef PANEL_DEBUG
1036
				printf("\nSOCKET XID: %lX\n\n", (long)*wid);
1037
#endif
1038 1039 1040

				panelspot_servant = (POA_GNOME_PanelSpot *)ext;
				acc = PortableServer_POA_servant_to_reference(thepoa, panelspot_servant, ev);
1041
				pg_return_val_if_fail(ev, ev->_major == CORBA_NO_EXCEPTION, CORBA_OBJECT_NIL);
1042
				ext->pspot = CORBA_Object_duplicate(acc, ev);
1043
				pg_return_val_if_fail(ev, ev->_major == CORBA_NO_EXCEPTION, CORBA_OBJECT_NIL);
1044 1045

				return CORBA_Object_duplicate(acc, ev);
1046 1047 1048 1049
			}
		}
	}
	
1050 1051
	/*this is an applet that was started from outside, otherwise we would
	  have already reserved a spot for it*/
1052
	ext = g_new0(Extern, 1);
1053
	ext->refcount = 1;
1054
	ext->started = FALSE;
1055
	ext->exactpos = FALSE;
1056
	ext->send_position = FALSE;
1057
	ext->send_draw = FALSE;
1058
	ext->orient = -1;
1059 1060 1061
	ext->applet = CORBA_Object_duplicate(panel_applet, ev);
	ext->goad_id = g_strdup(goad_id);
	ext->cfg = NULL;
1062 1063 1064 1065 1066

	panelspot_servant = (POA_GNOME_PanelSpot *)ext;
	panelspot_servant->_private = NULL;
	panelspot_servant->vepv = &panelspot_vepv;

1067
	POA_GNOME_PanelSpot__init (panelspot_servant, ev);
1068
	
1069
	CORBA_free(PortableServer_POA_activate_object (thepoa, panelspot_servant, ev));
1070 1071
	pg_return_val_if_fail(ev, ev->_major == CORBA_NO_EXCEPTION,
			      CORBA_OBJECT_NIL);
1072

1073
	acc = PortableServer_POA_servant_to_reference (thepoa, panelspot_servant, ev);
1074 1075
	pg_return_val_if_fail(ev, ev->_major == CORBA_NO_EXCEPTION,
			      CORBA_OBJECT_NIL);
1076 1077 1078

	ext->pspot = CORBA_Object_duplicate(acc, ev);

1079 1080
	pg_return_val_if_fail(ev, ev->_major == CORBA_NO_EXCEPTION,
			      CORBA_OBJECT_NIL);
1081

1082
	pw = get_us_position (panel, pos, goad_id, &newpos, &ext->exactpos);
1083

1084
	*wid = reserve_applet_spot (ext, pw, newpos,
1085
				    APPLET_EXTERN_RESERVED);
1086
	if (*wid == 0) {
1087
		extern_clean(ext);
1088 1089
		*globcfgpath = NULL;
		*cfgpath = NULL;
1090
		return CORBA_OBJECT_NIL;
1091
	}
1092
	*cfgpath = CORBA_string_dup(PANEL_CONFIG_PATH "Applet_Dummy/");
1093
	*globcfgpath = CORBA_string_dup (PANEL_CONFIG_PATH);
1094

1095
	return CORBA_Object_duplicate(acc, ev);
1096 1097
}

1098
static void
1099
s_panel_quit (PortableServer_Servant servant, CORBA_Environment *ev)
1100
{
1101
	panel_quit ();
1102 1103 1104
}

static CORBA_boolean
1105
s_panel_get_in_drag (PortableServer_Servant servant, CORBA_Environment *ev)
1106 1107 1108 1109
{
	return panel_applet_in_drag;
}

1110
static GNOME_StatusSpot
1111 1112 1113
s_panel_add_status (PortableServer_Servant servant,
		    CORBA_unsigned_long *wid,
		    CORBA_Environment *ev)
1114 1115 1116 1117 1118
{
	POA_GNOME_StatusSpot *statusspot_servant;
	GNOME_StatusSpot acc;
	StatusSpot *ss;
	
1119 1120
	*wid = 0;
	
1121
	ss = new_status_spot();
1122
	if (ss == NULL)
1123 1124 1125 1126 1127 1128 1129 1130
		return CORBA_OBJECT_NIL;
	
	statusspot_servant = (POA_GNOME_StatusSpot *)ss;
	statusspot_servant->_private = NULL;
	statusspot_servant->vepv = &statusspot_vepv;

	POA_GNOME_StatusSpot__init(statusspot_servant, ev);
	
1131 1132 1133
	CORBA_free (PortableServer_POA_activate_object (thepoa, statusspot_servant, ev));
	pg_return_val_if_fail (ev, ev->_major == CORBA_NO_EXCEPTION,
			       CORBA_OBJECT_NIL);
1134 1135

	acc = PortableServer_POA_servant_to_reference(thepoa, statusspot_servant, ev);
1136 1137
	pg_return_val_if_fail (ev, ev->_major == CORBA_NO_EXCEPTION,
			       CORBA_OBJECT_NIL);
1138

1139
	ss->sspot = CORBA_Object_duplicate (acc, ev);
1140

1141 1142
	pg_return_val_if_fail(ev, ev->_major == CORBA_NO_EXCEPTION,
			      CORBA_OBJECT_NIL);
1143 1144 1145 1146

	*wid = ss->wid;
	return CORBA_Object_duplicate(acc, ev);
}
1147

1148
static void
1149
s_panel_notice_config_changes(PortableServer_Servant servant,
1150 1151 1152 1153 1154
			      CORBA_Environment *ev)
{
	load_up_globals();
}

1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256
/** Panel2 additions **/

void
s_panel_suggest_sync (PortableServer_Servant _servant,
		      CORBA_Environment * ev)
{
	need_complete_save = TRUE;
	panel_config_sync();
}

void
s_panel_add_launcher (PortableServer_Servant _servant,
		      const CORBA_char * launcher_desktop,
		      const CORBA_short panel,
		      const CORBA_short pos,
		      CORBA_Environment * ev)
{
	Launcher *launcher;
	PanelWidget *panel_widget;

	g_assert (panels != NULL);

	panel_widget = g_slist_nth_data (panels, panel);
	if (panel_widget == NULL)
		panel_widget = panels->data;

	launcher = load_launcher_applet (launcher_desktop,
					 panel_widget, pos, FALSE);
	if (launcher != NULL)
		launcher_hoard (launcher);
}

void
s_panel_ask_about_launcher (PortableServer_Servant _servant,
			    const CORBA_char * exec_string,
			    const CORBA_short panel,
			    const CORBA_short pos,
			    CORBA_Environment * ev)
{
	PanelWidget *panel_widget;

	g_assert (panels != NULL);

	panel_widget = g_slist_nth_data (panels, panel);
	if (panel_widget == NULL)
		panel_widget = panels->data;

	ask_about_launcher (exec_string, panel_widget, pos, FALSE);
}

void
s_panel_add_launcher_from_info (PortableServer_Servant _servant,
				const CORBA_char * name,
				const CORBA_char * comment,
				const CORBA_char * exec,
				const CORBA_char * icon,
				const CORBA_short panel,
				const CORBA_short pos,
				CORBA_Environment * ev)
{
	PanelWidget *panel_widget;
	char *exec_argv[2] = { NULL, NULL };

	g_assert (panels != NULL);

	panel_widget = g_slist_nth_data (panels, panel);
	if (panel_widget == NULL)
		panel_widget = panels->data;

	/* ugly but works because of the way this actually works */
	exec_argv[0] = (char *)exec;
	load_launcher_applet_from_info (name, comment, exec_argv, 1,
					icon, panel_widget, pos, FALSE);
}

void
s_panel_add_launcher_from_info_url (PortableServer_Servant _servant,
				    const CORBA_char * name,
				    const CORBA_char * comment,
				    const CORBA_char * url,
				    const CORBA_char * icon,
				    const CORBA_short panel,
				    const CORBA_short pos,
				    CORBA_Environment * ev)
{
	PanelWidget *panel_widget;

	g_assert (panels != NULL);

	panel_widget = g_slist_nth_data (panels, panel);
	if (panel_widget == NULL)
		panel_widget = panels->data;

	load_launcher_applet_from_info_url (name, comment, url,
					    icon, panel_widget, pos, FALSE);
}

void
s_panel_run_box (PortableServer_Servant _servant,
		 const CORBA_char * initial_string,
		 CORBA_Environment * ev)
{
1257
	if (string_empty (initial_string))
1258
		show_run_dialog ();
1259 1260
	else
		show_run_dialog_with_text (initial_string);
1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288
}

void
s_panel_main_menu (PortableServer_Servant _servant,
		   CORBA_Environment * ev)
{
	PanelWidget *panel;
	GtkWidget *menu, *basep;

	/* check if anybody else has a grab */
	if (gdk_pointer_grab (GDK_ROOT_PARENT(), FALSE, 
			      0, NULL, NULL, GDK_CURRENT_TIME)
	    != GrabSuccess) {
		return;
	} else {
		gdk_pointer_ungrab (GDK_CURRENT_TIME);
	}

	panel = panels->data;
	menu = make_popup_panel_menu (panel);
	basep = panel->panel_parent;
	if (IS_BASEP_WIDGET(basep)) {
		BASEP_WIDGET(basep)->autohide_inhibit = TRUE;
		basep_widget_autohide (BASEP_WIDGET (basep));
	}
	gtk_menu_popup (GTK_MENU (menu), NULL, NULL,
			NULL, NULL, 0, GDK_CURRENT_TIME);
}
1289

1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316
void
s_panel_launch_an_applet (PortableServer_Servant _servant,
			  const CORBA_char *goad_id,
			  const GNOME_PanelSpot spot,
			  CORBA_Environment *ev)
{
	if (goad_id != NULL &&
	    spot != CORBA_OBJECT_NIL) {
		CORBA_Object applet;

		/* push us */
		push_outside_extern (goad_id, spot, ev);

		/* launch the applet, EVIL! this way shlib applets
		 * get dumped into the panel.  Reason?  Simple:  the
		 * shlib applet logic is complex, broken, evil and
		 * whatever, we do not want to impose it upon an
		 * unsuspecting PanelSpot. */
		applet = goad_server_activate_with_id (NULL, goad_id,
						       GOAD_ACTIVATE_NEW_ONLY |
						       GOAD_ACTIVATE_ASYNC,
						       NULL);

		CORBA_Object_release (applet, ev);
	}
}

1317 1318 1319
/*** PanelSpot stuff ***/

static CORBA_char *
1320
s_panelspot_get_tooltip(PortableServer_Servant servant,
1321
			CORBA_Environment *ev)
1322
{
1323 1324 1325 1326 1327 1328
	Extern *ext = (Extern *)servant;
	GtkTooltipsData *d = gtk_tooltips_data_get(ext->ebox);
	if(!d || !d->tip_text)
		return CORBA_string_dup("");
	else
		return CORBA_string_dup(d->tip_text);
1329 1330 1331
}

static void
1332 1333
s_panelspot_set_tooltip(PortableServer_Servant servant,
			const CORBA_char *val,
1334 1335 1336 1337
			CORBA_Environment *ev)
{
	Extern *ext = (Extern *)servant;
	if(val && *val)
1338
		gtk_tooltips_set_tip (panel_tooltips, ext->ebox, val, NULL);
1339
	else
1340
		gtk_tooltips_set_tip (panel_tooltips, ext->ebox, NULL, NULL);
1341 1342 1343
}

static CORBA_short
1344
s_panelspot_get_parent_panel(PortableServer_Servant servant,
1345 1346 1347
			     CORBA_Environment *ev)
{
	int panel;
1348
	GSList *list;
1349 1350 1351 1352 1353 1354 1355 1356
	gpointer p;
	Extern *ext = (Extern *)servant;

	g_assert(ext);
	g_assert(ext->info);

	p = PANEL_WIDGET(ext->info->widget->parent);

1357
	for(panel=0,list=panels;list!=NULL;list=g_slist_next(list),panel++)
1358 1359 1360 1361 1362 1363
		if(list->data == p)
			return panel;
	return -1;
}

static CORBA_short
1364
s_panelspot_get_spot_pos(PortableServer_Servant servant,
1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378
			 CORBA_Environment *ev)
{
	Extern *ext = (Extern *)servant;
	AppletData *ad;

	g_assert(ext);
	g_assert(ext->info);
	
	ad = gtk_object_get_data(GTK_OBJECT(ext->info->widget),
				 PANEL_APPLET_DATA);
	if(!ad)
		return -1;
	return ad->pos;
}
1379

1380
static GNOME_Panel_OrientType
1381
s_panelspot_get_parent_orient(PortableServer_Servant servant,
1382 1383 1384 1385
			      CORBA_Environment *ev)
{
	Extern *ext = (Extern *)servant;
	PanelWidget *panel;
1386

1387
	g_assert(ext);
1388
	g_assert(ext->info);
1389

1390
	panel = PANEL_WIDGET(ext->info->widget->parent);
1391

1392
	if(!panel) {
1393
		g_warning("%s:%d ??? Applet with no panel ???",
1394 1395 1396
			 __FILE__, __LINE__);
		return ORIENT_UP;
	}
1397 1398 1399 1400

	return get_applet_orient(panel);
}

1401 1402
static CORBA_short
s_panelspot_get_parent_size(PortableServer_Servant servant,
1403 1404 1405 1406 1407 1408 1409 1410 1411 1412
			    CORBA_Environment *ev)
{
	Extern *ext = (Extern *)servant;
	PanelWidget *panel;

	g_assert(ext);
	g_assert(ext->info);

	panel = PANEL_WIDGET(ext->info->widget->parent);

1413
	if(!panel) {
1414
		g_warning("%s:%d ??? Applet with no panel ???",
1415 1416 1417
			 __FILE__, __LINE__);
		return SIZE_STANDARD;
	}
1418 1419 1420 1421

	return panel->sz;
}

1422
static CORBA_short
1423
s_panelspot_get_free_space(PortableServer_Servant servant,
1424 1425 1426 1427 1428 1429 1430 1431 1432
			   CORBA_Environment *ev)
{
	Extern *ext = (Extern *)servant;
	PanelWidget *panel;

	g_assert(ext);
	g_assert(ext->info);

	panel = PANEL_WIDGET(ext->info->widget->parent);
1433 1434

	if(!panel) {
1435
		g_warning("%s:%d ??? Applet with no panel ???",
1436 1437 1438
			 __FILE__, __LINE__);
		return 0;
	}
1439 1440 1441 1442
	
	return panel_widget_get_free_space(panel,ext->info->widget);
}

1443
static CORBA_boolean
1444
s_panelspot_get_send_position(PortableServer_Servant servant,
1445 1446 1447 1448 1449 1450 1451 1452 1453 1454
			      CORBA_Environment *ev)
{
	Extern *ext = (Extern *)servant;

	g_assert(ext);
	
	return ext->send_position;
}

static void
1455
s_panelspot_set_send_position(PortableServer_Servant servant,
1456 1457 1458 1459 1460 1461 1462 1463 1464 1465
			      CORBA_boolean enable,
			      CORBA_Environment *ev)
{
	Extern *ext = (Extern *)servant;

	g_assert(ext);
	
	ext->send_position = enable?TRUE:FALSE;
}

1466
static CORBA_boolean
1467
s_panelspot_get_send_draw(PortableServer_Servant servant,
1468 1469 1470 1471 1472 1473 1474 1475 1476 1477
			  CORBA_Environment *ev)
{
	Extern *ext = (Extern *)servant;

	g_assert(ext);
	
	return ext->send_draw;
}

static void
1478
s_panelspot_set_send_draw(PortableServer_Servant servant,
1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489
			  CORBA_boolean enable,
			  CORBA_Environment *ev)
{
	Extern *ext = (Extern *)servant;

	g_assert(ext);
	
	ext->send_draw = enable?TRUE:FALSE;
}

static GNOME_Panel_RgbImage *
1490
s_panelspot_get_rgb_background(PortableServer_Servant servant,
1491 1492 1493 1494 1495 1496 1497
			       CORBA_Environment *ev)
{
	Extern *ext = (Extern *)servant;
	PanelWidget *panel;
	GNOME_Panel_RgbImage *image;
	int w, h, rowstride;
	guchar *rgb;
1498
	int r,g,b;
1499 1500 1501 1502 1503 1504 1505

	g_assert(ext);
	g_assert(ext->info);

	panel = PANEL_WIDGET(ext->info->widget->parent);

	panel_widget_get_applet_rgb_bg(panel, ext->ebox,
1506 1507 1508
				       &rgb,&w,&h,&rowstride,
				       TRUE,&r,&g,&b);

1509 1510 1511
	image = GNOME_Panel_RgbImage__alloc();
	image->width = w;
	image->height = h;
1512 1513 1514 1515 1516 1517 1518 1519
		
	/* if we got an rgb */
	if(rgb) {
		image->data._buffer = CORBA_sequence_CORBA_octet_allocbuf(h*rowstride);
		image->data._length = image->data._maximum = h*rowstride;
		memcpy(image->data._buffer,rgb,sizeof(guchar)*h*rowstride);
		image->rowstride = rowstride;
		image->color_only = FALSE;
1520
		g_free(rgb);
1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531
	} else { /* we must have gotten a color */
		image->data._buffer = CORBA_sequence_CORBA_octet_allocbuf(3);
		image->data._length = image->data._maximum = 3;
		*(image->data._buffer) = r;
		*(image->data._buffer+1) = g;
		*(image->data._buffer+2) = b;
		image->rowstride = 0;
		image->color_only = TRUE;
	}
	CORBA_sequence_set_release(&image->data, TRUE);

1532 1533 1534
	return image;
}

1535
static void
1536
s_panelspot_register_us(PortableServer_Servant servant,
1537 1538 1539 1540 1541
			CORBA_Environment *ev)
{
	PanelWidget *panel;
	Extern *ext = (Extern *)servant;

1542 1543
	g_assert (ext != NULL);
	g_assert (ext->info != NULL);
1544
	
1545
#ifdef PANEL_DEBUG
1546 1547
	printf("register ext: %lX\n",(long)ext);
	printf("register ext->info: %lX\n",(long)(ext->info));
1548
#endif
1549

1550 1551 1552 1553
	panel = PANEL_WIDGET