~ubuntu-branches/ubuntu/saucy/argyll/saucy

« back to all changes in this revision

Viewing changes to spectro/dispwin.c

  • Committer: Package Import Robot
  • Author(s): Christian Marillat
  • Date: 2012-04-25 07:46:07 UTC
  • mfrom: (1.2.2) (13.1.15 sid)
  • Revision ID: package-import@ubuntu.com-20120425074607-yjqadetw8kum9skc
Tags: 1.4.0-4
Should Build-Depends on libusb-dev (Closes: #670329).

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
 *
29
29
 * Is there a >8 bit way of getting/setting RAMDAC indexes ?
30
30
 *
 
31
 * It would be good to be able to calibrate this with a faste
 
32
 * meter like the i1d3. Run the i1d3 at (say) 10 msec sample time
 
33
 * and see how many msec white<->black until it is stable.
 
34
 * Double + add 50msec.
31
35
 */
32
36
 
33
37
#include <stdio.h>
50
54
#include "cgats.h"
51
55
#include "conv.h"
52
56
#include "dispwin.h"
 
57
#include "webwin.h"
53
58
#if defined(UNIX) && !defined(__APPLE__) && defined(USE_UCMM)
54
59
#include "ucmm.h"
55
60
#endif
1397
1402
        /* restoring the previous display profile whenever the current ColorSync display profile */
1398
1403
        /* is restored to the screen. NOTE that this trick will fail if it is not possible */
1399
1404
        /* to rename the currently selected profile file, ie. because it is a system profile. */
 
1405
        /* [ Would a workaround be to use a link, or copy of the system file ? ] */
1400
1406
        if (persist) {                                  /* Persistent */
1401
1407
                CMError ev;
1402
1408
                CMProfileRef prof;                      /* Current AVID profile */
1874
1880
        }
1875
1881
#endif /* NT */
1876
1882
 
 
1883
/* For Linux and OS X, make sure we don't create a file with the wrong owner */
 
1884
#if defined(UNIX)
 
1885
        /* If we're creating a user profile and running as root sudo */
 
1886
        if (scope == p_scope_user && geteuid() == 0) {
 
1887
                char *uids, *gids;
 
1888
                int uid, gid;
 
1889
 
 
1890
                debugr("We're setting a user profile running as root - run as user\n");
 
1891
                if ((uids = getenv("SUDO_UID")) != NULL
 
1892
                 && (gids = getenv("SUDO_GID")) != NULL) {
 
1893
                        uid = atoi(uids);
 
1894
                        gid = atoi(gids);
 
1895
                        if (setegid(gid) || seteuid(uid)) {
 
1896
                                debugr("seteuid or setegid failed\n");
 
1897
                        }
 
1898
                        debug2((errout,"Set euid %d and egid %d\n",uid,gid));
 
1899
                }
 
1900
        /* If setting local system proile and not effective root, but sudo */
 
1901
        } else if (scope != p_scope_user && getuid() == 0 && geteuid() != 0) {
 
1902
                if (getenv("SUDO_UID") != NULL
 
1903
                 && getenv("SUDO_GID") != NULL) {
 
1904
 
 
1905
                        debugr("We're setting a system profile running as user - revert to root\n");
 
1906
                        setegid(getgid());
 
1907
                        seteuid(getuid());
 
1908
                }
 
1909
        }
 
1910
#endif /* OS X || Linux */
 
1911
 
1877
1912
#ifdef __APPLE__
1878
1913
        {
1879
1914
                CMError ev;
2102
2137
        }
2103
2138
#endif /* NT */
2104
2139
 
 
2140
/* For Linux and OS X, make sure we don't create a file with the wrong owner */
 
2141
#if defined(UNIX)
 
2142
        /* If we're creating a user profile and running as root sudo */
 
2143
        if (scope == p_scope_user && geteuid() == 0) {
 
2144
                char *uids, *gids;
 
2145
                int uid, gid;
 
2146
 
 
2147
                debugr("We're setting a user profile running as root - run as user\n");
 
2148
                if ((uids = getenv("SUDO_UID")) != NULL
 
2149
                 && (gids = getenv("SUDO_GID")) != NULL) {
 
2150
                        uid = atoi(uids);
 
2151
                        gid = atoi(gids);
 
2152
                        if (setegid(gid) || seteuid(uid)) {
 
2153
                                debugr("seteuid or setegid failed\n");
 
2154
                        }
 
2155
                        debug2((errout,"Set euid %d and egid %d\n",uid,gid));
 
2156
                }
 
2157
        /* If setting local system proile and not effective root, but sudo */
 
2158
        } else if (scope != p_scope_user && getuid() == 0 && geteuid() != 0) {
 
2159
                if (getenv("SUDO_UID") != NULL
 
2160
                 && getenv("SUDO_GID") != NULL) {
 
2161
 
 
2162
                        debugr("We're setting a system profile running as user - revert to root\n");
 
2163
                        setegid(getgid());
 
2164
                        seteuid(getuid());
 
2165
                }
 
2166
        }
 
2167
#endif /* OS X || Linux */
 
2168
 
2105
2169
#ifdef __APPLE__
2106
2170
        {
2107
2171
                CMError ev;
2652
2716
        /* a measurement can take place. This allows for CRT */
2653
2717
        /* refresh, or LCD processing/update time, + */
2654
2718
        /* display settling time (quite long for smaller LCD changes). */
2655
 
        msec_sleep(200);
 
2719
        msec_sleep(110);
2656
2720
 
2657
2721
        return 0;
2658
2722
}
3026
3090
 
3027
3091
#endif /* NT */
3028
3092
 
3029
 
/* Create a RAMDAC access and display test window, default white */
 
3093
/* Create a RAMDAC access and display test window, default grey */
3030
3094
dispwin *new_dispwin(
3031
3095
disppath *disp,                                 /* Display to calibrate. */
3032
3096
double width, double height,    /* Width and height in mm */
3033
3097
double hoff, double voff,               /* Offset from center in fraction of screen, range -1.0 .. 1.0 */
3034
3098
int nowin,                                              /* NZ if no window should be created - RAMDAC access only */
3035
3099
int native,                                             /* 0 = use current current or given calibration curve */
3036
 
                                                                /* 1 = set native linear output and use ramdac high prec'n */
3037
 
                                                                /* 2 = set native linear output */
 
3100
                                                                /* 1 = use native linear out & high precision */
 
3101
int *noramdac,                                  /* Return nz if no ramdac access. native is set to 0 */
3038
3102
int blackbg,                                    /* NZ if whole screen should be filled with black */
3039
3103
int override,                                   /* NZ if override_redirect is to be used on X11 */
3040
3104
int ddebug                                              /* >0 to print debug statements to stderr */
3756
3820
                        debug("About to setup native mode\n");
3757
3821
                        if ((p->or = p->get_ramdac(p)) == NULL
3758
3822
                         || (p->r = p->or->clone(p->or)) == NULL) {
3759
 
                                if (p->native == 1) {
3760
 
                                        debugr("new_dispwin: Native mode can't work, no VideoLUT support\n");
3761
 
                                        warning("new_dispwin: Native mode can't work, no VideoLUT support");
3762
 
                                        dispwin_del(p);
3763
 
                                        return NULL;
3764
 
                                } else {
3765
 
                                        debugr("new_dispwin: Accessing VideoLUT failed, so no way to guarantee that calibration is turned off!!\n");
3766
 
                                        warning("new_dispwin: Accessing VideoLUT failed, so no way to guarantee that calibration is turned off!!");
3767
 
                                }
 
3823
                                if (noramdac != NULL)
 
3824
                                        *noramdac = 1;
 
3825
                                debugr("new_dispwin: Accessing VideoLUT failed, so no way to guarantee that calibration is turned off!!\n");
 
3826
                                warning("new_dispwin: Accessing VideoLUT failed, so no way to guarantee that calibration is turned off!!");
 
3827
                                p->native = 0;
3768
3828
                        } else {
3769
3829
                                p->r->setlin(p->r);
 
3830
                                if (noramdac != NULL)
 
3831
                                        *noramdac = 0;
3770
3832
                                debug("Saved original VideoLUT\n");
3771
3833
                        }
 
3834
                } else {
 
3835
                        if (p->get_ramdac(p) == NULL) {
 
3836
                                if (noramdac != NULL)
 
3837
                                        *noramdac = 1;
 
3838
                        }
3772
3839
                }
3773
3840
        
3774
3841
                /* Make sure initial test color is displayed */
3899
3966
                                                        break;
3900
3967
                                                if (verb) printf("Updating display %d = '%s'\n",i+1,dp[i]->description);
3901
3968
                
3902
 
                                                if ((dw = new_dispwin(dp[i], 0.0, 0.0, 0.0, 0.0, 1, 0, 0, 0, ddebug)) == NULL) {
 
3969
                                                if ((dw = new_dispwin(dp[i], 0.0, 0.0, 0.0, 0.0, 1, 0, NULL, 0, 0, ddebug)) == NULL) {
3903
3970
                                                        if (verb) printf("Failed to access screen %d of display '%s'\n",i+1,dnbuf);
3904
3971
                                                        continue;
3905
3972
                                                }
4048
4115
                }
4049
4116
        }
