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
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
|
\input texinfo @c -*-texinfo-*-
@c %%**start of header
@setfilename libgamma.info
@settitle libgamma
@afourpaper
@documentencoding UTF-8
@documentlanguage en
@finalout
@c %%**end of header
@dircategory Library
@direntry
* libgamma: (libgamma). Display server abstraction layer for gamma ramp adjustments
@end direntry
@copying
Copyright @copyright{} 2014, 2015 Mattias Andr@'ee
@quotation
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
Texts. A copy of the license is included in the section entitled
``GNU Free Documentation License''.
@end quotation
@end copying
%>set -u
%>cd src/extract
%>export PATH=".:../../info:${PATH}"
@ifnottex
@node Top
@top libgamma -- Display server abstraction layer for gamma ramp adjustments
@insertcopying
@end ifnottex
@titlepage
@title libgamma
@subtitle Display server abstraction layer for gamma ramp adjustments
@author by Mattias Andr@'e (maandree)
@page
@c @center `'
@vskip 0pt plus 1filll
@insertcopying
@end titlepage
@contents
@menu
* Overview:: Brief overview of @command{libgamma}.
* Jargon:: The jargon of @command{libgamma}.
* Compiling:: Configuring, compiling and installing @command{libgamma}.
* Linking:: Linking your software to @command{libgamma}.
* API:: @command{libgamma}'s advanced programming interface.
* GNU Free Documentation License:: Copying and sharing this manual.
@end menu
@node Overview
@chapter Overview
@command{libgamma} is a C library that aims to
abstract away the display server when adjusting
the colours curves for monitors via gamma ramps,
and to be cross-platform.
@command{libgamma} have support for the X RandR
(Resize and Rotate) extension, the X VidMode
extension and under Linux the Direct Rendering
Manager which lets software work with graphics
outside of graphical environments. Additionally
@command{libgamma} have support for Windows
Graphics Device Interface (Windows GDI) under
Windows and Quartz using CoreGraphics under OS X.
However Windows GDI and Quartz/CoreGraphics do
not receive first-party testing on their target
platforms but do receive first-party testing
using a compatibility layer that translates
the calls to RandR calls. Neither does
@command{libgamma}, currently, receive testing
on any of the BSD:s, it is only tested on GNU/Linux.
Furthermore @command{libgamma} provides a dummy
method that can be used to ignore adjustments
and can be controlled from another program to
pretend like the environment has changed. This
can be used test how well your software handles
such events. It can also be configured at runtime
to use another adjustment method such as RandR.
@node Jargon
@chapter Jargon
@command{libgamma} uses a small jargon,
parts of which is loaned from X.org,
and some is commonly used jargon.
@table @asis
@item adjustment method [libgamma]
A combination of the display server
and a protocol used to tell to the
display server.
@item display server [X.org]
The program used to display graphical
elements to the monitors. In @command{libgamma}
we also call the non-graphical environment
a display server.
@item display [X.org]
@itemx site [libgamma]
An instance of a display server.
Non-graphical environment are only
covered by `site'.
@item screen [X.org]
A group of CRTC:s within a display.
@item CRTC
@itemx cathode ray tube controller
Controller for the output on monitor.
Mapping from CRTC:s to encoders is an injection.
@item monitor
The physical medium used to display
text and graphics.
@item partition [libgamma]
Umbrella term for `screen' and
`graphics card'.
@item page [libgamma]
The desktop workspace or virtual
terminal that is displayed on a CRTC.
(This jargon is not currently used,
but is reserved for future features.)
@item output [X.org]
A connector and its encoder.
@item connector
Physical port on the graphics card where
a monitor can be plugged in. If and only
if the connector is disabled it does not
have a port and does not have a CRTC.
@item encoder
Translation layer between CRTC:s and connectors.
@item gamma ramp
@itemx colour curve
A lookup table that translates an encoded
value for a subpixel into its output value.
@item subpixel
@itemx colour channel
One of the three colours that makes up a pixel:
red, green or blue.
@item gamma ramp size
@itemx gamma stops
The number of possible values on the encoding
axis of a gamma ramp.
@end table
@node Compiling
@chapter Compiling
The build @command{libgamma} you will need
to run @command{./configure} before you
run @command{make}. @file{./configure} is
not a configuration script from the GNU build
system, rather it is just a simple shell script.
Each adjustment method needs selected, if none
are selected no adjustment method will be compiled
into @command{libgamma}. They can either be
selected explicitly and independently or by
operating system.
@table @option
@item --enable-dummy
Enables the dummy adjustment method.
@item --enable-randr
@itemx --linux
@itemx --bsd
Enables the X RandR extension adjustment method.
@item --enable-vidmode
@itemx --linux
@itemx --bsd
Enables the X VidMode extension adjustment method.
@item --enable-drm
@itemx --linux
Enables the Direct Rendering Manager adjustment method.
@item --enable-wayland
@itemx --linux
Enables the Wayland/Orbital adjustment method.
@item --enable-w32gdi
@itemx --windows
Enables the Windows GDI adjustment method.
@item --enable-quartz
@itemx --mac-os-x
Enables the Quartz/CoreGraphics adjustment method.
@item --enable-w32gdi=fake
Enables the Windows GDI adjustment method using
compatibility layer to either RandR or ``/dev/null''
depending on whether RandR is enabled or not.
@item --enable-quartz=fake
Enables the Quartz/CoreGraphics adjustment method
using a compatibility layer to either RandR or
``/dev/null'' depending on whether RandR is
enabled or not.
@end table
You may prefix anything to `bsd', for example
@option{--freebsd} or @option{--openbsd}. Any
prefix will be discard, but it may be a good
idea incase there will be a difference in the
future between the platforms.
Developers of @command{libgamma} and developers
who use @command{libgamma} for their software may
also want to use @option{--debug} which enables
extra checks to produce better error reports.
Additionally @option{--debug} adds the @option{-Og -g}
flags to the C compiler rather than @option{-Ofast}.
Developers can also use the developer options
instead of @option{--debug}, the adjustment and
operating systems.
@table @option
@item --linux=developer
@itemx --developer
Enables all adjustment methods, with compatibility
layers for Windows GDI and Quartz/CoreGraphics.
Also enables @option{--debug}.
@item --bsd=developer
Enables all adjustment methods, except the Linux
Direct Rendering Manager adjustment method, with
compatibility layers for Windows GDI and
Quartz/CoreGraphics.
Also enables @option{--debug}.
@item --windows=developer
Enables the dummy adjustment method and the
Windows GDI adjustment method.
Also enables @option{--debug}.
@item --mac-os-x=developer
Enables the dummy adjustment method and the
Quartz/CoreGraphics adjustment method.
Also enables @option{--debug}.
@end table
Configuring with @option{--windows} or
@option{--windows=developer} will also add
configurations to the make script needed
to compile for Windows. @option{--mac-os-x} or
@option{--mac-os-x=developer} will do add
configurations to the make script needed
to compile for OS X.
When you have configured @command{libgamma}
using @command{./configure} you can compile
the library with @command{make}. Straight up
@command{make} without additions options
should be all you need. But you can also use
specify some build rules.
@table @option
@item default
Builds the library, the test and the info manual.
@item all
Builds the library, the test and manual to all
available formats: info, PDF, DVI, PostScript.
@item lib
Builds the library.
@item test
Builds the test, which in turns builts the library.
@item doc
Builds the manual to all available formats:
info, PDF, DVI, PostScript.
@item info
Builds the info manual.
@item pdf
Builds the PDF manual.
@item dvi
Builds the DVI manual.
@item ps
Builds the PostScript manual.
@end table
You can also use @command{make clean}
to remove all compiled files, and
@command{make distclean} to remove
all compiled files and the files
generated by @command{./configure}.
To install @command{libgamma} once
it is compiled run @command{make install}
and then @command{make uninstall} once
you want to uninstall the library.
When running @command{make install}
include the option @option{DESTDIR="$@{pkgdir@}"},
where @file{$@{pkgdir@}} is the directory
you want the files to be installed to
instead of @file{/}, this could for example
be @file{/mnt} where you have mounted another
installed operating system or a temporary
location used by the package manager.
This is also a set of options to specify
how the system's file system hierarchy is
structured.
@table @option
@item PREFIX
The package path prefix, if you want to install
to another root, set @option{DESTDIR} to that root.
Defaults to @file{/usr}.
@item LIB
The library path excluding prefix.
Defaults to @file{/lib}.
@item INCLUDE
The library header path excluding prefix.
Defaults to @file{/include}.
@item DATA
The resource path excluding prefix.
Defaults to @file{/share}.
@item LIBDIR
The library path including prefix.
Defaults to @file{$(PREFIX)$(LIB)}.
@item INCLUDEDIR
The library header including prefix
Defaults to @file{$(PREFIX)$(INCLUDE)}.
@item DATADIR
The resource path including prefix.
Defaults to @file{$(PREFIX)$(DATA)}.
@item DOCDIR
The generic documentation path including prefix.
Defaults to @file{$(DATADIR)/doc}.
@item INFODIR
The info manual documentation path including prefix.
Defaults to @file{$(DATADIR)/info}.
@item LICENSEDIR
The license base path including prefix.
Defaults to @file{$(DATADIR)/licenses}
@end table
There is also an option to specify the package name
of the library: @option{PKGNAME}. This only affects
the name and location of files installed into
@option{DOCDIR}, @option{INFODIR} and @option{LICENSEDIR}.
It does not affect the name of the library.
For more control on what should be installed,
subsitute @option{install} from @command{make install}
for one or more of the following rules:
@table @option
@item install
Macro for @option{install-base} and @option{install-info}.
Installs everything but only the manual in the info format.
@command{install-info} will not be execute the install the
manual to the @file{dir} file for @command{info}.
@item install-all
Macro for @option{install-base} and @option{install-doc}.
Installs everything including all available formats of the manual.
@command{install-info} will not be execute the install the
manual to the @file{dir} file for @command{info}.
@item install-base
Macro for @option{install-lib}, @option{install-include} and
@option{install-copyright}.
Installs the library, the headers files for the library
so that you can compile other software that uses the library,
and the copyright file and the license file.
@item install-lib
Installs the library, but not its header files.
@item install-include
Installs the library's header files but not the
library itself.
@item install-copyright
Macro for @option{install-copying}, and @option{install-license}.
Installs the copyright file and the license file.
@item install-copying
Installs the copyright file but not the license file.
@item install-license
Installs the license file but not the copyright file.
@item install-doc
Macro for @option{install-info}, @option{install-pdf},
@option{install-ps} and @option{install-dvi}.
Installs the manual in all available formats.
@command{install-info} will not be execute the install the
manual to the @file{dir} file for @command{info}.
@item install-info
Installs the info manual.
@command{install-info} will not be execute the install the
manual to the @file{dir} file for @command{info}.
@item install-pdf
Installs the PDF manual.
@item install-ps
Installs the PostScript manual.
@item install-dvi
Installs the DVI manual.
@end table
@node Linking
@chapter Linking
When compiling your program use @command{libgamma},
you will not need to do anything for the compiling
phase. But for the linking phase, will need to add
the option @option{-lgamma}. Currently
@command{libgamma}, does not provide a pkg-config file.
Keep in mind that @command{libgamma} is GNU General
Public License version 3 software for your freedom
and for the freedom of all.
@node API
@chapter API
@menu
* Adjustment methods:: Selecting adjustment method.
* Monitors:: Selecting monitors.
* Adjustment method capabilities:: Identifying capabilities of adjustment methods.
* CRTC information:: Retrieving information about CRTC:s.
* Gamma ramps:: Fetch and manipulating gamma ramps.
* Errors:: Error codes and how to handle errors.
@end menu
To use @command{libgamma} add ``@code{#include <libgamma.h>}''
to and C file or C header file that requires anything
from @command{libgamma}. @file{libgamma.h} is the only
header file from @command{libgamma} which should be
included directly.
Once @file{libgamma.h} is included your program will
have access the @command{libgamma}'s API which includes
functions, data structures, error codes, and adjustment
method identifers.
It is highly recommened to add a check for new error
codes if your program will be using error codes from
@command{libgamma}. This allows you to get a notification
if you program is not up to date with new error codes
in @command{libgamma}. To do this, @file{libgamma.h}
provides the C preprocessor definition @code{LIBGAMMA_ERROR_MIN};
this is the lowest value of that any error code has,
all error codes are negative, a new error code is added
it will have a lower value that the ones added before it.
The first step in adding this check is to figure out
what the value of @code{LIBGAMMA_ERROR_MIN} is on your
system. To do this, use the @command{cpp} program, it
should be included with your C compiler.
@example
cpp <<EOF | tail --lines 1
#include <libgamma.h>
LIBGAMMA_ERROR_MIN
EOF
@end example
The next step is to add some C preprocessor directives
to one of your C files that includes @file{libgamma.h}.
@example
#if LIBGAMMA_ERROR_MIN < -10
# warning New error codes have been added to libgamma.
#endif
@end example
In this example, we assume that output of the first
step was `-10', which it really was not. So if you
use this in your program you should receive a warning
until you update the value.
In a similar manner, you should all a check to detect
when the value of either @code{GAMMA_METHOD_MAX} or
@code{GAMMA_METHOD_COUNT} (the latter will have value
of one higher than the earlier) have increased. This
will allow you to get a warning for when new adjustment
method have been added so you can take appropriate
actions if required. @command{libgamma} does not only
provide display server abstract, it optionally lets you
choose any available method you want despite of what
display server you are used.
You may also want to add checks for update to
@code{LIBGAMMA_CONNECTOR_TYPE_COUNT},
@code{LIBGAMMA_SUBPIXEL_ORDER_COUNT} and
@code{LIBGAMMA_CRTC_INFO_COUNT}.
@node Adjustment methods
@section Adjustment methods
@command{libgamma} is an abstraction layer that
lets you select which display server and protocol
--- together called adjustment method --- it
should use to work with the monitors' gamma
ramps. Supported adjustment method, even if
excluded at compile-time are identfier by numerical
values.
@table @code
%>for method in $(libgamma-method-extract --list --method); do
@item %{method}
%>libgamma-method-extract --method $method | texise
%>done
@end table
You can test whether an adjustment method
is available with the function
@code{libgamma_is_method_available}. It
takes the adjustment method's identifer
as its only argument, and returns an
@code{int}. The returned value is non-zero
if and only if the adjustment exists and
is available.
A more flexible more but advanced function,
that you probably want to use instead, is
@code{libgamma_list_methods}. It lists all
List available adjustment methods by their
order of preference based on the environment,
and can filter its output. This function
takes three arguments:
@table @asis
@item @code{methods} [@code{int*}]
Output array of adjustment method
identifiers. It should be able to hold
@code{LIBGAMMA_METHOD_COUNT} elements.
@item @code{buf_size} [@code{size_t}]
The number of elements that fits in
@code{methods}, it should be
@code{LIBGAMMA_METHOD_COUNT},
This is used to avoid writing outside
the output buffer if this library
adds new adjustment methods without
the users of the library recompiling.
@item @code{operation} [@code{int}]
Describes what adjustment methods to
include. There are five valid values
for this parameter, all other values
invoke undefined behaviour.
@table @code
@item 0
Adjustment methods that the environment
suggests will work, excluding fake
Adjustment methods.
@item 1
Adjustment methods that the environment
suggests will work, including fake
Adjustment methods.
@item 2
All real non-fake adjustment methods.
@item 3
All real adjustment methods.
@item 4
All adjustment methods.
@end table
@end table
@code{libgamma_list_methods} returns an
@code{size_t} with the value of how many
adjustment method that should have been
stored in the parameter @code{methods}
if were @code{buf_size}. This value is
how many value that have been stored
in @code{methods} if @code{buf_size}
is large enough.
@node Monitors
@section Monitors
@menu
* Site:: Display sites.
* Partition:: Display partitions.
* CRTC:: Display outputs.
@end menu
@command{libgamma} have a three level hierarchy for addressing
monitors. These levels are:
@table @asis
@item Sites
%>libgamma-method-extract --doc --site-t | behead 2 | texise
@item Partitions
%>libgamma-method-extract --doc --part-t | behead 2 | texise
@item CRTC:s (cathode ray tube controllers) @footnote{Do not be fooled by the legacy name, they are general video controllers.}
%>libgamma-method-extract --doc --crtc-t | behead 2 | texise
@end table
@command{libgamma} keeps tracks of these layers' states,
because of this there are one state data structure per
layer that also identifies the instance of the layer.
@node Site
@subsection Site
The state and identity of the site is track by
the data structure @code{libgamma_site_state_t}
@footnote{@code{struct libgamma_site_state}}.
This structure contains the following variables:
@table @asis
%>for site in $(libgamma-method-extract --list --site-t); do
@item @code{%{site}} [@code{%(libgamma-method-extract --type --site-t $site)}]
%>libgamma-method-extract --site-t $site | texise | sed -e 's/"/``/1' | sed -e 's/"/'\'\''/'
%>done
@end table
To select a site and initialise its state
call the function @code{libgamma_site_initialise}.
It returns zero on success, and and negative
@code{int} on failure. If the return is negative,
it is a @code{libgamma} error code; these are
listed in @ref{Errors}. For input
@code{libgamma_site_initialise} takes three
arguments:
@table @asis
@item @code{this} [@code{libgamma_site_state_t*}]
The site state to initialise.
@item @code{method} [@code{int}]
The adjustment method (display server and protocol),
these are listed in @ref{Adjustment methods}.
@item @code{site} [@code{char*}]
The site identifier, unless it is @code{NULL}
it must a @code{free}:able. One the state is
destroyed the library will attempt to free it.
There you should not free it yourself, and it
must not be a string constant or allocated on
the stack. Note however that it will not be
@code{free}:d if this function fails.
The name of the default site can be fetched
with the function @code{libgamma_method_default_site}.
It takes the value of @code{method} as its only
argument and returns the default site's name.
The returned value may be @code{NULL}, and
the value should not be @code{free}:d. Because
it should not be @code{free}:d you should
duplicate it with @code{strdup} if it is not
@code{NULL}. This value is @code{NULL} if
the default site cannot be determined or if
the adjustment method only supports one site.
The function @code{libgamma_method_default_site_variable}
works identically is @code{libgamma_method_default_site}
except it returns the name of the environment
variable that is read by @code{libgamma_method_default_site}
to determine the default site for the adjustment
method.
@end table
To release all resources held by a site state,
call the function @code{libgamma_site_destroy},
whose only parameter is the site state to
destroy. It does not return any value, and is
always successful assuming that the site is
valid and properly initialised. If you also
want to free the allocation for the site state
itself call the function @code{libgamma_site_free}
instead. These two functions are identical
with the exception that the latter also
performs a @code{free} call for the state.
@node Partition
@subsection Partition
The state and identity of the partition is track by
the data structure @code{libgamma_partition_state_t}
@footnote{@code{struct libgamma_partition_state}}.
This structure contains the following variables:
@table @asis
%>for part in $(libgamma-method-extract --list --part-t); do
@item @code{%{part}} [@code{%(libgamma-method-extract --type --part-t $part)}]
%>libgamma-method-extract --part-t $part | texise
%>done
@end table
To select a partition and initialise its state
call the function @code{libgamma_partition_initialise}.
It returns zero on success, and and negative
@code{int} on failure. If the return is negative,
it is a @code{libgamma} error code; these are
listed in @ref{Errors}. For input
@code{libgamma_partition_initialise} takes three
arguments:
@table @asis
@item @code{this} [@code{libgamma_partition_state_t*}]
The partition state to initialise.
@item @code{site} [@code{libgamma_site_state_t*}]
The site state for the site that the
partition belongs to.
@item @code{partition} [@code{size_t}]
The the index of the partition within the site.
@end table
To release all resources held by a partition state,
call the function @code{libgamma_partition_destroy},
whose only parameter is the partition state to
destroy. It does not return any value, and is
always successful assuming that the partition is
valid and properly initialised. If you also
want to free the allocation for the partition state
itself call the function @code{libgamma_partition_free}
instead. These two functions are identical
with the exception that the latter also
performs a @code{free} call for the state.
@node CRTC
@subsection CRTC
The state and identity of the partition is track
by the data structure @code{libgamma_crtc_state_t}
@footnote{@code{struct libgamma_crtc_state}}.
This structure contains the following variables:
@table @asis
%>for crtc in $(libgamma-method-extract --list --crtc-t); do
@item @code{%{crtc}} [@code{%(libgamma-method-extract --type --crtc-t crtc)}]
%>libgamma-method-extract --crtc-t $crtc | texise
%>done
@end table
To select a CRTC and initialise its state
call the function @code{libgamma_crtc_initialise}.
It returns zero on success, and and negative
@code{int} on failure. If the return is negative,
it is a @code{libgamma} error code; these are
listed in @ref{Errors}. For input
@code{libgamma_crtc_initialise} takes three
arguments:
@table @asis
@item @code{this} [@code{libgamma_crtc_state_t*}]
The CRTC state to initialise.
@item @code{partition} [@code{libgamma_partition_state_t*}]
The partition state for the
partition that the CRTC belongs to.
@item @code{crtc} [@code{size_t}]
The the index of the CRTC within
the partition. Be aware that adjustment
methods do not necessarily order than
CRTC:s in the same way. For example,
display environment may order the
CRTC:s so that the primary monitors
has the CRTC with index 0; but cannot
be done if there is no concept of
primary monitors, such as the case
of the Linux TTY and the Linux Direct
Rendering Manager adjustment method.
@end table
To release all resources held by a CRTC state,
call the function @code{libgamma_crtc_destroy},
whose only parameter is the CRTC state to
destroy. It does not return any value, and is
always successful assuming that the CRTC is
valid and properly initialised. If you also
want to free the allocation for the CRTC state
itself call the function @code{libgamma_crtc_free}
instead. These two functions are identical
with the exception that the latter also
performs a @code{free} call for the state.
@node Adjustment method capabilities
@section Adjustment method capabilities
Adjustment methods have different
capabilities. Because of this, you
will probably want to know at least
some this the capabilities of the
adjustment method that you are using.
This can be used to filter out
unimportant information for the user.
The function @code{libgamma_method_capabilities},
which does not return anything, can be
used to get an adjustment methods capabilities.
This function takes two arguments. The first
argument is a @code{libgamma_method_capabilities_t*}
that will be filled with this information, and
the second argument is an @code{int} whose
value should be the adjument method's identifier.
@code{libgamma_method_capabilities_t}
@footnote{@code{struct libgamma_method_capabilities}} is
a data structure with the following variables:
@table @asis
%>for cap in $(libgamma-method-extract --list --cap-t); do
@item @code{%{cap}} [@code{%(libgamma-method-extract --type --cap-t $cap)}]
%>libgamma-method-extract --cap-t $cap | texise
%>if [ $cap = crtc_information ]; then
See @ref{CRTC information} for more information.
%>fi
%>done
@end table
@node CRTC information
@section CRTC information
It is possible query information about a CRTC
using the function @code{libgamma_get_crtc_information}.
This function returns an @code{int} whose value
is zero on success and @code{-1} if at least on
of the requested informations about the CRTC
could not successfully be read. This function
takes three arguments:
@table @asis
@item @code{this} [@code{libgamma_crtc_information_t*}]
Instance of a data structure to fill with the
information about the CRTC.
@item @code{crtc} [@code{libgamma_crtc_state_t*}]
The state of the CRTC whose information should be read.
@item @code{fields} [@code{int32_t}]
OR:ed identifiers for the information about
the CRTC that should be read.
@end table
The valid values that can be OR:ed for the
@code{fields} parameters are:
@table @code
%>for info in $(libgamma-method-extract --list --info); do
@item %{info}
%>libgamma-method-extract --info $info | texise
%>done
@end table
@code{libgamma_crtc_information_t}
@footnote{@code{struct libgamma_crtc_information}},
which is the data structure that the read
information is stored in, contains the following
variables:
@table @asis
%>for info in $(libgamma-method-extract --list --info-t); do
@item @code{%{info}} [@code{%(libgamma-method-extract --type --info-t $info)}]
%>libgamma-method-extract --info-t $info | texise
%>done
@end table
The data type for the variable @code{subpixel_order}
is @code{libgamma_subpixel_order_t}
@footnote{@code{enum libgamma_subpixel_order}}.
Its possible values are:
@table @code
%>for order in $(libgamma-method-extract --list --subpixel); do
@item %{order}
%>libgamma-method-extract --subpixel $order | texise
%>done
@end table
The data type for the variable @code{connector_type}
is @code{libgamma_connector_type_t}
@footnote{@code{enum libgamma_connector_type}}.
Its possible values are:
@table @code
%>for type in $(libgamma-method-extract --list --connector); do
@item %{type}
%>libgamma-method-extract --connector $type | texise
%>done
@end table
The variable @code{edid} is in raw format.
To convert it to a human-readable format
you should convert it to hexadecimal
representation. To do this, you can call
either of the functions
@table @code
@item libgamma_behex_edid
@itemx libgamma_behex_edid_lowercase
Converts to lowercase hexadecimal.
@item libgamma_behex_edid_uppercase
Converts to uppercase hexadecimal.
@end table
These functions return the EDID as
a hexadecimal NUL-terminated
non-@code{NULL} string of the data
type @code{char*}, which you should
free when you do not need it anymore.
If enough memory cannot be allocated
@code{NULL} is returned and
@code{errno} is set accordingly.
These functions take two arguments:
@table @asis
@item @code{edid} [@code{const unsigned char*}]
The EDID in raw representation.
@item @code{length} [@code{size_t}]
The length of @code{edid}.
@end table
The values of these arguments should
be the values of the variables
@code{edid} and @code{edid_length},
respectively.
If you want to identify a monitor by
it's EDID@footnote{EDID:s should be
unique and even if the manufacture
for the monitor has not made sure if
this it is very unlikely that it is
not.} it is more effective to convert
the EDID you want to raw format and
compare the raw format rather than
converting all monitors EDID to
hexadecimal representation. To do
this use the function
@code{libgamma_unhex_edid}. This
function takes the EDID in NUL-terminated
non-@code{NULL} hexadecimal
representation as a @code{const char*}
as its only argument. The function
returns the EDID in raw format as an
@code{unsigned char*}. The returned
value will be @code{NULL} if enough
memory for the output cannot be allocated
or if the input is a hexadecimal
representation of a byte array;
@code{errno} will be set accordingly.
To release resources that are held by a
@code{libgamma_crtc_information_t*}
whose variables have been set by
@code{libgamma_get_crtc_information}
call the function @code{libgamma_crtc_information_destroy}
with that @code{libgamma_crtc_information_t}
as its only argument. If you also
want to release the allocation if the
@code{libgamma_crtc_information_t*}
itself call the function
@code{libgamma_crtc_information_free} instead.
@node Gamma ramps
@section Gamma ramps
@command{libgamma} has support for 5
different gamma ramps structures:
16-bit depth, 32-bit depth, 64-bit
depth, single precision floating point,
and double precision floating point.
For best performance, you should
select the one that the adjustment
method uses. If you choose a type
other than what the adjustment
method uses, it will be converted.
@table @asis
@item @code{libgamma_gamma_ramps8_t} (@code{struct libgamma_gamma_ramps8})
8-bit integer (@code{uint8_t}).
Currently no adjustment method.
@item @code{libgamma_gamma_ramps16_t} (@code{struct libgamma_gamma_ramps16})
16-bit integer (@code{uint16_t}).
This is by far the most common.
@item @code{libgamma_gamma_ramps32_t} (@code{struct libgamma_gamma_ramps32})
32-bit integer (@code{uint32_t}).
Currently no adjustment method.
@item @code{libgamma_gamma_ramps64_t} (@code{struct libgamma_gamma_ramps64})
64-bit integer (@code{uint64_t}).
Currently no adjustment method.
@item @code{libgamma_gamma_rampsf_t} (@code{struct libgamma_gamma_rampsf})
Single precision floating point (@code{float}).
Currently this is only used by the
Quartz/CoreGraphics adjustment method.
@item @code{libgamma_gamma_rampsd_t} (@code{struct libgamma_gamma_rampsd})
Double precision floating point (@code{double}).
Currently no adjustment method.
@end table
These structures are very similar.
They have three ramps, one per channels,
each have an array that is a lookup
table with one associated variable that
describes the size of the table. They
only differ in the element type of the
arrays --- @code{red}, @code{green} and
@code{blue} --- whose type is specified
in the table above. @code{red}, @code{green}
and @code{blue} is a pointer of that type.
For example, for @code{libgamma_gamma_ramps16_t}
@code{red}, @code{green} and @code{blue}
are of type @code{uint16_t*} since the
element type is @code{uint16_t}.
@table @asis
@item @code{red_size} [@code{size_t}]
The number of stops in @code{red}.
@item @code{green_size} [@code{size_t}]
The number of stops in @code{green}.
@item @code{blue_size} [@code{size_t}]
The number of stops in @code{blue}.
@item @code{red}
The lookup table for the red channel.
@item @code{green}
The lookup table for the green channel.
@item @code{blue}
The lookup table for the blue channel.
@end table
Because of how the adjustment method's
own API's are designed @code{red},
@code{green} and @code{blue} should
actually one array. To make sure that
this is done the right way and to reduce
you own code @code{libgamma} provides
functions to create and destroy gamma
ramp structures.
@table @asis
@item @code{libgamma_gamma_ramps8_initialise} [@code{int *(libgamma_gamma_ramps8_t*)}]
@itemx @code{libgamma_gamma_ramps16_initialise} [@code{int *(libgamma_gamma_ramps16_t*)}]
@itemx @code{libgamma_gamma_ramps32_initialise} [@code{int *(libgamma_gamma_ramps32_t*)}]
@itemx @code{libgamma_gamma_ramps64_initialise} [@code{int *(libgamma_gamma_ramps64_t*)}]
@itemx @code{libgamma_gamma_rampsf_initialise} [@code{int *(libgamma_gamma_rampsf_t*)}]
@itemx @code{libgamma_gamma_rampsd_initialise} [@code{int *(libgamma_gamma_rampsd_t*)}]
Initialise a gamma ramp in the proper way
that allows all adjustment methods to read
from and write to it without causing
segmentation violation.
The input must have @code{red_size},
@code{green_size} and @code{blue_size}
set to the sizes of the gamma ramps
that should be allocated.
Zero is returned on success. On error
@code{-1} is returned and @code{errno}
is set accordingly. These functions can
only fail on @code{malloc} error.
@item @code{libgamma_gamma_ramps8_destroy} [@code{void *(libgamma_gamma_ramps8_t*)}]
@itemx @code{libgamma_gamma_ramps16_destroy} [@code{void *(libgamma_gamma_ramps16_t*)}]
@itemx @code{libgamma_gamma_ramps32_destroy} [@code{void *(libgamma_gamma_ramps32_t*)}]
@itemx @code{libgamma_gamma_ramps64_destroy} [@code{void *(libgamma_gamma_ramps64_t*)}]
@itemx @code{libgamma_gamma_rampsf_destroy} [@code{void *(libgamma_gamma_rampsf_t*)}]
@itemx @code{libgamma_gamma_rampsd_destroy} [@code{void *(libgamma_gamma_rampsd_t*)}]
Release resources that are held by a gamma
ramp structure that has been allocated by
@code{libgamma_gamma_ramps_initialise} or
otherwise initialises in the proper manner.
@item @code{libgamma_gamma_ramps8_free} [@code{void *(libgamma_gamma_ramps8_t*)}]
@itemx @code{libgamma_gamma_ramps16_free} [@code{void *(libgamma_gamma_ramps16_t*)}]
@itemx @code{libgamma_gamma_ramps32_free} [@code{void *(libgamma_gamma_ramps32_t*)}]
@itemx @code{libgamma_gamma_ramps64_free} [@code{void *(libgamma_gamma_ramps64_t*)}]
@itemx @code{libgamma_gamma_rampsf_free} [@code{void *(libgamma_gamma_rampsf_t*)}]
@itemx @code{libgamma_gamma_rampsd_free} [@code{void *(libgamma_gamma_rampsd_t*)}]
Release resources that are held by a gamma
ramp structure that has been allocated by
@code{libgamma_gamma_ramps*_initialise} or
otherwise initialises in the proper manner,
as well as release the pointer to the
structure.
@end table
To read the current gamma ramps for a
CRTC, you can use the function
@code{libgamma_crtc_get_gamma_ramps16}.
This function returns zero on success,
and a negative @code{int} on failure.
If the function fails, the return
value will be one of the error codes
listed in @ref{Errors}. The function
takes two arguments: the
@code{libgamma_crtc_state_t*}
for the CRTC, and a
@code{libgamma_gamma_rampsd_t*}
that will be filled with the
current gamma ramps, it must
have been initialise by
@code{libgamma_gamma_ramps16_initialise}
or in a compatible manner.
Similarly you can use
@code{libgamma_crtc_set_gamma_ramps16}
to apply gamma ramps to a CRTC.
This function has the same return
value and the same first argument
as @code{libgamma_crtc_get_gamma_ramps16},
but its second argument is a
@code{libgamma_gamma_rampsd_t}
rather than a
@code{libgamma_gamma_rampsd_t*}.
Alternatively, but with some
performance impact, you can use
the function
@code{libgamma_crtc_set_gamma_ramps16_f}.
The difference between
@code{libgamma_crtc_set_gamma_ramps16_f}
and @code{libgamma_crtc_set_gamma_ramps16}
is that the second argument is
substitute for three separate argument
that are used to generate the gamma ramps:
@table @asis
@item @code{red_function} [@code{libgamma_gamma_ramps16_fun*}]
The function that generates the the
gamma ramp for the red channel.
@item @code{green_function} [@code{libgamma_gamma_ramps16_fun*}]
The function that generates the the
gamma ramp for the green channel.
@item @code{blue_function} [@code{libgamma_gamma_ramps16_fun*}]
The function that generates the the
gamma ramp for the blue channel.
@end table
@code{libgamma_gamma_ramps16_fun} is a
@code{typedef} of @code{uint16_t (float encoding)}.
As input, it takes a [0, 1] float of
the encoding value and as output
it should return the output value.
These functions for reading and applying
gamma ramps are for @code{uint16_t} element
type gamma ramps. But it is possible
to use other element types as well:
@table @code
@item uint8_t
Substitute all @code{ramps16} for @code{ramps8}
in the the function names and date type
definition names.
@item uint32_t
Substitute all @code{ramps16} for @code{ramps32}
in the the function names and date type
definition names.
@item uint64_t
Substitute all @code{ramps16} for @code{ramps64}
in the the function names and date type
definition names.
@item float
Substitute all @code{ramps16} for @code{rampsf}
in the the function names and date type
definition names.
@item double
Substitute all @code{ramps16} for @code{rampsd}
in the the function names and date type
definition names.
@end table
@node Errors
@section Errors
Many @command{libgamma} functions will return
@command{libgamma} specific error codes rather
than setting @code{errno} and return @code{-1}.
However @code{errno} may have been set, but
should in such case be ignored unless
@code{LIBGAMMA_ERRNO_SET} has been returned.
Other functions do set @code{errno} and return
@code{-1}. Other functions may store the error
code. In this case @code{LIBGAMMA_ERRNO_SET}
cannot be stored but the value that @code{errno}
had when an error occured can be stored instead
of a @command{libgamma} specific error codes.
@code{errno} values are allows positive whereas
@command{libgamma} specific error codes are
allows negative. On success zero is returned
or stored.
If @code{LIBGAMMA_DEVICE_REQUIRE_GROUP} is returned
the ID of the required group is stored in
@code{libgamma_group_gid} and the name of that
group is stored in @code{libgamma_group_name}.
@code{NULL} is stored if the name of the group
cannto be determined. @file{libgamma.h} give
you access to these variables, they are defined
as @code{gid_t} (@code{short int} for Windows)
and @code{const char*} types respectively.
Additionally, except on Windows, these use thread
local storage, defined with the @code{__thread}
qualifier.
@command{libgamma} defines the following error codes
that its functions may return:
@table @code
%>for err in $(libgamma-error-extract --list | sort); do
@item %{err}
%>libgamma-error-extract $err | texise
%>done
@end table
The function @code{libgamma_name_of_error} can
be used to return the name of an libgamma error.
For example @code{libgamma_name_of_error(LIBGAMMA_ERRNO_SET)}
will return the string ``LIBGAMMA_ERRNO_SET''.
Similarly @code{libgamma_value_of_error("LIBGAMMA_ERRNO_SET")}
will return the value of @code{LIBGAMMA_ERRNO_SET}.
The value returned from @code{libgamma_name_of_error}
shall not be @code{free}:d. @code{NULL} is returned
if the value does nto refer to a @command{libgamma}
error. @code{libgamma_value_of_error} will return zero
if the input is @code{NULL} or string that is not the
name of a @command{libgamma} error.
The function @code{libgamma_perror} can be used to
print an error to stderr in a @code{perror} fashion.
However @code{libgamma_perror} will not translate the
@command{libgamma} errors into human-readable strings,
it will simply print the name of the error.
@code{libgamma_perror} takes two arguments:
a @code{const char*} that work like the parameter for
@code{perror}, and an @code{int} with the error code.
If the error code is the value of @code{LIBGAMMA_ERRNO_SET}
@code{perror} will be used to print the current error
stored in @code{errno}. If the error code is non-negative
(an @code{errno} value), that value will be stored in
@code{errno} and @code{perror} will be used to print it.
Additionally, if the error code is the value of
@code{LIBGAMMA_DEVICE_REQUIRE_GROUP} the required group
will be printed with its numerical value and, if known,
its name.
@node GNU Free Documentation License
@appendix GNU Free Documentation License
@include fdl.texinfo
@bye
|