summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile15
-rw-r--r--src/blueshift_w32gdi_c.c179
-rw-r--r--src/blueshift_w32gdi_c.h76
3 files changed, 270 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index cf15470..d0023f3 100644
--- a/Makefile
+++ b/Makefile
@@ -37,7 +37,11 @@ COMMAND ?= blueshift
PKGNAME ?= blueshift
# Bindings for display server access
+ifeq ($(FAKE_W32),y)
+SERVER_BINDINGS ?= randr vidmode drm w32gdi
+else
SERVER_BINDINGS ?= randr vidmode drm
+endif
# Executable bindings for display server access
EXECS ?= idcrtc iccprofile
@@ -70,6 +74,11 @@ LIBS_iccprofile = xcb
LIBS_randr = xcb-randr
LIBS_vidmode = x11 xxf86vm
LIBS_drm = libdrm
+ifeq ($(FAKE_W32),y)
+LIBS_w32gdi = $(LIBS_randr)
+else
+LIBS_w32gdi =
+endif
LIBS = python3 $(foreach B,$(SERVER_BINDINGS) $(EXECS),$(LIBS_$(B)))
FLAGS = $$($(PKGCONFIG) --cflags $(LIBS)) -std=$(STD) $(WARN) $(OPTIMISE) -fPIC $(CFLAGS) $(LDFLAGS) $(CPPFLAGS)
@@ -114,6 +123,7 @@ bin/blueshift_iccprofile: obj/blueshift_iccprofile.o
bin/blueshift_drm.so: LIBS_=LIBS_drm
bin/blueshift_randr.so: LIBS_=LIBS_randr
bin/blueshift_vidmode.so: LIBS_=LIBS_vidmode
+bin/blueshift_w32gdi.so: LIBS_=LIBS_w32gdi
bin/%.so: obj/%.o obj/%_c.o
@mkdir -p bin
$(CC) $(FLAGS) $$($(PKGCONFIG) --libs $($(LIBS_))) -shared -o $@ $^
@@ -130,6 +140,11 @@ obj/%.o: obj/%.c
@mkdir -p obj
$(CC) $(FLAGS) -c -o $@ $<
+ifeq ($(FAKE_W32),y)
+obj/blueshift_w32gdi_c.o: FLAGS+=-DFAKE_W32GDI obj/fake_w32gdi.o obj/fake_w32gdi.h
+endif
+obj/fake_w32gdi.o: obj/fake_w32gdi.h
+
# Build rules for Cython source files
diff --git a/src/blueshift_w32gdi_c.c b/src/blueshift_w32gdi_c.c
new file mode 100644
index 0000000..6b5a394
--- /dev/null
+++ b/src/blueshift_w32gdi_c.c
@@ -0,0 +1,179 @@
+/**
+ * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "blueshift_w32gdi_c.h"
+
+
+
+/**
+ * The number of CRTC:s on the system
+ */
+static int crtc_count;
+
+/**
+ * The device contexts for each CRTC
+ */
+static HDC* crtcs;
+
+
+
+/**
+ * Start stage of colour curve control
+ *
+ * @return Zero on success
+ */
+int blueshift_w32gdi_open(void)
+{
+ int c;
+ DISPLAY_DEVICE display;
+ display.cb = sizeof(DISPLAY_DEVICE);
+
+ crtc_count = 0;
+ while (EnumDisplayDevices(NULL, crtc_count, &display, 0))
+ crtc_count++;
+
+ if (crtc_count == 0)
+ {
+ crtcs == NULL;
+ return 0;
+ }
+
+ crtcs = malloc(crtc_count * sizeof(HDC));
+ if (crtcs == NULL)
+ {
+ fprintf(stderr, "Out of memory\n");
+ return 1;
+ }
+
+ for (c = 0; c < crtc_count; c++)
+ {
+ /* Open device context */
+ if (EnumDisplayDevices(NULL, c, &display, 0) == FALSE)
+ {
+ fprintf(stderr, "Cannot find display, are you unplugging stuff?\n");
+ crtc_count = c;
+ return 1;
+ }
+ if (!(display.StateFlags & DISPLAY_DEVICE_ACTIVE))
+ {
+ fprintf(stderr, "Cannot to open device context, it is not active\n");
+ crtc_count = c;
+ return 1;
+ }
+ *(crtcs + c) = CreateDC(TEXT("DISPLAY"), display.DeviceName, NULL, NULL);
+ if (*(crtcs + c) == NULL)
+ {
+ fprintf(stderr, "Unable to open device context\n");
+ crtc_count = c;
+ return 1;
+ }
+
+ /* Check support for gamma ramps */
+ if (GetDeviceCaps(hDC, COLORMGMTCAPS) != CM_GAMMA_RAMP)
+ {
+ fprintf(stderr, "CRTC %i does not support gamma ramps\n", c);
+ ReleaseDC(NULL, *(crtcs + c));
+ crtc_count = c;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+
+/**
+ * Get the number of CRTC:s on the system
+ *
+ * @return The number of CRTC:s on the system
+ */
+int blueshift_w32gdi_crtc_count(void)
+{
+ return crtc_count;
+}
+
+
+/**
+ * Gets the current colour curves
+ *
+ * @param use_crtc The CRTC to use
+ * @return {the size of the each curve, *the red curve,
+ * *the green curve, *the blue curve},
+ * needs to be free:d. `NULL` on error.
+ */
+uint16_t* blueshift_w32gdi_read(int use_crtc)
+{
+ uint16_t* rc = NULL;
+ if ((use_crtc < 0) || (use_crtc >= crtc_count))
+ fprintf(stderr, "CRTC %i does not exist\n", use_crtc);
+ else
+ {
+ rc = malloc((1 + 3 * GAMMA_RAMP_SIZE) * sizeof(uint16_t));
+ if (rc == NULL)
+ fprintf(stderr, "Out of memory\n");
+ else
+ {
+ *rc = GAMMA_RAMP_SIZE;
+ if (GetDeviceGammaRamp(*(crtcs + use_crtc), rc + 1) == FALSE)
+ {
+ fprintf(stderr, "Unable to read current gamma ramps from CRTC %i\n", use_crtc);
+ free(rc);
+ rc = NULL;
+ }
+ }
+ }
+ return rc;
+}
+
+
+/**
+ * Apply stage of colour curve control
+ *
+ * @param use_crtc The CRTC to use, -1 if all
+ * @param rgb_curve The concatenation of the red, the green and the blue colour curves
+ * @return Zero on success
+ */
+int blueshift_w32gdi_apply(int use_crtc, uint16_t* rgb_curves)
+{
+ int r = 1;
+ if (use_crtc < crtc_count)
+ {
+ int c = use_crtc < 0 ? 0 : use_crtc;
+ int n = use_crtc < 0 ? crtc_count : (use_crtc + 1);
+ for (; c < n; c++)
+ if (!(r = SetDeviceGammaRamp(*(crtcs + c), rgb_curves)))
+ {
+ fprintf(stderr, "Unable to set gamma ramps\n");
+ break;
+ }
+ }
+ else
+ fprintf(stderr, "CRTC %i does not exist\n", use_crtc);
+ return !r;
+}
+
+
+/**
+ * Resource freeing stage of colour curve control
+ */
+void blueshift_w32gdi_close(void)
+{
+ for (c = 0; c < crtc_count; c++)
+ ReleaseDC(NULL, *(crtcs + c));
+ if (crtcs != NULL)
+ free(crtcs);
+}
+
diff --git a/src/blueshift_w32gdi_c.h b/src/blueshift_w32gdi_c.h
new file mode 100644
index 0000000..e34bebe
--- /dev/null
+++ b/src/blueshift_w32gdi_c.h
@@ -0,0 +1,76 @@
+/**
+ * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef WINVER
+# define WINVER 0x0500
+#endif
+#ifdef FAKE_W32GDI
+# include "fake-w32gdi.h"
+#else
+# include <windows.h>
+# include <wingdi.h>
+#endif
+
+
+
+/**
+ * The size of gamma ramps
+ */
+#define GAMMA_RAMP_SIZE 256
+
+
+
+/**
+ * Start stage of colour curve control
+ *
+ * @return Zero on success
+ */
+int blueshift_w32gdi_open(void);
+
+/**
+ * Get the number of CRTC:s on the system
+ *
+ * @return The number of CRTC:s on the system
+ */
+int blueshift_w32gdi_crtc_count(void);
+
+/**
+ * Gets the current colour curves
+ *
+ * @param use_crtc The CRTC to use
+ * @return {the size of the each curve, *the red curve,
+ * *the green curve, *the blue curve},
+ * needs to be free:d. `NULL` on error.
+ */
+uint16_t* blueshift_w32gdi_read(int use_crtc);
+
+/**
+ * Apply stage of colour curve control
+ *
+ * @param use_crtc The CRTC to use, -1 if all
+ * @param rgb_curve The concatenation of the red, the green and the blue colour curves
+ * @return Zero on success
+ */
+int blueshift_w32gdi_apply(int use_crtc, uint16_t* rgb_curves);
+
+/**
+ * Resource freeing stage of colour curve control
+ */
+void blueshift_w32gdi_close(void);
+