Author: wolvverine                   Date: Mon Apr  3 03:49:01 2006 GMT
Module: SOURCES                       Tag: HEAD
---- Log message:
- patch from http://bugzilla.gnome.org/show_bug.cgi?id=330894

---- Files affected:
SOURCES:
   gnome-bluetooth-obex.patch (NONE -> 1.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/gnome-bluetooth-obex.patch
diff -u /dev/null SOURCES/gnome-bluetooth-obex.patch:1.1
--- /dev/null   Mon Apr  3 05:49:01 2006
+++ SOURCES/gnome-bluetooth-obex.patch  Mon Apr  3 05:48:56 2006
@@ -0,0 +1,1176 @@
+diff -ur gnome-bluetooth-cvs/obex/chooser.c 
gnome-bluetooth-changed/obex/chooser.c
+--- gnome-bluetooth-cvs/obex/chooser.c 2004-06-04 22:29:04.000000000 +0300
++++ gnome-bluetooth-changed/obex/chooser.c     2005-11-22 00:20:23.000000000 
+0200
+@@ -25,9 +25,10 @@
+ #include "chooser.h"
+ 
+ gchar *
+-choose_bdaddr ()
++choose_bd (gchar **name)
+ {
+     gchar *ret = NULL;
++    GnomebtDeviceDesc *btDevice;
+     GnomebtController *btctl;
+     GnomebtChooser *btchooser;
+     gint result;
+@@ -37,7 +38,11 @@
+     result = gtk_dialog_run (GTK_DIALOG (btchooser));
+ 
+     if (result == GTK_RESPONSE_OK)
+-        ret = gnomebt_chooser_get_bdaddr (btchooser);
++    {
++      btDevice = gnomebt_chooser_get_bd (btchooser);
++        ret = g_strdup(btDevice->bdaddr);
++        *name = g_strdup(btDevice->name);
++    }
+ 
+     gtk_widget_destroy (GTK_WIDGET (btchooser));
+ 
+diff -ur gnome-bluetooth-cvs/obex/chooser.h 
gnome-bluetooth-changed/obex/chooser.h
+--- gnome-bluetooth-cvs/obex/chooser.h 2003-10-30 23:56:51.000000000 +0200
++++ gnome-bluetooth-changed/obex/chooser.h     2005-11-21 23:58:42.000000000 
+0200
+@@ -1,4 +1,5 @@
+ #ifndef __CHOOSER_H
+ #define __CHOOSER_H
+-gchar *choose_bdaddr (void);
++
++gchar *choose_bd (gchar **name);
+ #endif
+diff -ur gnome-bluetooth-cvs/obex/gnome-obex-send.c 
gnome-bluetooth-changed/obex/gnome-obex-send.c
+--- gnome-bluetooth-cvs/obex/gnome-obex-send.c 2005-11-23 02:57:11.000000000 
+0200
++++ gnome-bluetooth-changed/obex/gnome-obex-send.c     2006-02-10 
14:16:41.000000000 +0200
+@@ -1,6 +1,7 @@
+ /*
+  * gnome-obex-send
+- * Copyright (c) 2003-4 Edd Dumbill <[EMAIL PROTECTED]>.
++ * Copyright (c) 2003-4 Edd Dumbill <[EMAIL PROTECTED]>
++ * Copyright (c) 2006 Tadas Dailyda <[EMAIL PROTECTED]>
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+@@ -26,6 +27,8 @@
+ #include <string.h>
+ #include <fcntl.h>
+ #include <stdlib.h>
++#include <sys/time.h>
++#include <errno.h>
+ 
+ #include <glib.h>
+ #include <gtk/gtk.h>
+@@ -41,85 +44,163 @@
+ 
+ typedef struct _appinfo {
+       GladeXML        *xml;
+-      poptContext     context;
++      GtkWidget   *main_dialog;
++      GnomebtController *btmanager;
+       BtctlObexClient *obex;
+-      GnomeProgram    *prog;
+       gchar   *data;
+-      gchar   *error;
++      gsize   fileLength;
+ } MyApp;
+ 
++typedef enum {
++      BUTTONS_OK,
++      BUTTONS_RETRY_CANCEL,
++      BUTTONS_RETRY_SKIP_CANCEL
++} ButtonSet;
++
++static MyApp *app = NULL;
++static gchar **filesToSend = NULL;
++static guint currentFile = 0;
++static struct stat fileStat;
++static guint totalBytes = 0;
++static guint bytesSent = 0;
++static guint totalFiles = 0;
++static gint64 firstTransferTime = 0;
++static gint64 lastUpdateTime = 0;
++static gchar *bdaddrstr = NULL;
++static gchar *bdname = NULL;
++static gchar *temp_error_text = NULL;
++
++#define DIALOG_RESPONSE_SKIP 1
++#define DIALOG_RESPONSE_RETRY 2
+ #define GLADE_FILE DATA_DIR "/gnome-obex-send.glade"
+ #define ICON_FILE ICON_DIR "/blueradio-48.png"
+ 
+-static void mainloop (MyApp *app);
+-static uint8_t get_obex_channel (const gchar *bdaddr);
+-static gboolean send_one (MyApp *app);
+-
+-static gchar *bdaddrstr = NULL;
++static void mainloop ();
++static uint8_t get_obex_channel (GnomebtController *btmanager, const gchar 
*bdaddr, GError **err);
++static gboolean send_one ();
++static void establish_connection ();
++
++static const GOptionEntry options[] = {
++              {"dest", 'd', 0, G_OPTION_ARG_STRING, &bdaddrstr, 
++                              "Bluetooth address of destination device", 
"BDADDR"},
++              {G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_FILENAME_ARRAY, 
&filesToSend},
++              {NULL}
++      };
+ 
+-static const struct poptOption options[] = {
+-      {"dest", 'd', POPT_ARG_STRING, &bdaddrstr,
+-/* FIXME: find way of doing this:
+- * 0, _("Bluetooth address of destination device"), "BDADDR"}, */
+-   0, "Bluetooth address of destination device", "BDADDR"},
+-      {NULL, '\0', 0, NULL, 0}
+-};
+ 
+ static uint8_t
+-get_obex_channel (const gchar *bdaddr)
++get_obex_channel (GnomebtController *btmanager, const gchar *bdaddr, GError 
**err)
+ {
+-      GnomebtController *btmanager;
+       GSList *list, *item;
+       uint8_t ret=0;
+ 
+-      btmanager = gnomebt_controller_new ();
+-
+-      if (! btmanager) {
+-              g_warning ("gnomebt_controller_new() failed");
+-              return -1;
+-      }
+-
+       list = gnomebt_controller_channels_for_service (btmanager,
+                       (const gchar *) bdaddr,
+-                      OBEX_OBJPUSH_SVCLASS_ID);
++                      OBEX_OBJPUSH_SVCLASS_ID, err);
++      if (*err) {
++              g_warning("gnomebt_controller_channels_for_service() failed: %s 
(%s)", 
++                      (*err)->message, errno ? g_strerror(errno): "");
++              return ret;
++      }
+ 
+       for (item=list; item != NULL; item = g_slist_next(item)) {
+               ret = GPOINTER_TO_UINT(item->data);
+       }
++      
++      return ret;
++}
+ 
+-      g_object_unref (btmanager);
++static gint64
++get_system_time (void)
++{
++      struct timeval tmp;
+ 
+-      return ret;
++      gettimeofday (&tmp, NULL);
++      return (gint64)tmp.tv_usec + (gint64)tmp.tv_sec * G_GINT64_CONSTANT 
(1000000);
+ }
+ 
+ static void
+-update_gui (MyApp *app)
++update_gui ()
+ {
+       GladeXML *xml=app->xml;
+       GtkWidget *bar;
+-      gdouble frac = btctl_obex_client_progress (app->obex);
++      gdouble frac;
++      guint actualBytesSent;
++      gint elapsed_time;
++      gint transfer_rate;
++      gint time_remaining;
++      gint64 current_time;
++      gchar *str, *str2;
++      gchar *progressbar_text;
++      
+       bar = glade_xml_get_widget (xml, "progressbar1");
++      /* update progress bar fraction */
++      frac = btctl_obex_client_progress (app->obex);
++      actualBytesSent = bytesSent + app->fileLength * frac;
++      frac = (gdouble)actualBytesSent / totalBytes;
+       gtk_progress_bar_set_fraction( GTK_PROGRESS_BAR (bar), frac);
+-}
++      /* update progress bar text (time remaining)
++       * (only update once in a second) */
++      current_time = get_system_time();
++      elapsed_time = (current_time - firstTransferTime) / 1000000;
++      if (lastUpdateTime != 0) {
++              if (current_time < lastUpdateTime + 1000000)
++                      return;
++              else
++                      lastUpdateTime = current_time;
++      } else {
++              lastUpdateTime = current_time;
++      }
++      if (elapsed_time == 0) {
++              return;
++      }
++      transfer_rate = actualBytesSent / elapsed_time;
++      if (transfer_rate == 0) {
++              return;
++      }
++      time_remaining = (totalBytes - actualBytesSent) / transfer_rate;
++      
++      if (time_remaining >= 3600) {
++              str = g_strdup_printf (_("(%d:%02d:%d Remaining)"), 
++                                     time_remaining / 3600, (time_remaining % 
3600) / 60, (time_remaining % 3600) % 60);
+ 
+-static gboolean
+-is_palm_device (const char *bdaddr)
+-{
+-      return (g_str_has_prefix (bdaddr, "00:04:6B")
+-                      || g_str_has_prefix (bdaddr, "00:07:E0")
+-                      || g_str_has_prefix (bdaddr, "00:0E:20"));
++      }
++      else {
++              str = g_strdup_printf (_("(%d:%02d Remaining)"), 
++                                     time_remaining / 60, time_remaining % 
60);
++      }
++      
++      str2 = g_strdup_printf(_("Sending file: %d of %d"), currentFile+1, 
totalFiles);
++      progressbar_text = g_strconcat(str2, " ", str, NULL);
++      gtk_progress_bar_set_text(GTK_PROGRESS_BAR(bar), progressbar_text);
++      g_free(str);
++      g_free(str2);
++      g_free(progressbar_text);
+ }
+ 
+-static void
+-report_error (const gchar *msg) {
++static gint 
++show_error_dialog (GtkWindow *parent, ButtonSet buttons, const gchar 
*primary_text, const gchar *secondary_text)
++{
+       GtkWidget *dialog;
+-
+-      dialog = gnome_error_dialog (msg);
+-      gtk_signal_connect_object (GTK_OBJECT (dialog),
+-                      "close", GTK_SIGNAL_FUNC (gtk_main_quit),
+-                      (gpointer) dialog);
+-
+-      gtk_main ();
++      gchar *primary_text_markup;
++      gint ret;
++      
++      primary_text_markup = g_strdup_printf("<span weight=\"bold\" 
size=\"larger\">%s</span>", primary_text);
++      dialog = gtk_message_dialog_new_with_markup(parent, 0, 
GTK_MESSAGE_ERROR, 
++                                                      buttons==BUTTONS_OK? 
GTK_BUTTONS_OK: GTK_BUTTONS_CANCEL, 
++                                                      primary_text_markup);
++      gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), 
secondary_text);
++      if (buttons == BUTTONS_RETRY_SKIP_CANCEL) {
++              gtk_dialog_add_button(GTK_DIALOG(dialog), _("Skip"), 
DIALOG_RESPONSE_SKIP);
++      }
++      if (buttons != BUTTONS_OK) {
++              gtk_dialog_add_button(GTK_DIALOG(dialog), _("Retry"), 
DIALOG_RESPONSE_RETRY);
++      }
++      ret = gtk_dialog_run(GTK_DIALOG(dialog));
++      
++      gtk_widget_destroy(dialog);
++      g_free(primary_text_markup);
++      return ret;
+ }
+ 
+ static void
+@@ -131,54 +212,115 @@
+ static void
+ progress_callback (BtctlObexClient *bo, gchar * bdaddr, gpointer data) 
+ {
+-      update_gui ((MyApp *)data);
++      update_gui ();
+ }
+ 
+ static void
+ complete_callback (BtctlObexClient *bo, gchar * bdaddr, gpointer data) 
+ {
+-      MyApp *app = (MyApp *)data;
+-
+       if (app->data) {
+               g_free (app->data);
+               app->data = NULL;
+       }
++      
++      currentFile++;
++      bytesSent += app->fileLength;
+ 
+-      g_idle_add ((GSourceFunc) send_one, data);
++      g_idle_add ((GSourceFunc) send_one, NULL);
++}
++
++static void
++handle_file_sending_error (const gchar *error_text, const gchar 
*error_secondary_text)
++{
++      ButtonSet buttons;
++      int response_id;
++      
++      if (totalFiles > 1 && currentFile < totalFiles-1)
++              buttons = BUTTONS_RETRY_SKIP_CANCEL;
++      else
++              buttons = BUTTONS_RETRY_CANCEL;
++      gdk_threads_enter();
++      response_id = show_error_dialog(GTK_WINDOW(app->main_dialog), buttons, 
++                                                                              
error_text, error_secondary_text);
++      gdk_threads_leave();
++      switch (response_id) {
++              case DIALOG_RESPONSE_SKIP:
++                      currentFile++;
++                      bytesSent += app->fileLength;
++              case DIALOG_RESPONSE_RETRY:
++                      if (temp_error_text) {
++                              /* error happened during transfer */
++                              temp_error_text = NULL;
++                              firstTransferTime = 0;
++                              g_object_unref(app->obex);
++                              /* the connection might be lost, need to 
reestablish it */
++                              if 
(!g_thread_create((GThreadFunc)establish_connection, NULL, FALSE, NULL)) {
++                                      g_warning("Failed to create thread. 
Continuing synchroniously.");
++                                      establish_connection();
++                              }
++                      }
++                      else {
++                              /* continue sending */
++                              g_idle_add ((GSourceFunc) send_one, NULL);
++                      }
++                      break;
++              case GTK_RESPONSE_CANCEL:
++              default:
++                      gtk_main_quit ();
++                      break;
++      }
+ }
+ 
+ static gboolean
+-send_one (MyApp *app)
++send_one ()
+ {
+       const gchar *fname;
+-      gchar *bname;
+-      gsize len;
++      gchar *bname, *dirname;
+       GError *err = NULL;
+-      GtkWidget *label;
+-
+-      if ((fname = poptGetArg (app->context))) {
++      GtkWidget *from_label, *operation_label, *bar;
++      gchar *operation_text, *operation_markup, *progressbar_text;
++      
++      if (fname = *(filesToSend+currentFile)) {
+               /* there's a file to send */
+               app->data = NULL;
+-              if (g_file_get_contents (fname, &(app->data), &len, &err)) {
++              if (g_file_get_contents (fname, &(app->data), 
&(app->fileLength), &err)) {
++                      /* file read successfully, send it */
++                      if (firstTransferTime == 0) {
++                              firstTransferTime = get_system_time();
++                      }
+                       bname = g_path_get_basename (fname);
+-                      label = glade_xml_get_widget (app->xml, 
"filename_label");
+-                      gtk_label_set_text (GTK_LABEL (label), bname);
+-                      btctl_obex_client_push_data (app->obex,
+-                                      bname, app->data, len);
+-                      /* TODO: check error return here from command submit */
++                      dirname = g_path_get_dirname (fname);
++                      
++                      from_label = glade_xml_get_widget (app->xml, 
"from_label");
++                      operation_label = glade_xml_get_widget (app->xml, 
"operation_label");
++                      bar = glade_xml_get_widget (app->xml, "progressbar1");
++                      
++                      operation_text = g_strdup_printf (_("Sending %s"), 
bname);
++                      operation_markup = g_markup_printf_escaped 
("<i>%s</i>", operation_text);
++                      progressbar_text = g_strdup_printf (_("Sending file: %d 
of %d"), currentFile+1, totalFiles);
++                      gtk_label_set_text (GTK_LABEL (from_label), dirname);
++                      gtk_label_set_markup (GTK_LABEL (operation_label), 
operation_markup);
++                      gtk_progress_bar_set_text (GTK_PROGRESS_BAR(bar), 
progressbar_text);
++                      
++                      if (!btctl_obex_client_push_data (app->obex, bname, 
app->data, app->fileLength)) {
++                              /* obex error */
++                              
handle_file_sending_error(g_strdup_printf(_("Could not send file '%s'"), 
fname), "");
++                      }
++                      
+                       g_free (bname);
++                      g_free (dirname);
++                      g_free (operation_text);
++                      g_free (operation_markup);
++                      g_free (progressbar_text);
+               } else {
+-                      app->error = g_strdup_printf (_("Unable to read file 
'%s'."), fname);
+-                      /* TODO: implement error handling */
++                      /* error while reading file */
++                      handle_file_sending_error(_("Unable to read file"), 
err->message);
+                       g_error_free (err);
+-                      /* error, so we quit */
+-                      gtk_main_quit ();
+               }
+       } else {
+               /* nothing left to send, time to quit */
+               gtk_main_quit ();
+       }
+-      
+       return FALSE;
+ }
+ 
+@@ -186,101 +328,214 @@
+ connected_callback (BtctlObexClient *bo, gchar * bdaddr, gpointer data) 
+ {
+       /* OBEX connect has succeeded, so start sending */
+-      g_idle_add ((GSourceFunc) send_one, data);
++      g_idle_add ((GSourceFunc) send_one, NULL);
++}
++
++static gboolean
++error_callback_helper ()
++{
++      handle_file_sending_error (g_strdup_printf(_("An error occured while 
sending file '%s'"), *(filesToSend+currentFile)), 
++                                                                      
temp_error_text);
++      return FALSE;
+ }
+ 
+ static void
+ error_callback (BtctlObexClient *bo, gchar * bdaddr, guint reason,
+               gpointer data)
+ {
+-      MyApp *app = (MyApp *) data;
+-
+-      switch (reason) {
+-              case BTCTL_OBEX_ERR_LINK:
+-              case BTCTL_OBEX_ERR_PARSE:
+-                      app->error = g_strdup (_("An error occurred while 
sending data."));
+-                      break;
+-              case BTCTL_OBEX_ERR_ABORT:
+-                      app->error = g_strdup (_("The remote device canceled 
the transfer."));
+-                      break;
+-              default:
+-                      app->error = g_strdup (_("An unknown error occurred."));
++      if (app->data) {
++              g_free (app->data);
++              app->data = NULL;
+       }
+-      /* Error condition, so quit. */
+-      gtk_main_quit ();
++      
++      if (reason == BTCTL_OBEX_ERR_ABORT)
++              temp_error_text = _("The remote device canceled the transfer.");
++      else if (reason == BTCTL_OBEX_ERR_LINK)
++              temp_error_text = _("Connection to remote device was lost.");
++      
++      g_idle_add ((GSourceFunc) error_callback_helper, NULL);
+ }
+ 
+ static void
+-mainloop (MyApp *app)
++establish_connection ()
+ {
+-      GtkWidget *dialog, *label, *button;
+-
++      uint8_t channel;
++      gint response_id;
++      GError *err=NULL;
++      
++      /* try to connect */
++      channel = get_obex_channel (app->btmanager, bdaddrstr, &err);
++      if (channel) {
++              app->obex = BTCTL_OBEX_CLIENT (
++                              btctl_obex_client_new_and_connect (bdaddrstr, 
channel));
++              if (!btctl_obex_client_is_initialised (app->obex)) {
++                      /* it means remote device bluetooth subsystem is busy 
or has hanged
++                       * so we say that remote device doesn't support 
receiving objects */
++                      channel = 0;
++              }
++      }
++      
++      /* handle errors */
++      if (!channel) {
++              gdk_threads_enter();
++              if (err) {
++                      response_id = 
show_error_dialog(GTK_WINDOW(app->main_dialog), BUTTONS_RETRY_CANCEL, 
++                                              err->message, 
++                                              _("Make sure that remote device 
is on and that it accepts bluetooth connections."));
++                      g_error_free (err);
++              } else {
++                      response_id = 
show_error_dialog(GTK_WINDOW(app->main_dialog), BUTTONS_RETRY_CANCEL, 
++                                              _("Remote device can not 
receive files"), 
++                                              _("Make sure that remote device 
is not busy with another bluetooth connection."));
++              }
++              gdk_threads_leave();
++              if (response_id == DIALOG_RESPONSE_RETRY) {
++                      /* try reconnecting */
++                              
++                      if (!g_thread_create((GThreadFunc)establish_connection, 
NULL, FALSE, NULL)) {
++                              g_warning("Failed to create thread. Continuing 
synchroniously.");
++                              establish_connection();
++                      }
++                      return;
++              }
++              
++              gtk_main_quit();
++              return;
++      }
++      
++      /* connect signals */
+       g_signal_connect (G_OBJECT (app->obex), "progress",
+-              G_CALLBACK (progress_callback), (gpointer) app);
++              G_CALLBACK (progress_callback), NULL);
+       g_signal_connect (G_OBJECT (app->obex), "complete",
+-              G_CALLBACK (complete_callback), (gpointer) app);
++              G_CALLBACK (complete_callback), NULL);
+       g_signal_connect (G_OBJECT (app->obex), "connected",
+-              G_CALLBACK (connected_callback), (gpointer) app);
++              G_CALLBACK (connected_callback), NULL);
+       g_signal_connect (G_OBJECT (app->obex), "error",
+-              G_CALLBACK (error_callback), (gpointer) app);
++              G_CALLBACK (error_callback), NULL);
++}
++
++static void
++mainloop ()
++{
++      GtkWidget *label1, *label2, *label3, *target_label, *progressbar, 
*button;
++      gchar *text;
+ 
+-      dialog = glade_xml_get_widget (app->xml, "send_dialog");
++      /* initialize UI */
++      app->main_dialog = glade_xml_get_widget (app->xml, "send_dialog");
+ 
+-      gtk_widget_show_all (dialog);
++      gtk_widget_show_all (app->main_dialog);
+ 
+-      label = glade_xml_get_widget (app->xml, "filename_label");
++      label1 = glade_xml_get_widget (app->xml, "label1");
++      label2 = glade_xml_get_widget (app->xml, "label2");
++      label3 = glade_xml_get_widget (app->xml, "label3");
++      target_label = glade_xml_get_widget (app->xml, "target_label");
++      progressbar = glade_xml_get_widget(app->xml, "progressbar1");
+       button = glade_xml_get_widget (app->xml, "cancelbutton");
+ 
+       g_signal_connect (G_OBJECT (button), "clicked",
+                                               G_CALLBACK (cancel_clicked),
+                                               (gpointer) app);
+ 
+-      gtk_label_set_text (GTK_LABEL (label), _("Connecting..."));
++      text = g_markup_printf_escaped ("<span weight=\"bold\" 
size=\"larger\">%s</span>", _("Sending files via bluetooth"));
++      gtk_label_set_markup (GTK_LABEL (label1), text);
++      g_free (text);
++      text = g_markup_printf_escaped ("<b>%s</b>", _("From:"));
++      gtk_label_set_markup (GTK_LABEL (label2), text);
++      g_free (text);
++      text = g_markup_printf_escaped ("<b>%s</b>", _("To:"));
++      gtk_label_set_markup (GTK_LABEL (label3), text);
++      g_free (text);
++      gtk_progress_bar_set_text (GTK_PROGRESS_BAR (progressbar), 
_("Connecting..."));
++      text = g_strdup_printf("%s (%s)", bdname, bdaddrstr);
++      gtk_label_set_text (GTK_LABEL (target_label), text);
++      g_free (text);
++      
++      /* begin connecting in separate thread */
++      gdk_threads_init();
++      if (!g_thread_create((GThreadFunc)establish_connection, NULL, FALSE, 
NULL)) {
++              g_warning("Failed to create thread. Continuing 
synchroniously.");
++              establish_connection();
++      }
+ 
+       gtk_main ();
+ 
+-      gtk_widget_hide (dialog);
++      gtk_widget_hide (app->main_dialog);
++}
++
++static void
++free_mem ()
++{
++      if (filesToSend)
++              g_strfreev (filesToSend);
++      if (bdaddrstr)
++              g_free (bdaddrstr);
++      if (bdname)
++              g_free (bdname);
++      if (app) {
++              if (app->data)
++                      g_free (app->data);
++              if (app->obex)
++                      g_object_unref (app->obex);
++              if (app->btmanager)
++                      g_object_unref (app->btmanager);
++              g_free (app);
++      }
+ }
+ 
+ int
<<Diff was trimmed, longer than 597 lines>>
_______________________________________________
pld-cvs-commit mailing list
[email protected]
http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit

Reply via email to