4050
4117
        free_disppaths(dp);
 
4118
        fprintf(stderr," -dweb[:port]         Display via a web server at port (default 8080)\n");
4051
4119
        fprintf(stderr," -P ho,vo,ss          Position test window and scale it\n");
4052
4120
        fprintf(stderr," -F                   Fill whole screen with black background\n");
4053
4121
        fprintf(stderr," -i                   Run forever with random values\n");
4081
4149
        int fa, nfa, mfa;                       /* current argument we're looking at */
4082
4150
        int verb = 0;                           /* Verbose flag */
4083
4151
        int ddebug = 0;                         /* debug level */
 
4152
        int webdisp = 0;                        /* NZ for web display, == port number */
4084
4153
        disppath *disp = NULL;          /* Display being used */
4085
4154
        double patscale = 1.0;          /* scale factor for test patch size */
4086
4155
        double ho = 0.0, vo = 0.0;      /* Test window offsets, -1.0 to 1.0 */
4091
4160
        int native = 0;                         /* 0 = use current current or given calibration curve */
4092
4161
                                                                /* 1 = set native linear output and use ramdac high prec'n */
4093
4162
                                                                /* 2 = set native linear output */
 
4163
        int noramdac = 0;                       /* Set to nz if there is no VideoLUT access */
4094
4164
        int inf = 0;                            /* Infnite/manual patches flag */
