summaryrefslogtreecommitdiff
path: root/spectro/dispwin.h
blob: 47fd2566097d68ef7cfa23d23e52c14354a0da9b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437

#ifndef DISPWIN_H

/* 
 * Argyll Color Correction System
 * Display target patch window
 *
 * Author: Graeme W. Gill
 * Date:   4/10/96
 *
 * Copyright 1998 - 2013 Graeme W. Gill
 * All rights reserved.
 *
 * This material is licenced under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 :-
 * see the License.txt file for licencing details.
 */

/*
 * Hmm. Should make display settling time a user overridable parameter,
 * to allow for very fast response displays such as oled ?
 */

#define PATCH_UPDATE_DELAY 200		/* default & minimum patch update delay allowance */
#define INSTRUMENT_REACTIONTIME 0	/* default nominal instrument reaction time */

/* Display rise and fall time model. This is CRT like */
#define DISPLAY_RISE_TIME 0.04		/* Assumed rise time to 90% of target level */ 
#define DISPLAY_FALL_TIME 0.25		/* Assumed fall time to 90% of target level */
#define DISPLAY_SETTLE_AIM 0.1		/* Aim for 0.2 Delta E */

#ifdef NT
#define OEMRESOURCE
#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0501
#define _WIN32_WINNT 0x0501
#endif
#if !defined(WINVER) || WINVER < 0x0501
#if defined(WINVER)
# undef WINVER
#endif
#define WINVER 0x0501
#endif
#include <windows.h>
#include <icm.h>

#if(WINVER < 0x0500)
#error Require WINVER >= 0x500 to compile (multi-monitor API needed)
#endif

#ifndef COLORMGMTCAPS	/* In case SDK is out of date */

#define COLORMGMTCAPS   121

#define CM_NONE             0x00000000
#define CM_DEVICE_ICM       0x00000001
#define CM_GAMMA_RAMP       0x00000002
#define CM_CMYK_COLOR       0x00000004

#endif	/* !COLORMGMTCAPS */

/* Avoid shlwapi.h - there are problems in using it in latter SDKs */
#ifndef WINSHLWAPI
#define WINSHLWAPI DECLSPEC_IMPORT
#endif

WINSHLWAPI LPSTR WINAPI PathFindFileNameA(LPCSTR);
WINSHLWAPI LPWSTR WINAPI PathFindFileNameW(LPCWSTR);

#ifdef UNICODE
#define PathFindFileNameX PathFindFileNameW
#else
#define PathFindFileNameX PathFindFileNameA
#endif

#endif /* NT */

#ifdef UNIX_APPLE	/* Assume OS X Cocoa */

#include <Carbon/Carbon.h>		/* To declare CGDirectDisplayID  */

#endif /* UNIX_APPLE */

#if defined(UNIX_X11)
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/extensions/xf86vmode.h>
#include <X11/extensions/dpms.h>
#include <X11/extensions/Xinerama.h>
#include <X11/extensions/Xrandr.h>
#include <X11/extensions/scrnsaver.h>
#include <X11/extensions/dpms.h>
#endif /* UNIX_X11 */

/* - - - - - - - - - - - - - - - - - - - - - - - */

/* Profile instalation/association scope */
typedef enum {
	p_scope_user     = 0,		/* (user profiles) Linux, OS X & Vista */
	p_scope_local    = 1,		/* (local system profiles) Linux, OS X & vista */
	p_scope_system   = 2,		/* (system supplied profiles) OS X. [ Linux, Vista same as local ] */
	p_scope_network  = 3		/* (shared network profiles) [ OS X. Linux, Vista same as local ] */
} p_scope;

/* - - - - - - - - - - - - - - - - - - - - - - - */
/* Enumerate and list all the available displays */

/* Structure to store infomation about possible displays */
typedef struct {
	char *name;			/* Display name */
	char *description;	/* Description of display or URL */
	int sx,sy;			/* Displays offset in pixels */
	int sw,sh;			/* Displays width and height in pixels*/
#ifdef NT
	char monid[128];	/* Monitor ID */
	int prim;			/* NZ if primary display monitor */
#endif /* NT */
#ifdef UNIX_APPLE
	CGDirectDisplayID ddid;
#endif /* UNIX_APPLE */
#if defined(UNIX_X11)
	int screen;				/* Screen to select */
	int uscreen;			/* Underlying screen */
	int rscreen;			/* Underlying RAMDAC screen */
	Atom icc_atom;			/* ICC profile root atom for this display */
	unsigned char *edid;	/* 128 or 256 bytes of monitor EDID, NULL if none */
	int edid_len;			/* 128 or 256 */

#if RANDR_MAJOR == 1 && RANDR_MINOR >= 2
	/* Xrandr stuff - output is connected 1:1 to a display */
	RRCrtc crtc;				/* Associated crtc */
	RROutput output;			/* Associated output */
	Atom icc_out_atom;			/* ICC profile atom for this output */
#endif /* randr >= V 1.2 */
#endif /* UNIX_X11 */
} disppath;

