GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Thu Apr 24, 2014 6:50 pm

All times are UTC




Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: [SOLVED]Know if device is connected
PostPosted: Wed Oct 30, 2013 2:01 pm 
Offline
Familiar Face

Joined: Fri Jul 26, 2013 11:29 am
Posts: 5
Hi everyone!
I need to know in my gtk program if there is an usb pen drive connected, and if it's possible the path.

I found a very usefull program:
Code:
#include <gio/gio.h>
#include <gtk/gtk.h>
#include <string.h>

typedef struct {
    GtkWidget *window;
    GtkWidget *vbox;
    GtkWidget *scrolled_window;
    GtkWidget *view;
    GtkWidget *button;

    GtkListStore *store;
    GVolumeMonitor *monitor;
} Context[1];

enum {
    COL_DRIVE,
    COL_ICON,
    COL_NAME,
    NUM_COLS
};

static int find_drive(GtkTreeModel *model, GDrive *drive, GtkTreeIter *iter)
{
    gboolean valid;

    valid = gtk_tree_model_get_iter_first(model, iter);
    while (valid) {
        GDrive *cur;
        gtk_tree_model_get(model, iter, COL_DRIVE, &cur, -1);

        if (cur == drive)
            return 1;

        valid = gtk_tree_model_iter_next(model, iter);
    }

    return 0;
}

static void set_drive_iter(Context ctx, GDrive *drive, GtkTreeIter *iter)
{
    GIcon *icon = g_drive_get_icon(drive);
    gchar *name = g_drive_get_name(drive);

    gtk_list_store_set(ctx->store, iter,
        COL_DRIVE, drive,
        COL_ICON, icon,
        COL_NAME, name,
        -1);

    g_free(name);
}

static void add_drive(Context ctx, GDrive *drive)
{
    GtkTreeIter iter;
    gtk_list_store_append(ctx->store, &iter);
    set_drive_iter(ctx, drive, &iter);
}

static void refresh_drive_list(Context ctx)
{
    GList *drives, *l;
    drives = g_volume_monitor_get_connected_drives(ctx->monitor);

    gtk_list_store_clear(ctx->store);

    for (l = drives; l; l = l->next)
        add_drive(ctx, l->data);
}

static void update_drive(Context ctx, GDrive *drive)
{
    GtkTreeModel *model = GTK_TREE_MODEL(ctx->store);
    GtkTreeIter iter;

    if (find_drive(model, drive, &iter))
        set_drive_iter(ctx, drive, &iter);
    else
        refresh_drive_list(ctx); //Shouldn't happen
}

static void remove_drive(Context ctx, GDrive *drive)
{
    GtkTreeModel *model = GTK_TREE_MODEL(ctx->store);
    GtkTreeIter iter;

    if (find_drive(model, drive, &iter))
        gtk_list_store_remove(ctx->store, &iter);
    else
        refresh_drive_list(ctx); //Shouldn't happen
}

static void init_drive_list(Context ctx)
{
    ctx->store = gtk_list_store_new(3, G_TYPE_POINTER, G_TYPE_ICON, G_TYPE_STRING);
    refresh_drive_list(ctx);
}

static void init_drive_view(Context ctx)
{
    GtkTreeViewColumn *column;
    GtkCellRenderer *renderer;

    ctx->view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(ctx->store));
    g_object_set(ctx->view,
        "headers-visible", FALSE,
        NULL);

    renderer = gtk_cell_renderer_pixbuf_new();
    g_object_set(renderer, "stock-size", GTK_ICON_SIZE_DIALOG, NULL);
    column = gtk_tree_view_column_new_with_attributes("Icon", renderer, "gicon", COL_ICON, NULL);
    gtk_tree_view_column_set_resizable(column, TRUE);
    gtk_tree_view_append_column(GTK_TREE_VIEW(ctx->view), column);

    renderer = gtk_cell_renderer_text_new();
    column = gtk_tree_view_column_new_with_attributes("Name", renderer, "text", COL_NAME, NULL);
    gtk_tree_view_column_set_resizable(column, TRUE);
    gtk_tree_view_append_column(GTK_TREE_VIEW(ctx->view), column);
}

static void print_drive_info(GDrive *drive)
{
    GIcon *icon;
    gchar *name, *icon_string;

    name = g_drive_get_name(drive);
    icon = g_drive_get_icon(drive);
    icon_string = g_icon_to_string(icon);
    g_object_unref(icon);

    g_print("\tname: %s\n\ticon: %s\n",
        name ? name : "(null)",
        icon_string ? icon_string : "(null)");

    g_free(name);
    g_free(icon_string);
}