4095
4165
        char pcname[MAXNAMEL+1] = "\000";       /* CGATS patch color name */
4096
4166
        int clear = 0;                          /* Clear any display calibration (any calname is ignored) */
4148
4218
 
4149
4219
                        /* Display number */
4150
4220
                        else if (argv[fa][1] == 'd') {
 
4221
                                if (strncmp(na,"web",3) == 0
 
4222
                                 || strncmp(na,"WEB",3) == 0) {
 
4223
                                        webdisp = 8080;
 
4224
                                        if (na[3] == ':') {
 
4225
                                                webdisp = atoi(na+4);
 
4226
                                                if (webdisp == 0 || webdisp > 65535)
 
4227
                                                        usage("Web port number must be in range 1..65535");
 
4228
                                        }
 
4229
                                        fa = nfa;
 
4230
                                } else {
4151
4231
#if defined(UNIX) && !defined(__APPLE__)
4152
 
                                int ix, iv;
 
4232
                                        int ix, iv;
4153
4233
 
4154
 
                                /* X11 type display name. */
4155
 
                                if (strcmp(&argv[fa][2], "isplay") == 0 || strcmp(&argv[fa][2], "ISPLAY") == 0) {
4156
 
                                        if (++fa >= argc || argv[fa][0] == '-') usage("-DISPLAY parameter missing");
4157
 
                                        setenv("DISPLAY", argv[fa], 1);
4158
 
                                } else {
4159
 
                                        if (na == NULL) usage("-d parameter missing");
 
4234
                                        /* X11 type display name. */
 
4235
                                        if (strcmp(&argv[fa][2], "isplay") == 0 || strcmp(&argv[fa][2], "ISPLAY") == 0) {
 
4236
                                                if (++fa >= argc || argv[fa][0] == '-') usage("-DISPLAY parameter missing");
 
4237
                                                setenv("DISPLAY", argv[fa], 1);
 
4238
                                        } else {
 
4239
                                                if (na == NULL) usage("-d parameter missing");
 
4240
                                                fa = nfa;
 
4241
                                                if (sscanf(na, "%d,%d",&ix,&iv) != 2) {
 
4242
                                                        ix = atoi(na);
 
4243
                                                        iv = 0;
 
4244
                                                }
 
4245
                                                if (disp != NULL)
 
4246
                                                        free_a_disppath(disp);
 
4247
                                                if ((disp = get_a_display(ix-1)) == NULL)
 
4248
                                                        usage("-d parameter '%s' is out of range",na);
 
4249
                                                if (iv > 0)
 
4250
                                                        disp->rscreen = iv-1;
 
4251
                                        }
 
4252
#else
 
4253
                                        int ix;
 
4254
                                        if (na == NULL) usage("-d parameter is missing");
4160
4255
                                        fa = nfa;
4161
 
                                        if (sscanf(na, "%d,%d",&ix,&iv) != 2) {
4162
 
                                                ix = atoi(na);
4163
 
                                                iv = 0;
4164
 
                                        }
 
4256
                                        ix = atoi(na);
4165
4257
                                        if (disp != NULL)
4166
4258
                                                free_a_disppath(disp);
4167
4259
                                        if ((disp = get_a_display(ix-1)) == NULL)
4168
4260
                                                usage("-d parameter '%s' is out of range",na);
4169
 
                                        if (iv > 0)
4170
 
                                                disp->rscreen = iv-1;
 
4261
#endif
4171
4262
                                }
4172
 
#else
4173
 
                                int ix;
4174
 
                                if (na == NULL) usage("-d parameter is missing");
4175
 
                                fa = nfa;
4176
 
                                ix = atoi(na);
4177
 
                                if (disp != NULL)
4178
 
                                        free_a_disppath(disp);
4179
 
                                if ((disp = get_a_display(ix-1)) == NULL)
4180
 
                                        usage("-d parameter '%s' is out of range",na);
4181
 
#endif
4182
4263
                        }
4183
4264
 
4184
4265
                        /* Test patch offset and size */
4264
4345
        }
