Diff of /trunk/src/geotoad.c

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

revision 195 by harbaum, Wed Nov 18 20:09:39 2009 UTC revision 207 by harbaum, Tue Nov 24 14:02:35 2009 UTC
# Line 19  Line 19 
19    
20  #include "gpxview.h"  #include "gpxview.h"
21    
22    #define __USE_GNU
23    #include <string.h>
24    
25  #include <fcntl.h>  #include <fcntl.h>
26  #include <sys/types.h>  #include <sys/types.h>
27  #include <sys/wait.h>  #include <sys/wait.h>
28  #include <errno.h>  #include <errno.h>
29    #include <math.h>
30    
31    #if defined(USE_MAEMO) && (MAEMO_VERSION_MAJOR >= 5)
32    #include <hildon/hildon-entry.h>
33    #endif
34    
35    #define GEOTOAD "/usr/bin/geotoad"
36    
37  #define COLOR_ERR     "red"  #define COLOR_ERR     "red"
38  #define COLOR_OK      "darkgreen"  #define COLOR_OK      "darkgreen"
# Line 30  Line 40 
40    
41  #define BUFFER_SIZE  256  #define BUFFER_SIZE  256
42    
43    typedef enum {
44      GT_STATE_ILLEGAL = 0,
45      GT_STATE_STARTED,
46      GT_STATE_PREMATURE_END,
47      GT_STATE_SAVE_FOUND,
48    } gt_state_t;
49    
50  typedef struct {  typedef struct {
51    appdata_t *appdata;    appdata_t *appdata;
52    
53      GPtrArray *argv;
54      gchar *info, *color;
55      GMutex *update_mutex;
56      GCond *update_cond;
57    
58    char buf[BUFFER_SIZE];    gt_state_t state;
   int bused;  
59    
60    /** gdk input tag for async IO */    GtkWidget *dialog;
61    gint stdout_tag, stderr_tag;  
62    gint stdin_fd, stdout_fd, stderr_fd;    long pid;
63    
64    struct log_s {    struct log_s {
65      GtkTextBuffer *buffer;      GtkTextBuffer *buffer;
66      GtkWidget *view;      GtkWidget *view;
67    } log;    } log;
68    
69      GtkWidget *username, *password, *filename;
70      GtkWidget *lat, *lon, *dst;
71    
72  } gt_context_t;  } gt_context_t;
73    
74    static void arg_free(gpointer data, gpointer user_data) {
75      if(data) g_free(data);
76    }
77    
78    static void context_free(gt_context_t *context) {
79      //  printf("freeing context\n");
80    
81      if(context->info) g_free(context->info);
82    
83      g_ptr_array_foreach(context->argv, arg_free, NULL);
84      g_ptr_array_free (context->argv, TRUE);
85    
86      g_free(context);
87    }
88    
89  static void appendf(struct log_s *log, char *colname,  static void appendf(struct log_s *log, char *colname,
90                      const char *fmt, ...) {                      const char *fmt, ...) {
91    va_list args;    va_list args;
# Line 54  static void appendf(struct log_s *log, c Line 93  static void appendf(struct log_s *log, c
93    char *buf = g_strdup_vprintf(fmt, args);    char *buf = g_strdup_vprintf(fmt, args);
94    va_end( args );    va_end( args );
95    
96    printf("append: %s", buf);    //  printf("append: %s", buf);
97    
98    GtkTextTag *tag = NULL;    GtkTextTag *tag = NULL;
99    if(colname)    if(colname)
# Line 71  static void appendf(struct log_s *log, c Line 110  static void appendf(struct log_s *log, c
110    
111    g_free(buf);    g_free(buf);
112    
   gtk_text_buffer_get_end_iter(log->buffer, &end);  
113    gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(log->view),    gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(log->view),
114                                 &end, 0.0, FALSE, 0, 0);                                 &end, 0.0, TRUE, 0, 1.0);
115  }  }
116    
117  /* watch child process and receive events */  // This function receives a requst from a worker thread asking to
118  static void child_state_cb(GPid pid, gint status, gpointer data) {  // update the gui with the required info.
119    gt_context_t *context = (gt_context_t*)data;  gboolean cb_update_job(gt_context_t *context) {
120      if (context->info) {
121    puts("child state");  
122        /* check if client reports "saved to ..." */
123        if(strstr(context->info, "Saved to "))
124          context->state = GT_STATE_SAVE_FOUND;
125    
126    if(WIFEXITED(status)) {      appendf(&context->log, context->color, context->info);
127      printf("child exited with return code %d\n", WEXITSTATUS(status));  
128    } else      g_free(context->info);
129      printf("child failed\n");      context->info = NULL;
130      }
131    
132      // Indicate that the update is done
133      g_mutex_lock(context->update_mutex);
134      g_cond_signal(context->update_cond);
135      g_mutex_unlock(context->update_mutex);
136    
137      return FALSE;
138    }
139    
140    puts("gt exited");  // A helper function run in the job thread receiving the string that
141    // should be displayed in the textview.
142    void append_parentf(gt_context_t *context, char *colname,
143                 const char *fmt, ...) {
144      va_list args;
145      va_start( args, fmt );
146      context->info = g_strdup_vprintf(fmt, args);
147      va_end( args );
148    
149    appendf(&context->log, COLOR_SYSTEM, "GeoToad finished\n");    if(colname)
150        context->color = colname;
151      else
152        context->color = NULL;
153    
154    appendf(&context->log, COLOR_SYSTEM, "TODO: free context!!!\n");    // Lock mutex to make sure that we will receive the condition signal
155    //    printf("freeing context\n");    g_mutex_lock(context->update_mutex);
   //    g_free(context);  
156    
157    /* Reap child if needed. */    g_idle_add((GSourceFunc)cb_update_job, context);
158    waitpid (pid, NULL, WNOHANG);  
159      // Wait for cb_update_job to tell me that the update is done
160      g_cond_wait(context->update_cond, context->update_mutex);
161      g_mutex_unlock(context->update_mutex);
162  }  }
163    
164  static gboolean child_input_cb(GIOChannel *source,  /* custom version of popen to get access to the pid and to be able */
165                                 GIOCondition condition,  /* to slaughter the child process */
166                                 gpointer data) {  static FILE *gt_popen(gt_context_t *context, char **args,
167    gt_context_t *context = (gt_context_t*)data;                        const char *type, long *tid) {
168    int fd = g_io_channel_unix_get_fd(source);    int   p[2];
169    ssize_t bytes;    FILE *fp;
170    
171    g_assert(condition == G_IO_IN);    if (*type != 'r' && *type != 'w')
172        return NULL;
173    /* append to current buffer content */  
174    while( (bytes = read(fd, context->buf+context->bused,    if (pipe(p) < 0)
175                   sizeof(context->buf) - context->bused - 1)) > 0) {      return NULL;
176      context->bused += bytes;  
177      context->buf[context->bused]='\0';    if ((*tid = fork()) > 0) { /* then we are the parent */
178        if (*type == 'r') {
179          close(p[1]);
180          fp = fdopen(p[0], type);
181        } else {
182          close(p[0]);
183          fp = fdopen(p[1], type);
184        }
185    
186        return fp;
187      } else if (*tid == 0) {  /* we're the child */
188    
189      /* consume line by line */      /* make our thread id the process group leader */
190      gchar *ptr = context->buf;      setpgid(0, 0);
191    
192        if (*type == 'r') {
193          fflush(stdout);
194          fflush(stderr);
195          close(1);
196          if (dup(p[1]) < 0)
197            perror("dup of write side of pipe failed");
198          close(2);
199          if (dup(p[1]) < 0)
200            perror("dup of write side of pipe failed");
201        } else {
202          close(0);
203          if (dup(p[0]) < 0)
204            perror("dup of read side of pipe failed");
205        }
206    
207        close(p[0]); /* close since we dup()'ed what we needed */
208        close(p[1]);
209    
210      /* parse as long as the buffer contains a newline */      execve(args[0], args, NULL);
211      while( strchr(ptr, '\n') != NULL) {  
212        char *p = strchr(ptr, '\n');      /* this printf will actually be redirected through the pipe */
213        *p = '\0';      printf("Error: Failed to execute!\n");
214      } else {         /* we're having major problems... */
215        char *color = NULL;      close(p[0]);
216        if(strstr(ptr, "Saved to ") != NULL)      close(p[1]);
         color = COLOR_OK;  
217    
218        appendf(&context->log, color, "%s\n", ptr);      /* this printf will actually be redirected through the pipe */
219        printf("Error: Failed to fork!\n");
220      }
221    
222      return NULL;
223    }
224    
225        ptr = p+1;  // The thread entry point. It will do the job, send the data to the
226      }  // GUI and self destruct when it is done.
227    static gpointer thread_worker(gt_context_t *context)
228    {
229      FILE *fh;
230      GIOStatus status;
231      GError *error = NULL;
232      gsize length;
233      gsize terminator_pos;
234      gchar *str_return;
235    
236      fh = gt_popen(context, (char**)(context->argv->pdata),"r", &context->pid);
237      if(!fh) {
238        append_parentf(context, COLOR_ERR, _("Failed to run GeoToad"));
239        return NULL;
240      }
241    
242      /* move remaining bytes down the buffer */    /* switch to line buffered mode */
243      memmove(context->buf, ptr, sizeof(context->buf)-(ptr-context->buf));    if(setvbuf(fh, NULL, _IOLBF, 0))
244      context->bused -= ptr - context->buf;      perror("setvbuf(_IOLBF)");
245    
246      /* check if buffer is full but doesn't contain any newline */    GIOChannel *gh = g_io_channel_unix_new(fileno(fh));
247      if(context->bused >= sizeof(context->buf)-1) {  
248        printf("ERROR: reply buffer overflow\n");    while( (status = g_io_channel_read_line(gh,
249        context->bused = 0;                                            &str_return,
250      }                                            &length,
251                                              &terminator_pos,
252                                              &error)) == G_IO_STATUS_NORMAL) {
253        char *color = NULL;
254        if(strstr(str_return, "Saved to "))  color = COLOR_OK;
255        if(strcasestr(str_return, "error"))  color = COLOR_ERR;
256    
257        append_parentf(context, color, str_return);
258        g_free(str_return);
259    }    }
260    
261      g_io_channel_unref(gh);
262      pclose(fh);
263      append_parentf(context, COLOR_SYSTEM, "Job done!");
264    
265      g_thread_exit(NULL);
266      context_free(context);
267    
268      return NULL;
269    }
270    
271    return TRUE;  
272    static void arg_dsp(gpointer data, gpointer user_data) {
273      gt_context_t *context = (gt_context_t*)user_data;
274    
275      if(data)
276        appendf(&context->log, COLOR_SYSTEM, "%s\n", data);
277  }  }
278    
279  static void run(gt_context_t *context) {  static void run(gt_context_t *context) {
280    /* setup context */    GError *error = NULL;
281    context->bused = 0;    char str[8];
   context->stdout_tag = -1;  
   context->stderr_tag = -1;  
   context->stdin_fd  = -1;  
   context->stderr_fd = -1;  
   context->stderr_fd = -1;  
282    
283    /* build list of arguments to call geotoad */    /* build list of arguments to call geotoad */
284    GPtrArray *gt_argv = g_ptr_array_new();    context->argv = g_ptr_array_new();
285    g_ptr_array_add (gt_argv, "/usr/bin/geotoad");    g_ptr_array_add (context->argv, g_strdup_printf(GEOTOAD));
286    g_ptr_array_add (gt_argv, "--distanceMax=1.0");    g_ascii_dtostr(str, sizeof(str), context->appdata->gt.distance);
287    g_ptr_array_add (gt_argv, "--output=gtoad.gpx");    g_ptr_array_add (context->argv, g_strdup_printf("--distanceMax=%s", str));
288    g_ptr_array_add (gt_argv, "--password=winterblume");    g_ptr_array_add (context->argv, g_strdup_printf("--output=%s", context->appdata->gt.filename));
289    g_ptr_array_add (gt_argv, "--queryType=coord");    g_ptr_array_add (context->argv, g_strdup_printf("--password=%s", context->appdata->gt.password));
290    g_ptr_array_add (gt_argv, "--user=Tantil");    g_ptr_array_add (context->argv, g_strdup_printf("--queryType=coord"));
291      g_ptr_array_add (context->argv, g_strdup_printf("--user=%s", context->appdata->username));
292    
293    /* check if we need to add proxy config */    /* check if we need to add proxy config */
294    char *proxy = NULL;    char *proxy = NULL;
# Line 170  static void run(gt_context_t *context) { Line 297  static void run(gt_context_t *context) {
297         context->appdata->proxy->authentication_user &&         context->appdata->proxy->authentication_user &&
298         context->appdata->proxy->authentication_password)         context->appdata->proxy->authentication_password)
299        proxy = g_strdup_printf("--proxy=http://%s:%s@%s:%d",        proxy = g_strdup_printf("--proxy=http://%s:%s@%s:%d",
300                                context->appdata->proxy->authentication_user,                                context->appdata->proxy->authentication_user,
301                                context->appdata->proxy->authentication_password,                                context->appdata->proxy->authentication_password,
302                                context->appdata->proxy->host,                                context->appdata->proxy->host,
303                                context->appdata->proxy->port);                                context->appdata->proxy->port);
304      else      else
305        proxy = g_strdup_printf("--proxy=http://%s:%d",        proxy = g_strdup_printf("--proxy=http://%s:%d",
306                                context->appdata->proxy->host,                                context->appdata->proxy->host,
307                                context->appdata->proxy->port);                                context->appdata->proxy->port);
308    
309      appendf(&context->log, COLOR_SYSTEM, "Using proxy: %s\n", proxy);      g_ptr_array_add (context->argv, proxy);
     g_ptr_array_add (gt_argv, proxy);  
