static void add_to_list( LibHalContext *ctx, GSList **list, const char *udi, int size ) { struct battery_info *battery = g_malloc0( size ); LibHalPropertySetIterator iter; LibHalPropertySet *properties; DBusError error; /* this might be an adaptor! this is OK as long as 'udi' is the first * member of both structures. */ battery->udi = g_strdup( udi ); *list = g_slist_append( *list, battery ); dbus_error_init( &error ); libhal_device_add_property_watch( ctx, udi, &error ); properties = libhal_device_get_all_properties( ctx, udi, &error ); for( libhal_psi_init( &iter, properties ); libhal_psi_has_more( &iter ); libhal_psi_next( &iter ) ) { const char *key = libhal_psi_get_key( &iter ); property_callback( ctx, udi, key, FALSE, FALSE ); } libhal_free_property_set( properties ); dbus_error_free( &error ); }
static void device_added(LibHalContext *hal_ctx, const char *udi) { char *path = NULL, *driver = NULL, *name = NULL, *config_info = NULL; InputOption *options = NULL, *tmpo = NULL; DeviceIntPtr dev = NULL; DBusError error; struct xkb_options xkb_opts = {0}; int rc; LibHalPropertySet *set = NULL; LibHalPropertySetIterator set_iter; char *psi_key = NULL, *tmp_val; dbus_error_init(&error); driver = get_prop_string(hal_ctx, udi, "input.x11_driver"); if (!driver){ /* verbose, don't tell the user unless they _want_ to see it */ LogMessageVerb(X_INFO,7,"config/hal: no driver specified for device %s\n", udi); goto unwind; } path = get_prop_string(hal_ctx, udi, "input.device"); if (!path) { LogMessage(X_WARNING,"config/hal: no driver or path specified for %s\n", udi); goto unwind; } name = get_prop_string(hal_ctx, udi, "info.product"); if (!name) name = xstrdup("(unnamed)"); options = xcalloc(sizeof(*options), 1); if (!options){ LogMessage(X_ERROR, "config/hal: couldn't allocate space for input options!\n"); goto unwind; } options->key = xstrdup("_source"); options->value = xstrdup("server/hal"); if (!options->key || !options->value) { LogMessage(X_ERROR, "config/hal: couldn't allocate first key/value pair\n"); goto unwind; } /* most drivers use device.. not path. evdev uses both however, but the * path version isn't documented apparently. support both for now. */ add_option(&options, "path", path); add_option(&options, "device", path); add_option(&options, "driver", driver); add_option(&options, "name", name); config_info = xalloc(strlen(udi) + 5); /* "hal:" and NULL */ if (!config_info) { LogMessage(X_ERROR, "config/hal: couldn't allocate name\n"); goto unwind; } sprintf(config_info, "hal:%s", udi); /* Check for duplicate devices */ if (device_is_duplicate(config_info)) { LogMessage(X_WARNING, "config/hal: device %s already added. Ignoring.\n", name); goto unwind; } /* ok, grab options from hal.. iterate through all properties * and lets see if any of them are options that we can add */ set = libhal_device_get_all_properties(hal_ctx, udi, &error); if (!set) { LogMessage(X_ERROR, "config/hal: couldn't get property list for %s: %s (%s)\n", udi, error.name, error.message); goto unwind; } libhal_psi_init(&set_iter,set); while (libhal_psi_has_more(&set_iter)) { /* we are looking for supported keys.. extract and add to options */ psi_key = libhal_psi_get_key(&set_iter); if (psi_key){ /* normal options first (input.x11_options.<propname>) */ if (!strncasecmp(psi_key, LIBHAL_PROP_KEY, sizeof(LIBHAL_PROP_KEY)-1)){ char* tmp; /* only support strings for all values */ tmp_val = get_prop_string(hal_ctx, udi, psi_key); if (tmp_val){ /* xkb needs special handling. HAL specs include * input.xkb.xyz options, but the x11-input.fdi specifies * input.x11_options.Xkbxyz options. By default, we use * the former, unless the specific X11 ones are specified. * Since we can't predict the order in which the keys * arrive, we need to store them. */ if ((tmp = strcasestr(psi_key, "xkb")) && strlen(tmp) >= 4) { if (!strcasecmp(&tmp[3], "layout")) { if (xkb_opts.layout) xfree(xkb_opts.layout); xkb_opts.layout = strdup(tmp_val); } else if (!strcasecmp(&tmp[3], "model")) { if (xkb_opts.model) xfree(xkb_opts.model); xkb_opts.model = strdup(tmp_val); } else if (!strcasecmp(&tmp[3], "rules")) { if (xkb_opts.rules) xfree(xkb_opts.rules); xkb_opts.rules = strdup(tmp_val); } else if (!strcasecmp(&tmp[3], "variant")) { if (xkb_opts.variant) xfree(xkb_opts.variant); xkb_opts.variant = strdup(tmp_val); } else if (!strcasecmp(&tmp[3], "options")) { if (xkb_opts.options) xfree(xkb_opts.options); xkb_opts.options = strdup(tmp_val); } } else { /* all others */ add_option(&options, psi_key + sizeof(LIBHAL_PROP_KEY)-1, tmp_val); xfree(tmp_val); } } else { /* server 1.4 had xkb_options as strlist. */ if ((tmp = strcasestr(psi_key, "xkb")) && (strlen(tmp) >= 4) && (!strcasecmp(&tmp[3], "options")) && (tmp_val = get_prop_string_array(hal_ctx, udi, psi_key))) { if (xkb_opts.options) xfree(xkb_opts.options); xkb_opts.options = strdup(tmp_val); } } } else if (!strncasecmp(psi_key, LIBHAL_XKB_PROP_KEY, sizeof(LIBHAL_XKB_PROP_KEY)-1)){ char* tmp; /* only support strings for all values */ tmp_val = get_prop_string(hal_ctx, udi, psi_key); if (tmp_val && strlen(psi_key) >= sizeof(LIBHAL_XKB_PROP_KEY)) { tmp = &psi_key[sizeof(LIBHAL_XKB_PROP_KEY) - 1]; if (!strcasecmp(tmp, "layout")) { if (!xkb_opts.layout) xkb_opts.layout = strdup(tmp_val); } else if (!strcasecmp(tmp, "rules")) { if (!xkb_opts.rules) xkb_opts.rules = strdup(tmp_val); } else if (!strcasecmp(tmp, "variant")) { if (!xkb_opts.variant) xkb_opts.variant = strdup(tmp_val); } else if (!strcasecmp(tmp, "model")) { if (!xkb_opts.model) xkb_opts.model = strdup(tmp_val); } else if (!strcasecmp(tmp, "options")) { if (!xkb_opts.options) xkb_opts.options = strdup(tmp_val); } xfree(tmp_val); } else { /* server 1.4 had xkb options as strlist */ tmp_val = get_prop_string_array(hal_ctx, udi, psi_key); if (tmp_val && strlen(psi_key) >= sizeof(LIBHAL_XKB_PROP_KEY)) { tmp = &psi_key[sizeof(LIBHAL_XKB_PROP_KEY) - 1]; if (!strcasecmp(tmp, ".options") && (!xkb_opts.options)) xkb_opts.options = strdup(tmp_val); } } } } /* psi_key doesn't need to be freed */ libhal_psi_next(&set_iter); } /* Now add xkb options */ if (xkb_opts.layout) add_option(&options, "xkb_layout", xkb_opts.layout); if (xkb_opts.rules) add_option(&options, "xkb_rules", xkb_opts.rules); if (xkb_opts.variant) add_option(&options, "xkb_variant", xkb_opts.variant); if (xkb_opts.model) add_option(&options, "xkb_model", xkb_opts.model); if (xkb_opts.options) add_option(&options, "xkb_options", xkb_opts.options); /* this isn't an error, but how else do you output something that the user can see? */ LogMessage(X_INFO, "config/hal: Adding input device %s\n", name); if ((rc = NewInputDeviceRequest(options, &dev)) != Success) { LogMessage(X_ERROR, "config/hal: NewInputDeviceRequest failed (%d)\n", rc); dev = NULL; goto unwind; } for (; dev; dev = dev->next){ if (dev->config_info) xfree(dev->config_info); dev->config_info = xstrdup(config_info); } unwind: if (set) libhal_free_property_set(set); if (path) xfree(path); if (driver) xfree(driver); if (name) xfree(name); if (config_info) xfree(config_info); while (!dev && (tmpo = options)) { options = tmpo->next; xfree(tmpo->key); xfree(tmpo->value); xfree(tmpo); } if (xkb_opts.layout) xfree(xkb_opts.layout); if (xkb_opts.rules) xfree(xkb_opts.rules); if (xkb_opts.model) xfree(xkb_opts.model); if (xkb_opts.variant) xfree(xkb_opts.variant); if (xkb_opts.options) xfree(xkb_opts.options); dbus_error_free(&error); return; }
int prt_dev_props(LibHalContext *hal_ctx, char *dev_name) { LibHalPropertySet *props; LibHalPropertySetIterator it; DBusError error; int type; char *devfs_path; dbus_error_init(&error); if (!(props = libhal_device_get_all_properties(hal_ctx, dev_name, &error))) { fprintf(stderr, "%s: %s\n", error.name, error.message); dbus_error_free(&error); return (1); } devfs_path = libhal_device_get_property_string(hal_ctx, dev_name, "solaris.devfs_path", &error); if (devfs_path) { printf("devfs path:%s\n", devfs_path); libhal_free_string(devfs_path); } for (libhal_psi_init(&it, props); libhal_psi_has_more(&it); libhal_psi_next(&it)) { type = libhal_psi_get_type(&it); switch (type) { case LIBHAL_PROPERTY_TYPE_STRING: printf("%s:'%s'\n", libhal_psi_get_key(&it), libhal_psi_get_string(&it)); break; case LIBHAL_PROPERTY_TYPE_INT32: printf("%s:%d\n", libhal_psi_get_key(&it), libhal_psi_get_int(&it)); break; case LIBHAL_PROPERTY_TYPE_UINT64: printf("%s:%lld\n", libhal_psi_get_key(&it), (long long) libhal_psi_get_uint64(&it)); break; case LIBHAL_PROPERTY_TYPE_DOUBLE: printf("%s:%g\n", libhal_psi_get_key(&it), libhal_psi_get_double(&it)); break; case LIBHAL_PROPERTY_TYPE_BOOLEAN: printf("%s:%s\n", libhal_psi_get_key(&it), libhal_psi_get_bool(&it) ? "true" : "false"); break; case LIBHAL_PROPERTY_TYPE_STRLIST: { char **strlist; printf("%s:{ ", libhal_psi_get_key(&it)); strlist = libhal_psi_get_strlist(&it); while (*strlist) { printf("'%s'%s", *strlist, strlist[1] ? ", " : ""); strlist++; } printf(" }\n"); } break; default: printf("Unknown type:%d=0x%02x\n", type, type); break; } } libhal_free_property_set(props); printf("\n"); dbus_error_free(&error); return (0); }
gboolean check_libhal (const char *server_addr) { pid_t child_pid; child_pid = fork (); if (child_pid == -1) { printf ("Cannot fork\n"); exit (1); } else if (child_pid == 0) { DBusError error; DBusConnection *conn; LibHalContext *ctx; dbus_bool_t passed; printf ("server address='%s'\n", server_addr); dbus_error_init (&error); if ((conn = dbus_connection_open (server_addr, &error)) == NULL) { printf ("Error connecting to server: %s\n", error.message); goto fail; } dbus_connection_setup_with_g_main (conn, NULL); if ((ctx = libhal_ctx_new ()) == NULL) { printf ("Error getting libhal context\n"); goto fail; } libhal_ctx_set_dbus_connection (ctx, conn); libhal_ctx_init (ctx, &error); if (dbus_error_is_set (&error)) { printf ("FAILED98: %s\n", error.message); goto fail; } printf ("SUCCESS98\n"); libhal_device_print (ctx, "/org/freedesktop/Hal/devices/testobj1", &error); if (dbus_error_is_set (&error)) { printf ("FAILED99: %s\n", error.message); goto fail; } printf ("SUCCESS99\n"); passed = FALSE; { char *val; val = libhal_device_get_property_string (ctx, "/org/freedesktop/Hal/devices/testobj1", "test.string", &error); if (val == NULL || strcmp (val, "fooooobar22") != 0 || dbus_error_is_set (&error)) { libhal_free_string (val); printf ("FAILED100\n"); goto fail; } printf ("SUCCESS100\n"); libhal_free_string (val); } { char *val; val = libhal_device_get_property_string (ctx, "/org/freedesktop/Hal/devices/testobj1", "test.string2", &error); if (val == NULL || strcmp (val, "fooøةמ") != 0 || dbus_error_is_set (&error)) { libhal_free_string (val); printf ("FAILED101: %s\n", error.message); goto fail; } libhal_free_string (val); printf ("SUCCESS101\n"); } { dbus_bool_t b; b = libhal_device_get_property_bool ( ctx, "/org/freedesktop/Hal/devices/testobj1", "test.bool", &error); if (!b || dbus_error_is_set (&error)) { printf ("FAILED102: %s, %i\n", error.message, b); goto fail; } printf ("SUCCESS102\n"); } { double val; double expected_val = 0.53434343; val = libhal_device_get_property_double (ctx, "/org/freedesktop/Hal/devices/testobj1", "test.double", &error); if ( memcmp (&val, &expected_val, sizeof (double)) != 0 || dbus_error_is_set (&error)) { printf ("FAILED103\n"); goto fail; } printf ("SUCCESS103\n"); } if (libhal_device_get_property_uint64 ( ctx, "/org/freedesktop/Hal/devices/testobj1", "test.uint64", &error) != ((((dbus_uint64_t)1)<<35) + 5) || dbus_error_is_set (&error)) { printf ("FAILED104: %s\n", error.message); goto fail; } printf ("SUCCESS104\n"); { char **val; val = libhal_device_get_property_strlist (ctx, "/org/freedesktop/Hal/devices/testobj1", "test.strlist", &error); if (val == NULL || dbus_error_is_set (&error)) { libhal_free_string_array (val); printf ("FAILED105: %s\n", error.message); goto fail; } printf ("SUCCESS105\n"); if (libhal_string_array_length (val) != 2) { libhal_free_string_array (val); printf ("FAILED106\n"); goto fail; } printf ("SUCCESS106\n"); if (strcmp (val[0], "foostrlist2") != 0 || strcmp (val[1], "foostrlist3") != 0) { libhal_free_string_array (val); printf ("FAILED107\n"); goto fail; } printf ("SUCCESS107\n"); libhal_free_string_array (val); } if (libhal_device_get_property_int ( ctx, "/org/freedesktop/Hal/devices/testobj1", "test.int", &error) != 42 || dbus_error_is_set (&error)) { printf ("FAILED108\n"); goto fail; } printf ("SUCCESS108\n"); /* tests for libhal_psi */ { int type; char *key; LibHalPropertySet *pset; LibHalPropertySetIterator it; unsigned int psi_num_passed; unsigned int psi_num_elems; if ((pset = libhal_device_get_all_properties (ctx, "/org/freedesktop/Hal/devices/testobj1", &error)) == NULL) return FALSE; printf ("SUCCESS110\n"); psi_num_passed = 0; psi_num_elems = libhal_property_set_get_num_elems (pset); for (libhal_psi_init (&it, pset); libhal_psi_has_more (&it); libhal_psi_next (&it)) { type = libhal_psi_get_type (&it); key = libhal_psi_get_key (&it); switch (type) { case LIBHAL_PROPERTY_TYPE_STRING: if (strcmp (key, "info.udi") == 0) { if (strcmp (libhal_psi_get_string (&it), "/org/freedesktop/Hal/devices/testobj1") == 0) { psi_num_passed++; } else { printf ("fail on %s\n", key); } } else if (strcmp (key, "test.string") == 0) { if (strcmp (libhal_psi_get_string (&it), "fooooobar22") == 0) { psi_num_passed++; } else { printf ("fail on %s\n", key); } } else if (strcmp (key, "test.string2") == 0) { if (strcmp (libhal_psi_get_string (&it), "fooøةמ") == 0) { psi_num_passed++; } else { printf ("fail on %s\n", key); } } break; case LIBHAL_PROPERTY_TYPE_INT32: if (strcmp (key, "test.int") == 0) { if (libhal_psi_get_int (&it) == 42) psi_num_passed++; else printf ("fail on %s\n", key); } break; case LIBHAL_PROPERTY_TYPE_UINT64: if (strcmp (key, "test.uint64") == 0) { if (libhal_psi_get_uint64 (&it) == ((((dbus_uint64_t)1)<<35) + 5)) psi_num_passed++; else printf ("fail on %s\n", key); } break; case LIBHAL_PROPERTY_TYPE_BOOLEAN: if (strcmp (key, "test.bool") == 0) { if (libhal_psi_get_bool (&it) == TRUE) psi_num_passed++; else printf ("fail on %s\n", key); } break; case LIBHAL_PROPERTY_TYPE_DOUBLE: if (strcmp (key, "test.double") == 0) { double val = 0.53434343; double val2; val2 = libhal_psi_get_double (&it); if (memcmp (&val, &val2, sizeof (double)) == 0) psi_num_passed++; else printf ("fail on %s\n", key); } break; case LIBHAL_PROPERTY_TYPE_STRLIST: if (strcmp (key, "test.strlist") == 0) { char **val; val = libhal_psi_get_strlist (&it); if (libhal_string_array_length (val) == 2 && strcmp (val[0], "foostrlist2") == 0 && strcmp (val[1], "foostrlist3") == 0 && val[2] == NULL) psi_num_passed++; else printf ("fail on %s\n", key); } break; default: printf (" *** unknown type for key %s\n", key); break; } } libhal_free_property_set (pset); if (psi_num_passed != psi_num_elems) { printf ("FAILED111\n"); goto fail; } printf ("SUCCESS111\n"); } /* end libhal_test_psi */ printf ("Passed all libhal tests\n"); passed = TRUE; fail: if (dbus_error_is_set (&error)) dbus_error_free (&error); send_tests_done (conn, passed); exit (1); } else { printf ("child pid=%d\n", child_pid); } return TRUE; }
/* * Dump all devices. */ int dump_devices(LibHalContext *hal_ctx, char *arg) { int i; int num_devices; char **device_names; DBusError error; char *udi = NULL; if (arg) { if (*arg == '/') { udi = arg; } else { #ifdef HAVE_ASPRINTF asprintf(&udi, "/org/freedesktop/Hal/devices/%s", arg); #else udi = calloc(1, sizeof ("/org/freedesktop/Hal/devices/%s") + strlen(arg)); sprintf(udi, "/org/freedesktop/Hal/devices/%s", arg); #endif } } dbus_error_init(&error); if (!udi) { if (!(device_names = libhal_get_all_devices(hal_ctx, &num_devices, &error))) { fprintf(stderr, "Empty HAL device list.\n"); LIBHAL_FREE_DBUS_ERROR (&error); return 31; } } else { device_names = calloc(2, sizeof *device_names); device_names[0] = strdup(udi); num_devices = 1; } for(i = 0; i < num_devices; i++) { LibHalPropertySet *props; LibHalPropertySetIterator it; int type; if (!(props = libhal_device_get_all_properties(hal_ctx, device_names[i], &error))) { fprintf(stderr, "%s: %s\n", error.name, error.message); dbus_error_init(&error); continue; } if (!udi) printf("%d: ", i); printf("udi = '%s'\n", device_names[i]); for(libhal_psi_init(&it, props); libhal_psi_has_more(&it); libhal_psi_next(&it)) { type = libhal_psi_get_type(&it); switch (type) { case LIBHAL_PROPERTY_TYPE_STRING: printf(" %s = '%s' (string)\n", libhal_psi_get_key(&it), libhal_psi_get_string(&it) ); break; case LIBHAL_PROPERTY_TYPE_INT32: printf(" %s = %d (0x%x) (int)\n", libhal_psi_get_key(&it), libhal_psi_get_int(&it), libhal_psi_get_int(&it) ); break; case LIBHAL_PROPERTY_TYPE_UINT64: printf(" %s = %lld (0x%llx) (uint64)\n", libhal_psi_get_key(&it), (long long) libhal_psi_get_uint64(&it), (long long) libhal_psi_get_uint64(&it) ); break; case LIBHAL_PROPERTY_TYPE_DOUBLE: printf(" %s = %g (double)\n", libhal_psi_get_key(&it), libhal_psi_get_double(&it) ); break; case LIBHAL_PROPERTY_TYPE_BOOLEAN: printf(" %s = %s (bool)\n", libhal_psi_get_key(&it), libhal_psi_get_bool(&it) ? "true" : "false" ); break; case LIBHAL_PROPERTY_TYPE_STRLIST: { char **strlist; printf (" %s = { ", libhal_psi_get_key(&it)); strlist = libhal_psi_get_strlist(&it); while (*strlist) { printf("'%s'%s", *strlist, strlist[1] ? ", " : ""); strlist++; } printf(" } (string list)\n"); } break; default: printf("Unknown type %d = 0x%02x\n", type, type); break; } } libhal_free_property_set(props); printf("\n"); } libhal_free_string_array(device_names); dbus_error_free(&error); return 0; }