C/GTK/FreeBSD - waar vind ik de locatie van de te openen dir

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • blorf
  • Registratie: December 2003
  • Laatst online: 22-08 16:22
Hallo,

Ik ben aan het knoeien met een stuk software uit de FreeBSD ports: x11/libfm. Dit is de ondersteunende library van de PCmanfm filemanager.
Een leuke eigenschap van PCmanfm is dat ie ook in "desktop-mode" kan draaien, dwz hij kan de X.org/openbox desktop hetzelfde behandelen als een folder. Je kan bestanden en directories slepen of aanmaken en er is een programmeerbaar right-click menu.
Wat ik nu wil (het is vergezocht maar ik doe een poging) is die PCmanfm blijven gebruiken maar alleen voor die desktop-mode. De filemanager x11-fm/xfe moet de normale vensters gaan verzorgen.

Het probleem is dus dat PCmanfm zelf xfe moet opstarten als er op een desktop directory wordt geklikt. Oorspronkelijk startte hij een fork van zichzelf op in een nieuw venster met de betreffende directory.

In de libfm source heb ik het stukje code daarvoor gevonden:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// deel van bestand fm-file-launcher.c

    if(folders)
    {
        folders = g_list_reverse(folders);
        if(launcher->open_folder)
        {
            launcher->open_folder(ctx, folders, user_data, &err);
            if(err)
            {
                if(launcher->error)
                    launcher->error(ctx, err, user_data);
                g_error_free(err);
                err = NULL;
            }
        }
        g_list_free(folders);
    }
    return TRUE;



Hier wordt een nieuw pcmanfm venster gestart in de directory die waarschijnlijk in de "folders" parameter zit bij de aanroep launcher->open_folder(ctx, folders, user_data, &err);
Met de g_debug() functie kan ik tussentijdse info naar stdout sturen en met system() kan ik xfe opstarten vanuit een C-programma.

Eerste aanpassing:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
    if(folders)
    {
        folders = g_list_reverse(folders);
        if(launcher->open_folder)
        {

//          we hebben hier dus de die directory locatie nodig. Xfe opent zo altijd
//          in de directory van waaruit X.org is gestart.

//          call naar pcmanfm alvast vervangen met kaal shellcommando voor xfe
//           launcher->open_folder(ctx, folders, user_data, &err);
            system ("/usr/local/bin/xfe");

// proberen met g_debug de benodigde info op stdout te krijgen (tevergeefs, dit is niet leesbaar):
            g_debug("ctx: %s", ctx);
            g_debug("folders: %s", folders);
            g_debug("user_data: %s", user_data);

            if(err)
            {
                if(launcher->error)
                    launcher->error(ctx, err, user_data);
                g_error_free(err);
                err = NULL;
            }
        }
        g_list_free(folders);
    }
    return TRUE;


De console output daarvan na een run:
(onderaan de g_debug output, die missende icons zijn niet van belang.)
code:
1
2
3
4
5
6
7
** (pcmanfm:11606): DEBUG: adding new FmBackgroundCache for /usr/MBSD/wallpapers/freebsd.jpg
** (pcmanfm:11606): DEBUG: unable to load icon . GThemedIcon text-plain gnome-mime-text-plain text-x-generic application-x-executable
** (pcmanfm:11606): DEBUG: unable to load icon . GThemedIcon folder inode-directory gnome-mime-inode-directory inode-x-generic
** (pcmanfm:11606): DEBUG: unable to load icon . GThemedIcon folder inode-directory gnome-mime-inode-directory inode-x-generic
** (pcmanfm:11606): DEBUG: ctx: 
** (pcmanfm:11606): DEBUG: folders: \xb0\xe0D\u0007\u0008
** (pcmanfm:11606): DEBUG: user_data: \xa0\x80G\u0007\u0008


Wat ik nou niet voor elkaar krijg is die directorynaam leesbaar maken. De bedoeling is dat die system() aanroep een string krijgt als "/usr/local/bin/xfe <pad>"
Greppen naar "launcher" en "open_folders" in andere libfm source bestanden levert een hoop hits op, maar ik kan er niet achter komen hoe die data in (volgens mij) de "folders" parameter eruit ziet om dat vervolgens in een normale string te krijgen.
Ergens heb ik het idee dat ik een goeie C-GUI nodig heb die types en structs e.d. automatisch erbij zoekt. Tot nu toe ben ik alleen in terminals bezig. Heeft er iemand goeie raad m.b.t. hoe nu verder te gaan?

You are in a maze of little twisting passages, all different.


Acties:
  • 0 Henk 'm!

  • EddoH
  • Registratie: Maart 2009
  • Niet online

EddoH

Backpfeifengesicht

Zoek eerst eens op waar die variabelen(folders/user_data) gedeclareerd staan en welke types ze hebben. Je gaat er nu vanuit dat het char * zijn.

Acties:
  • 0 Henk 'm!

  • blorf
  • Registratie: December 2003
  • Laatst online: 22-08 16:22
de folders variabele is van het type GList welke in de include files van Glib wordt gedefinieerd:
(/usr/local/include/glib-2.0/glib/glist.h)

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
#error "Only <glib.h> can be included directly."
#endif

#ifndef __G_LIST_H__
#define __G_LIST_H__

#include <glib/gmem.h>

G_BEGIN_DECLS

typedef struct _GList GList;

struct _GList
{
  gpointer data;
  GList *next;
  GList *prev;
};

/* Doubly linked lists
 */
