Gosh, some little cosmetics here...
[midnight-commander.git] / gnome / gcorba.c
blob3adf8d3249826fdf4884d17390f9150b61c650e3
1 /* CORBA support for the Midnight Commander
3 * Copyright (C) 1999 The Free Sofware Foundation
5 * Authors: Miguel de Icaza <miguel@nuclecu.unam.mx>
6 * Federico Mena <federico@nuclecu.unam.mx>
7 * Elliot Lee <sopwith@cuc.edu>
8 */
10 #include <config.h>
11 #include "global.h"
12 #include <libgnorba/gnorba.h>
13 #include "panel.h"
14 #include "../vfs/vfs.h"
15 #include "FileManager.h"
16 #include "gcorba.h"
17 #include "gdesktop.h"
18 #include "global.h"
19 #include "gmain.h"
20 #include "gscreen.h"
21 #include "main.h"
24 /* The ORB for the whole program */
25 CORBA_ORB orb = CORBA_OBJECT_NIL;
27 /* The POA */
28 PortableServer_POA poa = CORBA_OBJECT_NIL;
32 /* Desktop servant */
33 typedef struct {
34 POA_GNOME_FileManager_Desktop servant;
35 } DesktopServant;
37 static PortableServer_ServantBase__epv desktop_base_epv;
38 static POA_GNOME_FileManager_Desktop__epv desktop_epv;
39 static POA_GNOME_FileManager_Desktop__vepv desktop_vepv;
41 /* Window servant */
42 typedef struct {
43 POA_GNOME_FileManager_Window servant;
45 WPanel *panel;
46 } WindowServant;
48 static PortableServer_ServantBase__epv window_base_epv;
49 static POA_GNOME_FileManager_Window__epv window_epv;
50 static POA_GNOME_FileManager_Window__vepv window_vepv;
52 /* WindowFactory servant */
54 typedef struct {
55 POA_GNOME_FileManager_WindowFactory servant;
56 } WindowFactoryServant;
58 static PortableServer_ServantBase__epv window_factory_base_epv;
59 static POA_GNOME_GenericFactory__epv window_factory_generic_factory_epv;
60 static POA_GNOME_FileManager_WindowFactory__epv window_factory_epv;
61 static POA_GNOME_FileManager_WindowFactory__vepv window_factory_vepv;
65 /* References to the window factory and desktop server objects */
67 static CORBA_Object window_factory_server = CORBA_OBJECT_NIL;
68 static CORBA_Object desktop_server = CORBA_OBJECT_NIL;
72 /* Desktop implementation */
74 /* Desktop::rescan method */
75 static void
76 Desktop_rescan (PortableServer_Servant servant, CORBA_Environment *ev)
78 desktop_reload_icons (FALSE, 0, 0);
81 /* Desktop::rescan_devices method */
82 static void
83 Desktop_rescan_devices (PortableServer_Servant servant, CORBA_Environment *ev)
85 desktop_rescan_devices ();
88 /* Desktop::arrange_icons method */
89 static void
90 Desktop_arrange_icons (PortableServer_Servant servant,
91 GNOME_FileManager_Desktop_ArrangeType type,
92 CORBA_Environment *ev)
94 SortType sort_type;
96 switch (type) {
97 case GNOME_FileManager_Desktop_BY_NAME:
98 sort_type = SORT_NAME;
99 break;
101 case GNOME_FileManager_Desktop_BY_TYPE:
102 sort_type = SORT_EXTENSION;
103 break;
105 case GNOME_FileManager_Desktop_BY_SIZE:
106 sort_type = SORT_SIZE;
107 break;
109 case GNOME_FileManager_Desktop_BY_ATIME:
110 sort_type = SORT_ACCESS;
111 break;
113 case GNOME_FileManager_Desktop_BY_MTIME:
114 sort_type = SORT_MODIFY;
115 break;
117 case GNOME_FileManager_Desktop_BY_CTIME:
118 sort_type = SORT_CHANGE;
119 break;
121 default:
122 return; /* Should we raise an exception instead? */
125 desktop_arrange_icons (sort_type);
128 /* Fills the vepv structure for the desktop object */
129 static void
130 Desktop_class_init (void)
132 static int inited = FALSE;
134 if (inited)
135 return;
137 inited = TRUE;
139 desktop_epv.rescan = Desktop_rescan;
140 desktop_epv.rescan_devices = Desktop_rescan_devices;
141 desktop_epv.arrange_icons = Desktop_arrange_icons;
143 desktop_vepv._base_epv = &desktop_base_epv;
144 desktop_vepv.GNOME_FileManager_Desktop_epv = &desktop_epv;
147 /* Creates a reference for the desktop object */
148 static GNOME_FileManager_Desktop
149 Desktop_create (PortableServer_POA poa, CORBA_Environment *ev)
151 DesktopServant *ds;
152 PortableServer_ObjectId *objid;
154 Desktop_class_init ();
156 ds = g_new0 (DesktopServant, 1);
157 ds->servant.vepv = &desktop_vepv;
159 POA_GNOME_FileManager_Desktop__init ((PortableServer_Servant) ds, ev);
160 objid = PortableServer_POA_activate_object (poa, ds, ev);
161 CORBA_free (objid);
163 return PortableServer_POA_servant_to_reference (poa, ds, ev);
168 /* Window implementation */
170 /* Window::close method */
171 static void
172 Window_close (PortableServer_Servant servant, CORBA_Environment *ev)
174 WindowServant *ws;
176 ws = (WindowServant *) servant;
177 gnome_close_panel (GTK_WIDGET (ws->panel->xwindow), ws->panel);
180 /* Destroys the servant for an image window */
181 static void
182 window_destroy (WindowServant *ws, CORBA_Environment *ev)
184 PortableServer_ObjectId *objid;
186 objid = PortableServer_POA_servant_to_id (poa, ws, ev);
187 PortableServer_POA_deactivate_object (poa, objid, ev);
188 CORBA_free (objid);
190 POA_GNOME_FileManager_Window__fini (ws, ev);
191 g_free (ws);
194 /* Fills the vepv structure for the window object */
195 static void
196 Window_class_init (void)
198 static int inited = FALSE;
200 if (inited)
201 return;
203 inited = TRUE;
205 window_epv.close = Window_close;
207 window_vepv._base_epv = &window_base_epv;
208 window_vepv.GNOME_FileManager_Window_epv = &window_epv;
213 /* WindowFactory implementation */
215 /* WindowFactory::the_desktop attribute getter */
216 static GNOME_FileManager_Desktop
217 WindowFactory_get_the_desktop (PortableServer_Servant servant,
218 CORBA_Environment *ev)
220 g_assert (desktop_server != CORBA_OBJECT_NIL);
222 return CORBA_Object_duplicate (desktop_server, ev);
225 /* Called when a panel created through CORBA is destroyed */
226 static void
227 panel_destroyed (GtkObject *object, gpointer data)
229 WindowServant *ws;
230 CORBA_Environment ev;
232 ws = data;
234 CORBA_exception_init (&ev);
235 window_destroy (ws, &ev);
236 CORBA_exception_free (&ev);
239 /* Returns a servant for a panel, creating one if necessary */
240 static WindowServant *
241 window_servant_from_panel (WPanel *panel, CORBA_Environment *ev)
243 WindowServant *ws;
244 PortableServer_ObjectId *objid;
246 if (panel->servant)
247 return panel->servant;
249 Window_class_init ();
251 ws = g_new0 (WindowServant, 1);
252 ws->servant.vepv = &window_vepv;
254 POA_GNOME_FileManager_Window__init ((PortableServer_Servant) ws, ev);
255 objid = PortableServer_POA_activate_object (poa, ws, ev);
256 CORBA_free (objid);
258 ws->panel = panel;
259 panel->servant = ws;
261 gtk_signal_connect (GTK_OBJECT (panel->xwindow), "destroy",
262 (GtkSignalFunc) panel_destroyed,
263 ws);
265 return ws;
268 /* WindowFactory::create_window method */
269 static GNOME_FileManager_Window
270 WindowFactory_create_window (PortableServer_Servant servant,
271 const CORBA_char *dir,
272 CORBA_Environment *ev)
274 WPanel *panel;
275 WindowServant *ws;
277 panel = new_panel_at (dir);
278 ws = window_servant_from_panel (panel, ev);
280 return PortableServer_POA_servant_to_reference (poa, ws, ev);
283 /* WindowFactory::rescan_directory method */
284 static void
285 WindowFactory_rescan_directory (PortableServer_Servant servant,
286 const CORBA_char *dir,
287 CORBA_Environment *ev)
289 PanelContainer *pc;
290 GList *l;
291 int len;
293 /* We do a blind compare against the panel's cwd */
295 len = strlen (dir);
296 if (dir[len - 1] == PATH_SEP)
297 len--;
299 for (l = containers; l; l = l->next) {
300 pc = l->data;
302 if (strncmp (dir, pc->panel->cwd, len) == 0
303 && (pc->panel->cwd[len] == 0 || pc->panel->cwd[len] == PATH_SEP))
304 update_one_panel_widget (pc->panel, UP_RELOAD, UP_KEEPSEL);
308 /* WindowFactory::close_invalid_windows method */
309 static void
310 WindowFactory_close_invalid_windows (PortableServer_Servant servant,
311 CORBA_Environment *ev)
313 PanelContainer *pc;
314 GList *l;
316 /* To see if a panel is valid or not, we try to cd to its cwd. If this
317 * fails, then we destroy the panel's window.
320 l = containers;
321 while (l) {
322 pc = l->data;
323 l = l->next;
325 if (mc_chdir (pc->panel->cwd) != 0)
326 gnome_close_panel (GTK_WIDGET (pc->panel->xwindow), pc->panel);
330 /* Creates an object reference for a panel */
331 static GNOME_FileManager_Window
332 window_reference_from_panel (WPanel *panel, CORBA_Environment *ev)
334 WindowServant *ws;
336 ws = window_servant_from_panel (panel, ev);
337 return PortableServer_POA_servant_to_reference (poa, ws, ev);
340 /* WindowFactory::get_window_by_directory method */
341 static GNOME_FileManager_WindowFactory_WindowSeq *
342 WindowFactory_get_windows_by_directory (PortableServer_Servant servant,
343 const CORBA_char *dir,
344 CORBA_Environment *ev)
346 GNOME_FileManager_WindowFactory_WindowSeq *seq;
347 PanelContainer *pc;
348 GList *l;
349 int n, i;
351 /* We return a sequence of the windows that match the specified
352 * directory.
355 /* Count 'em */
356 n = 0;
357 for (l = containers; l; l = l->next) {
358 pc = l->data;
360 if (strcmp (pc->panel->cwd, dir) == 0)
361 n++;
364 seq = GNOME_FileManager_WindowFactory_WindowSeq__alloc ();
365 seq->_length = n;
366 seq->_buffer = CORBA_sequence_GNOME_FileManager_Window_allocbuf (n);
368 i = 0;
370 for (l = containers; l; l = l->next) {
371 pc = l->data;
373 if (strcmp (pc->panel->cwd, dir) == 0)
374 seq->_buffer[i++] = window_reference_from_panel (pc->panel, ev);
377 return seq;
380 /* WindowFactory GenericFactory::supports method */
381 static CORBA_boolean
382 WindowFactory_supports (PortableServer_Servant servant,
383 const CORBA_char *obj_goad_id,
384 CORBA_Environment *ev)
386 if (strcmp (obj_goad_id, "IDL:GNOME:FileManager:Window:1.0") == 0
387 || strcmp (obj_goad_id, "IDL:GNOME:FileManager:Desktop:1.0") == 0)
388 return CORBA_TRUE;
389 else
390 return CORBA_FALSE;
393 /* WindowFactory GenericFactory::create_object method */
394 static CORBA_Object
395 WindowFactory_create_object (PortableServer_Servant servant,
396 const CORBA_char *goad_id,
397 const GNOME_stringlist *params,
398 CORBA_Environment *ev)
400 if (strcmp (goad_id, "IDL:GNOME:FileManager:Window:1.0") != 0)
401 return WindowFactory_create_window (
402 servant,
403 params->_length != 0 ? params->_buffer[0] : home_dir,
404 ev);
405 else if (strcmp (goad_id, "IDL:GNOME:FileManager:Desktop:1.0") == 0)
406 return WindowFactory_get_the_desktop (servant, ev);
407 else {
408 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
409 ex_GNOME_GenericFactory_CannotActivate,
410 NULL);
411 return CORBA_OBJECT_NIL;
415 /* Fills the vepv structure for the window factory object */
416 static void
417 WindowFactory_class_init (void)
419 static int inited = FALSE;
421 if (inited)
422 return;
424 inited = TRUE;
426 window_factory_generic_factory_epv.supports = WindowFactory_supports;
427 window_factory_generic_factory_epv.create_object = WindowFactory_create_object;
429 window_factory_epv._get_the_desktop = WindowFactory_get_the_desktop;
430 window_factory_epv.create_window = WindowFactory_create_window;
431 window_factory_epv.rescan_directory = WindowFactory_rescan_directory;
432 window_factory_epv.close_invalid_windows = WindowFactory_close_invalid_windows;
433 window_factory_epv.get_windows_by_directory = WindowFactory_get_windows_by_directory;
435 window_factory_vepv._base_epv = &window_factory_base_epv;
436 window_factory_vepv.GNOME_GenericFactory_epv = &window_factory_generic_factory_epv;
437 window_factory_vepv.GNOME_FileManager_WindowFactory_epv = &window_factory_epv;
440 /* Creates a reference for the window factory object */
441 static GNOME_FileManager_WindowFactory
442 WindowFactory_create (PortableServer_POA poa, CORBA_Environment *ev)
444 WindowFactoryServant *wfs;
445 PortableServer_ObjectId *objid;
447 WindowFactory_class_init ();
449 wfs = g_new0 (WindowFactoryServant, 1);
450 wfs->servant.vepv = &window_factory_vepv;
452 POA_GNOME_FileManager_WindowFactory__init ((PortableServer_Servant) wfs, ev);
453 objid = PortableServer_POA_activate_object (poa, wfs, ev);
454 CORBA_free (objid);
456 return PortableServer_POA_servant_to_reference (poa, wfs, ev);
461 /* Creates and registers the CORBA servers. Returns TRUE on success, FALSE
462 * otherwise.
464 static int
465 register_servers (void)
467 CORBA_Environment ev;
468 int retval;
469 int v;
471 retval = FALSE;
472 CORBA_exception_init (&ev);
474 /* Register the window factory and see if it was already there */
476 window_factory_server = WindowFactory_create (poa, &ev);
477 if (ev._major != CORBA_NO_EXCEPTION)
478 goto out;
480 v = goad_server_register (CORBA_OBJECT_NIL, window_factory_server,
481 "IDL:GNOME:FileManager:WindowFactory:1.0", "object", &ev);
482 switch (v) {
483 case 0:
484 corba_have_server = FALSE;
485 break;
487 case -2:
488 corba_have_server = FALSE;
489 break;
491 default:
492 goto out;
495 /* Register the desktop server */
497 desktop_server = Desktop_create (poa, &ev);
498 if (ev._major != CORBA_NO_EXCEPTION)
499 goto out;
501 goad_server_register (CORBA_OBJECT_NIL, desktop_server,
502 "IDL:GNOME:FileManager:Desktop:1.0", "object", &ev);
504 retval = TRUE;
506 /* Done */
507 out:
508 CORBA_exception_free (&ev);
510 return retval;
514 * corba_init_server:
515 * @void:
517 * Initializes the CORBA server for GMC. Returns whether initialization was
518 * successful or not, and sets the global corba_have_server variable.
520 * Return value: TRUE if successful, FALSE otherwise.
523 corba_init_server (void)
525 int retval;
526 CORBA_Environment ev;
528 retval = FALSE;
529 CORBA_exception_init (&ev);
531 /* Get the POA and create the server */
533 poa = (PortableServer_POA) CORBA_ORB_resolve_initial_references (orb, "RootPOA", &ev);
534 if (ev._major != CORBA_NO_EXCEPTION)
535 goto out;
537 CORBA_exception_free (&ev);
539 /* See if the servers are there */
541 window_factory_server = goad_server_activate_with_id (
542 NULL,
543 "IDL:GNOME:FileManager:WindowFactory:1.0",
544 GOAD_ACTIVATE_EXISTING_ONLY,
545 NULL);
547 desktop_server = goad_server_activate_with_id (
548 NULL,
549 "IDL:GNOME:FileManager:Desktop:1.0",
550 GOAD_ACTIVATE_EXISTING_ONLY,
551 NULL);
553 if (window_factory_server != CORBA_OBJECT_NIL) {
554 corba_have_server = TRUE;
555 retval = TRUE;
556 } else
557 retval = register_servers ();
559 out:
560 return retval;
564 * corba_activate_server:
565 * @void:
567 * Activates the POA manager and thus makes the services available to the
568 * outside world.
570 void
571 corba_activate_server (void)
573 CORBA_Environment ev;
574 PortableServer_POAManager poa_manager;
576 /* Do nothing if the server is already running */
577 if (corba_have_server)
578 return;
580 CORBA_exception_init (&ev);
582 poa_manager = PortableServer_POA__get_the_POAManager (poa, &ev);
583 if (ev._major != CORBA_NO_EXCEPTION)
584 goto out;
586 PortableServer_POAManager_activate (poa_manager, &ev);
587 if (ev._major != CORBA_NO_EXCEPTION)
588 goto out;
590 out:
592 CORBA_exception_free (&ev);
596 * corba_create_window:
597 * @dir: The directory in which to create the window, or NULL for the cwd.
599 * Creates a GMC window using a CORBA call to the server.
601 void
602 corba_create_window (char *dir)
604 CORBA_Environment ev;
605 char cwd[MC_MAXPATHLEN];
607 if (dir == NULL) {
608 mc_get_current_wd (cwd, MC_MAXPATHLEN);
609 dir = cwd;
612 CORBA_exception_init (&ev);
613 GNOME_FileManager_WindowFactory_create_window (window_factory_server, dir, &ev);
614 CORBA_exception_free (&ev);