310    }    }
311    
312    g_ptr_array_add (gt_argv, "N49 00.000 E008 23.000");    /* convert coordinates into simple ascii format */
313    g_ptr_array_add (gt_argv, NULL);    char n = (context->appdata->gt.lat >= 0)?'N':'S';
314      char e = (context->appdata->gt.lon >= 0)?'E':'W';
315    GError *error=NULL;    float lat = fabs(context->appdata->gt.lat);
316    GPid pid;    float lon = fabs(context->appdata->gt.lon);
317    GSource *gt_watch;    float lat_mint, lat_int, lat_frac = modff(lat, &lat_int);
318      float lon_mint, lon_int, lon_frac = modff(lon, &lon_int);
319    if (!g_spawn_async_with_pipes (NULL, /* CWD */    lat_frac = modff(lat_frac*60.0, &lat_mint);
320                                   (char **) gt_argv->pdata, /* argv */    lon_frac = modff(lon_frac*60.0, &lon_mint);
321                                   NULL, /* envp */  
322                                   G_SPAWN_DO_NOT_REAP_CHILD, /* flags */    g_ptr_array_add (context->argv,
323                                   NULL, /* child setup */             g_strdup_printf("%c%02u %02u.%03u %c%03u %02u.%03u",
324                                   NULL, /* user data */             n, (int)lat_int, (int)lat_mint, (int)(lat_frac*1000.0+0.5),
325                                   &pid,             e, (int)lon_int, (int)lon_mint, (int)(lon_frac*1000.0+0.5)));
326                                   &context->stdin_fd,  
327                                   &context->stdout_fd,    //  g_ptr_array_add (context->argv, g_strdup_printf("2>&1"));
328                                   &context->stderr_fd,    g_ptr_array_add (context->argv, NULL);
329                                   &error)) {  
330      g_ptr_array_free(gt_argv, TRUE);    /* show all entries */
331      if(proxy) g_free(proxy);    g_ptr_array_foreach(context->argv, arg_dsp, context);
332      appendf(&context->log, COLOR_ERR,  
333              _("GeoToad failed to start!\n%s\n"), error->message);    g_thread_create((GThreadFunc)thread_worker, context, FALSE, &error);
334      if (error) {
335        appendf(&context->log, COLOR_ERR, "Error: %s\n", error->message);
336      g_error_free(error);      g_error_free(error);
     return;  
337    }    }
   
   g_ptr_array_free (gt_argv, TRUE);  
   if(proxy) g_free(proxy);  
   
   gt_watch = g_child_watch_source_new(pid);  
   g_source_set_callback(gt_watch, (GSourceFunc) child_state_cb, context, NULL);  
   
   g_source_attach(gt_watch, NULL);  
   g_source_unref(gt_watch);  
   
   /* make nonblocking */  
   if(fcntl(context->stdout_fd, F_SETFL, O_NONBLOCK) == -1)  
     perror("fcntl failed");  
   
   if(fcntl(context->stderr_fd, F_SETFL, O_NONBLOCK) == -1)  
     perror("fcntl failed");  
   
   GIOChannel *ioc = g_io_channel_unix_new(context->stdout_fd);  
   g_io_channel_set_close_on_unref (ioc, TRUE);  
   g_io_channel_set_encoding (ioc, NULL, NULL);  
   g_io_add_watch(ioc, G_IO_IN,  child_input_cb, context);  
   g_io_channel_unref(ioc);  
   
   //  ioc = g_io_channel_unix_new(context->stderr_fd);  
   //  g_io_add_watch(ioc, G_IO_IN,  child_input_cb, context);  
   //  g_io_channel_unref(ioc);  
