On Sat, 2007-09-01 at 01:36 +0200, Sven Arvidsson wrote: > There's already a request upstream on having different search backends > instead of compile time options [0], this is apparently how the open > dialog in GTK+ 2.12 handles it [1].
I forgot to mention this; Fedora apparently already uses this method, but the nautilus developers doesn't consider this to be "nice code" so it wasn't included upstream. I'm attaching it to this bug, just in case. -- Cheers, Sven Arvidsson http://www.whiz.se PGP Key ID 760BDD22
--- nautilus-2.16.2/configure.in.dynamic-search 2006-11-06 12:12:05.000000000 -0500 +++ nautilus-2.16.2/configure.in 2006-11-14 01:41:48.000000000 -0500 @@ -230,42 +230,12 @@ dnl search implementations dnl **************************** -AM_CONDITIONAL(HAVE_TRACKER, false) +# We hardcode beagle and tracker use and then load it dynamically +AM_CONDITIONAL(HAVE_TRACKER, true) +AC_DEFINE(HAVE_TRACKER, 1, [Define to enable tracker support]) -dnl libtracker checking - -AC_ARG_ENABLE(tracker, [ --disable-tracker build without tracker support]) -msg_tracker=no -if test "x$enable_tracker" != "xno"; then - PKG_CHECK_MODULES(TRACKER, tracker >= tracker_minver, [ - AM_CONDITIONAL(HAVE_TRACKER, true) - AC_DEFINE(HAVE_TRACKER, 1, [Define to enable tracker support]) - ] - msg_tracker=yes, - [AM_CONDITIONAL(HAVE_TRACKER, false)]) - AC_SUBST(TRACKER_CFLAGS) - AC_SUBST(TRACKER_LIBS) -fi - -dnl ========================================================================== - - -AM_CONDITIONAL(HAVE_BEAGLE, false) - -dnl libbeagle checking - -AC_ARG_ENABLE(beagle, [ --disable-beagle build without beagle support]) -msg_beagle=no -if test "x$enable_beagle" != "xno"; then - PKG_CHECK_MODULES(BEAGLE, libbeagle-0.0 >= beagle_minver, [ - AM_CONDITIONAL(HAVE_BEAGLE, true) - AC_DEFINE(HAVE_BEAGLE, 1, [Define to enable beagle support]) - ] - msg_beagle=yes, - [AM_CONDITIONAL(HAVE_BEAGLE, false)]) - AC_SUBST(BEAGLE_CFLAGS) - AC_SUBST(BEAGLE_LIBS) -fi +AM_CONDITIONAL(HAVE_BEAGLE, true) +AC_DEFINE(HAVE_BEAGLE, 1, [Define to enable beagle support]) dnl ========================================================================== --- nautilus-2.16.2/libnautilus-private/nautilus-search-engine-beagle.c.dynamic-search 2006-08-07 06:34:30.000000000 -0400 +++ nautilus-2.16.2/libnautilus-private/nautilus-search-engine-beagle.c 2006-11-14 01:38:25.000000000 -0500 @@ -23,10 +23,20 @@ #include <config.h> #include "nautilus-search-engine-beagle.h" -#include <beagle/beagle.h> #include <eel/eel-gtk-macros.h> #include <eel/eel-glib-extensions.h> +#include <gmodule.h> + +typedef struct _BeagleHit BeagleHit; +typedef struct _BeagleQuery BeagleQuery; +typedef struct _BeagleClient BeagleClient; +typedef struct _BeagleRequest BeagleRequest; +typedef struct _BeagleFinishedResponse BeagleFinishedResponse; +typedef struct _BeagleHitsAddedResponse BeagleHitsAddedResponse; +typedef struct _BeagleQueryPartProperty BeagleQueryPartProperty; +typedef struct _BeagleQueryPart BeagleQueryPart; +typedef struct _BeagleHitsSubtractedResponse BeagleHitsSubtractedResponse; struct NautilusSearchEngineBeagleDetails { BeagleClient *client; @@ -37,6 +47,127 @@ gboolean query_finished; }; +/* We dlopen() all the following from libbeagle at runtime */ +#define BEAGLE_HIT(x) ((BeagleHit *)(x)) +#define BEAGLE_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), beagle_request_get_type(), BeagleRequest)) +#define BEAGLE_QUERY_PART(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), beagle_query_part_get_type(), BeagleQueryPart)) + +typedef enum { + BEAGLE_QUERY_PART_LOGIC_REQUIRED = 1, + BEAGLE_QUERY_PART_LOGIC_PROHIBITED = 2 +} BeagleQueryPartLogic; + +typedef enum { + BEAGLE_PROPERTY_TYPE_UNKNOWN = 0, + BEAGLE_PROPERTY_TYPE_TEXT = 1, + BEAGLE_PROPERTY_TYPE_KEYWORD = 2, + BEAGLE_PROPERTY_TYPE_DATE = 3, + BEAGLE_PROPERTY_TYPE_LAST = 4 +} BeaglePropertyType; + +/* *static* wrapper function pointers */ +static gboolean (*beagle_client_send_request_async) (BeagleClient *client, + BeagleRequest *request, + GError **err) = NULL; +static G_CONST_RETURN char *(*beagle_hit_get_uri) (BeagleHit *hit) = NULL; +static GSList *(*beagle_hits_added_response_get_hits) (BeagleHitsAddedResponse *response) = NULL; +static BeagleQuery *(*beagle_query_new) (void) = NULL; +static void (*beagle_query_add_text) (BeagleQuery *query, + const char *str) = NULL; +static void (*beagle_query_add_hit_type) (BeagleQuery *query, + const char *hit_type) = NULL; +static BeagleQueryPartProperty *(*beagle_query_part_property_new) (void) = NULL; +static void (*beagle_query_part_set_logic) (BeagleQueryPart *part, + BeagleQueryPartLogic logic) = NULL; +static void (*beagle_query_part_property_set_key) (BeagleQueryPartProperty *part, + const char *key) = NULL; +static void (*beagle_query_part_property_set_value) (BeagleQueryPartProperty *part, + const char * value) = NULL; +static void (*beagle_query_part_property_set_property_type) (BeagleQueryPartProperty *part, + BeaglePropertyType prop_type) = NULL; +static void (*beagle_query_add_part) (BeagleQuery *query, + BeagleQueryPart *part) = NULL; +static GType (*beagle_request_get_type) (void) = NULL; +static GType (*beagle_query_part_get_type) (void) = NULL; +static gboolean (*beagle_util_daemon_is_running) (void) = NULL; +static BeagleClient *(*beagle_client_new_real) (const char *client_name) = NULL; +static void (*beagle_query_set_max_hits) (BeagleQuery *query, + int max_hits) = NULL; +static void (*beagle_query_add_mime_type) (BeagleQuery *query, + const char *mime_type) = NULL; +static GSList *(*beagle_hits_subtracted_response_get_uris) (BeagleHitsSubtractedResponse *response) = NULL; + +static struct BeagleDlMapping +{ + const char *fn_name; + gpointer *fn_ptr_ref; +} beagle_dl_mapping[] = +{ +#define MAP(a) { #a, (gpointer *)&a } + MAP (beagle_client_send_request_async), + MAP (beagle_hit_get_uri), + MAP (beagle_hits_added_response_get_hits), + MAP (beagle_query_new), + MAP (beagle_query_add_text), + MAP (beagle_query_add_hit_type), + MAP (beagle_query_part_property_new), + MAP (beagle_query_part_set_logic), + MAP (beagle_query_part_property_set_key), + MAP (beagle_query_part_property_set_value), + MAP (beagle_query_part_property_set_property_type), + MAP (beagle_query_add_part), + MAP (beagle_request_get_type), + MAP (beagle_query_part_get_type), + MAP (beagle_util_daemon_is_running), + MAP (beagle_query_set_max_hits), + MAP (beagle_query_add_mime_type), + MAP (beagle_hits_subtracted_response_get_uris), +#undef MAP + { "beagle_client_new", (gpointer *)&beagle_client_new_real }, +}; + +static void +open_libbeagle (void) +{ + static gboolean done = FALSE; + + if (!done) + { + int i; + GModule *beagle; + + done = TRUE; + + beagle = g_module_open ("libbeagle.so.0", G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL); + if (!beagle) + return; + + for (i = 0; i < G_N_ELEMENTS (beagle_dl_mapping); i++) + { + if (!g_module_symbol (beagle, beagle_dl_mapping[i].fn_name, + beagle_dl_mapping[i].fn_ptr_ref)) + { + g_warning ("Missing symbol '%s' in libbeagle\n", + beagle_dl_mapping[i].fn_name); + g_module_close (beagle); + + for (i = 0; i < G_N_ELEMENTS (beagle_dl_mapping); i++) + beagle_dl_mapping[i].fn_ptr_ref = NULL; + + return; + } + } + } +} + +static BeagleClient * +beagle_client_new (const char *client_name) +{ + if (beagle_client_new_real) + return beagle_client_new_real (client_name); + + return NULL; +} static void nautilus_search_engine_beagle_class_init (NautilusSearchEngineBeagleClass *class); static void nautilus_search_engine_beagle_init (NautilusSearchEngineBeagle *engine); @@ -274,8 +405,11 @@ { NautilusSearchEngineBeagle *engine; BeagleClient *client; + + open_libbeagle (); - if (!beagle_util_daemon_is_running ()) { + if (beagle_util_daemon_is_running == NULL || + !beagle_util_daemon_is_running ()) { /* check whether daemon is running as beagle_client_new * doesn't fail when a stale socket file exists */ return NULL; --- nautilus-2.16.2/libnautilus-private/nautilus-search-engine-tracker.c.dynamic-search 2006-11-14 01:39:07.000000000 -0500 +++ nautilus-2.16.2/libnautilus-private/nautilus-search-engine-tracker.c 2006-11-14 01:40:36.000000000 -0500 @@ -23,12 +23,94 @@ #include <config.h> #include "nautilus-search-engine-tracker.h" -#include <tracker.h> +#include <gmodule.h> #include <libgnomevfs/gnome-vfs-utils.h> #include <eel/eel-gtk-macros.h> #include <eel/eel-glib-extensions.h> +typedef struct _TrackerClient TrackerClient; + +typedef void (*TrackerArrayReply) (char **result, GError *error, gpointer user_data); + +static TrackerClient * (*tracker_connect) (gboolean enable_warnings) = NULL; +static void (*tracker_disconnect) (TrackerClient *client) = NULL; +static void (*tracker_cancel_last_call) (TrackerClient *client) = NULL; + +static void (*tracker_search_metadata_by_text_async) (TrackerClient *client, + const char *query, + TrackerArrayReply callback, + gpointer user_data) = NULL; +static void (*tracker_search_metadata_by_text_and_mime_async) (TrackerClient *client, + const char *query, + const char **mimes, + TrackerArrayReply callback, + gpointer user_data) = NULL; +static void (*tracker_search_metadata_by_text_and_location_async) (TrackerClient *client, + const char *query, + const char *location, + TrackerArrayReply callback, + gpointer user_data) = NULL; +static void (*tracker_search_metadata_by_text_and_mime_and_location_async) (TrackerClient *client, + const char *query, + const char **mimes, + const char *location, + TrackerArrayReply callback, + gpointer user_data) = NULL; + + +static struct TrackerDlMapping +{ + const char *fn_name; + gpointer *fn_ptr_ref; +} tracker_dl_mapping[] = +{ +#define MAP(a) { #a, (gpointer *)&a } + MAP (tracker_connect), + MAP (tracker_disconnect), + MAP (tracker_cancel_last_call), + MAP (tracker_search_metadata_by_text_async), + MAP (tracker_search_metadata_by_text_and_mime_async), + MAP (tracker_search_metadata_by_text_and_location_async), + MAP (tracker_search_metadata_by_text_and_mime_and_location_async) +#undef MAP +}; + + +static void +open_libtracker (void) +{ + static gboolean done = FALSE; + + if (!done) + { + int i; + GModule *tracker; + + done = TRUE; + + tracker = g_module_open ("libtrackerclient.so.0", G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL); + if (!tracker) + return; + + for (i = 0; i < G_N_ELEMENTS (tracker_dl_mapping); i++) + { + if (!g_module_symbol (tracker, tracker_dl_mapping[i].fn_name, + tracker_dl_mapping[i].fn_ptr_ref)) + { + g_warning ("Missing symbol '%s' in libtracker\n", + tracker_dl_mapping[i].fn_name); + g_module_close (tracker); + + for (i = 0; i < G_N_ELEMENTS (tracker_dl_mapping); i++) + tracker_dl_mapping[i].fn_ptr_ref = NULL; + + return; + } + } + } +} + struct NautilusSearchEngineTrackerDetails { NautilusQuery *query; @@ -260,6 +342,12 @@ NautilusSearchEngineTracker *engine; TrackerClient *tracker_client; + open_libtracker (); + + if (!tracker_connect) { + return NULL; + } + tracker_client = tracker_connect (FALSE); if (!tracker_client) {
signature.asc
Description: This is a digitally signed message part