/* Return pointer to list of disppath. Last will be NULL. */
/* Return NULL on failure. */
/* Call free_disppaths() to free up allocation */
disppath **get_displays();

void free_disppaths(disppath **paths);

/* Delete the display at the given index from the paths */
void del_disppath(disppath **paths, int ix);

/* Return the given display given its index 0..n-1 */
disppath *get_a_display(int ix);

void free_a_disppath(disppath *path);

extern int callback_ddebug;		/* Diagnostic global for get_displays() and get_a_display() */  

/* - - - - - - - - - - - - - - - - - - - - - - - */
/* Structure to handle RAMDAC values */
struct _ramdac {

	/* Should have separate frame buffer depth + representation to account */
	/* for floating point frame buffers, even though this isn't currently used. */

	int fdepth;		/* Frame buffer depth, typically 8, could be more. */
	int rdepth;		/* Expected ramdac index depth. May be different to fdepth */
					/* if there is another level of mapping between the frame buffer */
					/* and ramdac, i.e. X11 DirectorColor Colormap. */

	int ndepth;		/* Actual ramdac depth, typically = rdepth */
	int nent;		/* Number of entries, = 2^ndepth, typically = 2^rdepth, */
					/* but may be different for some video cards. */
					/* Will be 0 if ramdac is not accessible */
					
	double *v[3];	/* nent entries for RGB, values 0.0 - 1.0 */

	/* Clone ourselves */
	struct _ramdac *(*clone)(struct _ramdac *p);

	/* Set the curves to linear */
	void (*setlin)(struct _ramdac *p);

	/* Destroy ourselves */
	void (*del)(struct _ramdac *p);
}; typedef struct _ramdac ramdac;


/* - - - - - - - - - - - - - - - - - - - - - - - */
/* Dispwin object */
/* This is used by all the different test patch window types, */
/* dispwin, webwin, madvrwin and ccwin. */
/* !!!! Make changes in dispwin.c, webwin.c, madvrwin.c & ccwin.c !!!!  */
/* !!!! if this structure gets changed. !!!! */

/* Full screen background handling */
typedef enum {
	dw_bg_black   = 0,		/* Black background */
	dw_bg_grey    = 1,		/* Grey background */
	dw_bg_cvideo  = 2,		/* Constant Average Video background */
	dw_bg_clight  = 3		/* Constant Average Light background */
} dw_bg_type;

struct _dispwin {

/* private: */
	char *name;			/* Display path (ie. '\\.\DISPLAY1') */
						/* or "10.0.0.1:0.0" */
	char *description;	/* Description of display */

	/* Plot instance information */
	int sx,sy;			/* Screen offset in pixels */
	int sw,sh;			/* Screen width and height in pixels*/
	int ww,wh;			/* Window width and height */
	int tx,ty;			/* Test area within window offset in pixels */
	int tw,th;			/* Test area width and height in pixels */

	double rgb[3];		/* Current color (full resolution, full range) */
	double s_rgb[3];	/* Current color (possibly scaled range) */
	double r_rgb[3];	/* Current color (raster value) */
	int out_tvenc;		/* 1 to use RGB Video Level encoding */
	int patch_delay;	/* Measured patch update latency delay in msec, default 200 */
	int inst_reaction;	/* Measured instrument reaction time delay in msec, default 0 */
	double rise_time;	/* Display settling rise time */
	double fall_time;	/* Display settling fall time */
	double de_aim;		/* Display settling deltaE aim */
	int min_update_delay;	/* Minimum overall update latency delay, default 20, */
							/* overriden by EnvVar */
	double settle_mult;	/* Settling time multiplier */
	int do_resp_time_del;	/* NZ to compute and use expected display response time */
	int do_update_del;		/* NZ to do update delay */ 
	double extra_update_delay;	/* Test window internal extra delay (used in delay cal.) */
	int nowin;			/* Don't create a test window */
	int native;			/*  X0 = use current per channel calibration curve */
						/*  X1 = set native linear output and use ramdac high precision */
						/*  0X = use current color management cLut (MadVR) */
						/*  1X = disable color management cLUT (MadVR) */
	ramdac *oor;		/* Original orgininal ramdac contents, NULL if not accessible */
	ramdac *or;			/* Original ramdac contents, NULL if not accessible, restored on exit */
	ramdac *r;			/* Ramdac in use for native mode or general use */
	double width, height;	/* Orginial size in mm or % */
	int fullscreen;		/* NZ if full screen background (default black) */
	dw_bg_type bge;		/* Full screen background color (ccwin only) */
	double area;		/* Patch area for bge calc 0..1 */