static void on_drive_changed(GVolumeMonitor *volume_monitor, GDrive *drive, Context ctx)
{
    g_print("Drive changed:\n");
    print_drive_info(drive);
    update_drive(ctx, drive);
}

static void on_drive_connected(GVolumeMonitor *volume_monitor, GDrive *drive, Context ctx)
{
    g_print("Drive connected:\n");
    print_drive_info(drive);
    add_drive(ctx, drive);
}

static void on_drive_disconnected(GVolumeMonitor *volume_monitor, GDrive *drive, Context ctx)
{
    g_print("Drive disconnected:\n");
    print_drive_info(drive);
    remove_drive(ctx, drive);
}

static void on_refresh_clicked(GtkButton *button, Context ctx)
{
    refresh_drive_list(ctx);
}

int main(int argc, char *argv[])
{
    Context ctx;
    memset(ctx, 0, sizeof(ctx));
    gtk_init(&argc, &argv);

    ctx->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    g_signal_connect(ctx->window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    ctx->vbox = gtk_vbox_new(FALSE, 0);
    gtk_widget_show(ctx->vbox);
    gtk_container_add(GTK_CONTAINER(ctx->window), ctx->vbox);

    ctx->scrolled_window = gtk_scrolled_window_new(NULL, NULL);
    gtk_scrolled_window_set_policy(
        GTK_SCROLLED_WINDOW(ctx->scrolled_window),
        GTK_POLICY_AUTOMATIC,
        GTK_POLICY_AUTOMATIC);
    gtk_box_pack_start(GTK_BOX(ctx->vbox), ctx->scrolled_window, TRUE, TRUE, 0);
    gtk_widget_show(ctx->scrolled_window);

    ctx->monitor = g_volume_monitor_get();
    g_signal_connect(ctx->monitor, "drive-changed", G_CALLBACK(on_drive_changed), ctx);
    g_signal_connect(ctx->monitor, "drive-connected", G_CALLBACK(on_drive_connected), ctx);
    g_signal_connect(ctx->monitor, "drive-disconnected", G_CALLBACK(on_drive_disconnected), ctx);

    init_drive_list(ctx);
    init_drive_view(ctx);
    gtk_widget_show(ctx->view);
    gtk_container_add(GTK_CONTAINER(ctx->scrolled_window), ctx->view);

    ctx->button = gtk_button_new_from_stock(GTK_STOCK_REFRESH);
    g_signal_connect(ctx->button, "clicked", G_CALLBACK(on_refresh_clicked), ctx);
    gtk_widget_show(ctx->button);
    gtk_box_pack_start(GTK_BOX(ctx->vbox), ctx->button, FALSE, FALSE, 0);

    gtk_window_set_default_size(GTK_WINDOW(ctx->window), 500, 500);
    gtk_widget_show(ctx->window);

    gtk_main();
    return 0;
}


and it works very good! There is only a little problem: in the real environment the program don't have a gnome session, so it doesn't work!
Here: http://stackoverflow.com/questions/13040138/use-glib-gio-gvolumemonitor-without-gnome?answertab=votes#tab-top I've understand that
for working the program needs gvfs-daemon and dbus-launch, so I've insert the two commands in the $HOME .xinitrc but nothing, the program still not works!

Someone please can help me? As always, thanks at everyone!
Bye.

Ghilander


Last edited by Ghilander on Tue Nov 05, 2013 8:46 am, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: Know if device is connected
PostPosted: Tue Nov 05, 2013 8:44 am 
Offline
Familiar Face

Joined: Fri Jul 26, 2013 11:29 am
Posts: 5
I've solved it, for who is curious I have used libhal and libhal-storage, that are based on the hal command the documentation you can find here:
- Libhal: http://harmattan-dev.nokia.com/docs/platform-api-reference/xml/daily-docs/libhal/libhal-libhal.html#libhal-manager-find-device-string-match
- Libhal-storage: http://maemo.org/api_refs/5.0/beta/libhal-storage/libhal-storage-libhal-storage.html#LibHalVolume

Here you can find a simple example:

Code:
/*
* File:   HallDemos.h
* Author: olcay
*
* Created on December 25, 2011, 5:05 AM
*/

#ifndef HALLDEMOS_H
#define HALLDEMOS_H

#ifdef  __cplusplus
extern "C" {
#endif

#include <hal/libhal.h>
#include <hal/libhal-storage.h>
#include <dbus/dbus.h>
#include <glib-1.2/glib.h>
//#include <dbus/dbus-glib-lowlevel.h>

    #define HAL_DBUS_SERVICE "org.freedesktop.Hal"
    #define HAL_ROOT_COMPUTER "/org/freedesktop/Hal/devices/computer"
    #define HAL_DBUS_INTERFACE_POWER "org.freedesktop.Hal.Device.SystemPowerManagement"

    static void handle_device_removed(LibHalContext *ctx, const char *udi);
    static void handle_device_added(LibHalContext *ctx, const char *udi);
    DBusConnection *connection;
    DBusError error;
    DBusMessage *mess;
    DBusMessage *reply;
    LibHalContext *ctx;
    LibHalDrive *drive;
    LibHalVolume *volume;
    const char *udi;
    int exit_code;

    int initHal();
    int getSystemInfo();
    int getDeviceWithCapability(const char *capability);
    void callbackLoop();
    void listDeviceContent();



#ifdef  __cplusplus
}
#endif

#endif  /* HALLDEMOS_H */




#include "HalDemos.h"
#include <stdio.h>

static void handle_device_removed(LibHalContext *ctx, const char *udi) {
    printf("Device with udi=%s is removed\n", udi);
}

static void handle_device_added(LibHalContext *ctx, const char *udi) {

    dbus_bool_t is_storage;

    is_storage = libhal_device_query_capability(ctx, udi, "storage", NULL);
    if (is_storage) {
        drive = libhal_drive_from_udi(ctx, udi);
        volume = libhal_volume_from_udi(ctx, udi);
        if (libhal_drive_is_hotpluggable(drive) || libhal_drive_uses_removable_media(drive)) {
            printf("Storage device added %s model %s\n",
                    libhal_drive_get_device_file(drive),
                    libhal_drive_get_model(drive));
            //printf("Mount point = %s\n", libhal_volume_get_mount_point(volume));
        }
        libhal_drive_free(drive);
    }

    //printf("Device with udi=%s is added\n", udi);
}

int initHal() {
    udi = "/org/freedesktop/Hal/devices/computer";
    dbus_error_init(&error);
    connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);

    if (dbus_error_is_set(&error)) {
        printf("Unable to connect to Dbus: %s\n", error.message);
        dbus_error_free(&error);
        return 1;
    }

    ctx = libhal_ctx_new();

    if (!libhal_ctx_set_dbus_connection(ctx, connection)) {
        printf("Error: %s\n", error.message);
        dbus_error_free(&error);
        return 1;
    }

    if (!libhal_ctx_init(ctx, &error)) {
        printf("Hal context initializing failure %s\n", error.message);
        return 1;
    }
}

