From d567bb3e0f402eb3ff2d1b0d9615bef85efd405e Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Mon, 10 Mar 2014 23:27:04 +0100 Subject: _icc_profile atom support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- info/blueshift.texinfo | 22 +++++++++++++++++++ src/blueshift_iccprofile.c | 15 +++++++------ src/icc.py | 53 +++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 78 insertions(+), 12 deletions(-) diff --git a/info/blueshift.texinfo b/info/blueshift.texinfo index 48cd214..bbd59d0 100644 --- a/info/blueshift.texinfo +++ b/info/blueshift.texinfo @@ -694,6 +694,28 @@ profile file. @code{load_icc} takes one argument, the pathname of the ICC profile file; the function returns a fuction that can be invoked to apply the profile. +Alternatively, you can use either of the functions: + +@table @code +@item parse_icc(data) +Parse raw (series of bytes) ICC profile data into a function +that applies the profile when invoked. + +@item get_current_icc_raw() +Load the raw data for the currently applied ICC profiles, +stored on the X server. This function returns a list of +3-tuples, each tuple contains the index of a screen, +the index of a monitor and the raw data (series of bytes) +of the ICC profile for indicated monitor on the indicated +screen. Monitors without profiles are not listed. + +@item get_current_icc() +This function works like @code{get_current_icc_raw}, except +rather than returning raw profile data it returns functions +that apply the profiles when invoked. + +@end table + If you want to apply your adjustments on top of the current colour adjustments, you can use the functions @code{randr_get} or @code{vidmode_get}. @code{randr_get} diff --git a/src/blueshift_iccprofile.c b/src/blueshift_iccprofile.c index 152b547..688b335 100644 --- a/src/blueshift_iccprofile.c +++ b/src/blueshift_iccprofile.c @@ -184,16 +184,17 @@ int main(int argc, char** argv) } { - char* value = alloca((len + 1) * sizeof(char)); + char* value = alloca((2 * len + 1) * sizeof(char)); char* value_ = xcb_get_property_value(prop_reply); - memcpy(value, value_, len); - *(value + len) = 0; + for (i = 0; i < len; i++) + { + *(value + i * 2 + 0) = "0123456789abcdef"[(*(value_ + i) >> 4) & 15]; + *(value + i * 2 + 1) = "0123456789abcdef"[(*(value_ + i) >> 0) & 15]; + } + *(value + 2 * len) = 0; - printf("%i: %i: %s", screen_i, monitor, value); - fflush(stdout); - putchar('\0'); - putchar('\n'); + printf("%i: %i: %s\n", screen_i, monitor, value); } free(prop_reply); diff --git a/src/icc.py b/src/icc.py index fbd7bdc..8e0dd14 100644 --- a/src/icc.py +++ b/src/icc.py @@ -15,6 +15,8 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +from subprocess import Popen, PIPE + from curve import * @@ -22,8 +24,52 @@ def load_icc(pathname): ''' Load ICC profile from a file - @param pathname The ICC profile file - @return Function to invoke, parameterless, to apply the ICC profile to the colour curves + @param pathname:str The ICC profile file + @return :()→void Function to invoke, parameterless, to apply the ICC profile to the colour curves + ''' + content = None + with open(pathname, 'rb') as file: + content = file.read() + return content + + +def get_current_icc(): + ''' + Get all currently applied ICC profiles as profile applying functions + + @return list<(screen:int, monitor:int, profile:()→void)> List of used profiles + ''' + return [(screen, monitor, parse_icc(profile)) for screen, monitor, profile in get_current_icc_raw()] + + +def get_current_icc_raw(): + ''' + Get all currently applied ICC profiles as raw profile data + + @return list<(screen:int, monitor:int, profile:bytes())> List of used profiles + ''' + process = Popen([LIBEXECDIR + "/blueshift_iccprofile"], stdout = PIPE) + lines = process.communicate()[0].decode('utf-8', 'error').split('\n') + while process.returncode is None: + process.wait() + if process.returncode != 0: + raise Exception('blueshift_iccprofile exited with value %i' % process.returncode) + rc = [] + for line in lines: + if len(line) == 0: + continue + (s, m, p) = lines.split(': ') + p = bytes([int(p[i : i + 2], 16) for i in range(0, len(p), 2)]) + rc.append((s, m, p)) + return rc + + +def parse_icc(content): + ''' + Parse ICC profile from raw data + + @param content:bytes The ICC profile data + @return :()→void Function to invoke, parameterless, to apply the ICC profile to the colour curves ''' MLUT_TAG = 0x6d4c5554 VCGT_TAG = 0x76636774 @@ -42,9 +88,6 @@ def load_icc(pathname): rc, content[:] = content[:n], content[n:] return rc - content = None - with open(pathname, 'rb') as file: - content = file.read() content = list(content) read(128) -- cgit v1.2.3-70-g09d2