rpms/bluez-gnome/devel main.c, NONE, 1.1 bluez-gnome-new-sendto-6.patch, 1.1, 1.2 bluez-gnome.spec, 1.31, 1.32
Bastien Nocera (hadess)
fedora-extras-commits at redhat.com
Wed Feb 6 13:12:40 UTC 2008
Author: hadess
Update of /cvs/pkgs/rpms/bluez-gnome/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv23088
Modified Files:
bluez-gnome-new-sendto-6.patch bluez-gnome.spec
Added Files:
main.c
Log Message:
Patching whole files sucks
--- NEW FILE main.c ---
/*
*
* BlueZ - Bluetooth protocol stack for Linux
*
* Copyright (C) 2005-2008 Marcel Holtmann <marcel at holtmann.org>
* Copyright (C) 2006-2007 Tadas Dailyda <tadas at dailyda.com>
* Copyright (C) 2007 Bastien Nocera <hadess at hadess.net>
*
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <dbus/dbus-glib.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include <gtk/gtk.h>
#include "dbus-glue.h"
#include "marshal.h"
#include "utils.h"
/* DBus */
static DBusGConnection *connection = NULL;
static DBusGProxy *manager_proxy = NULL;
static DBusGProxy *session_proxy = NULL;
/* GTK */
static GtkWidget *main_dialog, *from_label, *operation_label, *progress_bar;
/* sending related */
static gsize file_length = 0;
static guint file_count = 0;
static guint current_file = 0;
static GSList *file_list = NULL;
static guint byte_count = 0;
static guint bytes_sent = 0;
static gint64 first_transfer_time = 0;
static gint64 last_update_time = 0;
typedef enum {
BUTTONS_OK,
BUTTONS_RETRY_CANCEL,
BUTTONS_RETRY_SKIP_CANCEL
} ButtonSet;
/* Command line options */
static gchar **files_to_send = NULL;
static gchar *bdaddrstr = NULL;
static gchar *device_name = NULL;
#define DIALOG_RESPONSE_SKIP 1
#define DIALOG_RESPONSE_RETRY 2
static void error_occurred_cb(DBusGProxy *proxy, const gchar *error_name,
const gchar *error_message, gpointer user_data);
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, &files_to_send},
{NULL}
};
static gint64 get_system_time(void)
{
struct timeval tmp;
gettimeofday(&tmp, NULL);
return (gint64)tmp.tv_usec + (gint64)tmp.tv_sec * G_GINT64_CONSTANT(1000000);
}
static gboolean is_palm_device(const gchar *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"));
}
/* Return the local absolute filename for the file, and its size
* if the file exists and is stat()'able */
static gchar *normalise_filename(const gchar *filename, gint64 *size)
{
char *ret;
struct stat file_stat;
g_return_val_if_fail(filename != NULL, NULL);
g_return_val_if_fail(size != NULL, NULL);
if (g_str_has_prefix(filename, "file://")) {
ret = g_filename_from_uri(filename, NULL, NULL);
if (ret == NULL)
return NULL;
} else if (filename[0] == '/') {
ret = g_strdup(filename);
} else {
gchar *curdir;
curdir = g_get_current_dir();
ret = g_build_filename(curdir, filename, NULL);
g_free(curdir);
}
if (!g_file_test(ret, G_FILE_TEST_IS_REGULAR)) {
g_free(ret);
return NULL;
}
if (!g_stat(ret, &file_stat)) {
*size = file_stat.st_size;
} else {
g_free(ret);
return NULL;
}
return ret;
}
static gchar *get_device_name(void)
{
DBusGConnection *connection;
DBusGProxy *manager;
GError *error = NULL;
gchar *name, **adapters;
guint i;
name = NULL;
connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, NULL);
if (connection == NULL)
return NULL;
manager = dbus_g_proxy_new_for_name(connection, "org.bluez",
"/org/bluez", "org.bluez.Manager");
if (!manager) {
dbus_g_connection_unref(connection);
return NULL;
}
if (!manager_list_adapters(manager, &adapters, &error)) {
g_object_unref(manager);
dbus_g_connection_unref(connection);
return NULL;
}
for (i = 0; adapters[i] != NULL; i++) {
DBusGProxy *adapter;
adapter = dbus_g_proxy_new_for_name(connection, "org.bluez",
adapters[i], "org.bluez.Adapter");
if (dbus_g_proxy_call(adapter, "GetRemoteName", NULL,
G_TYPE_STRING, bdaddrstr, G_TYPE_INVALID,
G_TYPE_STRING, &name, G_TYPE_INVALID)) {
if (name != NULL && name[0] != '\0') {
g_object_unref(adapter);
break;
}
}
g_object_unref(adapter);
}
g_object_unref(manager);
dbus_g_connection_unref(connection);
return name;
}
static gint show_error_dialog(GtkWindow *parent, ButtonSet buttons,
const gchar *primary_text, const gchar *secondary_text)
{
GtkWidget *dialog;
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 gint show_connection_error_dialog(GtkWindow *parent, const gchar *bdaddr,
const gchar *primary_text)
{
if (!is_palm_device(bdaddrstr)) {
return show_error_dialog(parent,
BUTTONS_RETRY_CANCEL,
primary_text,
_("Make sure that remote device is on and that it accepts Bluetooth connections."));
} else {
return show_error_dialog(parent,
BUTTONS_RETRY_CANCEL,
primary_text,
_("Make sure \"Beam receive\" is enabled in the Power preferences, and Bluetooth is enabled, on your Palm device."));
}
}
static gint handle_file_sending_error(const gchar *error_text,
const gchar *error_secondary_text)
{
ButtonSet buttons;
gint response_id;
if (file_count > 1 && current_file < file_count - 1)
buttons = BUTTONS_RETRY_SKIP_CANCEL;
else
buttons = BUTTONS_RETRY_CANCEL;
response_id = show_error_dialog(GTK_WINDOW(main_dialog), buttons,
error_text, error_secondary_text);
switch (response_id) {
case DIALOG_RESPONSE_SKIP:
current_file++;
bytes_sent += file_length;
case DIALOG_RESPONSE_RETRY:
return TRUE;
case GTK_RESPONSE_CANCEL:
default:
gtk_main_quit();
break;
}
return response_id;
}
static void cancel_clicked_cb(GtkWidget *button, gpointer user_data)
{
gtk_main_quit();
}
static void ui_init(void)
{
GtkWidget *vbox, *vbox_parent, *table;
GtkWidget *label1, *label2, *label3, *target_label;
GtkWidget *button;
gchar *text;
/* initialize UI */
device_name = get_device_name();
/* main dialog */
main_dialog = gtk_dialog_new();
gtk_dialog_set_has_separator(GTK_DIALOG(main_dialog), FALSE);
gtk_window_set_title(GTK_WINDOW(main_dialog),
_("Bluetooth file transfer"));
gtk_window_set_icon_name(GTK_WINDOW(main_dialog), "stock_bluetooth");
gtk_window_set_type_hint(GTK_WINDOW(main_dialog),
GDK_WINDOW_TYPE_HINT_NORMAL);
gtk_window_set_position(GTK_WINDOW(main_dialog), GTK_WIN_POS_CENTER);
gtk_window_set_resizable(GTK_WINDOW(main_dialog), FALSE);
gtk_widget_set(main_dialog, "width-request", 400, NULL);
button = gtk_dialog_add_button(GTK_DIALOG(main_dialog),
GTK_STOCK_CANCEL,
GTK_RESPONSE_CANCEL);
g_signal_connect(G_OBJECT(button), "clicked",
G_CALLBACK(cancel_clicked_cb), NULL);
gtk_container_set_border_width(GTK_CONTAINER(main_dialog), 6);
/* table elements */
from_label = gtk_label_new(NULL);
gtk_misc_set_alignment(GTK_MISC(from_label), 0, 0.5);
gtk_label_set_ellipsize(GTK_LABEL(from_label), PANGO_ELLIPSIZE_MIDDLE);
target_label = gtk_label_new(NULL);
gtk_misc_set_alignment(GTK_MISC(target_label), 0, 0.5);
gtk_label_set_ellipsize(GTK_LABEL(target_label), PANGO_ELLIPSIZE_END);
gtk_label_set_text(GTK_LABEL(target_label), device_name ? device_name : bdaddrstr);
label2 = gtk_label_new(NULL);
text = g_markup_printf_escaped("<b>%s</b>", _("From:"));
gtk_label_set_markup(GTK_LABEL(label2), text);
g_free(text);
label3 = gtk_label_new(NULL);
gtk_misc_set_alignment(GTK_MISC(label3), 1, 0.5);
text = g_markup_printf_escaped("<b>%s</b>", _("To:"));
gtk_label_set_markup(GTK_LABEL(label3), text);
g_free(text);
/* table */
table = gtk_table_new(2, 2, FALSE);
gtk_table_set_col_spacings(GTK_TABLE(table), 4);
gtk_table_set_row_spacings(GTK_TABLE(table), 4);
gtk_table_attach_defaults(GTK_TABLE(table), from_label, 1, 2, 0, 1);
gtk_table_attach_defaults(GTK_TABLE(table), target_label, 1, 2, 1, 2);
gtk_table_attach(GTK_TABLE(table), label2, 0, 1, 0, 1, GTK_FILL, 0, 0, 0);
gtk_table_attach(GTK_TABLE(table), label3, 0, 1, 1, 2, GTK_FILL, 0, 0, 0);
/* vbox elements */
label1 = gtk_label_new(NULL);
gtk_misc_set_alignment(GTK_MISC(label1), 0, 0.5);
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);
progress_bar = gtk_progress_bar_new();
gtk_progress_bar_set_ellipsize(GTK_PROGRESS_BAR(progress_bar),
PANGO_ELLIPSIZE_END);
gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress_bar),
_("Connecting..."));
operation_label = gtk_label_new(NULL);
gtk_misc_set_alignment(GTK_MISC(operation_label), 0, 0.5);
gtk_label_set_ellipsize(GTK_LABEL(operation_label), PANGO_ELLIPSIZE_END);
/* vbox */
vbox = gtk_vbox_new(FALSE, 0);
gtk_box_set_spacing(GTK_BOX(vbox), 6);
gtk_container_set_border_width(GTK_CONTAINER(vbox), 6);
gtk_box_pack_start_defaults(GTK_BOX(vbox), label1);
gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 9);
gtk_box_pack_start_defaults(GTK_BOX(vbox), progress_bar);
gtk_box_pack_start(GTK_BOX(vbox), operation_label, TRUE, TRUE, 2);
vbox_parent = gtk_bin_get_child(GTK_BIN(main_dialog));
gtk_box_pack_start_defaults(GTK_BOX(vbox_parent), vbox);
/* show it */
gtk_widget_show_all(main_dialog);
}
static gboolean send_one(gpointer user_data)
{
const gchar *fname;
gint ret;
gchar *bname, *dirname;
GError *err = NULL;
gchar *operation_text, *operation_markup, *progressbar_text;
if ((fname = g_slist_nth_data(file_list, current_file))) {
/* there's a file to send */
dbus_g_proxy_call(session_proxy, "SendFile", &err,
G_TYPE_STRING, fname, G_TYPE_INVALID, G_TYPE_INVALID);
if (err != NULL) {
ret = handle_file_sending_error(_("Unable to read file"),
err->message);
if (ret != GTK_RESPONSE_CANCEL) {
g_idle_add((GSourceFunc) send_one, NULL);
}
g_error_free(err);
return FALSE;
}
if (!first_transfer_time) {
first_transfer_time = get_system_time();
}
bname = g_path_get_basename(fname);
dirname = g_path_get_dirname(fname);
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"),
current_file+1,
file_count);
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(progress_bar),
progressbar_text);
g_free(bname);
g_free(dirname);
g_free(operation_text);
g_free(operation_markup);
g_free(progressbar_text);
} else {
/* nothing left to send, time to quit */
gtk_main_quit();
}
return FALSE;
}
static void session_connected_cb(DBusGProxy *proxy, gpointer user_data)
{
/* OBEX connect has succeeded, so start sending */
g_idle_add((GSourceFunc) send_one, NULL);
}
static void transfer_started_cb(DBusGProxy *proxy, const gchar *filename,
const gchar *local_path, gint byte_count, gpointer user_data)
{
file_length = byte_count;
}
static void transfer_cancelled_cb(DBusGProxy *proxy, gpointer user_data)
{
gint ret;
gchar *error_text;
error_text = g_strdup_printf(_("An error occured while sending file '%s'"),
(gchar *)g_slist_nth_data(file_list, current_file));
ret = handle_file_sending_error(error_text,
_("The remote device cancelled the transfer"));
if (ret != GTK_RESPONSE_CANCEL)
g_idle_add((GSourceFunc) send_one, NULL);
g_free(error_text);
}
static void transfer_progress_cb(DBusGProxy *proxy, gint bytes_transferred, gpointer user_data)
{
gdouble frac;
guint actual_bytes_sent;
gint elapsed_time;
gint transfer_rate;
gint time_remaining;
gint64 current_time;
gchar *str, *str2;
gchar *progressbar_text;
/* update progress bar fraction */
actual_bytes_sent = bytes_sent + bytes_transferred;
frac = (gdouble)actual_bytes_sent / byte_count;
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress_bar), frac);
/* update progress bar text (time remaining)
* (only update once in a second) */
current_time = get_system_time();
elapsed_time = (current_time - first_transfer_time) / 1000000;
if (last_update_time) {
if (current_time < last_update_time + 1000000)
return;
else
last_update_time = current_time;
} else {
last_update_time = current_time;
}
if (!elapsed_time)
return;
transfer_rate = actual_bytes_sent / elapsed_time;
if (transfer_rate == 0)
return;
time_remaining = (byte_count - actual_bytes_sent) / 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);
} else {
str = g_strdup_printf(_("(%d:%02d Remaining)"),
time_remaining / 60,
time_remaining % 60);
}
/* Translators:
* Sending file 1 of 3 */
str2 = g_strdup_printf(_("Sending file %d of %d"),
current_file + 1,
file_count);
progressbar_text = g_strconcat(str2, " ", str, NULL);
gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress_bar),
progressbar_text);
g_free(str);
g_free(str2);
g_free(progressbar_text);
}
static void transfer_completed_cb(DBusGProxy *proxy, gpointer user_data)
{
current_file++;
bytes_sent += file_length;
g_idle_add((GSourceFunc) send_one, NULL);
}
static void session_created_cb(DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
{
GError *error = NULL;
const gchar *path = NULL;
if (!dbus_g_proxy_end_call(proxy, call, &error,
G_TYPE_STRING, &path, G_TYPE_INVALID)) {
const gchar *error_name = NULL;
gint response_id;
if (error && error->code == DBUS_GERROR_REMOTE_EXCEPTION)
error_name = dbus_g_error_get_name(error);
if (error_name && !strcmp(error_name, "org.openobex.Error.ConnectionAttemptFailed")) {
response_id = show_connection_error_dialog(GTK_WINDOW(main_dialog), bdaddrstr, error->message);
if (response_id == DIALOG_RESPONSE_RETRY) {
/* Try to create Session again */
dbus_g_proxy_begin_call(manager_proxy,
"CreateBluetoothSession",
(DBusGProxyCallNotify) session_created_cb, NULL, NULL,
G_TYPE_STRING, bdaddrstr, G_TYPE_STRING, "opp",
G_TYPE_BOOLEAN, FALSE, G_TYPE_INVALID);
goto out;
}
} else {
show_error_dialog(GTK_WINDOW(main_dialog), BUTTONS_OK,
error->message, "");
}
/* Failed, quit main loop */
gtk_main_quit();
goto out;
}
session_proxy = dbus_g_proxy_new_for_name(connection,
"org.openobex",
path,
"org.openobex.Session");
dbus_g_proxy_add_signal(session_proxy, "Connected",
G_TYPE_INVALID);
dbus_g_proxy_connect_signal(session_proxy, "Connected",
G_CALLBACK(session_connected_cb), NULL, NULL);
dbus_g_proxy_add_signal(session_proxy, "TransferStarted",
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INVALID);
dbus_g_proxy_connect_signal(session_proxy, "TransferStarted",
G_CALLBACK(transfer_started_cb), NULL, NULL);
dbus_g_proxy_add_signal(session_proxy, "Cancelled",
G_TYPE_INVALID);
dbus_g_proxy_connect_signal(session_proxy, "Cancelled",
G_CALLBACK(transfer_cancelled_cb), NULL, NULL);
dbus_g_proxy_add_signal(session_proxy, "ErrorOccurred",
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
dbus_g_proxy_connect_signal(session_proxy, "ErrorOccurred",
G_CALLBACK(error_occurred_cb), NULL, NULL);
dbus_g_proxy_add_signal(session_proxy, "TransferProgress",
G_TYPE_UINT, G_TYPE_INVALID);
dbus_g_proxy_connect_signal(session_proxy, "TransferProgress",
G_CALLBACK(transfer_progress_cb), NULL, NULL);
dbus_g_proxy_add_signal(session_proxy, "TransferCompleted",
G_TYPE_INVALID);
dbus_g_proxy_connect_signal(session_proxy, "TransferCompleted",
G_CALLBACK(transfer_completed_cb), NULL, NULL);
dbus_g_proxy_call(session_proxy, "Connect", &error, G_TYPE_INVALID,
G_TYPE_INVALID);
out:
if (error)
g_error_free(error);
}
static void error_occurred_cb(DBusGProxy *proxy, const gchar *error_name, const gchar *error_message, gpointer user_data)
{
gint ret;
gboolean link_error = FALSE;
gchar *error_text;
const gchar *reason;
g_message("ErrorOccurred");
g_message("Error name: %s", error_name);
g_message("Error message: %s", error_message);
error_text = g_strdup_printf(_("An error occured while sending file '%s'"),
(gchar *)g_slist_nth_data(file_list, current_file));
if (!strcmp(error_name, "org.openobex.Error.LinkError")) {
/* Connection to remote device was lost */
g_object_unref(G_OBJECT(session_proxy));
reason = _("Connection to remote device was lost");
link_error = TRUE;
} else if (!strcmp(error_name, "org.openobex.Error.Forbidden")) {
reason = _("Remote device rejected file");
} else {
reason = _("Unknown error");
}
ret = handle_file_sending_error(error_text, reason);
if (ret != GTK_RESPONSE_CANCEL) {
if (link_error) {
/* Need to reestablish connection */
dbus_g_proxy_begin_call(manager_proxy, "CreateBluetoothSession",
(DBusGProxyCallNotify) session_created_cb, NULL, NULL,
G_TYPE_STRING, bdaddrstr, G_TYPE_STRING, "opp",
G_TYPE_INVALID);
} else {
g_idle_add((GSourceFunc) send_one, NULL);
}
}
g_free(error_text);
}
static void free_mem(void)
{
if (files_to_send)
g_strfreev(files_to_send);
g_free(bdaddrstr);
if (main_dialog)
gtk_widget_destroy (main_dialog);
if (G_IS_OBJECT(manager_proxy))
g_object_unref(G_OBJECT(manager_proxy));
if (G_IS_OBJECT(session_proxy))
g_object_unref (G_OBJECT(session_proxy));
g_slist_free(file_list);
}
static void name_owner_changed(DBusGProxy *proxy, const char *name,
const char *prev, const char *new, gpointer user_data)
{
if (g_str_equal(name, "org.openobex") == TRUE && *new == '\0')
gtk_main_quit();
}
int main(int argc, char *argv[])
{
GOptionContext *option_context;
GError *error = NULL;
guint i;
/* initialize gettext */
bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
textdomain(GETTEXT_PACKAGE);
/* parse command line arguments */
option_context = g_option_context_new("<file list>");
g_option_context_add_main_entries(option_context, options, GETTEXT_PACKAGE);
g_option_context_add_group(option_context, gtk_get_option_group(TRUE));
g_option_context_parse(option_context, &argc, &argv, &error);
g_option_context_free(option_context);
if (error) {
printf("Usage:\n");
printf(" %s [--dest=BDADDR] <file list>\n", g_get_prgname());
g_error_free(error);
free_mem();
return 0;
}
gtk_init(&argc, &argv);
/* init DBus connection */
connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
if (!connection) {
show_error_dialog(NULL, GTK_BUTTONS_OK,
_("Please verify that D-Bus is correctly installed and setup."), error->message);
g_error_free(error);
return 1;
}
main_dialog = NULL;
from_label = NULL;
operation_label = NULL;
progress_bar = NULL;
/* get a list of files to send from command-line */
if (files_to_send)
file_count = g_strv_length(files_to_send);
else
file_count = 0;
for (i = 0; i < file_count; i++) {
file_list = g_slist_append(file_list,
g_strdup(*(files_to_send + i)));
}
/* show file chooser if no files were specified */
if (!file_count) {
file_list = select_files_dialog();
file_count = g_slist_length(file_list);
}
/* Check if there are some files to send */
if (!file_count) {
free_mem();
return 0;
}
/* Check for non regular and non existand files and
* determine total bytes to send */
for (i = 0; i < file_count; i++) {
GSList *item;
gchar *path, *filename;
gint64 size;
item = g_slist_nth(file_list, i);
path = (gchar *) item->data;
filename = normalise_filename(path, &size);
if (filename == NULL) {
g_free(path);
file_list = g_slist_remove_link(file_list, item);
continue;
}
g_free(item->data);
item->data = filename;
byte_count += size;
}
/* determine Bluetooth device to send to */
if (!bdaddrstr) {
bdaddrstr = browse_device_dialog();
if (!bdaddrstr) {
free_mem();
return 0;
}
}
dbus_g_object_register_marshaller(marshal_VOID__STRING_STRING_INT,
G_TYPE_NONE, G_TYPE_STRING,
G_TYPE_STRING, G_TYPE_INT, G_TYPE_INVALID);
dbus_g_object_register_marshaller(marshal_VOID__STRING_STRING,
G_TYPE_NONE, G_TYPE_STRING,
G_TYPE_STRING, G_TYPE_INVALID);
/* init UI */
ui_init();
/* init DBus proxy, create Session */
manager_proxy = dbus_g_proxy_new_for_name(connection,
"org.openobex",
"/org/openobex",
"org.openobex.Manager");
dbus_g_proxy_add_signal(manager_proxy, "NameOwnerChanged",
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
dbus_g_proxy_connect_signal(manager_proxy, "NameOwnerChanged",
G_CALLBACK(name_owner_changed), NULL, NULL);
dbus_g_proxy_begin_call(manager_proxy, "CreateBluetoothSession",
(DBusGProxyCallNotify) session_created_cb, NULL, NULL,
G_TYPE_STRING, bdaddrstr, G_TYPE_STRING, "opp",
G_TYPE_INVALID);
/* Go into main loop */
gtk_main();
/* done sending, free memory */
free_mem();
return 0;
}
bluez-gnome-new-sendto-6.patch:
Index: bluez-gnome-new-sendto-6.patch
===================================================================
RCS file: /cvs/pkgs/rpms/bluez-gnome/devel/bluez-gnome-new-sendto-6.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- bluez-gnome-new-sendto-6.patch 6 Feb 2008 13:08:00 -0000 1.1
+++ bluez-gnome-new-sendto-6.patch 6 Feb 2008 13:12:16 -0000 1.2
@@ -19,1007 +19,6 @@
MAINTAINERCLEANFILES = Makefile.in
+
-Index: sendto/main.c
-===================================================================
-RCS file: /cvsroot/bluez/gnome/sendto/main.c,v
-retrieving revision 1.17
-diff -u -p -r1.17 main.c
---- sendto/main.c 6 Feb 2008 12:22:48 -0000 1.17
-+++ sendto/main.c 6 Feb 2008 13:06:24 -0000
-@@ -3,6 +3,8 @@
- * BlueZ - Bluetooth protocol stack for Linux
- *
- * Copyright (C) 2005-2008 Marcel Holtmann <marcel at holtmann.org>
-+ * Copyright (C) 2006-2007 Tadas Dailyda <tadas at dailyda.com>
-+ * Copyright (C) 2007 Bastien Nocera <hadess at hadess.net>
- *
- *
- * This program is free software; you can redistribute it and/or modify
-@@ -25,260 +27,620 @@
- #include <config.h>
- #endif
-
--#include <dbus/dbus-glib.h>
-
- #include <glib/gi18n.h>
--
- #include <gtk/gtk.h>
-
--#include "bluetooth-device-selection.h"
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <sys/time.h>
-+#include <sys/types.h>
-+
-+#include <dbus/dbus-glib.h>
-+#include <glib.h>
-+#include <glib/gi18n.h>
-+#include <glib/gstdio.h>
-+#include <gtk/gtk.h>
-
-+#include "dbus-glue.h"
- #include "marshal.h"
-+#include "utils.h"
-
--static DBusGConnection *conn = NULL;
-+/* DBus */
-+static DBusGConnection *connection = NULL;
-+static DBusGProxy *manager_proxy = NULL;
-+static DBusGProxy *session_proxy = NULL;
-+/* GTK */
-+static GtkWidget *main_dialog, *from_label, *operation_label, *progress_bar;
-+/* sending related */
-+static gsize file_length = 0;
-+static guint file_count = 0;
-+static guint current_file = 0;
-+static GSList *file_list = NULL;
-+static guint byte_count = 0;
-+static guint bytes_sent = 0;
-+static gint64 first_transfer_time = 0;
-+static gint64 last_update_time = 0;
-+
-+typedef enum {
-+ BUTTONS_OK,
-+ BUTTONS_RETRY_CANCEL,
-+ BUTTONS_RETRY_SKIP_CANCEL
-+} ButtonSet;
-+
-+/* Command line options */
-+static gchar **files_to_send = NULL;
-+static gchar *bdaddrstr = NULL;
-+static gchar *device_name = NULL;
-+
-+#define DIALOG_RESPONSE_SKIP 1
-+#define DIALOG_RESPONSE_RETRY 2
-+
-+static void error_occurred_cb(DBusGProxy *proxy, const gchar *error_name,
-+ const gchar *error_message, gpointer user_data);
-+
-+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, &files_to_send},
-+ {NULL}
-+};
-
--static GtkWidget *dialog;
--static GtkWidget *label_filename;
--static GtkWidget *label_status;
--static GtkWidget *progress;
-+static gint64 get_system_time(void)
-+{
-+ struct timeval tmp;
-
--static gint filesize = -1;
-+ gettimeofday(&tmp, NULL);
-+ return (gint64)tmp.tv_usec + (gint64)tmp.tv_sec * G_GINT64_CONSTANT(1000000);
-+}
-
--static gchar *open_file_dialog(void)
-+static gboolean is_palm_device(const gchar *bdaddr)
- {
-- GtkWidget *dialog;
-- gchar *filename = NULL;
-+ 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"));
-+}
-
-- dialog = gtk_file_chooser_dialog_new(_("Select File"), NULL,
-- GTK_FILE_CHOOSER_ACTION_OPEN,
-- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-- GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
-+/* Return the local absolute filename for the file, and its size
-+ * if the file exists and is stat()'able */
-+static gchar *normalise_filename(const gchar *filename, gint64 *size)
-+{
-+ char *ret;
-+ struct stat file_stat;
-
-- if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
-- filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
-+ g_return_val_if_fail(filename != NULL, NULL);
-+ g_return_val_if_fail(size != NULL, NULL);
-
-- gtk_widget_destroy(dialog);
-+ if (g_str_has_prefix(filename, "file://")) {
-+ ret = g_filename_from_uri(filename, NULL, NULL);
-+ if (ret == NULL)
-+ return NULL;
-+ } else if (filename[0] == '/') {
-+ ret = g_strdup(filename);
-+ } else {
-+ gchar *curdir;
-
-- return filename;
--}
-+ curdir = g_get_current_dir();
-+ ret = g_build_filename(curdir, filename, NULL);
-+ g_free(curdir);
-+ }
-
--static void selected_device_changed(BluetoothDeviceSelection *selector,
-- gchar *address, gpointer user_data)
--{
-- GtkWidget *dialog = user_data;
-+ if (!g_file_test(ret, G_FILE_TEST_IS_REGULAR)) {
-+ g_free(ret);
-+ return NULL;
-+ }
-+
-+ if (!g_stat(ret, &file_stat)) {
-+ *size = file_stat.st_size;
-+ } else {
-+ g_free(ret);
-+ return NULL;
-+ }
-
-- gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog),
-- GTK_RESPONSE_ACCEPT, address != NULL);
-+ return ret;
- }
-
--static gchar *browse_device_dialog(void)
-+static gchar *get_device_name(void)
- {
-- GtkWidget *dialog;
-- GtkWidget *selector;
-- gchar *address = NULL;
-+ DBusGConnection *connection;
-+ DBusGProxy *manager;
-+ GError *error = NULL;
-+ gchar *name, **adapters;
-+ guint i;
-
-- dialog = gtk_dialog_new_with_buttons(_("Select Device"),
-- NULL, GTK_DIALOG_NO_SEPARATOR,
-- GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
-- GTK_STOCK_CONNECT, GTK_RESPONSE_ACCEPT, NULL);
-+ name = NULL;
-
-- gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog),
-- GTK_RESPONSE_ACCEPT, FALSE);
-+ connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, NULL);
-+ if (connection == NULL)
-+ return NULL;
-+
-+ manager = dbus_g_proxy_new_for_name(connection, "org.bluez",
-+ "/org/bluez", "org.bluez.Manager");
-+ if (!manager) {
-+ dbus_g_connection_unref(connection);
-+ return NULL;
-+ }
-
-- gtk_window_set_default_size(GTK_WINDOW(dialog), 450, 400);
-+ if (!manager_list_adapters(manager, &adapters, &error)) {
-+ g_object_unref(manager);
-+ dbus_g_connection_unref(connection);
-+ return NULL;
-+ }
-
-- gtk_container_set_border_width(GTK_CONTAINER(dialog), 5);
-- gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->vbox), 2);
-+ for (i = 0; adapters[i] != NULL; i++) {
-+ DBusGProxy *adapter;
-
-- selector = bluetooth_device_selection_new(_("Select destination device"));
-- gtk_container_set_border_width(GTK_CONTAINER(selector), 5);
-+ adapter = dbus_g_proxy_new_for_name(connection, "org.bluez",
-+ adapters[i], "org.bluez.Adapter");
-+ if (dbus_g_proxy_call(adapter, "GetRemoteName", NULL,
-+ G_TYPE_STRING, bdaddrstr, G_TYPE_INVALID,
-+ G_TYPE_STRING, &name, G_TYPE_INVALID)) {
-+ if (name != NULL && name[0] != '\0') {
-+ g_object_unref(adapter);
-+ break;
-+ }
-+ }
-+ g_object_unref(adapter);
-+ }
-
-- gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), selector);
-+ g_object_unref(manager);
-+ dbus_g_connection_unref(connection);
-
-- g_signal_connect(selector, "selected-device-changed",
-- G_CALLBACK(selected_device_changed), dialog);
-+ return name;
-+}
-
-- gtk_widget_show_all(selector);
-+static gint show_error_dialog(GtkWindow *parent, ButtonSet buttons,
-+ const gchar *primary_text, const gchar *secondary_text)
-+{
-+ GtkWidget *dialog;
-+ gchar *primary_text_markup;
-+ gint ret;
-
-- if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
-- g_object_get(selector, "device-selected", &address, NULL);
-+ 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;
-+}
-
-- return address;
-+static gint show_connection_error_dialog(GtkWindow *parent, const gchar *bdaddr,
-+ const gchar *primary_text)
-+{
-+ if (!is_palm_device(bdaddrstr)) {
-+ return show_error_dialog(parent,
-+ BUTTONS_RETRY_CANCEL,
-+ primary_text,
-+ _("Make sure that remote device is on and that it accepts Bluetooth connections."));
-+ } else {
-+ return show_error_dialog(parent,
-+ BUTTONS_RETRY_CANCEL,
-+ primary_text,
-+ _("Make sure \"Beam receive\" is enabled in the Power preferences, and Bluetooth is enabled, on your Palm device."));
-+ }
- }
-
--static void response_callback(GtkWidget *dialog,
-- gint response, gpointer user_data)
-+static gint handle_file_sending_error(const gchar *error_text,
-+ const gchar *error_secondary_text)
- {
-- gtk_widget_destroy(dialog);
-+ ButtonSet buttons;
-+ gint response_id;
-+
-+ if (file_count > 1 && current_file < file_count - 1)
-+ buttons = BUTTONS_RETRY_SKIP_CANCEL;
-+ else
-+ buttons = BUTTONS_RETRY_CANCEL;
-+
-+ response_id = show_error_dialog(GTK_WINDOW(main_dialog), buttons,
-+ error_text, error_secondary_text);
-+
-+ switch (response_id) {
-+ case DIALOG_RESPONSE_SKIP:
-+ current_file++;
-+ bytes_sent += file_length;
-+ case DIALOG_RESPONSE_RETRY:
-+ return TRUE;
-+ case GTK_RESPONSE_CANCEL:
-+ default:
-+ gtk_main_quit();
-+ break;
-+ }
-+ return response_id;
-+}
-
-+static void cancel_clicked_cb(GtkWidget *button, gpointer user_data)
-+{
- gtk_main_quit();
- }
-
--static void create_window(const gchar *filename)
-+static void ui_init(void)
- {
-- GtkWidget *vbox;
-- GtkWidget *label;
-+ GtkWidget *vbox, *vbox_parent, *table;
-+ GtkWidget *label1, *label2, *label3, *target_label;
-+ GtkWidget *button;
- gchar *text;
-
-- dialog = gtk_dialog_new_with_buttons(_("File Transfer"), NULL,
-- GTK_DIALOG_NO_SEPARATOR,
-- GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL);
--
-- gtk_window_set_default_size(GTK_WINDOW(dialog), 400, -1);
-+ /* initialize UI */
-
-- gtk_container_set_border_width(GTK_CONTAINER(dialog), 6);
-+ device_name = get_device_name();
-
-- vbox = gtk_vbox_new(FALSE, 6);
-- gtk_container_set_border_width(GTK_CONTAINER(vbox), 12);
-- gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), vbox);
--
-- label = gtk_label_new(NULL);
-- gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
-- gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
-+ /* main dialog */
-+ main_dialog = gtk_dialog_new();
-+ gtk_dialog_set_has_separator(GTK_DIALOG(main_dialog), FALSE);
-+ gtk_window_set_title(GTK_WINDOW(main_dialog),
-+ _("Bluetooth file transfer"));
-+ gtk_window_set_icon_name(GTK_WINDOW(main_dialog), "stock_bluetooth");
-+ gtk_window_set_type_hint(GTK_WINDOW(main_dialog),
-+ GDK_WINDOW_TYPE_HINT_NORMAL);
-+ gtk_window_set_position(GTK_WINDOW(main_dialog), GTK_WIN_POS_CENTER);
-+ gtk_window_set_resizable(GTK_WINDOW(main_dialog), FALSE);
-+ gtk_widget_set(main_dialog, "width-request", 400, NULL);
-+ button = gtk_dialog_add_button(GTK_DIALOG(main_dialog),
-+ GTK_STOCK_CANCEL,
-+ GTK_RESPONSE_CANCEL);
-+ g_signal_connect(G_OBJECT(button), "clicked",
-+ G_CALLBACK(cancel_clicked_cb), NULL);
-+ gtk_container_set_border_width(GTK_CONTAINER(main_dialog), 6);
-+
-+ /* table elements */
-+ from_label = gtk_label_new(NULL);
-+ gtk_misc_set_alignment(GTK_MISC(from_label), 0, 0.5);
-+ gtk_label_set_ellipsize(GTK_LABEL(from_label), PANGO_ELLIPSIZE_MIDDLE);
-+ target_label = gtk_label_new(NULL);
-+ gtk_misc_set_alignment(GTK_MISC(target_label), 0, 0.5);
-+ gtk_label_set_ellipsize(GTK_LABEL(target_label), PANGO_ELLIPSIZE_END);
-+ gtk_label_set_text(GTK_LABEL(target_label), device_name ? device_name : bdaddrstr);
-+ label2 = gtk_label_new(NULL);
-+ text = g_markup_printf_escaped("<b>%s</b>", _("From:"));
-+ gtk_label_set_markup(GTK_LABEL(label2), text);
-+ g_free(text);
-+ label3 = gtk_label_new(NULL);
-+ gtk_misc_set_alignment(GTK_MISC(label3), 1, 0.5);
-+ text = g_markup_printf_escaped("<b>%s</b>", _("To:"));
-+ gtk_label_set_markup(GTK_LABEL(label3), text);
-+ g_free(text);
-
-- label_filename = label;
-+ /* table */
-+ table = gtk_table_new(2, 2, FALSE);
-+ gtk_table_set_col_spacings(GTK_TABLE(table), 4);
-+ gtk_table_set_row_spacings(GTK_TABLE(table), 4);
-+ gtk_table_attach_defaults(GTK_TABLE(table), from_label, 1, 2, 0, 1);
-+ gtk_table_attach_defaults(GTK_TABLE(table), target_label, 1, 2, 1, 2);
-+ gtk_table_attach(GTK_TABLE(table), label2, 0, 1, 0, 1, GTK_FILL, 0, 0, 0);
-+ gtk_table_attach(GTK_TABLE(table), label3, 0, 1, 1, 2, GTK_FILL, 0, 0, 0);
-+
-+ /* vbox elements */
-+ label1 = gtk_label_new(NULL);
-+ gtk_misc_set_alignment(GTK_MISC(label1), 0, 0.5);
-+ 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);
-+ progress_bar = gtk_progress_bar_new();
-+ gtk_progress_bar_set_ellipsize(GTK_PROGRESS_BAR(progress_bar),
-+ PANGO_ELLIPSIZE_END);
-+ gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress_bar),
-+ _("Connecting..."));
-+ operation_label = gtk_label_new(NULL);
-+ gtk_misc_set_alignment(GTK_MISC(operation_label), 0, 0.5);
-+ gtk_label_set_ellipsize(GTK_LABEL(operation_label), PANGO_ELLIPSIZE_END);
-+
-+ /* vbox */
-+ vbox = gtk_vbox_new(FALSE, 0);
-+ gtk_box_set_spacing(GTK_BOX(vbox), 6);
-+ gtk_container_set_border_width(GTK_CONTAINER(vbox), 6);
-+ gtk_box_pack_start_defaults(GTK_BOX(vbox), label1);
-+ gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 9);
-+ gtk_box_pack_start_defaults(GTK_BOX(vbox), progress_bar);
-+ gtk_box_pack_start(GTK_BOX(vbox), operation_label, TRUE, TRUE, 2);
-+ vbox_parent = gtk_bin_get_child(GTK_BIN(main_dialog));
-+ gtk_box_pack_start_defaults(GTK_BOX(vbox_parent), vbox);
-+
-+ /* show it */
-+ gtk_widget_show_all(main_dialog);
-+}
-+
-+static gboolean send_one(gpointer user_data)
-+{
-+ const gchar *fname;
-+ gint ret;
-+ gchar *bname, *dirname;
-+ GError *err = NULL;
-+ gchar *operation_text, *operation_markup, *progressbar_text;
-+
-+ if ((fname = g_slist_nth_data(file_list, current_file))) {
-+ /* there's a file to send */
-+ dbus_g_proxy_call(session_proxy, "SendFile", &err,
-+ G_TYPE_STRING, fname, G_TYPE_INVALID, G_TYPE_INVALID);
-+
-+ if (err != NULL) {
-+ ret = handle_file_sending_error(_("Unable to read file"),
-+ err->message);
-+ if (ret != GTK_RESPONSE_CANCEL) {
-+ g_idle_add((GSourceFunc) send_one, NULL);
-+ }
-+ g_error_free(err);
-+ return FALSE;
-+ }
-
-- progress = gtk_progress_bar_new();
-- gtk_box_pack_start(GTK_BOX(vbox), progress, FALSE, FALSE, 0);
-+ if (!first_transfer_time) {
-+ first_transfer_time = get_system_time();
-+ }
-+ bname = g_path_get_basename(fname);
-+ dirname = g_path_get_dirname(fname);
-
-- label = gtk_label_new(NULL);
-- gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
-- gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
-- gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 6);
-+ 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"),
-+ current_file+1,
-+ file_count);
-+ 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(progress_bar),
-+ progressbar_text);
-+
-+ g_free(bname);
-+ g_free(dirname);
-+ g_free(operation_text);
-+ g_free(operation_markup);
-+ g_free(progressbar_text);
-+ } else {
-+ /* nothing left to send, time to quit */
-+ gtk_main_quit();
-+ }
-+ return FALSE;
-+}
-
-- label_status = label;
-+static void session_connected_cb(DBusGProxy *proxy, gpointer user_data)
-+{
-+ /* OBEX connect has succeeded, so start sending */
-+ g_idle_add((GSourceFunc) send_one, NULL);
-+}
-
-- text = g_strdup_printf("<b>%s</b>", filename);
-- gtk_label_set_markup(GTK_LABEL(label_filename), text);
-- g_free(text);
-+static void transfer_started_cb(DBusGProxy *proxy, const gchar *filename,
-+ const gchar *local_path, gint byte_count, gpointer user_data)
-+{
-+ file_length = byte_count;
-+}
-
-- gtk_label_set_markup(GTK_LABEL(label_status), _("Connecting..."));
-+static void transfer_cancelled_cb(DBusGProxy *proxy, gpointer user_data)
-+{
-+ gint ret;
-+ gchar *error_text;
-
-- gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog),
-- GTK_RESPONSE_CLOSE, FALSE);
-+ error_text = g_strdup_printf(_("An error occured while sending file '%s'"),
-+ (gchar *)g_slist_nth_data(file_list, current_file));
-+ ret = handle_file_sending_error(error_text,
-+ _("The remote device cancelled the transfer"));
-
-- g_signal_connect(G_OBJECT(dialog), "response",
-- G_CALLBACK(response_callback), NULL);
-+ if (ret != GTK_RESPONSE_CANCEL)
-+ g_idle_add((GSourceFunc) send_one, NULL);
-
-- gtk_widget_show_all(dialog);
-+ g_free(error_text);
- }
-
--static void transfer_started(DBusGProxy *proxy, gchar *a, gchar *b,
-- gint size, gpointer user_data)
-+static void transfer_progress_cb(DBusGProxy *proxy, gint bytes_transferred, gpointer user_data)
- {
-- gchar *text;
-+ gdouble frac;
-+ guint actual_bytes_sent;
-+ gint elapsed_time;
-+ gint transfer_rate;
-+ gint time_remaining;
-+ gint64 current_time;
-+ gchar *str, *str2;
-+ gchar *progressbar_text;
-
-- filesize = size;
-+ /* update progress bar fraction */
-+ actual_bytes_sent = bytes_sent + bytes_transferred;
-+ frac = (gdouble)actual_bytes_sent / byte_count;
-+ gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress_bar), frac);
-
-- text = g_strdup_printf(_("Starting transfer of %d bytes"), size);
-- gtk_label_set_markup(GTK_LABEL(label_status), text);
-- g_free(text);
-+ /* update progress bar text (time remaining)
-+ * (only update once in a second) */
-+ current_time = get_system_time();
-+ elapsed_time = (current_time - first_transfer_time) / 1000000;
-
-- gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress), 0.0);
--}
-+ if (last_update_time) {
-+ if (current_time < last_update_time + 1000000)
-+ return;
-+ else
-+ last_update_time = current_time;
-+ } else {
-+ last_update_time = current_time;
-+ }
-
--static void transfer_progress(DBusGProxy *proxy, guint bytes, gpointer user_data)
--{
-- gchar *text;
-- gdouble fraction;
-+ if (!elapsed_time)
-+ return;
-
-- text = g_strdup_printf(_("Transfered %d of %d bytes"), bytes, filesize);
-- gtk_label_set_markup(GTK_LABEL(label_status), text);
-- g_free(text);
-+ transfer_rate = actual_bytes_sent / elapsed_time;
-+ if (transfer_rate == 0)
-+ return;
-
-- fraction = (gdouble) bytes / (gdouble) filesize;
-- gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress), fraction);
--}
-+ time_remaining = (byte_count - actual_bytes_sent) / transfer_rate;
-
--static void transfer_completed(DBusGProxy *proxy, gpointer user_data)
--{
-- gtk_label_set_markup(GTK_LABEL(label_status), _("Completed"));
-+ if (time_remaining >= 3600) {
-+ str = g_strdup_printf(_("(%d:%02d:%d Remaining)"),
-+ time_remaining / 3600,
-+ (time_remaining % 3600) / 60,
-+ (time_remaining % 3600) % 60);
-+ } else {
-+ str = g_strdup_printf(_("(%d:%02d Remaining)"),
-+ time_remaining / 60,
-+ time_remaining % 60);
-+ }
-
-- gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress), 1.0);
-+ /* Translators:
-+ * Sending file 1 of 3 */
-+ str2 = g_strdup_printf(_("Sending file %d of %d"),
-+ current_file + 1,
-+ file_count);
-+ progressbar_text = g_strconcat(str2, " ", str, NULL);
-+ gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress_bar),
-+ progressbar_text);
-+ g_free(str);
-+ g_free(str2);
-+ g_free(progressbar_text);
-+}
-
-- dbus_g_proxy_call(proxy, "Disconnect", NULL, G_TYPE_INVALID,
-- G_TYPE_INVALID);
-+static void transfer_completed_cb(DBusGProxy *proxy, gpointer user_data)
-+{
-+ current_file++;
-+ bytes_sent += file_length;
-
-- gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog),
-- GTK_RESPONSE_CLOSE, TRUE);
-+ g_idle_add((GSourceFunc) send_one, NULL);
- }
-
--static void session_connected(DBusGProxy *proxy, gpointer user_data)
-+static void session_created_cb(DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
- {
-- gchar *filename = user_data;
- GError *error = NULL;
-+ const gchar *path = NULL;
-
-- gtk_label_set_markup(GTK_LABEL(label_status), _("Connected"));
-+ if (!dbus_g_proxy_end_call(proxy, call, &error,
-+ G_TYPE_STRING, &path, G_TYPE_INVALID)) {
-+ const gchar *error_name = NULL;
-+ gint response_id;
-+
-+ if (error && error->code == DBUS_GERROR_REMOTE_EXCEPTION)
-+ error_name = dbus_g_error_get_name(error);
-+ if (error_name && !strcmp(error_name, "org.openobex.Error.ConnectionAttemptFailed")) {
-+ response_id = show_connection_error_dialog(GTK_WINDOW(main_dialog), bdaddrstr, error->message);
-+ if (response_id == DIALOG_RESPONSE_RETRY) {
-+ /* Try to create Session again */
-+ dbus_g_proxy_begin_call(manager_proxy,
-+ "CreateBluetoothSession",
-+ (DBusGProxyCallNotify) session_created_cb, NULL, NULL,
-+ G_TYPE_STRING, bdaddrstr, G_TYPE_STRING, "opp",
-+ G_TYPE_BOOLEAN, FALSE, G_TYPE_INVALID);
-+ goto out;
-+ }
-+ } else {
-+ show_error_dialog(GTK_WINDOW(main_dialog), BUTTONS_OK,
-+ error->message, "");
-+ }
-
-- dbus_g_proxy_call(proxy, "SendFile", &error,
-- G_TYPE_STRING, filename, G_TYPE_INVALID,
-- G_TYPE_INVALID);
--
-- if (error != NULL) {
-- g_printerr("Sending of file %s failed: %s\n", filename,
-- error->message);
-- g_error_free(error);
-+ /* Failed, quit main loop */
- gtk_main_quit();
-+ goto out;
- }
--}
-
--static void create_notify(DBusGProxy *proxy,
-- DBusGProxyCall *call, void *user_data)
--{
-- GError *error = NULL;
-- const gchar *path = NULL;
-+ session_proxy = dbus_g_proxy_new_for_name(connection,
-+ "org.openobex",
-+ path,
-+ "org.openobex.Session");
-
-- if (dbus_g_proxy_end_call(proxy, call, &error,
-- G_TYPE_STRING, &path, G_TYPE_INVALID) == FALSE) {
-- gchar *text, *message;
--
-- if (error != NULL) {
-- message = g_strdup(error->message);
-- g_error_free(error);
-- } else
-- message = g_strdup(_("An unknown error occured"));
--
-- text = g_strdup_printf("<span foreground=\"red\">%s</span>",
-- message);
-- gtk_label_set_markup(GTK_LABEL(label_status), text);
-- g_free(text);
-+ dbus_g_proxy_add_signal(session_proxy, "Connected",
-+ G_TYPE_INVALID);
-
-- g_free(message);
-+ dbus_g_proxy_connect_signal(session_proxy, "Connected",
-+ G_CALLBACK(session_connected_cb), NULL, NULL);
-
-- gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog),
-- GTK_RESPONSE_CLOSE, TRUE);
-- return;
-- }
-+ dbus_g_proxy_add_signal(session_proxy, "TransferStarted",
-+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INVALID);
-+
-+ dbus_g_proxy_connect_signal(session_proxy, "TransferStarted",
-+ G_CALLBACK(transfer_started_cb), NULL, NULL);
-
-- proxy = dbus_g_proxy_new_for_name(conn, "org.openobex",
-- path, "org.openobex.Session");
-+ dbus_g_proxy_add_signal(session_proxy, "Cancelled",
-+ G_TYPE_INVALID);
-
-- dbus_g_proxy_add_signal(proxy, "Connected", G_TYPE_INVALID);
-+ dbus_g_proxy_connect_signal(session_proxy, "Cancelled",
-+ G_CALLBACK(transfer_cancelled_cb), NULL, NULL);
-
-- dbus_g_proxy_connect_signal(proxy, "Connected",
-- G_CALLBACK(session_connected), user_data, NULL);
-+ dbus_g_proxy_add_signal(session_proxy, "ErrorOccurred",
-+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
-
-- dbus_g_proxy_add_signal(proxy, "TransferStarted", G_TYPE_STRING,
-- G_TYPE_STRING, G_TYPE_INT, G_TYPE_INVALID);
-+ dbus_g_proxy_connect_signal(session_proxy, "ErrorOccurred",
-+ G_CALLBACK(error_occurred_cb), NULL, NULL);
-
-- dbus_g_proxy_connect_signal(proxy, "TransferStarted",
-- G_CALLBACK(transfer_started), NULL, NULL);
-+ dbus_g_proxy_add_signal(session_proxy, "TransferProgress",
-+ G_TYPE_UINT, G_TYPE_INVALID);
-
-- dbus_g_proxy_add_signal(proxy, "TransferProgress",
-- G_TYPE_UINT, G_TYPE_INVALID);
-+ dbus_g_proxy_connect_signal(session_proxy, "TransferProgress",
-+ G_CALLBACK(transfer_progress_cb), NULL, NULL);
-
-- dbus_g_proxy_connect_signal(proxy, "TransferProgress",
-- G_CALLBACK(transfer_progress), NULL, NULL);
-+ dbus_g_proxy_add_signal(session_proxy, "TransferCompleted",
-+ G_TYPE_INVALID);
-
-- dbus_g_proxy_add_signal(proxy, "TransferCompleted", G_TYPE_INVALID);
-+ dbus_g_proxy_connect_signal(session_proxy, "TransferCompleted",
-+ G_CALLBACK(transfer_completed_cb), NULL, NULL);
-
-- dbus_g_proxy_connect_signal(proxy, "TransferCompleted",
-- G_CALLBACK(transfer_completed), NULL, NULL);
-+ dbus_g_proxy_call(session_proxy, "Connect", &error, G_TYPE_INVALID,
-+ G_TYPE_INVALID);
-
-- dbus_g_proxy_call(proxy, "Connect", NULL, G_TYPE_INVALID,
-- G_TYPE_INVALID);
-+out:
-+ if (error)
-+ g_error_free(error);
-+}
-+
-+static void error_occurred_cb(DBusGProxy *proxy, const gchar *error_name, const gchar *error_message, gpointer user_data)
-+{
-+ gint ret;
-+ gboolean link_error = FALSE;
-+ gchar *error_text;
-+ const gchar *reason;
-+
-+ g_message("ErrorOccurred");
-+ g_message("Error name: %s", error_name);
-+ g_message("Error message: %s", error_message);
-+
-+ error_text = g_strdup_printf(_("An error occured while sending file '%s'"),
-+ (gchar *)g_slist_nth_data(file_list, current_file));
-+ if (!strcmp(error_name, "org.openobex.Error.LinkError")) {
-+ /* Connection to remote device was lost */
-+ g_object_unref(G_OBJECT(session_proxy));
-+ reason = _("Connection to remote device was lost");
-+ link_error = TRUE;
-+ } else if (!strcmp(error_name, "org.openobex.Error.Forbidden")) {
-+ reason = _("Remote device rejected file");
-+ } else {
-+ reason = _("Unknown error");
-+ }
-+ ret = handle_file_sending_error(error_text, reason);
-+
-+ if (ret != GTK_RESPONSE_CANCEL) {
-+ if (link_error) {
-+ /* Need to reestablish connection */
-+ dbus_g_proxy_begin_call(manager_proxy, "CreateBluetoothSession",
-+ (DBusGProxyCallNotify) session_created_cb, NULL, NULL,
-+ G_TYPE_STRING, bdaddrstr, G_TYPE_STRING, "opp",
-+ G_TYPE_INVALID);
-+ } else {
-+ g_idle_add((GSourceFunc) send_one, NULL);
-+ }
-+ }
-+
-+
-+ g_free(error_text);
-+}
-+
-+static void free_mem(void)
-+{
-+ if (files_to_send)
-+ g_strfreev(files_to_send);
-+ g_free(bdaddrstr);
-+
-+ if (main_dialog)
-+ gtk_widget_destroy (main_dialog);
-+ if (G_IS_OBJECT(manager_proxy))
-+ g_object_unref(G_OBJECT(manager_proxy));
-+ if (G_IS_OBJECT(session_proxy))
-+ g_object_unref (G_OBJECT(session_proxy));
-+ g_slist_free(file_list);
- }
-
- static void name_owner_changed(DBusGProxy *proxy, const char *name,
-@@ -288,95 +650,126 @@ static void name_owner_changed(DBusGProx
- gtk_main_quit();
- }
-
--static gchar *option_device = NULL;
--
--static GOptionEntry options[] = {
-- { "device", 0, 0, G_OPTION_ARG_STRING, &option_device,
-- N_("Remote device to use"), "ADDRESS" },
-- { NULL },
--};
--
- int main(int argc, char *argv[])
- {
-- DBusGProxy *proxy;
-+ GOptionContext *option_context;
- GError *error = NULL;
-- gchar *filename, *address;
-+ guint i;
-
-+ /* initialize gettext */
- bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
- bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
- textdomain(GETTEXT_PACKAGE);
-
-- error = NULL;
--
-- if (gtk_init_with_args(&argc, &argv, "[FILE...]",
-- options, GETTEXT_PACKAGE, &error) == FALSE) {
-- if (error != NULL) {
-- g_printerr("%s\n", error->message);
-- g_error_free(error);
-- } else
-- g_printerr("An unknown error occurred\n");
--
-- gtk_exit(1);
-- }
--
-- gtk_window_set_default_icon_name("stock_bluetooth");
--
-- if (argc < 2) {
-- filename = open_file_dialog();
-- if (filename == NULL)
-- gtk_exit(1);
-- } else
-- filename = g_strdup(argv[1]);
--
-- if (option_device == NULL) {
-- address = browse_device_dialog();
-- if (address == NULL) {
-- g_free(filename);
-- gtk_exit(1);
-- }
-- } else
-- address = g_strdup(option_device);
--
-- conn = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
-- if (conn == NULL) {
-- if (error != NULL) {
-- g_printerr("Connecting to session bus failed: %s\n",
-- error->message);
-- g_error_free(error);
-- } else
-- g_print("An unknown error occured\n");
--
-- gtk_exit(1);
-+ /* parse command line arguments */
-+ option_context = g_option_context_new("<file list>");
-+ g_option_context_add_main_entries(option_context, options, GETTEXT_PACKAGE);
-+ g_option_context_add_group(option_context, gtk_get_option_group(TRUE));
-+ g_option_context_parse(option_context, &argc, &argv, &error);
-+ g_option_context_free(option_context);
-+ if (error) {
-+ printf("Usage:\n");
-+ printf(" %s [--dest=BDADDR] <file list>\n", g_get_prgname());
-+ g_error_free(error);
-+ free_mem();
-+ return 0;
- }
-
-- dbus_g_object_register_marshaller(marshal_VOID__STRING_STRING_INT,
-- G_TYPE_NONE, G_TYPE_STRING,
-- G_TYPE_STRING, G_TYPE_INT, G_TYPE_INVALID);
-+ gtk_init(&argc, &argv);
-
-- create_window(filename);
--
-- proxy = dbus_g_proxy_new_for_name(conn, "org.openobex",
-- "/org/openobex", "org.openobex.Manager");
-+ /* init DBus connection */
-+ connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
-+ if (!connection) {
-+ show_error_dialog(NULL, GTK_BUTTONS_OK,
-+ _("Please verify that D-Bus is correctly installed and setup."), error->message);
-+ g_error_free(error);
-+ return 1;
-+ }
-
-- dbus_g_proxy_add_signal(proxy, "NameOwnerChanged",
-- G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
-+ main_dialog = NULL;
-+ from_label = NULL;
-+ operation_label = NULL;
-+ progress_bar = NULL;
-+
-+ /* get a list of files to send from command-line */
-+ if (files_to_send)
-+ file_count = g_strv_length(files_to_send);
-+ else
-+ file_count = 0;
-+ for (i = 0; i < file_count; i++) {
-+ file_list = g_slist_append(file_list,
-+ g_strdup(*(files_to_send + i)));
-+ }
-+ /* show file chooser if no files were specified */
-+ if (!file_count) {
-+ file_list = select_files_dialog();
-+ file_count = g_slist_length(file_list);
-+ }
-+ /* Check if there are some files to send */
-+ if (!file_count) {
-+ free_mem();
-+ return 0;
-+ }
-+ /* Check for non regular and non existand files and
-+ * determine total bytes to send */
-+ for (i = 0; i < file_count; i++) {
-+ GSList *item;
-+ gchar *path, *filename;
-+ gint64 size;
-+
-+ item = g_slist_nth(file_list, i);
-+ path = (gchar *) item->data;
-+ filename = normalise_filename(path, &size);
-+ if (filename == NULL) {
-+ g_free(path);
-+ file_list = g_slist_remove_link(file_list, item);
-+ continue;
-+ }
-+ g_free(item->data);
-+ item->data = filename;
-+ byte_count += size;
-+ }
-
-- dbus_g_proxy_connect_signal(proxy, "NameOwnerChanged",
-- G_CALLBACK(name_owner_changed), NULL, NULL);
-+ /* determine Bluetooth device to send to */
-+ if (!bdaddrstr) {
-+ bdaddrstr = browse_device_dialog();
-+ if (!bdaddrstr) {
-+ free_mem();
-+ return 0;
-+ }
-+ }
-
-- dbus_g_proxy_begin_call(proxy, "CreateBluetoothSession",
-- create_notify, filename, NULL,
-- G_TYPE_STRING, address, G_TYPE_STRING, "opp",
-+ dbus_g_object_register_marshaller(marshal_VOID__STRING_STRING_INT,
-+ G_TYPE_NONE, G_TYPE_STRING,
-+ G_TYPE_STRING, G_TYPE_INT, G_TYPE_INVALID);
-+ dbus_g_object_register_marshaller(marshal_VOID__STRING_STRING,
-+ G_TYPE_NONE, G_TYPE_STRING,
-+ G_TYPE_STRING, G_TYPE_INVALID);
-+
-+ /* init UI */
-+ ui_init();
-+
-+ /* init DBus proxy, create Session */
-+ manager_proxy = dbus_g_proxy_new_for_name(connection,
-+ "org.openobex",
-+ "/org/openobex",
-+ "org.openobex.Manager");
-+ dbus_g_proxy_add_signal(manager_proxy, "NameOwnerChanged",
-+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
-+ dbus_g_proxy_connect_signal(manager_proxy, "NameOwnerChanged",
-+ G_CALLBACK(name_owner_changed), NULL, NULL);
-+
-+ dbus_g_proxy_begin_call(manager_proxy, "CreateBluetoothSession",
-+ (DBusGProxyCallNotify) session_created_cb, NULL, NULL,
-+ G_TYPE_STRING, bdaddrstr, G_TYPE_STRING, "opp",
- G_TYPE_INVALID);
-
-+ /* Go into main loop */
- gtk_main();
-
-- g_object_unref(proxy);
--
-- dbus_g_connection_unref(conn);
--
-- g_free(address);
-- g_free(filename);
-+ /* done sending, free memory */
-+ free_mem();
-
- return 0;
- }
-+
Index: po/POTFILES.in
===================================================================
RCS file: /cvsroot/bluez/gnome/po/POTFILES.in,v
Index: bluez-gnome.spec
===================================================================
RCS file: /cvs/pkgs/rpms/bluez-gnome/devel/bluez-gnome.spec,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -r1.31 -r1.32
--- bluez-gnome.spec 6 Feb 2008 13:08:00 -0000 1.31
+++ bluez-gnome.spec 6 Feb 2008 13:12:16 -0000 1.32
@@ -9,6 +9,7 @@
Source0: http://bluez.sf.net/download/%{name}-%{version}.tar.gz
Patch1: bluez-gnome-remove-class.patch
Patch2: bluez-gnome-new-sendto-6.patch
+Patch3: main.c
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
@@ -50,6 +51,7 @@
%setup -q
%patch1 -p0 -b .remove-class
%patch2 -p0 -b .sendto
+cp -a %{PATCH3} sendto/
%build
aclocal
More information about the fedora-extras-commits
mailing list