int getSystemInfo() {

    char *kernel_version = libhal_device_get_property_string(ctx, udi, "system.kernel.version", &error);

    if (dbus_error_is_set(&error)) {
        printf("Error getting string property %s\n", error.message);
        dbus_error_free(&error);
        return 1;
    }

    char *power_management_type = libhal_device_get_property_string(ctx, udi, "power_management.type", &error);

    if (dbus_error_is_set(&error)) {
        printf("Error getting string property %s\n", error.message);
        dbus_error_free(&error);
        return 1;
    }

    dbus_bool_t can_hibernate = libhal_device_get_property_bool(ctx, udi, "power_management.can_hibernate", &error);

    if (dbus_error_is_set(&error)) {
        printf("Error getting bool property %s\n", error.message);
        dbus_error_free(&error);
        return 1;
    }

    printf("System information:\n");
    printf("Kernel                = %s\n", kernel_version);
    printf("Power management type = %s\n", power_management_type);
    printf("Hibernate             = %s\n", can_hibernate ? "Supported" : "Not supported");

    libhal_free_string(kernel_version);
    libhal_free_string(power_management_type);
    return 0;
}

int getDeviceWithCapability(const char* capability) {
    int num_devices = 0;
    char **udis = libhal_find_device_by_capability(ctx, capability, &num_devices, &error);

    if (dbus_error_is_set(&error)) {
        printf("Error getting bool property %s\n", error.message);
        dbus_error_free(&error);
        return 1;
    }
    if (num_devices == 0) {
        printf("No device found with input capability!");
        return 0;
    }
    int i;

    printf("Devices with input capability:\n");
    for (i = 0; udis[i]; i++) {
        printf("%2d - udi = %s\n", i + 1, udis[i]);
        /* Do something with it */
    }
    /* Free the string array */
    libhal_free_string_array(udis);
}

void callbackLoop() {
    GMainLoop *loop;
    loop = (GMainLoop*) g_main_loop_new(NULL, FALSE);
    dbus_connection_setup_with_g_main(connection, NULL);
    libhal_ctx_set_device_added(ctx, handle_device_added);
    libhal_ctx_set_device_removed(ctx, handle_device_removed);
    g_main_loop_run(loop);
}

void listDeviceContent(){

}


Bye,

Ghilander


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 

All times are UTC


Who is online

Users browsing this forum: asdfgh2091, Google [Bot] and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group