Diff of /trunk/src/geotoad.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 193 by harbaum, Tue Nov 17 20:13:09 2009 UTC revision 195 by harbaum, Wed Nov 18 20:09:39 2009 UTC
# Line 24  Line 24 
24  #include <sys/wait.h>  #include <sys/wait.h>
25  #include <errno.h>  #include <errno.h>
26    
27  #define BUFFER_SIZE  1500  #define COLOR_ERR     "red"
28    #define COLOR_OK      "darkgreen"
29    #define COLOR_SYSTEM  "darkblue"
30    
31    #define BUFFER_SIZE  256
32    
33  typedef struct {  typedef struct {
34      appdata_t *appdata;
35    
36    char buf[BUFFER_SIZE];    char buf[BUFFER_SIZE];
37    int bused;    int bused;
38    
# Line 34  typedef struct { Line 40  typedef struct {
40    gint stdout_tag, stderr_tag;    gint stdout_tag, stderr_tag;
41    gint stdin_fd, stdout_fd, stderr_fd;    gint stdin_fd, stdout_fd, stderr_fd;
42    
43      struct log_s {
44        GtkTextBuffer *buffer;
45        GtkWidget *view;
46      } log;
47    
48  } gt_context_t;  } gt_context_t;
49    
50    static void appendf(struct log_s *log, char *colname,
51                        const char *fmt, ...) {
52      va_list args;
53      va_start( args, fmt );
54      char *buf = g_strdup_vprintf(fmt, args);
55      va_end( args );
56    
57      printf("append: %s", buf);
58    
59      GtkTextTag *tag = NULL;
60      if(colname)
61        tag = gtk_text_buffer_create_tag(log->buffer, NULL,
62                                         "foreground", colname,
63                                         NULL);
64    
65      GtkTextIter end;
66      gtk_text_buffer_get_end_iter(log->buffer, &end);
67      if(tag)
68        gtk_text_buffer_insert_with_tags(log->buffer, &end, buf, -1, tag, NULL);
69      else
70        gtk_text_buffer_insert(log->buffer, &end, buf, -1);
71    
72      g_free(buf);
73    
74      gtk_text_buffer_get_end_iter(log->buffer, &end);
75      gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(log->view),
76                                   &end, 0.0, FALSE, 0, 0);
77    }
78    
79  /* watch child process and receive events */  /* watch child process and receive events */
80  static void child_state_cb(GPid pid, gint status, gpointer data) {  static void child_state_cb(GPid pid, gint status, gpointer data) {
81      gt_context_t *context = (gt_context_t*)data;
82    
83    puts("child state");    puts("child state");
84    
85    if(WIFEXITED(status)) {    if(WIFEXITED(status)) {
86    }      printf("child exited with return code %d\n", WEXITSTATUS(status));
87      } else
88        printf("child failed\n");
89    
90    puts("gt exited");    puts("gt exited");
91    
92      appendf(&context->log, COLOR_SYSTEM, "GeoToad finished\n");
93    
94      appendf(&context->log, COLOR_SYSTEM, "TODO: free context!!!\n");
95      //    printf("freeing context\n");
96      //    g_free(context);
97    
98    /* Reap child if needed. */    /* Reap child if needed. */
99    waitpid (pid, NULL, WNOHANG);    waitpid (pid, NULL, WNOHANG);
100  }  }
101    
102  static void child_input_cb(gpointer data, int fd, GdkInputCondition cond) {  static gboolean child_input_cb(GIOChannel *source,
103                                   GIOCondition condition,
104                                   gpointer data) {
105    gt_context_t *context = (gt_context_t*)data;    gt_context_t *context = (gt_context_t*)data;
106      int fd = g_io_channel_unix_get_fd(source);
107    ssize_t bytes;    ssize_t bytes;
   int errnosave=0;  
108    
109    if(cond != GDK_INPUT_READ) {    g_assert(condition == G_IO_IN);
     puts("fixme");  
     return;  
   }  
110    
111    /* append to current buffer content */    /* append to current buffer content */
112    while( (bytes = read(fd, context->buf+context->bused,    while( (bytes = read(fd, context->buf+context->bused,
# Line 75  static void child_input_cb(gpointer data Line 122  static void child_input_cb(gpointer data
122        char *p = strchr(ptr, '\n');        char *p = strchr(ptr, '\n');
123        *p = '\0';        *p = '\0';
124    
125        printf("line: %s\n", ptr);        char *color = NULL;
126          if(strstr(ptr, "Saved to ") != NULL)
127            color = COLOR_OK;
128    
129          appendf(&context->log, color, "%s\n", ptr);
130    
131        ptr = p+1;        ptr = p+1;
132      }      }
# Line 91  static void child_input_cb(gpointer data Line 142  static void child_input_cb(gpointer data
142      }      }
143    }    }
144    
145    /* save errno from read */    return TRUE;
   errnosave=errno;  
   
   if(errnosave != EAGAIN && errnosave != 0) {  
     /* we probably hit EOF */  
     puts("removing io");  
   
     // TODO: fixme, make sure process is dead! kill it otherwise, but dont  
     // issue an vpnc_disconnect(NULL) !!!!  
   
     gdk_input_remove(context->stdout_tag);  
     gdk_input_remove(context->stderr_tag);  
   
     printf("freeing context\n");  
     g_free(context);  
   }  
146  }  }
   
 void geotoad(appdata_t *appdata) {  
   gt_context_t *context = g_new0(gt_context_t, 1);  
   
   printf("geoToad\n");  
147    
148    static void run(gt_context_t *context) {
149    /* setup context */    /* setup context */
150    context->bused = 0;    context->bused = 0;
151    context->stdout_tag = -1;    context->stdout_tag = -1;
# Line 122  void geotoad(appdata_t *appdata) { Line 154  void geotoad(appdata_t *appdata) {
154    context->stderr_fd = -1;    context->stderr_fd = -1;
155    context->stderr_fd = -1;    context->stderr_fd = -1;
156    
157    /* build list of arguments */    /* build list of arguments to call geotoad */
158    GPtrArray *gt_argv = g_ptr_array_new();    GPtrArray *gt_argv = g_ptr_array_new();
159    g_ptr_array_add (gt_argv, "/usr/bin/env");    g_ptr_array_add (gt_argv, "/usr/bin/geotoad");
160    //  g_ptr_array_add (gt_argv, "/tmp");    g_ptr_array_add (gt_argv, "--distanceMax=1.0");
161      g_ptr_array_add (gt_argv, "--output=gtoad.gpx");
162      g_ptr_array_add (gt_argv, "--password=winterblume");
163      g_ptr_array_add (gt_argv, "--queryType=coord");
164      g_ptr_array_add (gt_argv, "--user=Tantil");
165    
166      /* check if we need to add proxy config */
167      char *proxy = NULL;
168      if(context->appdata->proxy && context->appdata->proxy->host) {
169        if(context->appdata->proxy->use_authentication &&
170           context->appdata->proxy->authentication_user &&
171           context->appdata->proxy->authentication_password)
172          proxy = g_strdup_printf("--proxy=http://%s:%s@%s:%d",
173                                  context->appdata->proxy->authentication_user,
174                                  context->appdata->proxy->authentication_password,
175                                  context->appdata->proxy->host,
176                                  context->appdata->proxy->port);
177        else
178          proxy = g_strdup_printf("--proxy=http://%s:%d",
179                                  context->appdata->proxy->host,
180                                  context->appdata->proxy->port);
181    
182        appendf(&context->log, COLOR_SYSTEM, "Using proxy: %s\n", proxy);
183        g_ptr_array_add (gt_argv, proxy);
184      }
185    
186      g_ptr_array_add (gt_argv, "N49 00.000 E008 23.000");
187    g_ptr_array_add (gt_argv, NULL);    g_ptr_array_add (gt_argv, NULL);
188    
189    GError *error=NULL;    GError *error=NULL;
190    GPid pid;    GPid pid;
191    GSource *gt_watch;    GSource *gt_watch;
# Line 144  void geotoad(appdata_t *appdata) { Line 202  void geotoad(appdata_t *appdata) {
202                                   &context->stderr_fd,                                   &context->stderr_fd,
203                                   &error)) {                                   &error)) {
204      g_ptr_array_free(gt_argv, TRUE);      g_ptr_array_free(gt_argv, TRUE);
205      errorf(_("GeoToad failed to start.\n\nError: '%s'"), error->message);      if(proxy) g_free(proxy);
206        appendf(&context->log, COLOR_ERR,
207                _("GeoToad failed to start!\n%s\n"), error->message);
208      g_error_free(error);      g_error_free(error);
209      return;      return;
210    }    }
   g_ptr_array_free (gt_argv, TRUE);  
