diff options
-rw-r--r-- | Makefile | 15 | ||||
-rw-r--r-- | src/blueshift_w32gdi_c.c | 179 | ||||
-rw-r--r-- | src/blueshift_w32gdi_c.h | 76 |
3 files changed, 270 insertions, 0 deletions
@@ -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); + |