diff --git a/src/instance.c b/src/instance.c index 6878ae8..7d8e269 100644 --- a/src/instance.c +++ b/src/instance.c @@ -193,6 +193,22 @@ static int drm_find_psvr_xcb(Instance * instance) return(0); } + // code for xcb_randr_query_output_property heavily inspired by https://github.com/tcatm/xbacklight/blob/master/xbacklight.c + xcb_generic_error_t *error; + xcb_intern_atom_cookie_t non_desktop_cookie = xcb_intern_atom (instance->connection, 1, strlen("non-desktop"), "non-desktop"); + xcb_intern_atom_reply_t *non_desktop_reply = xcb_intern_atom_reply (instance->connection, non_desktop_cookie, &error); + if (error != NULL || non_desktop_reply == NULL) + { + int ec = error ? error->error_code : -1; + fprintf (stderr, "Intern non-desktop Atom returned error %d\n", ec); + return(0); + } + if (non_desktop_reply->atom == XCB_NONE) + { + fprintf (stderr, "No outputs have non-desktop property\n"); + return(0); + } + const xcb_setup_t *setup = xcb_get_setup(instance->connection); int screen = instance->screen; @@ -230,28 +246,49 @@ static int drm_find_psvr_xcb(Instance * instance) xcb_randr_output_t *ro = xcb_randr_get_screen_resources_outputs(gsr_r); int o, c; - int num_outputs = gsr_r->num_outputs; + int num_outputs = gsr_r->num_outputs; xcb_randr_output_t output = 0; - char * output_name = NULL; + unsigned char * output_name = NULL; // currently only used for debug - /* Find a connected but idle output */ - for (o = 0; o < num_outputs; o++) { - xcb_randr_get_output_info_cookie_t goi_c = xcb_randr_get_output_info(instance->connection, ro[o], config_timestamp); + // find HMD display + for (o = 0; o < num_outputs; o++) + { + xcb_randr_get_output_info_cookie_t goi_c = xcb_randr_get_output_info(instance->connection, ro[o], config_timestamp); - xcb_randr_get_output_info_reply_t *goi_r = xcb_randr_get_output_info_reply(instance->connection, goi_c, NULL); + xcb_randr_get_output_info_reply_t *goi_r = xcb_randr_get_output_info_reply(instance->connection, goi_c, NULL); - output_name = xcb_randr_get_output_info_name(goi_r); + output_name = xcb_randr_get_output_info_name(goi_r); - /* Find the first connected but unused output */ - if (goi_r->connection == XCB_RANDR_CONNECTION_CONNECTED && - goi_r->crtc == 0) { - output = ro[o]; - break; + /* Find the first output that has the non-desktop property set */ + xcb_randr_get_output_property_cookie_t prop_cookie; + prop_cookie = xcb_randr_get_output_property (instance->connection, ro[o], non_desktop_reply->atom, XCB_ATOM_NONE, 0, 4, 0, 0); + xcb_randr_get_output_property_reply_t *prop_reply = NULL; + prop_reply = xcb_randr_get_output_property_reply (instance->connection, prop_cookie, &error); + if (error != NULL || prop_reply == NULL) + { + printf ("Getting non-desktop property reply failed\n"); + return 0; + } + + if (prop_reply == NULL || prop_reply->type != XCB_ATOM_INTEGER || prop_reply->num_items != 1 || prop_reply->format != 32) + { + printf ("Wrong non-desktop reply!\n"); + } + else + { + int value = *((int32_t *) xcb_randr_get_output_property_data (prop_reply)); + //printf ("non-desktop: %d\n", value); + if (value > 0) + { + output_name = xcb_randr_get_output_info_name(goi_r); + printf ("Using output %s for drm lease!\n", output_name); + output = ro[o]; } + } - free(goi_r); + free(goi_r); } if (!output)