~ubuntu-branches/ubuntu/utopic/pcmanfm/utopic

« back to all changes in this revision

Viewing changes to src/ptk/ptk-console-output.c

  • Committer: Bazaar Package Importer
  • Author(s): Andrew Lee (李健秋)
  • Date: 2010-05-23 23:04:11 UTC
  • mfrom: (8.1.1 experimental)
  • Revision ID: james.westby@ubuntu.com-20100523230411-4ei3g4u14pf5rozb
Tags: 0.9.5-2
* Upload to sid. No new additional bug report since last upload into 
  experimental. (Closes:#506243, #509257, #532973, #502225, #535810, 
  #570114, #581033, #518683)
* debian/control:
  Adjusted depends/recommends for people who doesn't want to have gvfs
  on their system. Without gvfs installed, pcmanfm would still works 
  but lose volume management and trashcan support.
  - Drop depends on gamin, shared-mime-info, desktop-file-utils, dbus, 
    xdg-user-dirs
  - Recommends on lxde-icon-theme | gnome-icon-theme, gvfs-backends,
    gvfs-fuse

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#include <gtk/gtk.h>
2
 
#include <glib/gi18n.h>
3
 
#include "glib-mem.h"
4
 
 
5
 
#include <unistd.h>
6
 
#include <fcntl.h>
7
 
#include <sys/wait.h>
8
 
#include <string.h>
9
 
#include <signal.h>     /* for kill(2) */
10
 
 
11
 
#include "ptk-utils.h"
12
 
 
13
 
typedef struct _PtkConsoleOutputData
14
 
{
15
 
    GtkWidget* main_dlg;
16
 
    GtkWidget* scroll;
17
 
    GtkTextView* view;
18
 
    GtkTextBuffer* buf;
19
 
 
20
 
    GPid pid;
21
 
    int stdo, stdi, stde;
22
 
    GIOChannel *chstdo, *chstdi, *chstde;
23
 
}PtkConsoleOutputData;
24
 
 
25
 
static gboolean on_complete( gpointer user_data )
26
 
{
27
 
    GtkAdjustment* adj = GTK_ADJUSTMENT( user_data );
28
 
    gdk_threads_enter();
29
 
    gtk_adjustment_set_value( adj, adj->upper-adj->page_size );
30
 
    gdk_threads_leave();
31
 
    return FALSE;
32
 
}
33
 
 
34
 
static gboolean delayed_destroy( gpointer dlg )
35
 
{
36
 
    gdk_threads_enter();
37
 
    gtk_widget_destroy( GTK_WIDGET( dlg ) );
38
 
    gdk_threads_leave();
39
 
    return FALSE;
40
 
}
41
 
 
42
 
static gboolean on_output( GIOChannel* ch, GIOCondition cond, gpointer user_data )
43
 
{
44
 
    GtkTextIter it;
45
 
    char buffer[4096];
46
 
    gsize rlen = 0;
47
 
    GtkAdjustment* adj;
48
 
    int status;
49
 
    PtkConsoleOutputData *data = (PtkConsoleOutputData*)user_data;
50
 
 
51
 
    if( cond & G_IO_IN )
52
 
    {
53
 
        g_io_channel_read_chars( ch, buffer, sizeof(buffer), &rlen, NULL );
54
 
        GDK_THREADS_ENTER();
55
 
        /*gdk_window_freeze_updates( GTK_WIDGET(data->view)->window );*/
56
 
        gtk_text_buffer_get_end_iter( data->buf, &it );
57
 
        gtk_text_buffer_insert( data->buf, &it, buffer, rlen );
58
 
        adj = gtk_scrolled_window_get_vadjustment( GTK_SCROLLED_WINDOW(data->scroll) );
59
 
        gtk_adjustment_set_value( adj, adj->upper-adj->page_size );
60
 
        /*gdk_window_thaw_updates( GTK_WIDGET(data->view)->window );*/
61
 
        GDK_THREADS_LEAVE();
62
 
    }
63
 
    if( cond == G_IO_HUP )
64
 
    {
65
 
        if( data->chstdo == ch )
66
 
        {
67
 
            strcpy(buffer, _("\nComplete!"));
68
 
            rlen = strlen(buffer);
69
 
 
70
 
            GDK_THREADS_ENTER();
71
 
 
72
 
            gtk_text_buffer_get_end_iter( data->buf, &it );
73
 
            gtk_text_buffer_insert( data->buf, &it, buffer, rlen );
74
 
            gtk_dialog_set_response_sensitive( GTK_DIALOG(data->main_dlg), GTK_RESPONSE_CANCEL, FALSE );
75
 
            gtk_dialog_set_response_sensitive( GTK_DIALOG(data->main_dlg), GTK_RESPONSE_CLOSE, TRUE );
76
 
 
77
 
            if( data->pid )
78
 
            {
79
 
                status = 0;
80
 
                waitpid( data->pid, &status, 0 );
81
 
                data->pid = 0;
82
 
 
83
 
                if( WIFEXITED(status) && 0 == WEXITSTATUS(status) )
84
 
                {
85
 
                    g_idle_add( delayed_destroy, data->main_dlg );
86
 
                    GDK_THREADS_LEAVE();
87
 
                    return FALSE;
88
 
                }
89
 
                adj = gtk_scrolled_window_get_vadjustment( GTK_SCROLLED_WINDOW(data->scroll) );
90
 
                gtk_adjustment_set_value( adj, adj->upper-adj->page_size );
91
 
                g_idle_add( on_complete, adj );
92
 
            }
93
 
            GDK_THREADS_LEAVE();
94
 
        }
95
 
 
96
 
        return FALSE;
97
 
    }
98
 
    return TRUE;
99
 
}
100
 
 
101
 
static void on_destroy( gpointer data, GObject* obj )
102
 
{
103
 
    int status = 0;
104
 
    PtkConsoleOutputData* ptk_data = (PtkConsoleOutputData *)data;
105
 
 
106
 
    do{}
107
 
    while( g_source_remove_by_user_data( ptk_data ) );
108
 
 
109
 
    if( ptk_data->chstdo )
110
 
    {
111
 
        g_io_channel_unref(ptk_data->chstdo);
112
 
        close( ptk_data->stdo );
113
 
    }
114
 
    if( ptk_data->chstde )
115
 
    {
116
 
        g_io_channel_unref(ptk_data->chstde);
117
 
        close( ptk_data->stde );
118
 
    }
119
 
 
120
 
    if( ptk_data->pid )
121
 
    {
122
 
        kill( ptk_data->pid, 15 );
123
 
        waitpid( ptk_data->pid, &status, 0 );
124
 
    }
125
 
    g_slice_free( PtkConsoleOutputData, ptk_data );
126
 
}
127
 
 
128
 
static void on_response( GtkDialog* dlg, int response,
129
 
                         PtkConsoleOutputData* data )
130
 
{
131
 
    gtk_widget_destroy( data->main_dlg );
132
 
}
133
 
 
134
 
int ptk_console_output_run( GtkWindow* parent_win,
135
 
                            const char* title,
136
 
                            const char* desc,
137
 
                            const char* working_dir,
138
 
                            int argc, char* argv[] )
139
 
{
140
 
    GtkWidget* main_dlg;
141
 
    GtkWidget* desc_label;
142
 
    PtkConsoleOutputData* data;
143
 
    GtkWidget* hbox;
144
 
    GtkWidget* entry;
145
 
    GdkColor black={0}, white={0, 65535, 65535, 65535};
146
 
    char* cmd;
147
 
    GError* err;
148
 
 
149
 
    data = g_slice_new0( PtkConsoleOutputData );
150
 
    cmd = g_strjoinv( " ", &argv[0] );
151
 
 
152
 
    main_dlg = gtk_dialog_new_with_buttons( title, NULL, 0,
153
 
                                            GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
154
 
                                            GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL );
155
 
    gtk_dialog_set_alternative_button_order( GTK_DIALOG(main_dlg), GTK_RESPONSE_CLOSE, GTK_RESPONSE_CANCEL, -1 );
156
 
 
157
 
    g_object_weak_ref( G_OBJECT(main_dlg), on_destroy, data );
158
 
 
159
 
    data->main_dlg = main_dlg;
160
 
    gtk_dialog_set_response_sensitive( GTK_DIALOG(main_dlg), GTK_RESPONSE_CLOSE, FALSE );
161
 
    gtk_window_set_type_hint( GTK_WINDOW(main_dlg),
162
 
                              GDK_WINDOW_TYPE_HINT_NORMAL );
163
 
 
164
 
    desc_label = gtk_label_new( desc );
165
 
    gtk_label_set_line_wrap( GTK_LABEL(desc_label), TRUE );
166
 
    gtk_box_pack_start( GTK_BOX(GTK_DIALOG(main_dlg)->vbox),
167
 
                        desc_label, FALSE, TRUE, 2 );
168
 
 
169
 
    hbox = gtk_hbox_new( FALSE, 2 );
170
 
 
171
 
    gtk_box_pack_start( GTK_BOX(hbox), gtk_label_new( _("Command:") ),
172
 
                        FALSE, FALSE, 2 );
173
 
 
174
 
    entry = gtk_entry_new();
175
 
    gtk_entry_set_text( GTK_ENTRY(entry), cmd );
176
 
    gtk_editable_set_position( GTK_EDITABLE(entry), 0 );
177
 
    gtk_editable_set_editable( GTK_EDITABLE(entry), FALSE );
178
 
    gtk_editable_select_region( GTK_EDITABLE(entry), 0, 0 );
179
 
    g_free( cmd );
180
 
    gtk_box_pack_start( GTK_BOX(hbox), entry, TRUE, TRUE, 2 );
181
 
 
182
 
    gtk_box_pack_start( GTK_BOX(GTK_DIALOG(main_dlg)->vbox),
183
 
                        hbox, FALSE, TRUE, 2 );
184
 
 
185
 
    data->buf = GTK_TEXT_BUFFER(gtk_text_buffer_new(NULL));
186
 
    data->view = GTK_TEXT_VIEW(gtk_text_view_new_with_buffer( data->buf ));
187
 
    gtk_widget_modify_base( GTK_WIDGET(data->view), GTK_STATE_NORMAL, &black );
188
 
    gtk_widget_modify_text( GTK_WIDGET(data->view), GTK_STATE_NORMAL, &white );
189
 
    data->scroll = gtk_scrolled_window_new(NULL, NULL);
190
 
    gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(data->scroll),
191
 
                                    GTK_POLICY_AUTOMATIC,
192
 
                                    GTK_POLICY_ALWAYS );
193
 
    gtk_container_add( GTK_CONTAINER(data->scroll), GTK_WIDGET(data->view) );
194
 
    gtk_box_pack_start( GTK_BOX(GTK_DIALOG(main_dlg)->vbox), data->scroll, TRUE, TRUE, 2 );
195
 
    gtk_widget_show_all( GTK_DIALOG(main_dlg)->vbox );
196
 
    gtk_window_set_default_size( GTK_WINDOW(main_dlg), 480, 240 );
197
 
 
198
 
    gtk_widget_show( main_dlg );
199
 
 
200
 
    if( g_spawn_async_with_pipes( working_dir, argv, NULL,
201
 
                                  G_SPAWN_SEARCH_PATH, NULL, NULL,
202
 
                                  &data->pid, NULL/*&stdi*/,
203
 
                                  &data->stdo, &data->stde, &err ) )
204
 
    {
205
 
        /* fcntl(stdi,F_SETFL,O_NONBLOCK); */
206
 
        fcntl(data->stdo,F_SETFL,O_NONBLOCK);
207
 
        fcntl(data->stde,F_SETFL,O_NONBLOCK);
208
 
 
209
 
        data->chstdo = g_io_channel_unix_new( data->stdo );
210
 
        g_io_channel_set_encoding( data->chstdo, NULL, NULL );
211
 
        g_io_channel_set_buffered( data->chstdo, FALSE );
212
 
        g_io_add_watch( data->chstdo, G_IO_IN|G_IO_HUP, on_output, data );
213
 
 
214
 
        fcntl(data->stde,F_SETFL,O_NONBLOCK);
215
 
        data->chstde = g_io_channel_unix_new( data->stde );
216
 
        g_io_channel_set_encoding( data->chstde, NULL, NULL );
217
 
        g_io_channel_set_buffered( data->chstde, FALSE );
218
 
        g_io_add_watch( data->chstde, G_IO_IN|G_IO_HUP, on_output, data );
219
 
        g_signal_connect( main_dlg, "delete-event", G_CALLBACK(gtk_widget_destroy), NULL );
220
 
        g_signal_connect( main_dlg, "response", G_CALLBACK(on_response), data );
221
 
    }
222
 
    else
223
 
    {
224
 
        gtk_widget_destroy( main_dlg );
225
 
        ptk_show_error( parent_win, _("Error"), err->message );
226
 
        g_error_free( err );
227
 
        return 1;
228
 
    }
229
 
    return 0;
230
 
}