GNU Octave 11.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 
Loading...
Searching...
No Matches
cdisplay.c
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 2009-2026 The Octave Project Developers
4//
5// See the file COPYRIGHT.md in the top-level directory of this
6// distribution or <https://octave.org/copyright/>.
7//
8// This file is part of Octave.
9//
10// Octave is free software: you can redistribute it and/or modify it
11// under the terms of the GNU General Public License as published by
12// the Free Software Foundation, either version 3 of the License, or
13// (at your option) any later version.
14//
15// Octave is distributed in the hope that it will be useful, but
16// WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with Octave; see the file COPYING. If not, see
22// <https://www.gnu.org/licenses/>.
23//
24////////////////////////////////////////////////////////////////////////
25
26#if defined (HAVE_CONFIG_H)
27# include "config.h"
28#endif
29
30#include <stdlib.h>
31
32#if defined (OCTAVE_USE_WINDOWS_API)
33# include <windows.h>
34#elif defined (HAVE_FRAMEWORK_CARBON)
35# include <Carbon/Carbon.h>
36#else
37# if defined (HAVE_X_WINDOWS)
38# include <X11/Xlib.h>
39# endif
40# if defined (HAVE_WAYLAND_CLIENT)
41# include <string.h>
42# include <wayland-client.h>
43# endif
44#endif
45
46#include "cdisplay.h"
47
48// Programming Note: This file exists so that we can hide system
49// header files that make heavy use of macros and C-style casts in a C
50// language file and avoid warnings about using old-style casts in C++.
51// Additionally, on OS X systems, including the Carbon.h header file
52// results in the declaration of a "panic" function that conflicts with
53// Octave's global panic function, so Carbon.h can't be included in any
54// file that also includes Octave's error.h header file.
55
56// Please do NOT eliminate this file and move code from here to
57// display.cc.
58
59#if defined (HAVE_WAYLAND_CLIENT)
60
61// struct to store display information
62struct s_display_info {
63 int ht;
64 int wd;
65 int ht_mm;
66 int wd_mm;
67 int scale;
68 int avail;
69};
70
71// set up Wayland output event listener to capture the relevant information
72
73static void
74oct_wl_geometry (void *data, struct wl_output *output, int x, int y,
75 int physical_width, int physical_height, int subpixel,
76 const char *make, const char *model, int transform)
77{
78 struct s_display_info *info = data;
79 info->ht_mm = physical_height;
80 info->wd_mm = physical_width;
81
82 octave_unused_parameter (output);
83 octave_unused_parameter (x);
84 octave_unused_parameter (y);
85 octave_unused_parameter (subpixel);
86 octave_unused_parameter (make);
87 octave_unused_parameter (model);
88 octave_unused_parameter (transform);
89}
90
91static void
92oct_wl_mode (void *data, struct wl_output *output, unsigned int flags,
93 int width, int height, int refresh)
94{
95 struct s_display_info *info = data;
96
97 if (flags & WL_OUTPUT_MODE_CURRENT)
98 {
99 info->wd = width;
100 info->ht = height;
101 info->avail = 1;
102 }
103
104 octave_unused_parameter (output);
105 octave_unused_parameter (refresh);
106}
107
108static void oct_wl_done (void *data, struct wl_output *output)
109{
110 octave_unused_parameter (data);
111 octave_unused_parameter (output);
112}
113
114static void
115oct_wl_scale (void *data, struct wl_output *output, int32_t factor)
116{
117 struct s_display_info *info = data;
118 info->scale = factor;
119
120 octave_unused_parameter (output);
121}
122
123static const struct wl_output_listener output_listener = {
124 .geometry = oct_wl_geometry,
125 .mode = oct_wl_mode,
126 .done = oct_wl_done,
127 .scale = oct_wl_scale
128};
129
130// register above output listener
131
132static void
133oct_wl_global (void *data, struct wl_registry *registry, uint32_t name,
134 const char *interface, uint32_t version)
135{
136 struct s_display_info *info = data;
137
138 // collect info only for output device
139 if (strcmp (interface, wl_output_interface.name) == 0)
140 {
141 // bind wl_output interface
142 struct wl_output *output = wl_registry_bind (registry, name,
143 &wl_output_interface, 1);
144 // set up event listener
145 wl_output_add_listener (output, &output_listener, info);
146 }
147
148 octave_unused_parameter (version);
149}
150
151static void
152oct_wl_global_remove (void *data, struct wl_registry *registry, uint32_t name)
153{
154 octave_unused_parameter (data);
155 octave_unused_parameter (registry);
156 octave_unused_parameter (name);
157}
158
159static const struct wl_registry_listener registry_listener = {
160 .global = oct_wl_global,
161 .global_remove = oct_wl_global_remove
162};
163
164#endif
165
166const char *
167octave_get_display_info (const char *dpy_name, int *ht, int *wd, int *dp,
168 double *rx, double *ry, int *dpy_avail)
169{
170 const char *msg = NULL;
171
172 *dpy_avail = 0;
173
174 double ht_mm = 0.0;
175 double wd_mm = 0.0;
176
177#if defined (OCTAVE_USE_WINDOWS_API)
178
179 octave_unused_parameter (dpy_name);
180
181 HDC hdc = GetDC (0);
182
183 if (hdc)
184 {
185 *dp = GetDeviceCaps (hdc, BITSPIXEL);
186
187 *ht = GetDeviceCaps (hdc, VERTRES);
188 *wd = GetDeviceCaps (hdc, HORZRES);
189
190 ht_mm = GetDeviceCaps (hdc, VERTSIZE);
191 wd_mm = GetDeviceCaps (hdc, HORZSIZE);
192
193 *dpy_avail = 1;
194 }
195 else
196 msg = "no graphical display found";
197
198#elif defined (HAVE_FRAMEWORK_CARBON)
199
200 octave_unused_parameter (dpy_name);
201
202 CGDirectDisplayID display = CGMainDisplayID ();
203
204 if (display)
205 {
206#if defined (HAVE_CARBON_CGDISPLAYBITSPERPIXEL)
207
208 *dp = CGDisplayBitsPerPixel (display);
209
210#else
211
212 /* FIXME: This will only work for MacOS > 10.5. For earlier versions
213 this code is not needed (use CGDisplayBitsPerPixel instead). */
214
215 CGDisplayModeRef mode = CGDisplayCopyDisplayMode (display);
216 CFStringRef pixelEncoding = CGDisplayModeCopyPixelEncoding (mode);
217
218 if (CFStringCompare (pixelEncoding, CFSTR (IO32BitDirectPixels), 0) == 0)
219 *dp = 32;
220 else if (CFStringCompare (pixelEncoding,
221 CFSTR (IO16BitDirectPixels), 0) == 0)
222 *dp = 16;
223 else
224 *dp = 8;
225
226#endif
227
228 *ht = CGDisplayPixelsHigh (display);
229 *wd = CGDisplayPixelsWide (display);
230
231 CGSize sz_mm = CGDisplayScreenSize (display);
232
233 /* For MacOS >= 10.6, CGSize is a struct keeping 2 CGFloat
234 values, but the CGFloat typedef is not present on older
235 systems, so use double instead. */
236
237 ht_mm = sz_mm.height;
238 wd_mm = sz_mm.width;
239
240 *dpy_avail = 1;
241 }
242 else
243 msg = "no graphical display found";
244
245#elif defined (HAVE_X_WINDOWS) || defined (HAVE_WAYLAND_CLIENT)
246
247# if defined (HAVE_X_WINDOWS)
248
249 /* If dpy_name is NULL, XopenDisplay will look for DISPLAY in the
250 environment. */
251
252 Display *display = XOpenDisplay (dpy_name);
253
254 if (display)
255 {
256 Screen *screen = DefaultScreenOfDisplay (display);
257
258 if (screen)
259 {
260 *dp = DefaultDepthOfScreen (screen);
261
262 *ht = HeightOfScreen (screen);
263 *wd = WidthOfScreen (screen);
264
265 int screen_number = XScreenNumberOfScreen (screen);
266
267 ht_mm = DisplayHeightMM (display, screen_number);
268 wd_mm = DisplayWidthMM (display, screen_number);
269
270 *dpy_avail = 1;
271 }
272# if ! defined (HAVE_WAYLAND_CLIENT)
273 else
274 msg = "X11 display has no default screen";
275# endif
276
277 XCloseDisplay (display);
278 }
279# if ! defined (HAVE_WAYLAND_CLIENT)
280 else
281 msg = "unable to open X11 DISPLAY";
282# endif
283# endif
284
285# if defined (HAVE_WAYLAND_CLIENT)
286 if (*dpy_avail == 0)
287 {
288 // try to connect to Wayland display
289 struct wl_display *wldisplay = wl_display_connect (dpy_name);
290
291 if (wldisplay)
292 {
293 struct s_display_info info = {0};
294
295 // set up Wayland registry
296 struct wl_registry *registry = wl_display_get_registry (wldisplay);
297 // add output listener
298 wl_registry_add_listener (registry, &registry_listener, &info);
299 // process display events
300 // first roundtrip to get registry events
301 wl_display_roundtrip (wldisplay);
302 // second roundtrip to get output events
303 wl_display_roundtrip (wldisplay);
304 // disconnect display
305 wl_display_disconnect (wldisplay);
306
307 if (info.avail)
308 {
309 // FIXME: There is no easy way to query the pixel depth using
310 // Wayland. The closest might be to query the used buffer
311 // format and to try and defer the pixel depth from that.
312 // But that is not easily done. So, just assume a pixel
313 // depth of 32 bits.
314 *dp = 32;
315
316 *ht = info.ht;
317 *wd = info.wd;
318
319 ht_mm = info.ht_mm;
320 wd_mm = info.wd_mm;
321
322 *dpy_avail = 1;
323 }
324 else
325# if defined (HAVE_X_WINDOWS)
326 msg = "no Wayland or X11 display available";
327# else
328 msg = "no Wayland display available";
329# endif
330 }
331 else
332# if defined (HAVE_X_WINDOWS)
333 msg = "unable to open Wayland or X11 display";
334# else
335 msg = "unable to open Wayland display";
336# endif
337 }
338# endif
339
340#else
341
342 octave_unused_parameter (dpy_name);
343 octave_unused_parameter (ht);
344 octave_unused_parameter (wd);
345 octave_unused_parameter (dp);
346 octave_unused_parameter (rx);
347 octave_unused_parameter (ry);
348
349 msg = "no graphical display found";
350
351#endif
352
353 if (*dpy_avail)
354 {
355 if (wd_mm == 0 || ht_mm == 0)
356 {
357 msg = "screen width or height reported to be zero";
358
359 // Sizes reported as zero have been found on some systems.
360 // For example, X/Wayland running inside virtualbox.
361
362 // Guess a DPI.
363
364 *rx = 96.0;
365 *ry = 96.0;
366 }
367 else
368 {
369 *rx = *wd * 25.4 / wd_mm;
370 *ry = *ht * 25.4 / ht_mm;
371 }
372 }
373
374 return msg;
375}
const char * octave_get_display_info(const char *dpy_name, int *ht, int *wd, int *dp, double *rx, double *ry, int *dpy_avail)
Definition cdisplay.c:167
void scale(Matrix &m, double x, double y, double z)
Definition graphics.cc:5741
ColumnVector transform(const Matrix &m, double x, double y, double z)
Definition graphics.cc:5709
bool strcmp(const T &str_a, const T &str_b)
Octave string utility functions.
F77_RET_T const F77_DBLE * x