211    
212    printf("GeoToad: pid = %d\n", pid);    g_ptr_array_free (gt_argv, TRUE);
213      if(proxy) g_free(proxy);
214    
215    gt_watch = g_child_watch_source_new(pid);    gt_watch = g_child_watch_source_new(pid);
216    g_source_set_callback(gt_watch, (GSourceFunc) child_state_cb, NULL, NULL);    g_source_set_callback(gt_watch, (GSourceFunc) child_state_cb, context, NULL);
217    
218    g_source_attach(gt_watch, NULL);    g_source_attach(gt_watch, NULL);
219    g_source_unref(gt_watch);    g_source_unref(gt_watch);
# Line 165  void geotoad(appdata_t *appdata) { Line 225  void geotoad(appdata_t *appdata) {
225    if(fcntl(context->stderr_fd, F_SETFL, O_NONBLOCK) == -1)    if(fcntl(context->stderr_fd, F_SETFL, O_NONBLOCK) == -1)
226      perror("fcntl failed");      perror("fcntl failed");
227    
228    /* use gdk to monitor read end of stdout */    GIOChannel *ioc = g_io_channel_unix_new(context->stdout_fd);
229    context->stdout_tag =    g_io_channel_set_close_on_unref (ioc, TRUE);
230      gdk_input_add(context->stdout_fd, GDK_INPUT_READ, child_input_cb, context);    g_io_channel_set_encoding (ioc, NULL, NULL);
231    context->stderr_tag =    g_io_add_watch(ioc, G_IO_IN,  child_input_cb, context);
232      gdk_input_add(context->stderr_fd, GDK_INPUT_READ, child_input_cb, context);    g_io_channel_unref(ioc);
233    
234      //  ioc = g_io_channel_unix_new(context->stderr_fd);
235      //  g_io_add_watch(ioc, G_IO_IN,  child_input_cb, context);
236      //  g_io_channel_unref(ioc);
237    }
238    
239    void geotoad(appdata_t *appdata) {
240      gt_context_t *context = g_new0(gt_context_t, 1);
241      context->appdata = appdata;
242    
243      printf("geoToad\n");
244    
245      GtkWidget *dialog = gtk_dialog_new_with_buttons(_("GeoToad"),
246                              GTK_WINDOW(appdata->window),
247                              GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
248                              GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
249                              NULL);
250    
251      gtk_window_set_default_size(GTK_WINDOW(dialog), 640, 480);
252    
253    #ifndef USE_PANNABLE_AREA
254      GtkWidget *scrolled_window = gtk_scrolled_window_new(NULL, NULL);
255      gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
256                                     GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
257    #else
258      GtkWidget *pannable_area = hildon_pannable_area_new();
259    #endif
260    
261      context->log.buffer = gtk_text_buffer_new(NULL);
262    
263    #ifndef USE_HILDON_TEXT_VIEW
264      context->log.view = gtk_text_view_new_with_buffer(context->log.buffer);
265    #else
266      context->log.view = hildon_text_view_new();
267      hildon_text_view_set_buffer(HILDON_TEXT_VIEW(context->log.view),
268                                  context->log.buffer);
269    #endif
270    
271    #ifndef USE_PANNABLE_AREA
272      gtk_container_add(GTK_CONTAINER(scrolled_window), context->log.view);
273      gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW(scrolled_window),
274                                           GTK_SHADOW_IN);
275    
276      gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
277                         scrolled_window, TRUE, TRUE, 0);
278    #else
279      gtk_container_add(GTK_CONTAINER(pannable_area), context->log.view);
280      gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
281                         pannable_area, TRUE, TRUE, 0);
282    #endif
283    
284      gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_CLOSE);
285    
286      gtk_widget_show_all(dialog);
287    
288      appendf(&context->log, COLOR_SYSTEM, "Running GeoToad\n");
289      run(context);
290    
291      gtk_dialog_run(GTK_DIALOG(dialog));
292    
293      gtk_widget_destroy(dialog);
294  }  }

Legend:
Removed from v.193  
changed lines
  Added in v.195