4265
4346
 
4266
4347
        /* No explicit display has been set */
4267
 
        if (disp == NULL) {
 
4348
        if (webdisp == 0 && disp == NULL) {
4268
4349
                int ix = 0;
4269
4350
#if defined(UNIX) && !defined(__APPLE__)
4270
4351
                char *dn, *pp;
4290
4371
        }
4291
4372
 
4292
4373
#if defined(UNIX) && !defined(__APPLE__)
4293
 
        if (daemonmode) {
 
4374
        if (webdisp == 0 && daemonmode) {
4294
4375
                return x11_daemon_mode(disp, verb, ddebug);
4295
4376
        }
4296
4377
#endif
4312
4393
        if (ramd != 0 || sname[0] != '\000' || clear != 0 || verify != 0 || loadfile != 0 || installprofile != 0 || loadprofile != 0)
4313
4394
                nowin = 1;
4314
4395
 
4315
 
        if (verb)
4316
 
                printf("About to open dispwin object on the display\n");
4317
 
 
4318
 
        if ((dw = new_dispwin(disp, 100.0 * patscale, 100.0 * patscale, ho, vo, nowin, native, blackbg, 1, ddebug)) == NULL) {
4319
 
                printf("Error - new_dispwin failed!\n");
4320
 
                return -1;
 
4396
 
 
4397
        if (webdisp != 0) {
 
4398
                if ((dw = new_webwin(webdisp, 100.0 * patscale, 100.0 * patscale, ho, vo, nowin, blackbg, verb, ddebug)) == NULL) {
 
4399
                        printf("Error - new_webpwin failed!\n");
 
4400
                        return -1;
 
4401
                }
 
4402
                noramdac = 1;
 
4403
 
 
4404
        } else {
 
4405
                if (verb) printf("About to open dispwin object on the display\n");
 
4406
                if ((dw = new_dispwin(disp, 100.0 * patscale, 100.0 * patscale, ho, vo, nowin, native, &noramdac, blackbg, 1, ddebug)) == NULL) {
 
4407
                        printf("Error - new_dispwin failed!\n");
 
4408
                        return -1;
 
4409
                }
4321
4410
        }
4322
4411
 
 
4412
        if (native != 0 && noramdac) {
 
4413
                error("We don't have access to the VideoLUT so can't display native colors\n");
 
4414
        } 
 
4415
 
4323
4416
        /* Save the current Video LUT to the calfile */
4324
4417
        if (sname[0] != '\000') {
4325
4418
                cgats *ocg;                     /* output cgats structure */
4401
4494
                        printf("About to clear the calibration\n");
4402
4495
                if ((rv = dw->set_ramdac(dw,r,1)) != 0) {
4403
4496
                        if (rv == 2)
4404
 
                                error("Failed to set VideoLUTs persistently due to current System Profile");
 
4497
                                warning("Failed to set VideoLUTs persistently because current System Profile can't be renamed");
4405
4498
                        else
4406
4499
                                error("Failed to set VideoLUTs");
4407
4500
                }
4434
4527
                icc *icco = NULL;
4435
4528
                cgats *ccg = NULL;                      /* calibration cgats structure */
4436
4529
                
4437
 
                if ((r = dw->get_ramdac(dw)) == NULL) {
4438
 
                        error("We don't have access to the VideoLUT");
4439
 
                }
 
4530
                /* Get a calibration that's compatible with the display. */
 
4531
                /* This can fail and return NULL - error if we later need it */
 
4532
                r = dw->get_ramdac(dw);
4440
4533
 
4441
4534
                /* Should we load calfile instead of installed profile if it's present ??? */
4442
4535
                if (loadprofile) {
4466
4559
                        is_ok_icc = 1;                  /* The profile is OK */
4467
4560
 
4468
4561
                        if ((wo = (icmVideoCardGamma *)icco->read_tag(icco, icSigVideoCardGammaTag)) == NULL) {
4469
 
                                warning("No vcgt tag found in profile - using linear\n");
4470
 
                                for (i = 0; i < r->nent; i++) {
4471
 
                                        iv = i/(r->nent-1.0);
4472
 
                                        r->v[0][i] = iv;
4473
 
                                        r->v[1][i] = iv;
4474
 
                                        r->v[2][i] = iv;
 
4562
                                warning("No vcgt tag found in profile - assuming linear\n");
 
4563
                                if (r != NULL) {
 
4564
                                        for (i = 0; i < r->nent; i++) {
 
4565
                                                iv = i/(r->nent-1.0);
 
4566
                                                r->v[0][i] = iv;
 
4567
                                                r->v[1][i] = iv;
 
4568
                                                r->v[2][i] = iv;
 
4569
                                        }
4475
4570
                                }
4476
4571
                        } else {
4477
4572
                                
 
4573
                                /* Hmm. Perhaps we should ignore this if the vcgt is linear ?? */
 
4574
                                if (r == NULL)
 
4575
                                        error("We don't have access to the VideoLUT");
 
4576
 
4478
4577
                                if (wo->u.table.channels == 3) {
4479
4578
                                        for (i = 0; i < r->nent; i++) {
4480
4579
                                                iv = i/(r->nent-1.0);
4553
4652
                                cal[2][i] = *((double *)ccg->t[0].fdata[i][bi]);
4554
4653
                        }
4555
4654
 
 
4655
                        if (r == NULL)
 
4656
                                error("We don't have access to the VideoLUT");
 
4657
 
4556
4658
                        /* Interpolate from cal value to RAMDAC entries */
4557
4659
                        for (i = 0; i < r->nent; i++) {
4558
4660
                                double val, w;
4597
4699
        } else if (loadfile != 0 || (loadprofile != 0 && verify == 0)) {
4598
4700
                int rv;
4599
4701
 
4600
 
                if (r == NULL)
4601
 
                        error("ICC profile '%s' has no vcgt calibration table",calname);
4602
 
                if (verb)
4603
 
                        printf("About to set display to given calibration\n");
4604
 
                if ((rv = dw->set_ramdac(dw,r,1)) != 0) {
4605
 
                        if (rv == 2)
4606
 
                                error("Failed to set VideoLUTs persistently due to current System Profile");
4607
 
                        else
4608
 
                                error("Failed to set VideoLUTs");
 
4702
                /* r == NULL if no VideoLUT access and ICC profile without vcgt */
 
4703
                if (r == NULL) {
 
4704
                        warning("No linear calibration loaded because there is no access to the VideoLUT");
 
4705
                } else {
 
4706
                        if (verb)
 
4707
                                printf("About to set display to given calibration\n");
 
4708
                        if ((rv = dw->set_ramdac(dw,r,1)) != 0) {
 
4709
                                if (rv == 2)
 
4710
                                        error("Failed to set VideoLUTs persistently because current System Profile can't be renamed");
 
4711
                                else
 
4712
                                        error("Failed to set VideoLUTs");
 
4713
                        }
 
4714
                        if (verb)
 
4715
                                printf("Calibration set\n");
4609
4716
                }
4610
 
                if (verb)
4611
 
                        printf("Calibration set\n");
4612
4717
        }
4613
4718
 
4614
4719
        if (verify != 0) {
4617
4722
                if ((or = dw->get_ramdac(dw)) == NULL)
4618
4723
                        error("Unable to get current VideoLUT for verify");
4619
4724
        
 
4725
                if (r == NULL)
 
4726
                        error("No calibration to verify against");
 
4727
 
4620
4728
                for (j = 0; j < 3; j++) {
4621
4729
                        for (i = 0; i < r->nent; i++) {
4622
4730
                                double err;
4823
4931
                                else
4824
4932
                                        sleep(2);
4825
4933
 
4826
 
 
4827
4934
                                if (inf == 1) {
4828
4935
                                        for (;inf != 0;) {
4829
4936
                                                double col[3];
4909
5016
                }
4910
5017
        }
4911
5018
        
4912
 
        free_a_disppath(disp);
 
5019
        if (disp != NULL)
 
5020
                free_a_disppath(disp);
4913
5021
 
4914
5022
        if (verb)
4915
5023
                printf("About to destroy dispwin object\n");