	char *callout;		/* if not NULL - set color Shell callout routine */

	/* Linked list to automate SIGKILL cleanup */
	struct _dispwin *next;

#ifdef NT
	char monid[128];	/* Monitor ID (ie. 'Monitor\MEA1773\{4D36E96E-E325-11CE-BFC1-08002BE10318}\0015'*/
	HDC hdc;			/* Handle to display */
	char *AppName;
	HWND hwnd;			/* Window handle */
	HCURSOR curs;		/* Invisible cursor */
	
	MSG msg;
	ATOM arv;

	int xo, yo, wi, he;	/* Window location & size */
	athread *mth;		/* Window message thread */
	int inited;
	int quit;			/* Request to quit */

	volatile int colupd;		/* Color update count */
	volatile int colupde;		/* Color update count echo */

#endif /* NT */

#ifdef UNIX_APPLE
	CGDirectDisplayID ddid;
	void *osx_cntx;			/* OSX specific info */	
	int btf;				/* Flag, nz if window has been brought to the front once */
	int winclose;			/* Flag, set to nz if window was closed */
#endif /* UNIX_APPLE */

#if defined(UNIX_X11)
	Display *mydisplay;
	int myscreen;			/* Usual or virtual screen with Xinerama */
	int myuscreen;			/* Underlying screen */
	int myrscreen;			/* Underlying RAMDAC screen */
	Atom icc_atom;			/* ICC profile root atom for this display */
	unsigned char *edid;	/* 128 or 256 bytes of monitor EDID, NULL if none */
	int edid_len;			/* 128 or 256 */

	int shift[3];			/* Bit shift to create RGB value from components */
	int *rmap[3];			/* Map of fdepth to rdepth values */

#if RANDR_MAJOR == 1 && RANDR_MINOR >= 2
	/* Xrandr stuff - output is connected 1:1 to a display */
	RRCrtc crtc;				/* Associated crtc */
	RROutput output;			/* Associated output */
	Atom icc_out_atom;			/* ICC profile atom for this output */
#endif /* randr >= V 1.2 */

	/* Test window access */
	Window mywindow;
	GC mygc;

    /* Screensaver state */
	int xsssuspend;				/* Was able to suspend the screensaver using XScreenSaverSuspend */

	int xssvalid;				/* Was able to save & disable X screensaver using XSetScreenSaver */
	int timeout, interval;
	int prefer_blanking;
	int allow_exposures;

	int xssrunning;				/* Disabled xscreensaver */

	int gnomessrunning;			/* Disabled gnome screensaver and is was enabled */
	pid_t gnomepid;				/* gnome-screensaver-command -i pid */

	int kdessrunning;			/* Disabled kde screensaver and is was enabled */

	int dpmsenabled;			/* DPMS is enabled */
	
#endif /* UNIX_X11 */

	void *pcntx;				/* Private context (ie., webwin, ccwin) */
	volatile unsigned int ncix, ccix;	/* Counters to trigger webwin colorchange */
	volatile int mg_stop;				/* Stop flag */

	volatile int cberror;		/* NZ if error detected in a callback routine */
	int ddebug;					/* >0 to print debug to stderr */

	int warned;		/* Warning message has been issued */

/* public: */
	int fdepth;		/* Frame buffer depth, typically 8, could be more */
	int rdepth;		/* Expected ramdac index depth. May be different to fdepth */
					/* if there is another level of mapping between the frame buffer */
					/* and ramdac, i.e. X11 DirectorColor Colormap. */

	int ndepth;		/* Actual ramdac depth, typically = rdepth */
	int nent;		/* Number of entries, = s^ndepth, typically = 2^rdepth, */
					/* but may be different for some video cards. */
					/* Will be 0 if ramdac is not accessible */
					
