1 2 #ifndef DISPWIN_H 3 4 /* 5 * Argyll Color Correction System 6 * Display target patch window 7 * 8 * Author: Graeme W. Gill 9 * Date: 4/10/96 10 * 11 * Copyright 1998 - 2013 Graeme W. Gill 12 * All rights reserved. 13 * 14 * This material is licenced under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 :- 15 * see the License.txt file for licencing details. 16 */ 17 18 /* 19 * Hmm. Should make display settling time a user overridable parameter, 20 * to allow for very fast response displays such as oled ? 21 */ 22 23 #define PATCH_UPDATE_DELAY 200 /* default & minimum patch update delay allowance */ 24 #define INSTRUMENT_REACTIONTIME 0 /* default nominal instrument reaction time */ 25 26 /* Display rise and fall time model. This is CRT like */ 27 #define DISPLAY_RISE_TIME 0.04 /* Assumed rise time to 90% of target level */ 28 #define DISPLAY_FALL_TIME 0.25 /* Assumed fall time to 90% of target level */ 29 #define DISPLAY_SETTLE_AIM 0.1 /* Aim for 0.2 Delta E */ 30 31 #ifdef NT 32 #define OEMRESOURCE 33 #if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0501 34 #define _WIN32_WINNT 0x0501 35 #endif 36 #if !defined(WINVER) || WINVER < 0x0501 37 #if defined(WINVER) 38 # undef WINVER 39 #endif 40 #define WINVER 0x0501 41 #endif 42 #include <windows.h> 43 #include <icm.h> 44 45 #if(WINVER < 0x0500) 46 #error Require WINVER >= 0x500 to compile (multi-monitor API needed) 47 #endif 48 49 #ifndef COLORMGMTCAPS /* In case SDK is out of date */ 50 51 #define COLORMGMTCAPS 121 52 53 #define CM_NONE 0x00000000 54 #define CM_DEVICE_ICM 0x00000001 55 #define CM_GAMMA_RAMP 0x00000002 56 #define CM_CMYK_COLOR 0x00000004 57 58 #endif /* !COLORMGMTCAPS */ 59 60 /* Avoid shlwapi.h - there are problems in using it in latter SDKs */ 61 #ifndef WINSHLWAPI 62 #define WINSHLWAPI DECLSPEC_IMPORT 63 #endif 64 65 WINSHLWAPI LPSTR WINAPI PathFindFileNameA(LPCSTR); 66 WINSHLWAPI LPWSTR WINAPI PathFindFileNameW(LPCWSTR); 67 68 #ifdef UNICODE 69 #define PathFindFileNameX PathFindFileNameW 70 #else 71 #define PathFindFileNameX PathFindFileNameA 72 #endif 73 74 #endif /* NT */ 75 76 #ifdef UNIX_APPLE /* Assume OS X Cocoa */ 77 78 #include <Carbon/Carbon.h> /* To declare CGDirectDisplayID */ 79 80 #endif /* UNIX_APPLE */ 81 82 #if defined(UNIX_X11) 83 #include <X11/Xlib.h> 84 #include <X11/Xutil.h> 85 #include <X11/Xatom.h> 86 #include <X11/extensions/xf86vmode.h> 87 #include <X11/extensions/dpms.h> 88 #include <X11/extensions/Xinerama.h> 89 #include <X11/extensions/Xrandr.h> 90 #include <X11/extensions/scrnsaver.h> 91 #include <X11/extensions/dpms.h> 92 #endif /* UNIX_X11 */ 93 94 /* - - - - - - - - - - - - - - - - - - - - - - - */ 95 96 /* Profile instalation/association scope */ 97 typedef enum { 98 p_scope_user = 0, /* (user profiles) Linux, OS X & Vista */ 99 p_scope_local = 1, /* (local system profiles) Linux, OS X & vista */ 100 p_scope_system = 2, /* (system supplied profiles) OS X. [ Linux, Vista same as local ] */ 101 p_scope_network = 3 /* (shared network profiles) [ OS X. Linux, Vista same as local ] */ 102 } p_scope; 103 104 /* - - - - - - - - - - - - - - - - - - - - - - - */ 105 /* Enumerate and list all the available displays */ 106 107 /* Structure to store infomation about possible displays */ 108 typedef struct { 109 char *name; /* Display name */ 110 char *description; /* Description of display or URL */ 111 int sx,sy; /* Displays offset in pixels */ 112 int sw,sh; /* Displays width and height in pixels*/ 113 #ifdef NT 114 char monid[128]; /* Monitor ID */ 115 int prim; /* NZ if primary display monitor */ 116 #endif /* NT */ 117 #ifdef UNIX_APPLE 118 CGDirectDisplayID ddid; 119 #endif /* UNIX_APPLE */ 120 #if defined(UNIX_X11) 121 int screen; /* Screen to select */ 122 int uscreen; /* Underlying screen */ 123 int rscreen; /* Underlying RAMDAC screen */ 124 Atom icc_atom; /* ICC profile root atom for this display */ 125 unsigned char *edid; /* 128 or 256 bytes of monitor EDID, NULL if none */ 126 int edid_len; /* 128 or 256 */ 127 128 #if RANDR_MAJOR == 1 && RANDR_MINOR >= 2 129 /* Xrandr stuff - output is connected 1:1 to a display */ 130 RRCrtc crtc; /* Associated crtc */ 131 RROutput output; /* Associated output */ 132 Atom icc_out_atom; /* ICC profile atom for this output */ 133 #endif /* randr >= V 1.2 */ 134 #endif /* UNIX_X11 */ 135 } disppath; 136 137 /* Return pointer to list of disppath. Last will be NULL. */ 138 /* Return NULL on failure. */ 139 /* Call free_disppaths() to free up allocation */ 140 disppath **get_displays(); 141 142 void free_disppaths(disppath **paths); 143 144 /* Delete the display at the given index from the paths */ 145 void del_disppath(disppath **paths, int ix); 146 147 /* Return the given display given its index 0..n-1 */ 148 disppath *get_a_display(int ix); 149 150 void free_a_disppath(disppath *path); 151 152 extern int callback_ddebug; /* Diagnostic global for get_displays() and get_a_display() */ 153 154 /* - - - - - - - - - - - - - - - - - - - - - - - */ 155 /* Structure to handle RAMDAC values */ 156 struct _ramdac { 157 158 /* Should have separate frame buffer depth + representation to account */ 159 /* for floating point frame buffers, even though this isn't currently used. */ 160 161 int fdepth; /* Frame buffer depth, typically 8, could be more. */ 162 int rdepth; /* Expected ramdac index depth. May be different to fdepth */ 163 /* if there is another level of mapping between the frame buffer */ 164 /* and ramdac, i.e. X11 DirectorColor Colormap. */ 165 166 int ndepth; /* Actual ramdac depth, typically = rdepth */ 167 int nent; /* Number of entries, = 2^ndepth, typically = 2^rdepth, */ 168 /* but may be different for some video cards. */ 169 /* Will be 0 if ramdac is not accessible */ 170 171 double *v[3]; /* nent entries for RGB, values 0.0 - 1.0 */ 172 173 /* Clone ourselves */ 174 struct _ramdac *(*clone)(struct _ramdac *p); 175 176 /* Set the curves to linear */ 177 void (*setlin)(struct _ramdac *p); 178 179 /* Destroy ourselves */ 180 void (*del)(struct _ramdac *p); 181 }; typedef struct _ramdac ramdac; 182 183 184 /* - - - - - - - - - - - - - - - - - - - - - - - */ 185 /* Dispwin object */ 186 /* This is used by all the different test patch window types, */ 187 /* dispwin, webwin, madvrwin and ccwin. */ 188 /* !!!! Make changes in dispwin.c, webwin.c, madvrwin.c & ccwin.c !!!! */ 189 /* !!!! if this structure gets changed. !!!! */ 190 191 /* Full screen background handling */ 192 typedef enum { 193 dw_bg_black = 0, /* Black background */ 194 dw_bg_grey = 1, /* Grey background */ 195 dw_bg_cvideo = 2, /* Constant Average Video background */ 196 dw_bg_clight = 3 /* Constant Average Light background */ 197 } dw_bg_type; 198 199 struct _dispwin { 200 201 /* private: */ 202 char *name; /* Display path (ie. '\\.\DISPLAY1') */ 203 /* or "10.0.0.1:0.0" */ 204 char *description; /* Description of display */ 205 206 /* Plot instance information */ 207 int sx,sy; /* Screen offset in pixels */ 208 int sw,sh; /* Screen width and height in pixels*/ 209 int ww,wh; /* Window width and height */ 210 int tx,ty; /* Test area within window offset in pixels */ 211 int tw,th; /* Test area width and height in pixels */ 212 213 double rgb[3]; /* Current color (full resolution, full range) */ 214 double s_rgb[3]; /* Current color (possibly scaled range) */ 215 double r_rgb[3]; /* Current color (raster value) */ 216 int out_tvenc; /* 1 to use RGB Video Level encoding */ 217 int patch_delay; /* Measured patch update latency delay in msec, default 200 */ 218 int inst_reaction; /* Measured instrument reaction time delay in msec, default 0 */ 219 double rise_time; /* Display settling rise time */ 220 double fall_time; /* Display settling fall time */ 221 double de_aim; /* Display settling deltaE aim */ 222 int min_update_delay; /* Minimum overall update latency delay, default 20, */ 223 /* overriden by EnvVar */ 224 double settle_mult; /* Settling time multiplier */ 225 int do_resp_time_del; /* NZ to compute and use expected display response time */ 226 int do_update_del; /* NZ to do update delay */ 227 double extra_update_delay; /* Test window internal extra delay (used in delay cal.) */ 228 int nowin; /* Don't create a test window */ 229 int native; /* X0 = use current per channel calibration curve */ 230 /* X1 = set native linear output and use ramdac high precision */ 231 /* 0X = use current color management cLut (MadVR) */ 232 /* 1X = disable color management cLUT (MadVR) */ 233 ramdac *oor; /* Original orgininal ramdac contents, NULL if not accessible */ 234 ramdac *or; /* Original ramdac contents, NULL if not accessible, restored on exit */ 235 ramdac *r; /* Ramdac in use for native mode or general use */ 236 double width, height; /* Orginial size in mm or % */ 237 int fullscreen; /* NZ if full screen background (default black) */ 238 dw_bg_type bge; /* Full screen background color (ccwin only) */ 239 double area; /* Patch area for bge calc 0..1 */ 240 241 char *callout; /* if not NULL - set color Shell callout routine */ 242 243 /* Linked list to automate SIGKILL cleanup */ 244 struct _dispwin *next; 245 246 #ifdef NT 247 char monid[128]; /* Monitor ID (ie. 'Monitor\MEA1773\{4D36E96E-E325-11CE-BFC1-08002BE10318}\0015'*/ 248 HDC hdc; /* Handle to display */ 249 char *AppName; 250 HWND hwnd; /* Window handle */ 251 HCURSOR curs; /* Invisible cursor */ 252 253 MSG msg; 254 ATOM arv; 255 256 int xo, yo, wi, he; /* Window location & size */ 257 athread *mth; /* Window message thread */ 258 int inited; 259 int quit; /* Request to quit */ 260 261 volatile int colupd; /* Color update count */ 262 volatile int colupde; /* Color update count echo */ 263 264 #endif /* NT */ 265 266 #ifdef UNIX_APPLE 267 CGDirectDisplayID ddid; 268 void *osx_cntx; /* OSX specific info */ 269 int btf; /* Flag, nz if window has been brought to the front once */ 270 int winclose; /* Flag, set to nz if window was closed */ 271 #endif /* UNIX_APPLE */ 272 273 #if defined(UNIX_X11) 274 Display *mydisplay; 275 int myscreen; /* Usual or virtual screen with Xinerama */ 276 int myuscreen; /* Underlying screen */ 277 int myrscreen; /* Underlying RAMDAC screen */ 278 Atom icc_atom; /* ICC profile root atom for this display */ 279 unsigned char *edid; /* 128 or 256 bytes of monitor EDID, NULL if none */ 280 int edid_len; /* 128 or 256 */ 281 282 int shift[3]; /* Bit shift to create RGB value from components */ 283 int *rmap[3]; /* Map of fdepth to rdepth values */ 284 285 #if RANDR_MAJOR == 1 && RANDR_MINOR >= 2 286 /* Xrandr stuff - output is connected 1:1 to a display */ 287 RRCrtc crtc; /* Associated crtc */ 288 RROutput output; /* Associated output */ 289 Atom icc_out_atom; /* ICC profile atom for this output */ 290 #endif /* randr >= V 1.2 */ 291 292 /* Test window access */ 293 Window mywindow; 294 GC mygc; 295 296 /* Screensaver state */ 297 int xsssuspend; /* Was able to suspend the screensaver using XScreenSaverSuspend */ 298 299 int xssvalid; /* Was able to save & disable X screensaver using XSetScreenSaver */ 300 int timeout, interval; 301 int prefer_blanking; 302 int allow_exposures; 303 304 int xssrunning; /* Disabled xscreensaver */ 305 306 int gnomessrunning; /* Disabled gnome screensaver and is was enabled */ 307 pid_t gnomepid; /* gnome-screensaver-command -i pid */ 308 309 int kdessrunning; /* Disabled kde screensaver and is was enabled */ 310 311 int dpmsenabled; /* DPMS is enabled */ 312 313 #endif /* UNIX_X11 */ 314 315 void *pcntx; /* Private context (ie., webwin, ccwin) */ 316 volatile unsigned int ncix, ccix; /* Counters to trigger webwin colorchange */ 317 volatile int mg_stop; /* Stop flag */ 318 319 volatile int cberror; /* NZ if error detected in a callback routine */ 320 int ddebug; /* >0 to print debug to stderr */ 321 322 int warned; /* Warning message has been issued */ 323 324 /* public: */ 325 int fdepth; /* Frame buffer depth, typically 8, could be more */ 326 int rdepth; /* Expected ramdac index depth. May be different to fdepth */ 327 /* if there is another level of mapping between the frame buffer */ 328 /* and ramdac, i.e. X11 DirectorColor Colormap. */ 329 330 int ndepth; /* Actual ramdac depth, typically = rdepth */ 331 int nent; /* Number of entries, = s^ndepth, typically = 2^rdepth, */ 332 /* but may be different for some video cards. */ 333 /* Will be 0 if ramdac is not accessible */ 334 335 int edepth; /* Notional frame buffer/ramdac entry size in bits. (Bits actually used */ 336 /* may be less). This is just used to scale out_tvenc appropriately. */ 337 338 /* Get RAMDAC values. ->del() when finished. */ 339 /* Return NULL if not possible */ 340 ramdac *(*get_ramdac)(struct _dispwin *p); 341 342 /* Set the RAMDAC values. */ 343 /* Return nz if not possible */ 344 int (*set_ramdac)(struct _dispwin *p, ramdac *r, int persist); 345 346 /* Install a display profile and make */ 347 /* it the defult for this display. */ 348 /* Return nz if failed */ 349 int (*install_profile)(struct _dispwin *p, char *fname, ramdac *r, p_scope scope); 350 351 /* Un-install a display profile. */ 352 /* Return nz if failed */ 353 int (*uninstall_profile)(struct _dispwin *p, char *fname, p_scope scope); 354 355 /* Get the currently installed display profile and return it as an icmFile. */ 356 /* Return the name as well, up to mxlen chars, excluding nul. */ 357 /* Return NULL if failed */ 358 icmFile *(*get_profile)(struct _dispwin *p, char *name, int mxlen); 359 360 /* Set a color (values 0.0 - 1.0) */ 361 /* Return nz on error */ 362 int (*set_color)(struct _dispwin *p, double r, double g, double b); 363 364 /* Set/unset the fullscreen black flag. */ 365 /* Will only change on next set_col() */ 366 /* Return nz on error */ 367 int (*set_fc)(struct _dispwin *p, int fullscreen); 368 369 /* Change the patch display parameters. */ 370 /* Optional - may be NULL */ 371 int (*set_patch_win)(struct _dispwin *p, 372 double hoff, double voff, /* Offset from c. in fraction of screen, -1.0 .. 1.0 */ 373 double area, /* Patch area 0..1 */ 374 dw_bg_type bge /* Background */ 375 ); 376 377 /* set patch user info */ 378 /* Return nz on error */ 379 int (*set_pinfo)(struct _dispwin *p, int pno, int tno); 380 381 /* Set a patch delay and instrument reaction time values. */ 382 /* The overall delay between patch change and triggering */ 383 /* the instrument is (patch_delay + display_settle - inst_reaction) */ 384 /* and will never be less than the min_update_delay value. */ 385 void (*set_update_delay)(struct _dispwin *p, int patch_delay, int inst_reaction); 386 387 /* Set the display settling time constants. Use -ve value to leave current value */ 388 /* unchanged. (These values are used as part of the update delay calculations - see above). */ 389 void (*set_settling_delay)(struct _dispwin *p, double rise_time, double fall_time, double de_aim); 390 391 /* Enable or disable the update delay. This is used to disable the update delay */ 392 /* when measuring the patch_delay and inst_reaction */ 393 void (*enable_update_delay)(struct _dispwin *p, int enable); 394 395 /* Set a shell set color callout command line */ 396 void (*set_callout)(struct _dispwin *p, char *callout); 397 398 399 /* Destroy ourselves */ 400 void (*del)(struct _dispwin *p); 401 402 }; typedef struct _dispwin dispwin; 403 404 /* Create a RAMDAC access and display test window, default white */ 405 dispwin *new_dispwin( 406 disppath *screen, /* Screen to calibrate. */ 407 double width, double height, /* Width and height in mm */ 408 double hoff, double voff, /* Offset from c. in fraction of screen, range -1.0 .. 1.0 */ 409 int nowin, /* NZ if no window should be created - RAMDAC access only */ 410 int native, /* X0 = use current per channel calibration curve */ 411 /* X1 = set native linear output and use ramdac high precn. */ 412 /* 0X = use current color management cLut (MadVR) */ 413 /* 1X = disable color management cLUT (MadVR) */ 414 int *noramdac, /* Return nz if no ramdac access. native is set to X0 */ 415 int *nocm, /* Return nz if no CM cLUT access. native is set to 0X */ 416 int out_tvenc, /* 1 = use RGB Video Level encoding */ 417 int fullscreen, /* NZ if whole screen should be filled with black */ 418 int override, /* NZ if override_redirect is to be used on X11 */ 419 int ddebug /* >0 to print debug statements to stderr */ 420 ); 421 422 /* Shared implementation */ 423 void dispwin_set_default_delays(dispwin *p); 424 void dispwin_set_update_delay(dispwin *p, int patch_delay, int inst_reaction); 425 void dispwin_set_settling_delay(dispwin *p, double rise_time, double fall_time, double de_aim); 426 void dispwin_enable_update_delay(dispwin *p, int enable); 427 int dispwin_compute_delay(dispwin *p, double *orgb); 428 429 ramdac *dispwin_clone_ramdac(ramdac *r); 430 void dispwin_setlin_ramdac(ramdac *r); 431 void dispwin_del_ramdac(ramdac *r); 432 433 434 435 #define DISPWIN_H 436 #endif /* DISPWIN_H */ 437 438