void ratbag_device_destroy(struct ratbag_device *device) { struct ratbag_profile *profile, *next; if (!device) return; /* if we get to the point where the device is destroyed, profiles, * buttons, etc. are at a refcount of 0, so we can destroy * everything */ if (device->driver && device->driver->remove) device->driver->remove(device); list_for_each_safe(profile, next, &device->profiles, link) ratbag_profile_destroy(profile); if (device->udev_device) udev_device_unref(device->udev_device); list_remove(&device->link); ratbag_unref(device->ratbag); ratbag_device_data_unref(device->data); free(device->name); free(device); }
END_TEST START_TEST(device_profiles) { struct ratbag *r; struct ratbag_device *d; struct ratbag_profile *p; int nprofiles; int i; bool is_active; int device_freed_count = 0; struct ratbag_test_device td = sane_device; td.destroyed_data = &device_freed_count; r = ratbag_create_context(&abort_iface, NULL); d = ratbag_device_new_test_device(r, &td); nprofiles = ratbag_device_get_num_profiles(d); ck_assert_int_eq(nprofiles, 3); for (i = 0; i < nprofiles; i++) { p = ratbag_device_get_profile(d, i); ck_assert(p != NULL); is_active = ratbag_profile_is_active(p); ck_assert_int_eq(is_active, (i == 0)); ratbag_profile_unref(p); } ratbag_device_unref(d); ratbag_unref(r); ck_assert_int_eq(device_freed_count, 1); }
END_TEST START_TEST(device_profiles_get_invalid) { struct ratbag *r; struct ratbag_device *d; struct ratbag_profile *p; int nprofiles; int device_freed_count = 0; struct ratbag_test_device td = sane_device; td.destroyed_data = &device_freed_count; r = ratbag_create_context(&abort_iface, NULL); d = ratbag_device_new_test_device(r, &td); nprofiles = ratbag_device_get_num_profiles(d); ck_assert_int_eq(nprofiles, 3); p = ratbag_device_get_profile(d, nprofiles); ck_assert(p == NULL); p = ratbag_device_get_profile(d, nprofiles + 1); ck_assert(p == NULL); p = ratbag_device_get_profile(d, -1); ck_assert(p == NULL); p = ratbag_device_get_profile(d, INT_MAX); ck_assert(p == NULL); p = ratbag_device_get_profile(d, UINT_MAX); ck_assert(p == NULL); ratbag_device_unref(d); ratbag_unref(r); ck_assert_int_eq(device_freed_count, 1); }
END_TEST START_TEST(context_ref) { struct ratbag *lr; struct ratbag *lr2; lr = ratbag_create_context(&simple_iface, NULL); ck_assert(lr != NULL); lr2 = ratbag_ref(lr); ck_assert_ptr_eq(lr, lr2); lr2 = ratbag_unref(lr2); ck_assert_ptr_eq(lr2, lr); lr2 = ratbag_unref(lr2); ck_assert_ptr_eq(lr2, NULL); }
END_TEST START_TEST(context_init) { struct ratbag *lr; lr = ratbag_create_context(&simple_iface, NULL); ck_assert(lr != NULL); ratbag_unref(lr); }
END_TEST START_TEST(device_profiles_num_0) { struct ratbag *r; struct ratbag_device *d; struct ratbag_test_device td = sane_device; td.num_profiles = 0; r = ratbag_create_context(&abort_iface, NULL); d = ratbag_device_new_test_device(r, &td); ck_assert(d == NULL); ratbag_unref(r); }
END_TEST START_TEST(device_profiles_multiple_active) { struct ratbag *r; struct ratbag_device *d; struct ratbag_test_device td = sane_device; td.profiles[0].active = true; td.profiles[1].active = true; r = ratbag_create_context(&abort_iface, NULL); d = ratbag_device_new_test_device(r, &td); ck_assert(d == NULL); ratbag_unref(r); }
END_TEST START_TEST(device_free_context_before_device) { struct ratbag *r; struct ratbag_device *d; struct ratbag_test_device td = sane_device; r = ratbag_create_context(&abort_iface, NULL); d = ratbag_device_new_test_device(r, &td); ck_assert(d != NULL); r = ratbag_unref(r); ck_assert(r == NULL); d = ratbag_device_unref(d); ck_assert(d == NULL); }
END_TEST START_TEST(device_profiles_ref_unref) { struct ratbag *r; struct ratbag_device *d; struct ratbag_profile *p; struct ratbag_test_device td = sane_device; r = ratbag_create_context(&abort_iface, NULL); d = ratbag_device_new_test_device(r, &td); p = ratbag_device_get_profile(d, 1); ratbag_unref(r); ratbag_device_unref(d); ref_unref_test(ratbag_profile, p); ratbag_profile_unref(p); }
END_TEST #define ref_unref_test(T, a) \ { \ int i; \ struct T *tmp = NULL; \ \ for (i = 0; i <= 256; i++) { \ tmp = T##_ref(a); \ ck_assert(tmp == a); \ } \ for (i = 0; i <= 256; i++) { \ tmp = T##_unref(a); \ ck_assert(tmp == NULL); \ } \ for (i = 0; i <= 256; i++) { \ tmp = T##_ref(a); \ ck_assert(tmp == a); \ tmp = T##_unref(a); \ ck_assert(tmp == NULL); \ } \ } START_TEST(device_ref_unref) { struct ratbag *r; struct ratbag_device *d; struct ratbag_test_device td = sane_device; r = ratbag_create_context(&abort_iface, NULL); d = ratbag_device_new_test_device(r, &td); ck_assert(d != NULL); ratbag_unref(r); ref_unref_test(ratbag_device, d); ratbag_device_unref(d); }
int main(int argc, char **argv) { struct ratbag *ratbag; const char *command; int rc = SUCCESS; struct ratbag_cmd_options options = {0}; ratbag = ratbag_create_context(&interface, NULL); if (!ratbag) { rc = ERR_DEVICE; error("Failed to initialize ratbag\n"); goto out; } options.flags = 0; while (1) { int c; int option_index = 0; static struct option opts[] = { { "verbose", 2, 0, OPT_VERBOSE }, { "help", 0, 0, OPT_HELP }, }; c = getopt_long(argc, argv, "+h", opts, &option_index); if (c == -1) break; switch(c) { case 'h': case OPT_HELP: usage(); goto out; case OPT_VERBOSE: if (optarg && streq(optarg, "raw")) options.flags |= FLAG_VERBOSE_RAW; else options.flags |= FLAG_VERBOSE; break; default: goto out; } } if (optind >= argc) { rc = ERR_USAGE; goto out; } if (options.flags & FLAG_VERBOSE_RAW) ratbag_log_set_priority(ratbag, RATBAG_LOG_PRIORITY_RAW); else if (options.flags & FLAG_VERBOSE) ratbag_log_set_priority(ratbag, RATBAG_LOG_PRIORITY_DEBUG); argc -= optind; argv += optind; command = argv[0]; rc = run_subcommand(command, ratbag_commands, ratbag, &options, argc, argv); if (options.device) rc = ratbag_device_commit(options.device); out: ratbag_resolution_unref(options.resolution); ratbag_button_unref(options.button); ratbag_profile_unref(options.profile); ratbag_device_unref(options.device); ratbag_unref(ratbag); if (rc == ERR_USAGE) usage(); return rc; }