summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO6
-rw-r--r--src/blueshift_randr.pyx14
-rw-r--r--src/blueshift_randr_c.c5
-rw-r--r--src/blueshift_randr_c.h3
-rw-r--r--src/blueshift_vidmode.pyx14
-rw-r--r--src/blueshift_vidmode_c.c25
-rw-r--r--src/blueshift_vidmode_c.h3
-rw-r--r--src/monitor.py93
8 files changed, 92 insertions, 71 deletions
diff --git a/TODO b/TODO
index fa56580..a1cd619 100644
--- a/TODO
+++ b/TODO
@@ -2,15 +2,17 @@ High priority:
Add support for monitor hotplugging
Add models for calculating fade and refresh rate parameters
Test with multiple X screens
+ Test, document and demo multi-display support
Medium priority:
Add a section in manual for information on which order
to apply settings and how it affects the result.
+ Import multi-screen and multi-display support so that new
+ connections are not need all the time.
Low priority:
- Raw ramp applying functions with precalcuated interpolation, polynomial
+ Raw ramp applying functions with precalcuated polynomial interpolation
Add support for temporarily closing DRM connection so that multiple users can run in DRM
- Add multi-display support (for example operating on two X displays)
Future stuff:
Add wayland support (could not find an API for it, but xwayland works)
diff --git a/src/blueshift_randr.pyx b/src/blueshift_randr.pyx
index f54a5c9..756ea73 100644
--- a/src/blueshift_randr.pyx
+++ b/src/blueshift_randr.pyx
@@ -19,7 +19,7 @@ cimport cython
from libc.stdlib cimport malloc, free
-cdef extern int blueshift_randr_open(int use_screen)
+cdef extern int blueshift_randr_open(int use_screen, char* display)
cdef extern unsigned short int* blueshift_randr_read(int use_crtc)
cdef extern int blueshift_randr_apply(unsigned long long int use_crtcs,
unsigned short int* r_curve,
@@ -40,14 +40,18 @@ if (r_c is NULL) or (g_c is NULL) or (b_c is NULL):
-def randr_open(int use_screen):
+def randr_open(int use_screen, display):
'''
Start stage of colour curve control
- @param use_screen The screen to use
- @return Zero on success
+ @param use_screen The screen to use
+ @param display:str? The display to use, `None` for the current
+ @return :int Zero on success
'''
- return blueshift_randr_open(use_screen)
+ cdef char* display_ = NULL
+ if display is not None:
+ display_ = display
+ return blueshift_randr_open(use_screen, display_)
def randr_read(int use_crtc):
diff --git a/src/blueshift_randr_c.c b/src/blueshift_randr_c.c
index 6a15715..0c99533 100644
--- a/src/blueshift_randr_c.c
+++ b/src/blueshift_randr_c.c
@@ -48,9 +48,10 @@ static blueshift_randr_crtc_t* crtcs_end;
* Start stage of colour curve control
*
* @param use_screen The screen to use
+ * @param display The display to use, `NULL` for the current one
* @return Zero on success
*/
-int blueshift_randr_open(int use_screen)
+int blueshift_randr_open(int use_screen, char* display)
{
blueshift_randr_crtc_t* crtcs_;
@@ -69,7 +70,7 @@ int blueshift_randr_open(int use_screen)
/* Get X connection */
- connection = xcb_connect(NULL, NULL);
+ connection = xcb_connect(display, NULL);
/* Check RandR protocol version */
diff --git a/src/blueshift_randr_c.h b/src/blueshift_randr_c.h
index 5bae1de..db12770 100644
--- a/src/blueshift_randr_c.h
+++ b/src/blueshift_randr_c.h
@@ -62,9 +62,10 @@ typedef struct blueshift_randr_crtc
* Start stage of colour curve control
*
* @param use_screen The screen to use
+ * @param display The display to use, `NULL` for the current one
* @return Zero on success
*/
-int blueshift_randr_open(int use_screen);
+int blueshift_randr_open(int use_screen, char* display);
/**
* Gets the current colour curves
diff --git a/src/blueshift_vidmode.pyx b/src/blueshift_vidmode.pyx
index 7f1810d..e4262d7 100644
--- a/src/blueshift_vidmode.pyx
+++ b/src/blueshift_vidmode.pyx
@@ -19,7 +19,7 @@ cimport cython
from libc.stdlib cimport malloc, free
-cdef extern int blueshift_vidmode_open(int use_screen)
+cdef extern int blueshift_vidmode_open(int use_screen, char* display)
cdef extern int blueshift_vidmode_read(int use_crtc,
unsigned short int* r_curve,
unsigned short int* g_curve,
@@ -46,15 +46,19 @@ if (r_c is NULL) or (g_c is NULL) or (b_c is NULL):
-def vidmode_open(int use_screen):
+def vidmode_open(int use_screen, display):
'''
Start stage of colour curve control
- @param use_screen The screen to use
- @return :bool Whether call was successful
+ @param use_screen The screen to use
+ @param display:str? The display to use, `None` for the current
+ @return :bool Whether call was successful
'''
global vidmode_gamma_size
- vidmode_gamma_size = blueshift_vidmode_open(use_screen)
+ cdef char* display_ = NULL
+ if display is not None:
+ display_ = display
+ vidmode_gamma_size = blueshift_vidmode_open(use_screen, display_)
return vidmode_gamma_size > 1
diff --git a/src/blueshift_vidmode_c.c b/src/blueshift_vidmode_c.c
index bd5efb5..b6d30f8 100644
--- a/src/blueshift_vidmode_c.c
+++ b/src/blueshift_vidmode_c.c
@@ -20,7 +20,7 @@
/**
* The X server display
*/
-static Display* display;
+static Display* connection;
/**
* The X screen
@@ -38,16 +38,17 @@ static int curve_size;
* Start stage of colour curve control
*
* @param use_screen The screen to use
+ * @param display The display to use, `NULL` for the current one
* @return Zero on error, otherwise the size of colours curves
*/
-int blueshift_vidmode_open(int use_screen)
+int blueshift_vidmode_open(int use_screen, char* display)
{
int _major, _minor;
/* Get X display */
- if ((display = XOpenDisplay(NULL)) == NULL)
+ if ((connection = XOpenDisplay(display)) == NULL)
{
fprintf(stderr, "Cannot open X display\n");
return 0;
@@ -56,10 +57,10 @@ int blueshift_vidmode_open(int use_screen)
/* Check for VidMode extension */
- if (XF86VidModeQueryVersion(display, &_major, &_minor) == 0)
+ if (XF86VidModeQueryVersion(connection, &_major, &_minor) == 0)
{
fprintf(stderr, "VidMode version query failed\n");
- XCloseDisplay(display);
+ XCloseDisplay(connection);
return 0;
}
@@ -67,17 +68,17 @@ int blueshift_vidmode_open(int use_screen)
/* Get curve's size on the encoding axis */
screen = use_screen;
- if (XF86VidModeGetGammaRampSize(display, screen, &curve_size) == 0)
+ if (XF86VidModeGetGammaRampSize(connection, screen, &curve_size) == 0)
{
fprintf(stderr, "VidMode gamma size query failed\n");
- XCloseDisplay(display);
+ XCloseDisplay(connection);
return 0;
}
if (curve_size <= 1)
{
fprintf(stderr, "VidMode gamma size query failed, impossible dimension\n");
- XCloseDisplay(display);
+ XCloseDisplay(connection);
return 0;
}
@@ -100,10 +101,10 @@ int blueshift_vidmode_read(int use_crtc, uint16_t* r_gamma, uint16_t* g_gamma, u
/* Read curves */
- if (XF86VidModeGetGammaRamp(display, screen, curve_size, r_gamma, g_gamma, b_gamma) == 0)
+ if (XF86VidModeGetGammaRamp(connection, screen, curve_size, r_gamma, g_gamma, b_gamma) == 0)
{
fprintf(stderr, "VidMode gamma query failed\n");
- XCloseDisplay(display);
+ XCloseDisplay(connection);
return 1;
}
@@ -126,7 +127,7 @@ int blueshift_vidmode_apply(uint64_t use_crtcs, uint16_t* r_curve, uint16_t* g_c
/* Apply curves */
- if (XF86VidModeSetGammaRamp(display, screen, curve_size, r_curve, g_curve, b_curve) == 0)
+ if (XF86VidModeSetGammaRamp(connection, screen, curve_size, r_curve, g_curve, b_curve) == 0)
{
fprintf(stderr, "VidMode gamma control failed\n");
return 1;
@@ -143,6 +144,6 @@ void blueshift_vidmode_close(void)
{
/* Free remaining resources */
- XCloseDisplay(display);
+ XCloseDisplay(connection);
}
diff --git a/src/blueshift_vidmode_c.h b/src/blueshift_vidmode_c.h
index c99f841..c94a297 100644
--- a/src/blueshift_vidmode_c.h
+++ b/src/blueshift_vidmode_c.h
@@ -31,9 +31,10 @@
* Start stage of colour curve control
*
* @param use_screen The screen to use
+ * @param display The display to use, `NULL` for the current one
* @return Zero on error, otherwise the size of colours curves
*/
-int blueshift_vidmode_open(int use_screen);
+int blueshift_vidmode_open(int use_screen, char* display);
/**
* Gets the current colour curves
diff --git a/src/monitor.py b/src/monitor.py
index 2f58999..36f9235 100644
--- a/src/monitor.py
+++ b/src/monitor.py
@@ -48,12 +48,12 @@ except:
randr_opened = None
'''
-:int? The index of the, with RandR, opened X screen, if any
+:(int, str)? The index of the, with RandR, opened X screen and X display, if any
'''
vidmode_opened = None
'''
-:int? The index of the, with vidmode, opened X screen, if any
+:(int, str)? The index of the, with vidmode, opened X screen and X display, if any
'''
@@ -76,61 +76,64 @@ def close_c_bindings():
drm_manager.close()
-def randr_get(crtc = 0, screen = 0):
+def randr_get(crtc = 0, screen = 0, display = None):
'''
Gets the current colour curves using the X11 extension RandR
- @param crtc:int The CRTC of the monitor to read from
- @param screen:int The screen that the monitor belong to
- @return :()→void Function to invoke to apply the curves that was used when this function was invoked
+ @param crtc:int The CRTC of the monitor to read from
+ @param screen:int The screen to which the monitors belong
+ @param display:str? The display to which to connect, `None` for current display
+ @return :()→void Function to invoke to apply the curves that was used when this function was invoked
'''
from blueshift_randr import randr_open, randr_read, randr_close
global randr_opened
- # Open new RandR connection if non is open or one is open to the wrong screen
- if (randr_opened is None) or not (randr_opened == screen):
- # Close RandR connection, if any, because its is connected to the wrong screen
+ # Open new RandR connection if non is open or one is open to the wrong screen or display
+ if (randr_opened is None) or not (randr_opened == (screen, display)):
+ # Close RandR connection, if any, because its is connected to the wrong screen or display
if randr_opened is not None:
randr_close()
# Open RandR connection
- if randr_open(screen) == 0:
- randr_opened = screen
+ if randr_open(screen, display) == 0:
+ randr_opened = (screen, display)
else:
raise Exception('Cannot open RandR connection')
# Read current curves and create function
return ramps_to_function(*(randr_read(crtc)))
-def vidmode_get(crtc = 0, screen = 0):
+def vidmode_get(crtc = 0, screen = 0, display = None):
'''
Gets the current colour curves using the X11 extension VidMode
- @param crtc:int The CRTC of the monitor to read from
- @param screen:int The screen that the monitor belong to
- @return :()→void Function to invoke to apply the curves that was used when this function was invoked
+ @param crtc:int The CRTC of the monitor to read from
+ @param screen:int The screen to which the monitors belong
+ @param display:str? The display to which to connect, `None` for current display
+ @return :()→void Function to invoke to apply the curves that was used when this function was invoked
'''
from blueshift_vidmode import vidmode_open, vidmode_read, vidmode_close
global vidmode_opened
- # Open new vidmode connection if non is open or one is open to the wrong screen
- if (vidmode_opened is None) or not (vidmode_opened == screen):
- # Close vidmode connection, if any, because its is connected to the wrong screen
+ # Open new vidmode connection if non is open or one is open to the wrong screen or display
+ if (vidmode_opened is None) or not (vidmode_opened == (screen, display)):
+ # Close vidmode connection, if any, because its is connected to the wrong screen or display
if vidmode_opened is not None:
vidmode_close()
# Open vidmode connection
- if vidmode_open(screen):
- vidmode_opened = screen
+ if vidmode_open(screen, display):
+ vidmode_opened = (screen, display)
else:
raise Exception('Cannot open vidmode connection')
# Read current curves and create function
return ramps_to_function(*(vidmode_read(crtc)))
-def drm_get(crtc = 0, screen = 0):
+def drm_get(crtc = 0, screen = 0, display = None):
'''
Gets the current colour curves using DRM
- @param crtc:int The CRTC of the monitor to read from
- @param screen:int The graphics card that the monitor belong to, named `screen` for compatibility with randr_get and vidmode_get
- @return :()→void Function to invoke to apply the curves that was used when this function was invoked
+ @param crtc:int The CRTC of the monitor to read from
+ @param screen:int The graphics card to which the monitors belong, named `screen` for compatibility with `randr_get` and `vidmode_get`
+ @param display:str? Dummy parameter for compatibility with `randr_get` and `vidmode_get`
+ @return :()→void Function to invoke to apply the curves that was used when this function was invoked
'''
# Get DRM connection, open if necessary
connection = drm_manager.open_card(screen)
@@ -138,12 +141,13 @@ def drm_get(crtc = 0, screen = 0):
return ramps_to_function(*(drm_get_gamma_ramps(connection, crtc, i_size)))
-def randr(*crtcs, screen = 0):
+def randr(*crtcs, screen = 0, display = None):
'''
Applies colour curves using the X11 extension RandR
- @param crtcs:*int The CRT controllers to use, all are used if none are specified
- @param screen:int The screen that the monitors belong to
+ @param crtcs:*int The CRT controllers to use, all are used if none are specified
+ @param screen:int The screen to which the monitors belong
+ @param display:str? The display to which to connect, `None` for current display
'''
from blueshift_randr import randr_open, randr_apply, randr_close
global randr_opened
@@ -152,14 +156,14 @@ def randr(*crtcs, screen = 0):
# Convert curves to [0, 0xFFFF] integer lists
(R_curve, G_curve, B_curve) = translate_to_integers()
- # Open new RandR connection if non is open or one is open to the wrong screen
- if (randr_opened is None) or not (randr_opened == screen):
- # Close RandR connection, if any, because its is connected to the wrong screen
+ # Open new RandR connection if non is open or one is open to the wrong screen or display
+ if (randr_opened is None) or not (randr_opened == (screen, display)):
+ # Close RandR connection, if any, because its is connected to the wrong screen or display
if randr_opened is not None:
randr_close()
# Open RandR connection
- if randr_open(screen) == 0:
- randr_opened = screen
+ if randr_open(screen, display) == 0:
+ randr_opened = (screen, display)
else:
raise Exception('Cannot open RandR connection')
try:
@@ -170,12 +174,13 @@ def randr(*crtcs, screen = 0):
pass # Happens on exit by TERM signal
-def vidmode(*crtcs, screen = 0):
+def vidmode(*crtcs, screen = 0, display = None):
'''
Applies colour curves using the X11 extension VidMode
- @param crtcs:*int The CRT controllers to use, all are used if none are specified
- @param screen:int The screen that the monitors belong to
+ @param crtcs:*int The CRT controllers to use, all are used if none are specified
+ @param screen:int The screen to which the monitors belong
+ @param display:str? The display to which to connect, `None` for current display
'''
from blueshift_vidmode import vidmode_open, vidmode_apply, vidmode_close
global vidmode_opened
@@ -184,14 +189,14 @@ def vidmode(*crtcs, screen = 0):
# Convert curves to [0, 0xFFFF] integer lists
(R_curve, G_curve, B_curve) = translate_to_integers()
- # Open new vidmode connection if non is open or one is open to the wrong screen
- if (vidmode_opened is None) or not (vidmode_opened == screen):
- # Close vidmode connection, if any, because its is connected to the wrong screen
+ # Open new vidmode connection if non is open or one is open to the wrong screen or display
+ if (vidmode_opened is None) or not (vidmode_opened == (screen, display)):
+ # Close vidmode connection, if any, because its is connected to the wrong screen or display
if vidmode_opened is not None:
vidmode_close()
# Open vidmode connection
- if vidmode_open(screen):
- vidmode_opened = screen
+ if vidmode_open(screen, display):
+ vidmode_opened = (screen, display)
else:
raise Exception('Cannot open vidmode connection')
try:
@@ -202,12 +207,14 @@ def vidmode(*crtcs, screen = 0):
pass # Happens on exit by TERM signal
-def drm(*crtcs, screen = 0):
+def drm(*crtcs, screen = 0, display = None):
'''
Applies colour curves using DRM
- @param crtcs:*int The CRT controllers to use, all are used if none are specified
- @param screen:int The card that the monitors belong to, named `screen` for compatibility with randr_get and vidmode_get
+ @param crtcs:*int The CRT controllers to use, all are used if none are specified
+ @param screen:int The graphics card to which the monitors belong,
+ named `screen` for compatibility with `randr` and `vidmode`
+ @param display:str? Dummy parameter for compatibility with `randr` and `vidmode`
'''
# Get DRM connection, open if necessary
connection = drm_manager.open_card(screen)