Ansel
0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
display_profile.c
Go to the documentation of this file.
1
/*
2
* This file is part of darktable,
3
* Copyright (C) 2016-2022 the darktable authors.
4
* Copyright (C) 2026 Aurélien PIERRE.
5
*
6
* darktable is free software: you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation, either version 3 of the License, or
9
* (at your option) any later version.
10
*
11
* darktable is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
15
*
16
* You should have received a copy of the GNU General Public License
17
* along with darktable. If not, see <http://www.gnu.org/licenses/>.
18
*/
19
20
/* Monitor ICC profile interrogation, extracted from common/colorspaces.c.
21
*
22
* For X11 this follows the ICC profile specification version 0.2 from
23
* http://burtonini.com/blog/computers/xicc, based on code from Gimp's
24
* modules/cdisplay_lcms.c.
25
*/
26
27
#include "
system/display_profile.h
"
28
#include "
system/mem_alloc.h
"
29
30
#include "
system/macros.h
"
31
32
#ifdef _WIN32
33
#include <dwmapi.h>
34
#include <gdk/gdkwin32.h>
35
#endif
36
37
#if 0
38
#include <ApplicationServices/ApplicationServices.h>
39
#include <Carbon/Carbon.h>
40
#include <CoreServices/CoreServices.h>
41
#endif
42
43
#if defined GDK_WINDOWING_X11
44
/* GdkMonitor carries no index of its own, and the X ICC atom is numbered by monitor
45
* index, so the index has to be recovered by identity. */
46
static
int
_monitor_index
(
GdkMonitor
*
monitor
)
47
{
48
GdkDisplay
*display =
gdk_monitor_get_display
(
monitor
);
49
const
int
n_monitors
=
gdk_display_get_n_monitors
(display);
50
for
(
int
i
= 0;
i
<
n_monitors
;
i
++)
51
{
52
if
(
gdk_display_get_monitor
(display,
i
) ==
monitor
)
return
i
;
53
}
54
55
return
-1;
56
}
57
#endif
58
59
void
dt_display_profile_read
(
GtkWidget
*widget,
guint8
**buffer, gint *buffer_size, gchar **source)
60
{
61
if
(
IS_NULL_PTR
(widget) ||
IS_NULL_PTR
(buffer) ||
IS_NULL_PTR
(buffer_size) ||
IS_NULL_PTR
(source))
return
;
62
63
#if defined GDK_WINDOWING_X11
64
65
GdkWindow
*
window
=
gtk_widget_get_window
(widget);
66
GdkScreen
*screen =
gtk_widget_get_screen
(widget);
67
if
(
IS_NULL_PTR
(screen)) screen =
gdk_screen_get_default
();
68
69
GdkDisplay
*display =
gtk_widget_get_display
(widget);
70
const
int
monitor
=
_monitor_index
(
gdk_display_get_monitor_at_window
(display,
window
));
71
72
char
*
atom_name
;
73
if
(
monitor
> 0)
74
atom_name
=
g_strdup_printf
(
"_ICC_PROFILE_%d"
,
monitor
);
75
else
76
atom_name
=
g_strdup
(
"_ICC_PROFILE"
);
77
78
*source =
g_strdup_printf
(
"xatom %s"
,
atom_name
);
79
80
GdkAtom
type
=
GDK_NONE
;
81
gint format = 0;
82
gdk_property_get
(
gdk_screen_get_root_window
(screen),
gdk_atom_intern
(
atom_name
,
FALSE
),
GDK_NONE
, 0,
83
64 * 1024 * 1024,
FALSE
, &
type
, &format, buffer_size, buffer);
84
dt_free
(
atom_name
);
85
86
#elif defined GDK_WINDOWING_QUARTZ
87
#if 0
88
GdkScreen
*screen =
gtk_widget_get_screen
(widget);
89
if
(
IS_NULL_PTR
(screen)) screen =
gdk_screen_get_default
();
90
const
int
monitor
=
gdk_screen_get_monitor_at_window
(screen,
gtk_widget_get_window
(widget));
91
92
CGDirectDisplayID
ids[
monitor
+ 1];
93
uint32_t
total_ids
;
94
CMProfileRef
prof
=
NULL
;
95
if
(
CGGetOnlineDisplayList
(
monitor
+ 1, &ids[0], &
total_ids
) ==
kCGErrorSuccess
&&
total_ids
==
monitor
+ 1)
96
CMGetProfileByAVID
(ids[
monitor
], &
prof
);
97
if
(!
IS_NULL_PTR
(
prof
))
98
{
99
CFDataRef
data;
100
data =
CMProfileCopyICCData
(
NULL
,
prof
);
101
CMCloseProfile
(
prof
);
102
103
UInt8 *
tmp_buffer
= (UInt8 *)
g_malloc
(
CFDataGetLength
(data));
104
CFDataGetBytes
(data,
CFRangeMake
(0,
CFDataGetLength
(data)),
tmp_buffer
);
105
106
*buffer = (
guint8
*)
tmp_buffer
;
107
*buffer_size =
CFDataGetLength
(data);
108
109
CFRelease
(data);
110
}
111
*source =
g_strdup
(
"osx color profile api"
);
112
#endif
113
114
#elif defined G_OS_WIN32
115
116
GdkWindow
*
window
=
gtk_widget_get_window
(widget);
117
HWND
hwnd
= (
HWND
)
gdk_win32_window_get_handle
(
window
);
// get window handle
118
HMONITOR
hMonitor
=
MonitorFromWindow
(
hwnd
,
MONITOR_DEFAULTTONEAREST
);
// get monitor handle
119
if
(
IS_NULL_PTR
(
hMonitor
))
return
;
// TODO log error
120
121
MONITORINFOEX
monitorInfo
;
122
monitorInfo
.cbSize =
sizeof
(
MONITORINFOEX
);
123
if
(!
GetMonitorInfoW
(
hMonitor
, (
LPMONITORINFO
)&
monitorInfo
))
return
;
// TODO log error
124
125
HDC
hdc
=
CreateIC
(
L
"MONITOR"
,
monitorInfo
.szDevice,
NULL
,
NULL
);
// device-info context of the monitor
126
if
(!
IS_NULL_PTR
(
hdc
))
127
{
128
DWORD len = 0;
129
GetICMProfile
(
hdc
, &len,
NULL
);
130
wchar_t
*
wpath
=
g_new
(
wchar_t
, len);
131
132
if
(
GetICMProfileW
(
hdc
, &len,
wpath
))
133
{
134
gchar *path =
g_utf16_to_utf8
(
wpath
, -1,
NULL
,
NULL
,
NULL
);
135
if
(path)
136
{
137
gsize
size
;
138
g_file_get_contents
(path, (gchar **)buffer, &
size
,
NULL
);
139
*buffer_size =
size
;
140
dt_free
(path);
141
}
142
}
143
dt_free
(
wpath
);
144
DeleteDC
(
hdc
);
145
}
146
*source =
g_strdup
(
"windows color profile api"
);
147
148
#endif
149
}
150
151
// clang-format off
152
// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
153
// vim: shiftwidth=2 expandtab tabstop=2 cindent
154
// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
155
// clang-format on
FALSE
#define FALSE
Definition
ashift_lsd.c:158
GtkWidget
struct _GtkWidget GtkWidget
GtkWidget, opaque, spelled exactly as GTK spells it.
Definition
colorspaces.h:98
i
const float i
Definition
colorspaces_inline_conversions.h:441
L
const float L
Definition
colorspaces_inline_conversions.h:494
dt_display_profile_read
void dt_display_profile_read(GtkWidget *widget, guint8 **buffer, gint *buffer_size, gchar **source)
Definition
display_profile.c:59
display_profile.h
type
_lib_location_type_t type
Definition
location.c:1
macros.h
IS_NULL_PTR
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
Definition
macros.h:65
mem_alloc.h
dt_free
#define dt_free(ptr)
Definition
mem_alloc.h:97
size
size_t size
Definition
mipmap_cache.c:3
window
GtkWidget * window
Definition
supervisor_window.c:39
src
system
display_profile.c
Generated by
1.9.8