GList*   g_list_alloc                   (void) G_GNUC_WARN_UNUSED_RESULT;
void     g_list_free                    (GList            *list);
void     g_list_free_1                  (GList            *list);
#define  g_list_free1                   g_list_free_1
void     g_list_free_full               (GList            *list,
                     GDestroyNotify    free_func);
GList*   g_list_append                  (GList            *list,
                     gpointer          data) G_GNUC_WARN_UNUSED_RESULT;
GList*   g_list_prepend                 (GList            *list,
                     gpointer          data) G_GNUC_WARN_UNUSED_RESULT;
GList*   g_list_insert                  (GList            *list,
                     gpointer          data,
                     gint              position) G_GNUC_WARN_UNUSED_RESULT;
+-----GList*   g_list_insert_sorted           (GList            *list,
                     gpointer          data,
                     GCompareFunc      func) G_GNUC_WARN_UNUSED_RESULT;
GList*   g_list_insert_sorted_with_data (GList            *list,
                     gpointer          data,
                     GCompareDataFunc  func,
                     gpointer          user_data) G_GNUC_WARN_UNUSED_RESULT;
GList*   g_list_insert_before           (GList            *list,
                     GList            *sibling,
                     gpointer          data) G_GNUC_WARN_UNUSED_RESULT;
GList*   g_list_concat                  (GList            *list1,
                     GList            *list2) G_GNUC_WARN_UNUSED_RESULT;
GList*   g_list_remove                  (GList            *list,
                     gconstpointer     data) G_GNUC_WARN_UNUSED_RESULT;
GList*   g_list_remove_all              (GList            *list,
                     gconstpointer     data) G_GNUC_WARN_UNUSED_RESULT;
GList*   g_list_remove_link             (GList            *list,
                     GList            *llink) G_GNUC_WARN_UNUSED_RESULT;
GList*   g_list_delete_link             (GList            *list,
                     GList            *link_) G_GNUC_WARN_UNUSED_RESULT;
GList*   g_list_reverse                 (GList            *list) G_GNUC_WARN_UNUSED_RESULT;
GList*   g_list_copy                    (GList            *list) G_GNUC_WARN_UNUSED_RESULT;
GList*   g_list_nth                     (GList            *list,
                     guint             n);
GList*   g_list_nth_prev                (GList            *list,
                     guint             n);
GList*   g_list_find                    (GList            *list,
                     gconstpointer     data);
GList*   g_list_find_custom             (GList            *list,
                     gconstpointer     data,
                     GCompareFunc      func);
gint     g_list_position                (GList            *list,
                     GList            *llink);
gint     g_list_index                   (GList            *list,
                     gconstpointer     data);
GList*   g_list_last                    (GList            *list);
GList*   g_list_first                   (GList            *list);
guint    g_list_length                  (GList            *list);
void     g_list_foreach                 (GList            *list,
                     GFunc             func,
                     gpointer          user_data);
GList*   g_list_sort                    (GList            *list,
                     GCompareFunc      compare_func) G_GNUC_WARN_UNUSED_RESULT;
GList*   g_list_sort_with_data          (GList            *list,
                     GCompareDataFunc  compare_func,
                     gpointer          user_data)  G_GNUC_WARN_UNUSED_RESULT;
gpointer g_list_nth_data                (GList            *list,
                     guint             n);


#define g_list_previous(list)           ((list) ? (((GList *)(list))->prev) : NULL)
#define g_list_next(list)           ((list) ? (((GList *)(list))->next) : NULL)

#ifndef G_DISABLE_DEPRECATED
void     g_list_push_allocator          (gpointer          allocator);
void     g_list_pop_allocator           (void);
#endif

G_END_DECLS

#endif /* __G_LIST_H__ */


user_data is van het type gpointer, welke ook in die GList typedef voorkomt en gedeclaceerd wordt in /usr/local/include/glib-2.0/glib/gtypes.h als: typedef void* gpointer;

You are in a maze of little twisting passages, all different.


Acties:
  • 0 Henk 'm!

  • blorf
  • Registratie: December 2003
  • Laatst online: 22-08 16:22
Na heel wat uren verder knoeien ben ik er min of meer uitgekomen. Het hele gtk/glib gebeuren gebruikt het UTF-8 formaat voor alle data dus vandaar die onleesbare output. Dat letterlijk proberen te converten oid lukte me niet dankzij de hell van pointers en types waar je in terecht komt als je dat probeert. Maar elders in de source van pcmanfm vond ik gelukkig de functie fm_path_to_str die een echte "stdlib"-string maakt van de door pcmanfm gebruikte path variabele die later opgesomd worden in de (GList)folders var.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
char* fm_path_to_str(FmPath* path)
{
    gchar *ret;
    fm_path_to_str_int( path, &ret, 0 );
    return ret;
}

static gchar* fm_path_to_str_int(FmPath* path, gchar** ret, gint str_len)
{
    gint name_len = strlen(path->name);
    gchar* pbuf;
     
    if (!path->parent)
    {
        *ret = g_new0(gchar, str_len + name_len + 1 );
        pbuf = *ret;
    }
    else
    {
        pbuf = fm_path_to_str_int( path->parent, ret, str_len + name_len + 1 );
        if (path->parent->parent) /* if parent dir is not root_path */
            *pbuf++ = G_DIR_SEPARATOR;
    }
    memcpy( pbuf, path->name, name_len );
    return pbuf + name_len;
}


Dit gaat me een beetje te ver maar het werkt, dus [solved]
Gelukkig hoefde ik nu dus niet het hele GTK/glib framewerk te leren maar op zich lijkt het me best de moeite waard.

[ Voor 6% gewijzigd door blorf op 22-12-2012 14:39 ]

You are in a maze of little twisting passages, all different.