summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/blueshift_randr.c142
1 files changed, 100 insertions, 42 deletions
diff --git a/src/blueshift_randr.c b/src/blueshift_randr.c
index 891c8b6..0f5c62c 100644
--- a/src/blueshift_randr.c
+++ b/src/blueshift_randr.c
@@ -35,32 +35,42 @@
-int main(int argc __attribute__((unused)), char** argv __attribute__((unused)))
+/**
+ * Data structure for CRTC caches
+ */
+typedef struct blueshift_randr_crtc
{
- uint64_t use_crtcs = ~0;
-
- xcb_connection_t* connection;
- xcb_generic_error_t* error;
- xcb_randr_query_version_cookie_t version_cookie;
- xcb_randr_query_version_reply_t* randr_version;
- const xcb_setup_t* setup;
- xcb_screen_iterator_t iter;
- xcb_screen_t* screen;
- xcb_randr_get_screen_resources_current_cookie_t res_cookie;
- xcb_randr_get_screen_resources_current_reply_t* res_reply;
- unsigned int crtc_count;
- xcb_randr_crtc_t* crtcs;
- xcb_randr_crtc_t* crtcs_end;
- xcb_randr_get_crtc_gamma_size_cookie_t gamma_size_cookie;
- xcb_randr_get_crtc_gamma_size_reply_t* gamma_size_reply;
unsigned int curve_size;
- xcb_randr_get_crtc_gamma_cookie_t gamma_get_cookie;
xcb_randr_get_crtc_gamma_reply_t* gamma_get_reply;
uint16_t* r_gamma;
uint16_t* g_gamma;
uint16_t* b_gamma;
- unsigned int i;
- xcb_void_cookie_t gamma_set_cookie;
+ xcb_randr_crtc_t* crtc;
+} blueshift_randr_crtc_t;
+
+
+
+static xcb_connection_t* connection;
+static xcb_randr_query_version_cookie_t version_cookie;
+static xcb_randr_query_version_reply_t* randr_version;
+static xcb_generic_error_t* error;
+static const xcb_setup_t* setup;
+static xcb_screen_iterator_t iter;
+static xcb_screen_t* screen;
+static xcb_randr_get_screen_resources_current_cookie_t res_cookie;
+static xcb_randr_get_screen_resources_current_reply_t* res_reply;
+static unsigned int crtc_count;
+static blueshift_randr_crtc_t* crtcs;
+static blueshift_randr_crtc_t* crtcs_end;
+
+
+
+int blueshift_randr_open(void)
+{
+ blueshift_randr_crtc_t* crtcs_;
+ xcb_randr_get_crtc_gamma_size_cookie_t gamma_size_cookie;
+ xcb_randr_get_crtc_gamma_size_reply_t* gamma_size_reply;
+ xcb_randr_get_crtc_gamma_cookie_t gamma_get_cookie;
/* Get X connection */
@@ -113,23 +123,24 @@ int main(int argc __attribute__((unused)), char** argv __attribute__((unused)))
/* Get CRTC:s */
crtc_count = res_reply->num_crtcs;
- crtcs = xcb_randr_get_screen_resources_current_crtcs(res_reply);
+ crtcs = malloc(crtc_count * sizeof(blueshift_randr_crtc_t));
+ crtcs->crtc = xcb_randr_get_screen_resources_current_crtcs(res_reply);
crtcs_end = crtcs + crtc_count;
- /* Use CRTC:s */
+ /* Prepare CRTC:s */
- while (crtcs != crtcs_end)
+ for (crtcs_ = crtcs; crtcs_ != crtcs_end; crtcs_++)
{
- /* Check whether we should use the CRTC */
-
- if ((use_crtcs & 1) == 0)
- goto next_crtc;
+ /* Set CRTC */
+
+ if (crtcs_ != crtcs)
+ crtcs_->crtc = (crtcs_ - 1)->crtc + 1;
/* Get curve X-axis size */
- gamma_size_cookie = xcb_randr_get_crtc_gamma_size(connection, *crtcs);
+ gamma_size_cookie = xcb_randr_get_crtc_gamma_size(connection, *(crtcs_->crtc));
gamma_size_reply = xcb_randr_get_crtc_gamma_size_reply(connection, gamma_size_cookie, &error);
if (error)
@@ -139,14 +150,14 @@ int main(int argc __attribute__((unused)), char** argv __attribute__((unused)))
return 1;
}
- curve_size = gamma_size_reply->size;
+ crtcs_->curve_size = gamma_size_reply->size;
free(gamma_size_reply);
/* Acquire curve control */
- gamma_get_cookie = xcb_randr_get_crtc_gamma(connection, *crtcs);
- gamma_get_reply = xcb_randr_get_crtc_gamma_reply(connection, gamma_get_cookie, &error);
+ gamma_get_cookie = xcb_randr_get_crtc_gamma(connection, *(crtcs_->crtc));
+ crtcs_->gamma_get_reply = xcb_randr_get_crtc_gamma_reply(connection, gamma_get_cookie, &error);
if (error)
{
@@ -155,24 +166,48 @@ int main(int argc __attribute__((unused)), char** argv __attribute__((unused)))
return 1;
}
- r_gamma = xcb_randr_get_crtc_gamma_red(gamma_get_reply);
- g_gamma = xcb_randr_get_crtc_gamma_green(gamma_get_reply);
- b_gamma = xcb_randr_get_crtc_gamma_blue(gamma_get_reply);
+ crtcs_->r_gamma = xcb_randr_get_crtc_gamma_red(crtcs_->gamma_get_reply);
+ crtcs_->g_gamma = xcb_randr_get_crtc_gamma_green(crtcs_->gamma_get_reply);
+ crtcs_->b_gamma = xcb_randr_get_crtc_gamma_blue(crtcs_->gamma_get_reply);
+ }
+
+
+ return 0;
+}
+
+
+int blueshift_randr_apply(uint64_t use_crtcs)
+{
+ blueshift_randr_crtc_t* crtcs_ = crtcs;
+
+ unsigned int i;
+ xcb_void_cookie_t gamma_set_cookie;
+
+
+ /* Use CRTC:s */
+
+ while (crtcs_ != crtcs_end)
+ {
+ /* Check whether we should use the CRTC */
+
+ if ((use_crtcs & 1) == 0)
+ goto next_crtc;
/* Set curves */
- for (i = 0; i < curve_size; i++)
+ for (i = 0; i < crtcs_->curve_size; i++)
{
- *(r_gamma + i) = (1 << 16) - 1 - *(r_gamma + i);
- *(g_gamma + i) = (1 << 16) - 1 - *(g_gamma + i);
- *(b_gamma + i) = (1 << 16) - 1 - *(b_gamma + i);
+ *(crtcs_->r_gamma + i) = (1 << 16) - 1 - *(crtcs_->r_gamma + i);
+ *(crtcs_->g_gamma + i) = (1 << 16) - 1 - *(crtcs_->g_gamma + i);
+ *(crtcs_->b_gamma + i) = (1 << 16) - 1 - *(crtcs_->b_gamma + i);
}
/* Apply curves */
- gamma_set_cookie = xcb_randr_set_crtc_gamma_checked(connection, *crtcs, curve_size, r_gamma, g_gamma, b_gamma);
+ gamma_set_cookie = xcb_randr_set_crtc_gamma_checked(connection, *(crtcs_->crtc), crtcs_->curve_size,
+ crtcs_->r_gamma, crtcs_->g_gamma, crtcs_->b_gamma);
error = xcb_request_check(connection, gamma_set_cookie);
if (error)
@@ -181,24 +216,47 @@ int main(int argc __attribute__((unused)), char** argv __attribute__((unused)))
return 1;
}
- free(gamma_get_reply);
-
/* Next CRTC */
next_crtc:
- crtcs++;
+ crtcs_++;
use_crtcs >>= 1;
}
+ return 0;
+}
+
+
+void blueshift_randr_close(void)
+{
+ blueshift_randr_crtc_t* crtcs_;
+
+
+ /* Free CRTC resources */
+
+ for (crtcs_ = crtcs; crtcs_ != crtcs_end; crtcs_++)
+ free(crtcs_->gamma_get_reply);
/* Free remaining resources */
+ free(crtcs);
free(res_reply);
xcb_disconnect(connection);
+}
+
+
+
+int main(int argc, char** argv)
+{
+ (void) argc;
+ (void) argv;
+ if (blueshift_randr_open() || blueshift_randr_apply(~0))
+ return 1;
+ blueshift_randr_close();
return 0;
}