338  }  }
339    
340  void geotoad(appdata_t *appdata) {  /* show text window and display output of running geotoad */
341    gt_context_t *context = g_new0(gt_context_t, 1);  static void gui_run(gt_context_t *context) {
342    context->appdata = appdata;    GtkWidget *dialog = gtk_dialog_new_with_buttons(_("GeoToad - Run"),
343                              GTK_WINDOW(context->appdata->window),
   printf("geoToad\n");  
   
   GtkWidget *dialog = gtk_dialog_new_with_buttons(_("GeoToad"),  
                           GTK_WINDOW(appdata->window),  
344                            GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,                            GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
345                            GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,                            GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
346                            NULL);                            NULL);
# Line 291  void geotoad(appdata_t *appdata) { Line 388  void geotoad(appdata_t *appdata) {
388    gtk_dialog_run(GTK_DIALOG(dialog));    gtk_dialog_run(GTK_DIALOG(dialog));
389    
390    gtk_widget_destroy(dialog);    gtk_widget_destroy(dialog);
391    
392      errorf("Fertig!\n");
393    
394    }
395    
396    static void on_browse(GtkWidget *widget, gpointer data) {
397      gt_context_t *context = (gt_context_t*)data;
398    
399      printf("Browse %p\n", context->dialog);
400    
401    #ifdef USE_MAEMO
402      GtkWidget *dialog = hildon_file_chooser_dialog_new(GTK_WINDOW(context->dialog),
403                                              GTK_FILE_CHOOSER_ACTION_SAVE);
404    #else
405      GtkWidget *dialog = gtk_file_chooser_dialog_new(_("Save GPX file"),
406                                           GTK_WINDOW(context->dialog),
407                                           GTK_FILE_CHOOSER_ACTION_SAVE,
408                                           GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
409                                           GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
410                                           NULL);
411    #endif
412    
413      printf("set filename <%s>\n", context->appdata->gt.filename);
414    
415      if(!g_file_test(context->appdata->gt.filename, G_FILE_TEST_EXISTS)) {
416        char *last_sep = strrchr(context->appdata->gt.filename, '/');
417        if(last_sep) {
418          *last_sep = 0;  // seperate path from file
419    
420          /* the user just created a new document */
421          gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),
422                                              context->appdata->gt.filename);
423          gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), last_sep+1);
424    
425          /* restore full filename */
426          *last_sep = '/';
427        }
428      } else
429        gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog),
430                                      context->appdata->gt.filename);
431    
432      if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_FM_OK) {
433        gchar *name = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
434        gtk_label_set_text(GTK_LABEL(context->filename), name);
435      }
436    
437      gtk_widget_destroy (dialog);
438    }
439    
440    static gboolean gui_setup(gt_context_t *context) {
441      appdata_t *appdata = context->appdata;
442      gboolean ok = FALSE;
443    
444      /* if no filename has been setup yet, create one */
445      if(!appdata->gt.filename && appdata->path) {
446        printf("creating path\n");
447        appdata->gt.filename =
448          g_strdup_printf("%s/gtoad.gpx", appdata->path);
449      }
450    
451      context->dialog = gtk_dialog_new_with_buttons(_("GeoToad - Setup"),
452                            GTK_WINDOW(appdata->window),
453                            GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
454                            GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
455                            GTK_STOCK_OK,     GTK_RESPONSE_OK,
456                            NULL);
457    
458      /* ------------------- Coordinates ------------------------- */
459      GtkWidget *hbox = gtk_hbox_new(FALSE, 0);
460    
461      GtkWidget *vbox = gtk_vbox_new(FALSE, 0);
462      gtk_box_pack_start_defaults(GTK_BOX(vbox), left_label_new(_("Position:")));
463      gtk_box_pack_start_defaults(GTK_BOX(vbox), left_label_new(_("Distance:")));
464      gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
465    
466      /* setup default positions */
467      pos_t *refpos = get_pos(appdata);
468      if((isnan(appdata->gt.lat) || isnan(appdata->gt.lat)) && refpos) {
469        appdata->gt.lat = refpos->lat;
470        appdata->gt.lon = refpos->lon;
471      }
472    
473      vbox = gtk_vbox_new(FALSE, 0);
474      GtkWidget *ihbox = gtk_hbox_new(FALSE, 0);
475      context->lat = lat_entry_new(appdata->gt.lat);
476      gtk_box_pack_start_defaults(GTK_BOX(ihbox), context->lat);
477      context->lon = lon_entry_new(appdata->gt.lon);
478      gtk_box_pack_start_defaults(GTK_BOX(ihbox), context->lon);
479      gtk_box_pack_start_defaults(GTK_BOX(vbox), ihbox);
480      float dst = appdata->gt.distance;  // distance is given in kilometers
481      if(appdata->imperial) dst /= 1.609344;
482      context->dst = dist_entry_new(dst, appdata->imperial);
483      gtk_box_pack_start_defaults(GTK_BOX(vbox), context->dst);
484      gtk_box_pack_start_defaults(GTK_BOX(hbox), vbox);
485    
486      gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(context->dialog)->vbox), hbox);
487    
488      /* ------------------- file name ------------------------- */
489      hbox = gtk_hbox_new(FALSE, 0);
490    
491      context->filename = gtk_label_new(appdata->gt.filename);
492      gtk_misc_set_alignment(GTK_MISC(context->filename), 0.f, 0.5f);
493      gtk_label_set_ellipsize(GTK_LABEL(context->filename), PANGO_ELLIPSIZE_MIDDLE);
494      gtk_box_pack_start_defaults(GTK_BOX(hbox), context->filename);
495    
496      GtkWidget *button = gtk_button_new_with_label(_("Browse"));
497    #if defined(USE_MAEMO) && (MAEMO_VERSION_MAJOR == 5)
498      hildon_gtk_widget_set_theme_size(button,
499               (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH));
500    #endif
501      gtk_signal_connect(GTK_OBJECT(button), "clicked",
502                         GTK_SIGNAL_FUNC(on_browse), context);
503      gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
504    
505      gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(context->dialog)->vbox), hbox);
506    
507    
508      /* ------------------- Username/Password ------------------------- */
509      hbox = gtk_hbox_new(FALSE, 0);
510      vbox = gtk_vbox_new(FALSE, 0);
511      gtk_box_pack_start_defaults(GTK_BOX(vbox), left_label_new(_("Username:")));
512      gtk_box_pack_start_defaults(GTK_BOX(vbox), left_label_new(_("Password:")));
513      gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
514    
515      vbox = gtk_vbox_new(FALSE, 0);
516    #ifndef FREMANTLE
517      context->username = gtk_entry_new();
518      context->password = gtk_entry_new();
519    #else
520      context->username = hildon_entry_new(HILDON_SIZE_AUTO);
521      hildon_gtk_entry_set_input_mode(GTK_ENTRY(context->username),
522                                      HILDON_GTK_INPUT_MODE_FULL);
523      context->password = hildon_entry_new(HILDON_SIZE_AUTO);
524      hildon_gtk_entry_set_input_mode(GTK_ENTRY(context->password),
525                                      HILDON_GTK_INPUT_MODE_FULL);
526    #endif
527      gtk_entry_set_visibility(GTK_ENTRY(context->password), FALSE);
528    
529      /* set saved defaults */
530      if(appdata->username)
531        gtk_entry_set_text(GTK_ENTRY(context->username),
532                           appdata->username);
533    
534      if(appdata->gt.password)
535        gtk_entry_set_text(GTK_ENTRY(context->password),
536                           appdata->gt.password);
537    
538      gtk_box_pack_start_defaults(GTK_BOX(vbox), context->username);
539      gtk_box_pack_start_defaults(GTK_BOX(vbox), context->password);
540      gtk_box_pack_start_defaults(GTK_BOX(hbox), vbox);
541    
542      gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(context->dialog)->vbox), hbox);
543    
544      gtk_dialog_set_default_response(GTK_DIALOG(context->dialog), GTK_RESPONSE_OK);
545    
546      gtk_widget_show_all(context->dialog);
547    
548      if(gtk_dialog_run(GTK_DIALOG(context->dialog)) == GTK_RESPONSE_OK) {
549    
550        /* parse coordinates */
551        appdata->gt.lat = lat_get(context->lat);
552        appdata->gt.lon = lon_get(context->lon);
553    
554        /* save values */
555        if(appdata->username) g_free(appdata->username);
556        appdata->username =
557          g_strdup(gtk_entry_get_text(GTK_ENTRY(context->username)));
558    
559        if(appdata->gt.password) g_free(appdata->gt.password);
560        appdata->gt.password =
561          g_strdup(gtk_entry_get_text(GTK_ENTRY(context->password)));
562    
563        if(appdata->gt.filename) g_free(appdata->gt.filename);
564        appdata->gt.filename =
565          g_strdup(gtk_label_get_text(GTK_LABEL(context->filename)));
566    
567        /* get distance in kilometers */
568        appdata->gt.distance = dist_get(context->dst, FALSE);
569    
570    
571        /* check for valid entries */
572        if(isnan(appdata->gt.lat) || isnan(appdata->gt.lon) ||
573           isnan(appdata->gt.distance) || !appdata->gt.filename ||
574           !appdata->username || !appdata->gt.password)
575          errorf(_("GeoToad setup not complete"));
576        else
577          ok = TRUE;
578      }
579    
580      gtk_widget_destroy(context->dialog);
581    
582      return ok;
583  }  }
584    
585    void geotoad(appdata_t *appdata) {
586      if(!geotoad_available()) {
587        errorf(_("GeoToad is not installed on this device.\n"
588                 "You need to install it in order to be able to use it."));
589        return;
590      }
591    
592      gt_context_t *context = g_new0(gt_context_t, 1);
593      context->appdata = appdata;
594    
595      context->update_mutex = g_mutex_new();
596      context->update_cond = g_cond_new();
597      //  context->mutex_to_run = mutex_to_run;
598    
599      printf("geoToad\n");
600    
601      if(gui_setup(context))
602        gui_run(context);
603    }
604    
605    gboolean geotoad_available(void) {
606      /* before doing anything make sure geotoad is installed */
607      return g_file_test(GEOTOAD, G_FILE_TEST_IS_EXECUTABLE);
608    }
609    
610    

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