	int edepth;		/* Notional frame buffer/ramdac entry size in bits. (Bits actually used  */
					/* may be less). This is just used to scale out_tvenc appropriately. */

	/* Get RAMDAC values. ->del() when finished. */
	/* Return NULL if not possible */
	ramdac *(*get_ramdac)(struct _dispwin *p);

	/* Set the RAMDAC values. */
	/* Return nz if not possible */
	int (*set_ramdac)(struct _dispwin *p, ramdac *r, int persist);

	/* Install a display profile and make */
	/* it the defult for this display. */
	/* Return nz if failed */
	int (*install_profile)(struct _dispwin *p, char *fname, ramdac *r, p_scope scope);

	/* Un-install a display profile. */
	/* Return nz if failed */
	int (*uninstall_profile)(struct _dispwin *p, char *fname, p_scope scope);

	/* Get the currently installed display profile and return it as an icmFile. */
	/* Return the name as well, up to mxlen chars, excluding nul. */
	/* Return NULL if failed */
	icmFile *(*get_profile)(struct _dispwin *p, char *name, int mxlen);

	/* Set a color (values 0.0 - 1.0) */
	/* Return nz on error */
	int (*set_color)(struct _dispwin *p, double r, double g, double b);

	/* Set/unset the fullscreen black flag. */
	/* Will only change on next set_col() */
	/* Return nz on error */
	int (*set_fc)(struct _dispwin *p, int fullscreen);

	/* Change the patch display parameters. */
	/* Optional - may be NULL */
	int (*set_patch_win)(struct _dispwin *p, 
		double hoff, double voff,		/* Offset from c. in fraction of screen, -1.0 .. 1.0 */
		double area,					/* Patch area 0..1 */
		dw_bg_type bge					/* Background */  
	);

	/* set patch user info */
	/* Return nz on error */
	int (*set_pinfo)(struct _dispwin *p, int pno, int tno);

	/* Set a patch delay and instrument reaction time values. */
	/* The overall delay between patch change and triggering */
	/* the instrument is (patch_delay + display_settle - inst_reaction) */
	/* and will never be less than the min_update_delay value. */
	void (*set_update_delay)(struct _dispwin *p, int patch_delay, int inst_reaction);

	/* Set the display settling time constants. Use -ve value to leave current value */
	/* unchanged. (These values are used as part of the update delay calculations - see above). */
	void (*set_settling_delay)(struct _dispwin *p, double rise_time, double fall_time, double de_aim);

	/* Enable or disable the update delay. This is used to disable the update delay */
	/* when measuring the patch_delay and inst_reaction */
	void (*enable_update_delay)(struct _dispwin *p, int enable);

	/* Set a shell set color callout command line */
	void (*set_callout)(struct _dispwin *p, char *callout);


	/* Destroy ourselves */
	void (*del)(struct _dispwin *p);

}; typedef struct _dispwin dispwin;

/* Create a RAMDAC access and display test window, default white */
dispwin *new_dispwin(
	disppath *screen,				/* Screen to calibrate. */
	double width, double height,	/* Width and height in mm */
	double hoff, double voff,		/* Offset from c. in fraction of screen, range -1.0 .. 1.0 */
	int nowin,						/* NZ if no window should be created - RAMDAC access only */
	int native,						/* X0 = use current per channel calibration curve */
									/* X1 = set native linear output and use ramdac high precn. */
									/* 0X = use current color management cLut (MadVR) */
									/* 1X = disable color management cLUT (MadVR) */
	int *noramdac,					/* Return nz if no ramdac access. native is set to X0 */
	int *nocm,						/* Return nz if no CM cLUT access. native is set to 0X */
	int out_tvenc,					/* 1 = use RGB Video Level encoding */
	int fullscreen,					/* NZ if whole screen should be filled with black */
	int override,					/* NZ if override_redirect is to be used on X11 */
	int ddebug						/* >0 to print debug statements to stderr */
);

/* Shared implementation */
void dispwin_set_default_delays(dispwin *p);
void dispwin_set_update_delay(dispwin *p, int patch_delay, int inst_reaction);
void dispwin_set_settling_delay(dispwin *p, double rise_time, double fall_time, double de_aim);
void dispwin_enable_update_delay(dispwin *p, int enable);
int dispwin_compute_delay(dispwin *p, double *orgb);

ramdac *dispwin_clone_ramdac(ramdac *r);
void dispwin_setlin_ramdac(ramdac *r);
void dispwin_del_ramdac(ramdac *r);



#define DISPWIN_H
#endif /* DISPWIN_H */