123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624 |
- /*
- * Midnight Commander -- GNOME frontend
- *
- * Copyright (C) 1997, 1998 The Free Software Foundation
- *
- * Author: Miguel de Icaza (miguel@gnu.org)
- *
- */
- #include <config.h>
- #include <stdarg.h>
- #include <string.h>
- #include <ctype.h>
- #define WANT_WIDGETS
- #include "tty.h" /* for KEY_BACKSPACE */
- #include "x.h"
- #include "main.h"
- #include "key.h"
- #include "global.h"
- #include "dir.h"
- #include "panel.h"
- #include "gscreen.h"
- #include "command.h"
- #include "cmd.h"
- #include "gdesktop.h"
- GdkColorContext *mc_cc;
- #define MAX_COLOR_PAIRS 32
- struct gmc_color_pairs_s gmc_color_pairs [MAX_COLOR_PAIRS];
- char *default_edition_colors =
- "normal=black:"
- "selected=white,darkblue:"
- "viewunderline=brightred,blue:"
- "directory=blue:"
- "markselect=yellow,darkblue:"
- "marked=yellow,seagreen:"
- "execute=slateblue:"
- "link=green:"
- "device=magenta:"
- "core=red:"
- "menuhotsel=cyan,black:"
- "errors=white,red:"
- "reverse=black,lightcyan:"
- "special=black";
- int dialog_panel_callback (struct Dlg_head *h, int id, int msg);
- /* The Dlg_head for the whole desktop */
- Dlg_head *desktop_dlg;
- /* This is only used by the editor, so we provide a dummy implementation */
- void
- try_alloc_color_pair (char *str, char *str2)
- {
- }
- void
- init_pair (int index, GdkColor *fore, GdkColor *back)
- {
- if (index < 0 || index > MAX_COLOR_PAIRS){
- printf ("init_pair called with invalid index\n");
- exit (1);
- }
- gmc_color_pairs [index].fore = fore;
- gmc_color_pairs [index].back = back;
- }
- void
- get_color (char *cpp, GdkColor **colp)
- {
- GdkColor *new_color;
- gint status;
- new_color = g_new (GdkColor, 1);
- gdk_color_parse (cpp, new_color);
- new_color->pixel = 0;
- status = 0;
- gdk_color_context_get_pixels (mc_cc, &new_color->red, &new_color->green, &new_color->blue, 1,
- &new_color->pixel, &status);
- *colp = new_color;
- }
- static void
- gmc_color_init (void)
- {
- mc_cc = gdk_color_context_new (gtk_widget_get_default_visual (),
- gtk_widget_get_default_colormap ());
- }
- int
- xtoolkit_init (int *argc, char *argv [])
- {
- LINES = 40;
- COLS = 80;
- printf (
- "The GNOME file manager is going trough a massive code\n"
- "rewrite, so many problems are known to exist due to a major\n"
- "code design shift.\n\n"
- "Yes, we know there are lots of problems in the current code\n"
- "so dont even report them, when the major design has finished\n"
- "I will remove this notice\n");
- gmc_color_init ();
- return 0;
- }
- int
- xtoolkit_end (void)
- {
- return 1;
- }
- /*
- * Keystroke event handler for all of the Gtk widgets created by
- * the GNOME Midnight Commander. A special case is handled at
- * the top
- */
- int
- dialog_key_pressed (GtkWidget *win, GdkEventKey *event, Dlg_head *h)
- {
- GtkWidget *w;
- static int on_escape;
- int key;
- /*
- * Find out if the focused widget is an IconList and
- * if so, check if it has a currently focused item is
- * on editing mode as we do not want to handle key
- * events while the icon name is being edited.
- */
- w = win;
- while (w && (GTK_IS_CONTAINER (w) && !GNOME_IS_ICON_LIST (w)))
- w = GTK_CONTAINER (w)->focus_child;
-
- if (w && GNOME_IS_ICON_LIST (w)){
- GnomeCanvas *c = GNOME_CANVAS (w);
- if (c->focused_item && GNOME_IS_ICON_TEXT_ITEM (c->focused_item)){
- GnomeIconTextItem *i = GNOME_ICON_TEXT_ITEM (c->focused_item);
- if (i->editing)
- return FALSE;
- }
- }
- key = translate_gdk_keysym_to_curses (event);
- if (key == -1)
- return FALSE;
- if (!on_escape){
- if (key == 27){
- on_escape = 1;
- gtk_signal_emit_stop_by_name (GTK_OBJECT (win), "key_press_event");
- return TRUE;
- }
- } else {
- if (key != 27){
- if (key >= '0' && key <= '9')
- key = KEY_F(key - '0');
- else
- key = ALT (key);
- if (key == ALT('<'))
- key = KEY_HOME;
- if (key == ALT('>'))
- key = KEY_END;
- }
- on_escape = 0;
- }
-
- if (dlg_key_event (h, key)){
- gtk_signal_emit_stop_by_name (GTK_OBJECT (win), "key_press_event");
- return TRUE;
- } else
- return FALSE;
- }
- void
- bind_gtk_keys (GtkWidget *w, Dlg_head *h)
- {
- gtk_signal_connect (GTK_OBJECT (w),
- "key_press_event",
- GTK_SIGNAL_FUNC (dialog_key_pressed),
- h);
- }
- widget_data
- xtoolkit_create_dialog (Dlg_head *h, int flags)
- {
- GtkWidget *win, *ted;
- if (!(flags & DLG_NO_TOPLEVEL)){
- if (flags & DLG_GNOME_APP)
- win = gnome_app_new ("mc", h->name);
- else {
- win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_window_position (GTK_WINDOW (win), GTK_WIN_POS_MOUSE);
- }
- } else
- win = 0;
-
- h->grided = flags;
- h->idle_fn_tag = -1;
- if (!(flags & DLG_NO_TED)){
- ted = gtk_ted_new_layout (h->name, LIBDIR "/layout");
- gtk_container_add (GTK_CONTAINER (win), ted);
- gtk_widget_show (ted);
-
- bind_gtk_keys (GTK_WIDGET (ted), h);
- }
- if (win){
- bind_gtk_keys (GTK_WIDGET (win), h);
- }
- return (widget_data) win;
- }
- /* Used to bind a window for an already created Dlg_head. This is
- * used together with the DLG_NO_TOPLEVEL: the dialog is created
- * with the DLG_NO_TOPLEVEL and later, when the window is created
- * it is assigned with this routine
- */
- void
- x_dlg_set_window (Dlg_head *h, GtkWidget *win)
- {
- h->wdata = (widget_data) win;
- bind_gtk_keys (GTK_WIDGET (win), h);
- }
- void
- x_set_dialog_title (Dlg_head *h, char *title)
- {
- gtk_window_set_title (GTK_WINDOW (h->wdata), title);
- }
- widget_data
- xtoolkit_get_main_dialog (Dlg_head *h)
- {
- GtkWidget *win;
- win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- return (widget_data) win;
- }
- /* Creates the containers */
- widget_data
- x_create_panel_container (int which)
- {
- GtkWidget *win;
- win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- return (widget_data) 0;
- }
- void
- x_panel_container_show (widget_data wdata)
- {
- gtk_widget_show (GTK_WIDGET (wdata));
- }
- void
- x_add_widget (Dlg_head *h, Widget_Item *w)
- {
- if (!(h->grided & DLG_NO_TED)){
- GtkTed *ted = GTK_TED (GTK_BIN (h->wdata)->child);
- gtk_ted_add (ted, GTK_WIDGET (w->widget->wdata), w->widget->tkname);
- bind_gtk_keys (GTK_WIDGET (w->widget->wdata), h);
- }
- }
- static int
- gnome_dlg_send_destroy (GtkWidget *widget, GdkEvent *event, Dlg_head *h)
- {
- gtk_widget_hide (GTK_WIDGET (h->wdata));
- h->ret_value = B_CANCEL;
- dlg_stop (h);
- return TRUE;
- }
- void
- x_init_dlg (Dlg_head *h)
- {
- if (!(h->grided & DLG_NO_TED)){
- GtkTed *ted = GTK_TED (GTK_BIN (h->wdata)->child);
- Widget_Item *p, *first;
-
- first = p = h->current;
- do {
- gtk_ted_add (ted, GTK_WIDGET (p->widget->wdata), p->widget->tkname);
- bind_gtk_keys (GTK_WIDGET (p->widget->wdata), h);
- p = p->next;
- } while (p != first);
- gtk_ted_prepare (ted);
-
- if (!ted->need_gui){
- gtk_grab_add (GTK_WIDGET (ted));
- gtk_window_set_policy (GTK_WINDOW (h->wdata), 0, 0, 0);
- }
- gtk_widget_show (GTK_WIDGET (h->wdata));
- }
- gtk_signal_connect (GTK_OBJECT (h->wdata), "delete_event",
- GTK_SIGNAL_FUNC (gnome_dlg_send_destroy), h);
- x_focus_widget (h->current);
- }
- /*
- * This function is invoked when the dialog is started to be
- * destroyed, before any widgets have been destroyed.
- *
- * We only hide the toplevel Gtk widget to avoid the flickering
- * of the destruction process
- */
- void
- x_destroy_dlg_start (Dlg_head *h)
- {
- gtk_widget_hide (GTK_WIDGET (h->wdata));
- }
- /*
- * Called when the Dlg_head has been destroyed. This only cleans
- * up/releases the frontend resources
- */
- void
- x_destroy_dlg (Dlg_head *h)
- {
- if (!(h->grided & DLG_NO_TED))
- gtk_grab_remove (GTK_WIDGET (GTK_BIN (h->wdata)->child));
- if (h->wdata){
- gtk_widget_destroy (GTK_WIDGET(h->wdata));
- h->wdata = 0;
- }
- }
- void
- gtkrundlg_event (Dlg_head *h)
- {
- gtk_main ();
- }
- void
- edition_pre_exec ()
- {
- }
- void
- edition_post_exec ()
- {
- }
- void
- done_screen ()
- {
- }
- void
- setup_sigwinch ()
- {
- }
- void
- x_flush_events (void)
- {
- while (gtk_events_pending ())
- gtk_main_iteration ();
- }
- static int
- gnome_idle_handler (gpointer data)
- {
- Dlg_head *h = data;
- if (h->send_idle_msg){
- (*h->callback)(h, 0, DLG_IDLE);
- return TRUE;
- } else
- return FALSE;
- }
- /* Turn on and off the idle message sending */
- void
- x_set_idle (Dlg_head *h, int enable_idle)
- {
- if (enable_idle){
- if (h->idle_fn_tag != -1)
- return;
- h->idle_fn_tag = gtk_idle_add (gnome_idle_handler, h);
- } else {
- if (h->idle_fn_tag == -1)
- return;
- gtk_idle_remove (h->idle_fn_tag);
- h->idle_fn_tag = -1;
- gnome_idle_handler (h);
- }
- }
- int
- dialog_panel_callback (struct Dlg_head *h, int id, int msg)
- {
- WPanel *p;
- WInput *in;
- Widget_Item *dh;
- void *current_widget; /* The current widget */
-
- if (msg == DLG_KEY && id == '\n'){
- current_widget = (void *) h->current->widget;
- if (is_a_panel (current_widget))
- return 0;
- dh = h->current;
- do {
- if (is_a_panel (dh->widget)){
- WPanel *p = (WPanel *) dh->widget;
- if (current_widget == p->filter_w){
- in = (WInput *) current_widget;
- set_panel_filter_to (p, strdup (in->buffer));
- return MSG_HANDLED;
- }
-
- if (current_widget == p->current_dir){
- WInput *in = p->current_dir;
-
- do_panel_cd (p, in->buffer, cd_parse_command);
- assign_text (in, p->cwd);
- update_input (in, 1);
-
- return MSG_HANDLED;
- }
- }
- dh = dh->next;
- } while (dh != h->current);
- }
- if (msg == DLG_UNHANDLED_KEY || msg == DLG_HOTKEY_HANDLED)
- return midnight_callback (h, id, msg);
- return 0;
- }
- extern char *cmdline_geometry;
- typedef struct {
- char *dir; char *geometry;
- } dir_and_geometry;
- static int
- idle_create_panel (void *data)
- {
- dir_and_geometry *dg = data;
- new_panel_with_geometry_at (dg->dir, dg->geometry);
- g_free (data);
- return 0;
- }
- static int
- idle_destroy_window (void *data)
- {
- WPanel *panel = data;
- gnome_close_panel (GTK_WIDGET (panel->widget.wdata), panel);
- return 0;
- }
- /*
- * wrapper for new_panel_with_geometry_at.
- * first invocation is called directly, further calls use
- * the idle handler
- */
- static WPanel *
- create_one_panel (char *dir, char *geometry)
- {
- static int first = 1;
-
- if (first){
- first = 0;
- return new_panel_with_geometry_at (dir, geometry);
- } else {
- dir_and_geometry *dg = g_new (dir_and_geometry, 1);
- dg->dir = dir;
- dg->geometry = geometry;
- gtk_idle_add (idle_create_panel, dg);
- return NULL;
- }
- }
- /*
- * Only at startup we have a strange condition: if more than one
- * panel is created, then the code hangs inside X, it keeps waiting
- * for a reply for something in Imlib that never returns.
- *
- * Creating the panels on the idle loop takes care of this
- */
- void
- create_panels (void)
- {
- GList *p, *g;
- char *geo;
- WPanel *panel;
- #if 1
- desktop_init ();
- #else
- start_desktop ();
- #endif
- cmdline = command_new (0, 0, 0);
- the_hint = label_new (0, 0, 0, NULL);
- gnome_init_panels ();
-
- desktop_dlg = create_dlg (0, 0, 24, 80, 0, dialog_panel_callback, "[panel]", "midnight", DLG_NO_TED);
- #if 0
- if (directory_list){
- for (p = directory_list; p; p = p->next){
- create_one_panel (p->data, cmdline_geometry);
- }
- panel = NULL;
- } else
- #endif
- {
- panel = create_one_panel (".", cmdline_geometry);
- if (nowindows){
- gtk_idle_add (idle_destroy_window, panel);
- panel->widget.options |= W_PANEL_HIDDEN;
- }
- }
- #if 0
- g_list_free (directory_list);
- #endif
- run_dlg (desktop_dlg);
- /* shutdown gnome specific bits of midnight commander */
- #if 1
- desktop_destroy ();
- #else
- stop_desktop ();
- #endif
- }
- static void
- session_die (void)
- {
- extern int quit;
-
- /* FIXME: This wont get us out from a dialog box */
- gtk_main_quit ();
- quit = 1;
- dlg_stop (desktop_dlg);
- }
- /*
- * Save the session callback
- */
- static int
- session_save_state (GnomeClient *client, gint phase, GnomeRestartStyle save_style, gint shutdown,
- GnomeInteractStyle interact_style, gint fast, gpointer client_data)
- {
- char *sess_id;
- char **argv = g_malloc (sizeof (char *) * ((g_list_length (containers) * 3) + 2));
- GList *l, *free_list = 0;
- int i;
- sess_id = gnome_client_get_id (client);
-
- argv [0] = client_data;
- for (i = 1, l = containers; l; l = l->next){
- PanelContainer *pc = l->data;
- int x, y, w, h;
- char *buffer = g_malloc (32);
- gdk_window_get_origin (GTK_WIDGET (pc->panel->widget.wdata)->window, &x, &y);
- gdk_window_get_size (GTK_WIDGET (pc->panel->widget.wdata)->window, &w, &h);
- sprintf (buffer, "%dx%d+%d+%d", w, h, x, y);
- argv [i++] = pc->panel->cwd;
- argv [i++] = "--geometry";
- argv [i++] = buffer;
- free_list = g_list_append (free_list, buffer);
- }
- /* If no windows were open */
- if (i == 1){
- argv [i++] = "--nowindows";
- }
- argv [i] = NULL;
- gnome_client_set_clone_command (client, i, argv);
- gnome_client_set_restart_command (client, i, argv);
- for (l = free_list; l; l = l->next)
- g_free (l->data);
- g_list_free (free_list);
- g_free (argv);
- if (shutdown){
- quit = 1;
- dlg_stop (midnight_dlg);
- }
- return 1;
- }
- void
- session_management_setup (char *name)
- {
- GnomeClient *client;
-
- client = gnome_master_client ();
- if (client){
- gtk_signal_connect (GTK_OBJECT (client), "save_yourself",
- GTK_SIGNAL_FUNC (session_save_state), name);
- gtk_signal_connect (GTK_OBJECT (client), "die",
- GTK_SIGNAL_FUNC (session_die), NULL);
- }
- }
|