Tscope5
display.c
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // __ ______
4 // / /_______________ ____ ___ / ____/
5 // / __/ ___/ ___/ __ \/ __ \/ _ \ /___ )
6 // / /_(__ ) /__/ /_/ / /_/ / __/ ____/ /
7 // \__/____/\___/\____/ .___/\___/ /_____/
8 // /_/
9 //
10 /// \file display.c
11 /// Definitions of display functions.
12 /// \example display01.c
13 /// \example display01.cpp
14 /// \example display02.c
15 /// \example display03.c
16 /// \example display04.c
17 /// \example display05.c
18 /// \example display06.c
19 ////////////////////////////////////////////////////////////////////////////////
20 
21 
22 #include "../include/tscope5/display.h"
23 #include "../include/tscope5/graphics.h"
24 #include "../include/tscope5/bitmaps.h"
25 #include "../include/tscope5/display_internal.h"
26 #include "../include/tscope5/system_internal.h"
27 #include "../include/tscope5/graphics_internal.h"
28 
29 #include <math.h>
30 
31 
32 ////////////////////////////////////////////////////////////////////////////////
33 /// @name Basic operations
34 /// A display can either be a window or a fullscreen display.
35 /// There are three basic display operations:
36 /// - You will need to install a display with ts5_install_display()
37 /// before anything can be drawn.
38 /// - The contents of a display can be cleared with ts5_clear_display().
39 /// - Anything that is drawn on a display only becomes visible
40 /// after a call to ts5_flip_display().
41 //@{
42 ////////////////////////////////////////////////////////////////////////////////
43 
44 
45 ////////////////////////////////////////////////////////////////////////////////
46 /// Open a new display.
47 ///
48 /// \return The index of the new display.
49 ///
50 /// TS5_FULLSCREEN_WINDOW mode:
51 /// - A fullscreen display will be opened using the same
52 /// display size and refreshrate as the desktop.
53 /// - In this mode, the display size, position and refreshrate
54 /// cannot be set by the user. These parameters will be ignored.
55 /// - Tscope5 will check whether the new display is the first
56 /// display on the adapter. If not, the program is aborted.
57 ///
58 /// TS5_FULLSCREEN mode:
59 /// - A fullscreen display will be opened.
60 /// The user can specify the display size and refreshrate.
61 /// - In this mode, the display position cannot be set by the user.
62 /// This parameter will be ignored.
63 /// - Tscope5 will check whether the new display is the
64 /// first display on the adapter. If not, the program is aborted.
65 /// - Tscope5 will check whether the display size and refreshrate is
66 /// supported by the adapter. If not, the program is aborted.
67 /// - A call to ts5_print_status() will list all combinations of
68 /// size and refreshrate that are supported by the adapter.
69 ///
70 /// TS5_WINDOWED mode:
71 /// - Opens a window. The user can specifiy the display size and position.
72 /// - In this mode, the refreshrate cannot be set by the user.
73 /// This parameter will be ignored.
74 /// - Tscope5 will check whether the adapter is already in use by
75 /// a TS5_FULLSCREEN_WINDOW or TS5_FULLSCREEN display.
76 /// If so, the program is aborted.
77 /// - Tscope5 will check whether the window will fit on the display.
78 /// If not, the dimensions of the display are reduced.
79 /// - Tscope5 will check whether the window will be visible on the screen.
80 /// If not, the window position is changed.
81 ///
82 /// The new display is the drawing target for future drawing operations.
83 ////////////////////////////////////////////////////////////////////////////////
85 {
86  ts5_check_display("ts5_install_display");
87 
88  TS5_DISPLAY_STATUS request = ts5_nextdisplay;
89 
90  // TS5_FULLSCREEN_WINDOW
91  if (ts5_nextdisplay.display_mode == TS5_FULLSCREEN_WINDOW) {
92 
93  // the adapter cannot be in use by another tscope5 display
94  int i;
95  for (i = 0; i < _ts5_status.num_displays; i++) {
96 
97  if (_ts5_status.display[i].adapter
98  == ts5_nextdisplay.adapter) {
99  ts5_fatal ("%s: %s, %s (%d)\n", "ts5_install_display",
100  "cannot open fullscreen display",
101  "adapter already in use by another display", i);
102  }
103  }
104 
105  // copy relevant settings
106  request.w = 320;
107  request.h = 240;
108  request.x = -1;
109  request.y = -1;
110  request.refreshrate = -1;
111  request.display_mode = TS5_FULLSCREEN_WINDOW;
112  request.vsync_mode = ts5_nextdisplay.vsync_mode;
113  request.multisampling = ts5_nextdisplay.multisampling;
114  request.sampling_factor = ts5_nextdisplay.sampling_factor;
115 
116  #ifdef TS5_RASPBERRYPI
117 
118  request.display_mode = TS5_FULLSCREEN;
119  request.w = ts5_get_display_adapter_width(1);
120  request.h = ts5_get_display_adapter_height(1);
121 
122 
123  #endif
124  }
125 
126 
127  // TS5_FULLSCREEN
128  if (ts5_nextdisplay.display_mode == TS5_FULLSCREEN) {
129 
130  // the adapter cannot be in use by another tscope5 display
131  int i;
132  for (i = 0; i < _ts5_status.num_displays; i++) {
133 
134  if (_ts5_status.display[i].adapter
135  == ts5_nextdisplay.adapter) {
136  ts5_fatal ("%s: %s, %s (%d)\n", "ts5_install_display",
137  "cannot open fullscreen display",
138  " adapter already in use by another display", i);
139  }
140  }
141 
142  // is the combination of display size and refresh rate supported by
143  // the adapter?
144  ALLEGRO_DISPLAY_MODE *mode;
145  mode = (ALLEGRO_DISPLAY_MODE *)al_malloc(sizeof(ALLEGRO_DISPLAY_MODE));
146  int nmodes = al_get_num_display_modes();
147  int found=0;
148 
149  for (i=0; i<nmodes; i++) {
150 
151  mode = al_get_display_mode(i, mode);
152 
153  if (mode->width==ts5_nextdisplay.w
154  && mode->height==ts5_nextdisplay.h
155  && (mode->refresh_rate==ts5_nextdisplay.refreshrate
156  || mode->refresh_rate==0)) {
157  found=1;
158  }
159  }
160 
161  al_free(mode);
162 
163  if (!found) {
164  ts5_fatal ("%s: %s (%d, %d) %s (%d) %s %d\n",
165  "ts5_install_display",
166  "the requested combination of size",
168  "and refreshate", ts5_nextdisplay.refreshrate,
169  "is not supported by display adapter",
170  ts5_nextdisplay.adapter);
171  }
172 
173  // copy relevant settings
174  request.w = ts5_nextdisplay.w;
175  request.h = ts5_nextdisplay.h;
176  request.x = -1;
177  request.y = -1;
178  request.refreshrate = ts5_nextdisplay.refreshrate;
179  request.display_mode = TS5_FULLSCREEN;
180  request.vsync_mode = ts5_nextdisplay.vsync_mode;
181  request.multisampling = ts5_nextdisplay.multisampling;
182  request.sampling_factor = ts5_nextdisplay.sampling_factor;
183  }
184 
185  // TS5_WINDOWED
186  if (ts5_nextdisplay.display_mode == TS5_WINDOWED) {
187 
188  // the adapter cannot be in used by a
189  // TS5_FULLSCREEN_WINDOW or TS5_FULLSCREEN display
190  int i;
191  for (i = 0; i < _ts5_status.num_displays; i++) {
192 
193  if (_ts5_status.display[i].adapter
194  == ts5_nextdisplay.adapter
195  && (_ts5_status.display[i].display_mode
196  == TS5_FULLSCREEN
197  || _ts5_status.display[i].display_mode
198  == TS5_FULLSCREEN_WINDOW)) {
199 
200  ts5_fatal ("%s: %s, %s (%d)\n", "ts5_install_display",
201  "cannot open display",
202  " adapter already in use by a fullscreen display",
203  i);
204  }
205  }
206 
207  // window should be at least 320 pixels wide
208  // and smaller than the width of the monitor
209  if (ts5_nextdisplay.w < 320 ) {
210  request.w = 320;
211  ts5_log(TS5_LOGLEVEL_1, "%s: %s %d (was %d)\n",
212  "ts5_install_display", "adjusting display width to",
213  request.w, ts5_nextdisplay.w);
214  }
215  else if (ts5_nextdisplay.w
216  > _ts5_status.display_adapter
217  [ts5_nextdisplay.adapter].w) {
218 
219  request.w = _ts5_status.display_adapter[ts5_nextdisplay.adapter].w;
220 
221  ts5_log(TS5_LOGLEVEL_1, "%s: %s %d (was %d)\n",
222  "ts5_install_display", "adjusting display width to",
223  request.w, ts5_nextdisplay.w);
224  }
225  else {
226  request.w = ts5_nextdisplay.w;
227  }
228 
229  // window should be at least 240 pixels high
230  // and smaller than the height of the monitor
231  if (ts5_nextdisplay.h < 240 ) {
232  request.h = 240;
233  ts5_log(TS5_LOGLEVEL_1, "%s: %s %d (was %d)\n",
234  "ts5_install_display", "adjusting display height to",
235  request.h, ts5_nextdisplay.h);
236  }
237  else if (ts5_nextdisplay.h
238  > _ts5_status.display_adapter
239  [ts5_nextdisplay.adapter].h) {
240 
241  request.h = _ts5_status.display_adapter
242  [ts5_nextdisplay.adapter].h;
243 
244  ts5_log(TS5_LOGLEVEL_1, "%s: %s %d (was %d)\n",
245  "ts5_install_display", "adjusting display height to",
246  request.h, ts5_nextdisplay.h);
247  }
248  else {
249  request.h = ts5_nextdisplay.h;
250  }
251 
252  request.x = ts5_nextdisplay.x;
253  request.y = ts5_nextdisplay.y;
254 
255  if (request.x == -1) {
256 
257  if (_ts5_status.graphics.coordinate_system
258  == TS5_CARTESIAN_COORDINATES) {
259 
260  request.x = (_ts5_status.display_adapter
261  [request.adapter].w - request.w)/2;
262  }
263  else {
264  request.x = 0;
265  }
266 
267  request.x += _ts5_status.display_adapter[request.adapter].x1;
268  }
269 
270  if (request.y == -1) {
271 
272  if (_ts5_status.graphics.coordinate_system
273  == TS5_CARTESIAN_COORDINATES) {
274 
275  request.y = (_ts5_status.display_adapter
276  [request.adapter].h - request.h)/2;
277  }
278  else {
279  request.y = 0;
280  }
281 
282  request.y += _ts5_status.display_adapter[request.adapter].y1;
283  }
284 
285  // copy relevant settings
286  request.refreshrate = -1;
287  request.display_mode = TS5_WINDOWED;
288  request.vsync_mode = ts5_nextdisplay.vsync_mode;
289  request.multisampling = ts5_nextdisplay.multisampling;
290  request.sampling_factor = ts5_nextdisplay.sampling_factor;
291  }
292 
293 
294  // pass on display parameters to Allegro
295  al_set_new_display_adapter(request.adapter);
296  al_set_new_display_refresh_rate(request.refreshrate);
297 
298  al_set_new_display_option(ALLEGRO_VSYNC, (int)request.vsync_mode,
299  ALLEGRO_SUGGEST);
300 
301 
302  if (request.display_mode == TS5_WINDOWED) {
303  al_set_new_window_position(request.x, request.y);
304  }
305 
306  if (request.display_mode == TS5_FULLSCREEN_WINDOW) {
307  al_set_new_window_position(INT_MAX, INT_MAX);
308  }
309 
310  al_set_new_display_flags(request.display_mode);
311 
312  // update counters
313  _ts5_status.num_displays++;
314  _ts5_status.active_display = _ts5_status.num_displays - 1;
315 
316  // try top open display
317  ts5_log(TS5_LOGLEVEL_1, "ts5_install_display: Opening display\n");
318 
319  TS5_DISPLAY **display;
320  display = al_realloc(_ts5_data.display,
321  _ts5_status.num_displays * sizeof(TS5_DISPLAY *));
322 
323  if (display == NULL) {
324  ts5_fatal("%s: %s\n", "ts5_install_display",
325  "failed to allocate memory for display pointer");
326  }
327 
328  _ts5_data.display = (TS5_DISPLAY **) display;
329 
330  _ts5_data.display[_ts5_status.active_display] =
331  al_create_display(request.w, request.h);
332 
333  if (!_ts5_data.display[_ts5_status.active_display]) {
334  ts5_fatal("ts5_install_display: could not open display\n");
335  }
336 
337  if (ts5_nextdisplay.display_mode == TS5_FULLSCREEN_WINDOW) {
338  request.w = _ts5_status.display_adapter[request.adapter].w;
339  request.h = _ts5_status.display_adapter[request.adapter].h;
340  }
341 
342  // make a display buffer
343  TS5_BITMAP **display_buffer;
344 
345  display_buffer = al_realloc(_ts5_data.display_buffer,
346  _ts5_status.num_displays * sizeof(TS5_BITMAP *));
347 
348  if (display_buffer == NULL) {
349  ts5_fatal("%s: %s\n", "ts5_install_display",
350  "failed to allocate memory for display buffer pointer");
351  }
352 
353  _ts5_data.display_buffer = (TS5_BITMAP **) display_buffer;
354 
355  _ts5_data.display_buffer[_ts5_status.active_display] =
356  al_create_bitmap(request.w * request.sampling_factor, request.h * request.sampling_factor);
357 
358  if (!_ts5_data.display_buffer[_ts5_status.active_display]) {
359  ts5_fatal("ts5_install_display: could not open display buffer\n");
360  }
361 
362 
363  // make a backup of the display buffer
364  TS5_BITMAP **display_backup;
365 
366  display_backup = al_realloc(_ts5_data.display_backup,
367  _ts5_status.num_displays * sizeof(TS5_BITMAP *));
368 
369  if (display_backup == NULL) {
370  ts5_fatal("%s: %s\n", "ts5_install_display",
371  "failed to allocate memory for display backup pointer");
372  }
373 
374  _ts5_data.display_backup = (TS5_BITMAP **) display_backup;
375 
376  _ts5_data.display_backup[_ts5_status.active_display] =
377  al_create_bitmap(request.w * request.sampling_factor, request.h * request.sampling_factor);
378 
379  if (!_ts5_data.display_backup[_ts5_status.active_display]) {
380  ts5_fatal("ts5_install_display: could not open display backup\n");
381  }
382 
383 
384  // copy the settings in the structure
385  TS5_DISPLAY_STATUS *display_status;
386  display_status = al_realloc(_ts5_status.display,
387  _ts5_status.num_displays * sizeof(TS5_DISPLAY_STATUS));
388 
389  if (display_status == NULL) {
390  ts5_fatal("%s: %s\n", "ts5_install_display",
391  "failed to allocate memory for display settings");
392  }
393 
394  _ts5_status.display = (TS5_DISPLAY_STATUS *) display_status;
395 
396  _ts5_status.display[_ts5_status.active_display].adapter =
397  request.adapter;
398 
399  if (request.display_mode==TS5_WINDOWED) {
400 
401  al_get_window_position(_ts5_data.display[_ts5_status.active_display],
402  &request.x, &request.y);
403 
404  if (request.x + request.w
405  > _ts5_status.display_adapter[ts5_nextdisplay.adapter].x2) {
406 
407  int oldw = request.w;
408 
409  request.w = _ts5_status.display_adapter
410  [ts5_nextdisplay.adapter].x2 - request.x;
411 
412  al_resize_display(_ts5_data.display[_ts5_status.active_display],
413  request.w, request.h);
414 
415  ts5_log(TS5_LOGLEVEL_1, "%s: %s %d (was %d)\n",
416  "ts5_install_display", "adjusting display width to",
417  request.w, oldw);
418  }
419 
420  if (request.y + request.h > _ts5_status.display_adapter
421  [ts5_nextdisplay.adapter].y2) {
422 
423  int oldh = request.h;
424 
425  request.h = _ts5_status.display_adapter
426  [ts5_nextdisplay.adapter].y2 - request.y;
427 
428  al_resize_display(_ts5_data.display[_ts5_status.active_display],
429  request.w, request.h);
430 
431  al_set_window_position(_ts5_data.display
432  [_ts5_status.active_display],
433  request.x, request.y + (request.h-oldh));
434 
435  ts5_log(TS5_LOGLEVEL_1, "%s: %s %d (was %d)\n",
436  "ts5_install_display", "adjusting display height to",
437  request.h, oldh);
438 
439  al_get_window_position(
440  _ts5_data.display[_ts5_status.active_display],
441  &request.x, &request.y);
442  }
443 
444  request.x -= _ts5_status.display_adapter[request.adapter].x1;
445  request.y -= _ts5_status.display_adapter[request.adapter].y1;
446 
447  if (_ts5_status.graphics.coordinate_system
448  == TS5_CARTESIAN_COORDINATES) {
449 
450  request.x =
451  request.x
452  - (_ts5_status.display_adapter[request.adapter].w
453  - request.w)/2.0;
454 
455  request.y =
456  (_ts5_status.display_adapter[request.adapter].h
457  - request.h)/2.0
458  - request.y;
459  }
460  }
461 
462  _ts5_status.display[_ts5_status.active_display].x = request.x;
463  _ts5_status.display[_ts5_status.active_display].y = request.y;
464  _ts5_status.display[_ts5_status.active_display].w = request.w;
465  _ts5_status.display[_ts5_status.active_display].h = request.h;
466 
467  _ts5_status.display[_ts5_status.active_display].refreshrate =
468  ts5_nextdisplay.refreshrate;
469 
470  _ts5_status.display[_ts5_status.active_display].display_mode =
471  request.display_mode;
472 
473  _ts5_status.display[_ts5_status.active_display].vsync_mode =
474  request.vsync_mode;
475 
476  _ts5_status.display[_ts5_status.active_display].multisampling =
477  request.multisampling;
478 
479  _ts5_status.display[_ts5_status.active_display].sampling_factor =
480  request.sampling_factor;
481 
482  // set the new display as the drawing target and clear the display
483  ts5_set_drawing_target(_ts5_data.display_backup
484  [_ts5_status.active_display]);
485  al_clear_to_color(_ts5_status.graphics.background_color);
486 
487  ts5_set_drawing_target(_ts5_data.display_buffer
488  [_ts5_status.active_display]);
489 
490 
491  // clear and flip
492  int i;
493  for(i=0; i<4; i++) {
494  al_flip_display();
495  }
496  _ts5_status.display[_ts5_status.active_display].last_sync = al_get_time();
499 
500  // set atexit and return
501  atexit(ts5_uninstall_displays);
502 
503  return _ts5_status.active_display;
504 }
505 
506 
507 ////////////////////////////////////////////////////////////////////////////////
508 /// Clear the current drawing target.
509 ///
510 /// The drawing target can either be a display or a bitmap (to clear a bitmap:
511 /// set it as drawing target and call ts5_clear_display()).
512 ///
513 /// The background color is controlled by ts5_set_background_color().
514 ////////////////////////////////////////////////////////////////////////////////
516 {
517  ts5_check_display("ts5_clear_display");
518  ts5_log(TS5_LOGLEVEL_5, "ts5_clear_display()\n");
519 
520  if (_ts5_data.target == NULL) {
521  ts5_fatal("ts5_clear_display: target is a NULL pointer\n");
522  }
523 
524  al_clear_to_color(_ts5_status.graphics.background_color);
525 }
526 
527 
528 ////////////////////////////////////////////////////////////////////////////////
529 /// Make what has been drawn visible on the screen.
530 ///
531 /// \return The time when the display flip occurs.
532 ///
533 /// All drawing operations (primitives, text, bitmaps, ...)
534 /// are performed on a back buffer.
535 /// Once you have finished drawing you should call this function
536 /// to make your drawings visible on the screen.
537 /// After a call to this function the back buffer is not cleared.
538 ////////////////////////////////////////////////////////////////////////////////
540 {
541  ts5_check_display("ts5_flip_display");
542  ts5_log(TS5_LOGLEVEL_5, "ts5_flip_display()\n");
543 
544 
545  // if we do not synchronize with _every_ vsync
546  // we need to call al_wait_for_vsync to get in sync again
547  #ifdef TS5_WINDOWS
548  if (al_get_time() - _ts5_status.display[_ts5_status.active_display].last_sync >
549  1.0 / _ts5_status.display[_ts5_status.active_display].refreshrate + 0.003) {
550  al_wait_for_vsync();
551  }
552  #endif
553 
554 
555  // helper functions for multisampling
556  double w = _ts5_status.display[_ts5_status.active_display].w;
557  double h = _ts5_status.display[_ts5_status.active_display].h;
558  double factor = (double)_ts5_status.display[_ts5_status.active_display].sampling_factor;
559 
560  // on mac we need another trick for this:
561  // blit the backup of the buffer
562  // then make a new backup of the buffer
563  #ifdef TS5_MACOSX
564  if (al_get_time() - _ts5_status.display[_ts5_status.active_display].last_sync >
565  1.0 / _ts5_status.display[_ts5_status.active_display].refreshrate + 0.003) {
566 
567  al_set_target_backbuffer(_ts5_data.display[_ts5_status.active_display]);
568  if (_ts5_status.display[_ts5_status.active_display].multisampling) {
569  al_draw_scaled_bitmap(_ts5_data.display_backup[_ts5_status.active_display],
570  0.0, 0.0, w*factor, h*factor,
571  0.0, 0.0, w, h,
572  0);
573  }
574  else {
575  al_draw_bitmap(_ts5_data.display_backup[_ts5_status.active_display], 0.0, 0.0, 0);
576  }
577  al_flip_display();
578  }
579 
580  al_set_target_bitmap(_ts5_data.display_backup[_ts5_status.active_display]);
581  al_clear_to_color(_ts5_status.graphics.background_color);
582  al_draw_bitmap(_ts5_data.display_buffer[_ts5_status.active_display], 0.0, 0.0, 0);
583 
584  #endif
585 
586  al_set_target_backbuffer(_ts5_data.display[_ts5_status.active_display]);
587  if (_ts5_status.display[_ts5_status.active_display].multisampling) {
588  al_draw_scaled_bitmap(_ts5_data.display_buffer[_ts5_status.active_display],
589  0.0, 0.0, w*factor, h*factor,
590  0.0, 0.0, w, h,
591  0);
592  }
593  else {
594  al_draw_bitmap(_ts5_data.display_buffer[_ts5_status.active_display], 0.0, 0.0, 0);
595  }
596  al_flip_display();
597 
598  _ts5_status.display[_ts5_status.active_display].last_sync = al_get_time();
599 
600  al_clear_to_color(_ts5_status.graphics.background_color);
601 
602  al_set_target_bitmap(_ts5_data.display_buffer
603  [_ts5_status.active_display]);
604 
605  return _ts5_status.display[_ts5_status.active_display].last_sync;
606 }
607 
608 
609 ////////////////////////////////////////////////////////////////////////////////
610 //@}
611 ////////////////////////////////////////////////////////////////////////////////
612 
613 
614 ////////////////////////////////////////////////////////////////////////////////
615 /// @name Setting the display target
616 /// Tscope5 supports multiple displays
617 /// (each call to ts5_install_display() opens a new display).
618 /// - By default everything is drawn on the display that was opened last.
619 /// - With ts5_set_active_display() you can change the target display.
620 ///
621 /// You can also redirect drawing to memory bitmaps (see bitmaps.c)
622 /// using ts5_set_drawing_target().
623 //@{
624 ////////////////////////////////////////////////////////////////////////////////
625 
626 
627 ////////////////////////////////////////////////////////////////////////////////
628 /// Set the active display.
629 ///
630 /// \param display Index of the display.
631 ///
632 /// \return The index of the previous active display.
633 ///
634 /// The 'active' display is the display that will be used
635 /// for drawing operations.
636 ////////////////////////////////////////////////////////////////////////////////
637 int ts5_set_active_display(const int display)
638 {
639  ts5_check_display2("ts5_set_active_display", display);
640  ts5_log(TS5_LOGLEVEL_4, "ts5_set_active_display(%d)\n", display);
641 
642  int retval = _ts5_status.active_display + 1;
643  _ts5_status.active_display = display - 1;
644  _ts5_data.target = _ts5_data.display_buffer[_ts5_status.active_display];
645  al_set_target_bitmap(_ts5_data.target);
646 
647  _ts5_status.graphics.target_width =
648  ts5_get_bitmap_width(_ts5_data.target);
649 
650  _ts5_status.graphics.target_height =
651  ts5_get_bitmap_height(_ts5_data.target);
652 
653  return retval;
654 }
655 
656 
657 ////////////////////////////////////////////////////////////////////////////////
658 /// Get the active display.
659 ///
660 /// \return The index of the active display.
661 ///
662 /// The 'active' display is the display that will be used
663 /// for drawing operations.
664 ////////////////////////////////////////////////////////////////////////////////
666 {
667  ts5_check_display("ts5_get_active_display");
668  ts5_log(TS5_LOGLEVEL_4, "ts5_get_active_display()\n");
669 
670  return _ts5_status.active_display + 1;
671 }
672 
673 
674 ////////////////////////////////////////////////////////////////////////////////
675 //@}
676 ////////////////////////////////////////////////////////////////////////////////
677 
678 
679 ////////////////////////////////////////////////////////////////////////////////
680 /// @name Display adapter settings
681 /// A display adapter is a physical monitor that is attached to the computer.
682 /// Tscope5 supports multiple display adapters.
683 /// Functions are available to query the number and dimensions of
684 /// each display adapter.
685 //@{
686 ////////////////////////////////////////////////////////////////////////////////
687 
688 
689 ////////////////////////////////////////////////////////////////////////////////
690 /// Get the number of display adapters that are connected to the system.
691 ///
692 /// \return The number of display adapters that are connected to the system.
693 ////////////////////////////////////////////////////////////////////////////////
695 {
696  ts5_check_display("ts5_get_num_display_adapters");
697  ts5_log(TS5_LOGLEVEL_4, "ts5_get_num_display_adapters()\n");
698 
699  return _ts5_status.num_display_adapters;
700 }
701 
702 
703 ////////////////////////////////////////////////////////////////////////////////
704 /// Get the size of the monitor attached to a display adapter.
705 ///
706 /// \param adapter Index of the display adapter.
707 /// \param w Variable that will store the width.
708 /// \param h Variable that will store the height.
709 ///
710 /// w and h are the maximum size of a window that can be opened on that adapter.
711 ///
712 /// Pass 0 to get the size of the display adapter for the next display.
713 ///
714 /// You can pass NULL for values you are not interested in.
715 ////////////////////////////////////////////////////////////////////////////////
716 void ts5_get_display_adapter_size(const int adapter, double *w, double *h)
717 {
718  ts5_check_display("ts5_get_display_adapter_size");
719  ts5_log(TS5_LOGLEVEL_4, "ts5_get_display_adapter_size(%d,%f,%f)\n",
720  adapter, w, h);
721 
722  double ww, hh;
723 
724  if (adapter < 0) {
725  ts5_fatal("ts5_get_display_adapter_size: adapter index not valid\n");
726  }
727  else if (adapter == 0) {
728  ww = _ts5_status.display_adapter[ts5_nextdisplay.adapter].w;
729  hh = _ts5_status.display_adapter[ts5_nextdisplay.adapter].h;
730  }
731  else if (adapter <= _ts5_status.num_display_adapters) {
732  ww = _ts5_status.display_adapter[adapter-1].w;
733  hh = _ts5_status.display_adapter[adapter-1].h;
734  }
735  else {
736  ts5_fatal("ts5_get_display_adapter_size: adapter index not valid\n");
737  }
738 
739  if (w) {
740  *w = ww;
741  }
742 
743  if (h) {
744  *h = hh;
745  }
746 }
747 
748 
749 ////////////////////////////////////////////////////////////////////////////////
750 /// Get the width of the monitor attached to a display adapter.
751 ///
752 /// \param adapter Index of the display adapter.
753 ///
754 /// \return the width of the display adapter.
755 ///
756 /// Pass 0 to get the width of the display adapter for the next display.
757 ////////////////////////////////////////////////////////////////////////////////
758 double ts5_get_display_adapter_width(const int adapter)
759 {
760  ts5_check_display("ts5_get_display_adapter_width");
761  ts5_log(TS5_LOGLEVEL_4, "ts5_get_display_adapter_width(%d)\n", adapter);
762 
763  double w;
764  ts5_get_display_adapter_size(adapter, &w, NULL);
765 
766  return w;
767 }
768 
769 
770 ////////////////////////////////////////////////////////////////////////////////
771 /// Get the heigth of the monitor attached to a display adapter.
772 ///
773 /// \param adapter Index of the display adapter.
774 ///
775 /// \return the height of the display adapter.
776 ///
777 /// Pass 0 to get the height of the display adapter for the next display.
778 ////////////////////////////////////////////////////////////////////////////////
779 double ts5_get_display_adapter_height(const int adapter)
780 {
781  ts5_check_display("ts5_get_display_adapter_height");
782  ts5_log(TS5_LOGLEVEL_4, "ts5_get_display_adapter_height(%d)\n", adapter);
783 
784  double h;
785  ts5_get_display_adapter_size(adapter, NULL, &h);
786 
787  return h;
788 }
789 
790 
791 ////////////////////////////////////////////////////////////////////////////////
792 //@}
793 ////////////////////////////////////////////////////////////////////////////////
794 
795 
796 ////////////////////////////////////////////////////////////////////////////////
797 /// @name Display settings
798 /// Before opening a display various settings can be requested
799 /// using the functions below.
800 /// Once a display is opened the settings remain until the end of the program.
801 //@{
802 ////////////////////////////////////////////////////////////////////////////////
803 
804 
805 ////////////////////////////////////////////////////////////////////////////////
806 /// Set the display adapter for the next display that will be opened.
807 ///
808 /// \param adapter Index of the active display adapter.
809 ///
810 /// \return The index of the previous active display adapter.
811 ///
812 /// A display adapter corresponds to a physical display that is
813 /// attached to the computer.
814 /// The first adapter has index 1, etc.
815 ///
816 /// The display is attached to adapter 1 by default.
817 ////////////////////////////////////////////////////////////////////////////////
818 int ts5_set_display_adapter(const int adapter)
819 {
820  ts5_check_display("ts5_set_display_adapter");
821  ts5_log(TS5_LOGLEVEL_4, "ts5_set_display_adapter(%d)\n", adapter);
822 
823  int retval = ts5_nextdisplay.adapter + 1;
824 
825  if (adapter > 0 && adapter <= _ts5_status.num_display_adapters) {
826  ts5_nextdisplay.adapter = adapter - 1;
827  ts5_log(TS5_LOGLEVEL_4, "%s: %s %d (was %d)\n",
828  "ts5_set_display_adapter",
829  "set display adapter for next display to",
830  retval-1, ts5_nextdisplay.adapter+1);
831  }
832  else {
833  ts5_fatal ("ts5_set_display_adapter: adapter index not valid\n");
834  }
835 
836  return retval;
837 }
838 
839 
840 ////////////////////////////////////////////////////////////////////////////////
841 /// Get the index of the display adapter of a display.
842 ///
843 /// \param display Index of the display.
844 ///
845 /// \return The index of the adapter that the display is attached to.
846 ///
847 /// Pass 0 to get the index of the display adapter for the next display.
848 ////////////////////////////////////////////////////////////////////////////////
849 int ts5_get_display_adapter(const int display)
850 {
851  ts5_check_display2("ts5_get_display_adapter", display);
852  ts5_log(TS5_LOGLEVEL_4, "ts5_get_display_adapter(%d)\n", display);
853 
854  int retval;
855 
856  if (display == 0) {
857  retval = ts5_nextdisplay.adapter + 1;
858  }
859  else {
860  retval = _ts5_status.display[display-1].adapter + 1;
861  }
862 
863  return retval;
864 }
865 
866 
867 ////////////////////////////////////////////////////////////////////////////////
868 /// Set the size of the next display.
869 ///
870 /// \param w Width of the next display in pixels.
871 /// \param h Height of the next display in pixels.
872 ///
873 /// The default width and height is 320 x 240. This is also the minimum.
874 ////////////////////////////////////////////////////////////////////////////////
875 void ts5_set_display_size(double w, double h)
876 {
877  ts5_check_display("ts5_set_display_size");
878  ts5_log(TS5_LOGLEVEL_4, "ts5_set_display_size(%f,%f)\n", w, h);
879 
880  int oldw = ts5_nextdisplay.w;
881  int oldh = ts5_nextdisplay.h;
882 
883  if (_ts5_status.graphics.coordinate_scale
884  == TS5_RELATIVE_COORDINATES) {
885  w *= _ts5_status.display_adapter[ts5_nextdisplay.adapter].w;
886  h *= _ts5_status.display_adapter[ts5_nextdisplay.adapter].h;
887  }
888 
889  ts5_nextdisplay.w = w;
890  ts5_nextdisplay.h = h;
891 
892  ts5_log(TS5_LOGLEVEL_4, "%s: %s %d x %d (was %d x %d)\n",
893  "ts5_set_display_size",
894  "set display size for next display to",
895  ts5_nextdisplay.w, ts5_nextdisplay.h, oldw, oldh);
896 }
897 
898 
899 ////////////////////////////////////////////////////////////////////////////////
900 /// Get the size of a display.
901 ///
902 /// \param display Index of the display.
903 /// \param w Variable that will store the width.
904 /// \param h Variable that will store the height.
905 ///
906 /// Set display to 0 to get the width of the next display.
907 ///
908 /// You can pass NULL for values you are not interested in.
909 ////////////////////////////////////////////////////////////////////////////////
910 void ts5_get_display_size(const int display, double *w, double *h)
911 {
912  ts5_check_display2("ts5_get_display_size", display);
913  ts5_log(TS5_LOGLEVEL_4, "ts5_get_display_size(%d,%p,%p)\n", display, w, h);
914 
915  double ww, hh;
916 
917  if (display == 0) {
918  ww = ts5_nextdisplay.w;
919  hh = ts5_nextdisplay.h;
920  }
921  else {
922  ww = _ts5_status.display[display-1].w;
923  hh = _ts5_status.display[display-1].h;
924  }
925 
926  if (w) {
927  *w = ww;
928  }
929 
930  if (h) {
931  *h = hh;
932  }
933 }
934 
935 
936 ////////////////////////////////////////////////////////////////////////////////
937 /// Get the width of a display.
938 ///
939 /// \param display Index of the display.
940 ///
941 /// \return the width of the display.
942 ///
943 /// Set display to 0 to get the width of the next display.
944 ////////////////////////////////////////////////////////////////////////////////
945 double ts5_get_display_width(const int display)
946 {
947  ts5_check_display2("ts5_get_display_width", display);
948  ts5_log(TS5_LOGLEVEL_4, "ts5_get_display_width(%d)\n", display);
949 
950  double w;
951  ts5_get_display_size(display, &w, NULL);
952 
953  return w;
954 }
955 
956 
957 ////////////////////////////////////////////////////////////////////////////////
958 /// Get the height of a display.
959 ///
960 /// \param display Index of the display.
961 ///
962 /// \return the height of the display.
963 ///
964 /// Set display to 0 to get the height of the next display.
965 ////////////////////////////////////////////////////////////////////////////////
966 double ts5_get_display_height(const int display)
967 {
968  ts5_check_display2("ts5_get_display_height", display);
969  ts5_log(TS5_LOGLEVEL_4, "ts5_get_display_height(%d)\n", display);
970 
971  double h;
972  ts5_get_display_size(display, NULL, &h);
973 
974  return h;
975 }
976 
977 
978 ////////////////////////////////////////////////////////////////////////////////
979 /// Set the position of the next display.
980 ///
981 /// \param x Horizontal position of the display on the desktop.
982 /// \param y Vertical position of the display on the desktop.
983 ///
984 /// Only meaningful for non-fullscreen displays.
985 ///
986 /// CARTESIAN coordinates: Center of the display is the origin,
987 /// default position is the center of the display.
988 ///
989 /// COMPUTER coordinates: The upper left corner of the display is the origin,
990 /// default position is top left corner of the display.
991 ////////////////////////////////////////////////////////////////////////////////
992 void ts5_set_display_position(double x, double y)
993 {
994  ts5_check_display("ts5_set_display_position");
995  ts5_log(TS5_LOGLEVEL_4, "ts5_set_display_position(%f,%f)\n", x, y);
996 
997  int oldx = ts5_nextdisplay.x;
998  int oldy = ts5_nextdisplay.y;
999 
1000  if (_ts5_status.graphics.coordinate_scale
1001  == TS5_RELATIVE_COORDINATES) {
1002 
1003  if (_ts5_status.graphics.coordinate_system
1004  == TS5_CARTESIAN_COORDINATES) {
1005 
1006  x *= _ts5_status.display_adapter[ts5_nextdisplay.adapter].w
1007  / 2.0;
1008 
1009  y *= _ts5_status.display_adapter[ts5_nextdisplay.adapter].h
1010  / 2.0;
1011  }
1012  else {
1013  x *= _ts5_status.display_adapter[ts5_nextdisplay.adapter].w;
1014  y *= _ts5_status.display_adapter[ts5_nextdisplay.adapter].h;
1015  }
1016  }
1017 
1018  if (_ts5_status.graphics.coordinate_system
1019  == TS5_CARTESIAN_COORDINATES) {
1020 
1021  x += _ts5_status.display_adapter[ts5_nextdisplay.adapter].w/2.0;
1022  x -= ts5_nextdisplay.w/2.0;
1023  y = -y;
1024  y += _ts5_status.display_adapter[ts5_nextdisplay.adapter].h/2.0;
1025  y -= ts5_nextdisplay.h/2.0;
1026  }
1027 
1028  x += _ts5_status.display_adapter[ts5_nextdisplay.adapter].x1;
1029  y += _ts5_status.display_adapter[ts5_nextdisplay.adapter].y1;
1030 
1031  ts5_nextdisplay.x = x;
1032  ts5_nextdisplay.y = y;
1033 
1034  ts5_log(TS5_LOGLEVEL_4, "%s: %s (%d,%d) (was (%d,%d))\n",
1035  "ts5_set_display_position",
1036  "set display position for next display to",
1038  oldx, oldy);
1039 }
1040 
1041 
1042 ////////////////////////////////////////////////////////////////////////////////
1043 /// Get the position of a display.
1044 ///
1045 /// \param display Index of the display.
1046 /// \param x Variable that will store the horizontal position.
1047 /// \param y Variable that will store the vertical position.
1048 ///
1049 /// Only meaningful for non-fullscreen displays.
1050 ///
1051 /// Set display to 0 to get the x position of the next display.
1052 ///
1053 /// You can pass NULL for values you are not interested in.
1054 ////////////////////////////////////////////////////////////////////////////////
1055 void ts5_get_display_position(const int display, double *x, double *y)
1056 {
1057  ts5_check_display2("ts5_get_display_position", display);
1058  ts5_log(TS5_LOGLEVEL_4, "ts5_get_display_position(%d,%p,%p)\n",
1059  display, x, y);
1060 
1061  double xx, yy;
1062  double dw, dh, aw, ah;
1063 
1064  // get the values we need
1065  if (display != 0) {
1066 
1067  int adapter = ts5_get_display_adapter(display);
1068  al_get_window_position(_ts5_data.display[display-1],
1069  &_ts5_status.display[display-1].x,
1070  &_ts5_status.display[display-1].y);
1071 
1072  xx = _ts5_status.display[display-1].x;
1073  yy = _ts5_status.display[display-1].y;
1074 
1075  xx -= _ts5_status.display_adapter[adapter-1].x1;
1076  yy -= _ts5_status.display_adapter[adapter-1].y1;
1077 
1078  dw = _ts5_status.display[display-1].w;
1079  dh = _ts5_status.display[display-1].h;
1080 
1081  aw = _ts5_status.display_adapter[adapter-1].w;
1082  ah = _ts5_status.display_adapter[adapter-1].h;
1083  }
1084  else {
1085 
1086  xx = ts5_nextdisplay.x;
1087  yy = ts5_nextdisplay.y;
1088 
1089  dw = ts5_nextdisplay.w;
1090  dh = ts5_nextdisplay.h;
1091 
1092  aw = _ts5_status.display_adapter[ts5_nextdisplay.adapter].w;
1093  ah = _ts5_status.display_adapter[ts5_nextdisplay.adapter].h;
1094  }
1095 
1096  // if the settings are not default, compute xx and yy
1097  if (xx!=-1 && yy!=-1) {
1098 
1099 
1100  // convert to cartesian if necessary
1101  if (_ts5_status.graphics.coordinate_system
1102  == TS5_CARTESIAN_COORDINATES) {
1103  xx = xx + dw/2.0 - aw/2.0;
1104  yy = ah/2.0 - yy - dh/2.0;
1105  }
1106 
1107  // convert to relative if necessary
1108  if (_ts5_status.graphics.coordinate_scale
1109  == TS5_RELATIVE_COORDINATES) {
1110 
1111  if (_ts5_status.graphics.coordinate_system
1112  == TS5_CARTESIAN_COORDINATES) {
1113  xx /= aw/2.0;
1114  yy /= ah/2.0;
1115  }
1116  else {
1117  xx /= aw;
1118  yy /= ah;
1119  }
1120  }
1121  }
1122 
1123  if (x) {
1124  *x = xx;
1125  }
1126 
1127  if (y) {
1128  *y = yy;
1129  }
1130 
1131 
1132 }
1133 
1134 
1135 ////////////////////////////////////////////////////////////////////////////////
1136 /// Get the horizontal position of a display.
1137 ///
1138 /// \param display Index of the display.
1139 ///
1140 /// \return
1141 /// The horizontal position of the display.
1142 ////////////////////////////////////////////////////////////////////////////////
1143 double ts5_get_display_x(const int display)
1144 {
1145  ts5_check_display2("ts5_get_display_x", display);
1146  ts5_log(TS5_LOGLEVEL_4, "ts5_get_display_x(%d)\n", display);
1147 
1148  double x;
1149  ts5_get_display_position(display, &x, NULL);
1150 
1151  return x;
1152 }
1153 
1154 
1155 ////////////////////////////////////////////////////////////////////////////////
1156 /// Get the vertical position of a display.
1157 ///
1158 /// \param display Index of the display.
1159 ///
1160 /// \return
1161 /// The vertical position of the display.
1162 ////////////////////////////////////////////////////////////////////////////////
1163 double ts5_get_display_y(const int display)
1164 {
1165  ts5_check_display2("ts5_get_display_y", display);
1166  ts5_log(TS5_LOGLEVEL_4, "ts5_get_display_y(%d)\n", display);
1167 
1168  double y;
1169  ts5_get_display_position(display, NULL, &y);
1170 
1171  return y;
1172 }
1173 
1174 
1175 
1176 
1177 ////////////////////////////////////////////////////////////////////////////////
1178 /// Set the requested refreshrate for the next display.
1179 ///
1180 /// \param rate Refreshrate in cycles per second.
1181 ///
1182 /// \return The previous refresh rate.
1183 ///
1184 /// The refreshrate can only be changed for real fullscreen displays.
1185 ///
1186 /// Even then this is only a request.
1187 ///
1188 /// The default value 0 (let the system choose).
1189 ////////////////////////////////////////////////////////////////////////////////
1190 int ts5_set_refreshrate(const int rate)
1191 {
1192  ts5_check_display("ts5_set_refreshrate");
1193  ts5_log(TS5_LOGLEVEL_4, "ts5_set_refreshrate(%d)\n", rate);
1194 
1195  int retval = ts5_nextdisplay.refreshrate;
1196 
1197  ts5_nextdisplay.refreshrate = rate;
1198 
1199  ts5_log(TS5_LOGLEVEL_4, "%s: %s %d (was %d)\n", "ts5_set_refreshrate",
1200  "set refreshrate for next display to",
1201  ts5_nextdisplay.refreshrate, retval);
1202 
1203  return retval;
1204 }
1205 
1206 
1207 ////////////////////////////////////////////////////////////////////////////////
1208 /// Get the refreshrate of a display.
1209 ///
1210 /// \param display Index of the display.
1211 ///
1212 /// \return The refresh rate of the display.
1213 ///
1214 /// Set display to 0 to get the refreshrate of the next display.
1215 ////////////////////////////////////////////////////////////////////////////////
1216 int ts5_get_refreshrate(const int display)
1217 {
1218  ts5_check_display2("ts5_get_refreshrate", display);
1219  ts5_log(TS5_LOGLEVEL_4, "ts5_get_refreshrate(%d)\n", display);
1220 
1221  int retval;
1222 
1223  if (display == 0) {
1224  retval = ts5_nextdisplay.refreshrate;
1225  }
1226  else {
1227  retval = _ts5_status.display[display-1].refreshrate;
1228  }
1229 
1230  return retval;
1231 }
1232 
1233 
1234 ////////////////////////////////////////////////////////////////////////////////
1235 /// Set the display mode for the next display.
1236 ///
1237 /// \param mode Window mode.
1238 /// Can be TS5_WINDOWED, TS5_FULLSCREEN or TS5_FULLSCREEN_WINDOW.
1239 ///
1240 /// \return The previous display mode.
1241 ///
1242 /// In TS5_WINDOWED mode the window can have any dimension that
1243 /// will fit on the physical display
1244 /// and the position of the window on the display can be adjusted.
1245 /// Multiple TS5_WINDOWED displays can be combined on one physical display.
1246 /// The refreshrate is always the refreshrate of the physical display.
1247 ///
1248 /// In TS5_FULLSCREEN_WINDOW mode the display always has the dimension
1249 /// of the desktop.
1250 /// The refreshrate is always the refreshrate of the physical display.
1251 /// Only one TS5_FULLSCREEN_WINDOW display can be used
1252 /// per physical display.
1253 ///
1254 /// TS5_FULLSCREEN modes are the most flexible:
1255 /// any combination of display dimension and refreshrate
1256 /// that is supported by the monitor can be set.
1257 /// Does not seem to work on Mac OS X.
1258 ///
1259 /// The default window mode is TS5_WINDOWED.
1260 ////////////////////////////////////////////////////////////////////////////////
1261 int ts5_set_display_mode(const int mode)
1262 {
1263  ts5_check_display("ts5_set_display_mode");
1264  ts5_log(TS5_LOGLEVEL_4, "ts5_set_display_mode(%d)\n", mode);
1265 
1266  int retval = ts5_nextdisplay.display_mode;
1267 
1268  if (mode != TS5_WINDOWED
1269  && mode != TS5_FULLSCREEN
1270  && mode != TS5_FULLSCREEN_WINDOW) {
1271  ts5_fatal ("%s: %s (%d)\n", "ts5_set_display_mode",
1272  "requested display mode not available", mode);
1273  }
1274 
1275  ts5_nextdisplay.display_mode = mode;
1276 
1277  ts5_log(TS5_LOGLEVEL_4, "%s: %s %d (was %d)\n", "ts5_set_display_mode",
1278  "set display mode for next display to",
1279  ts5_nextdisplay.display_mode, retval);
1280 
1281  return retval;
1282 }
1283 
1284 
1285 ////////////////////////////////////////////////////////////////////////////////
1286 /// Get the display mode of a display.
1287 ///
1288 /// \param display Index of the display.
1289 ///
1290 /// \return The window mode of the display.
1291 ///
1292 /// Set display to 0 to get the display mode of the next display.
1293 ////////////////////////////////////////////////////////////////////////////////
1294 int ts5_get_display_mode(const int display)
1295 {
1296  ts5_check_display2("ts5_get_display_mode", display);
1297  ts5_log(TS5_LOGLEVEL_4, "ts5_get_display_mode(%d)\n", display);
1298 
1299  int retval;
1300 
1301  if (display == 0) {
1302  retval = ts5_nextdisplay.display_mode;
1303  }
1304  else {
1305  retval = _ts5_status.display[display-1].display_mode;
1306  }
1307 
1308  return retval;
1309 }
1310 
1311 
1312 ////////////////////////////////////////////////////////////////////////////////
1313 /// Set the vsync mode for the next display.
1314 ///
1315 /// \param mode Vsync mode.
1316 /// Can be TS5_VSYNC_OFF, TS5_VSYNC_ON or TS5_VSYNC_WHATEVER.
1317 ///
1318 /// \return The previous vsync mode.
1319 ///
1320 /// The default vsync mode is TS5_VSYNC_ON.
1321 ////////////////////////////////////////////////////////////////////////////////
1322 int ts5_set_vsync_mode(const int mode)
1323 {
1324  ts5_check_display("ts5_set_vsync_mode");
1325  ts5_log(TS5_LOGLEVEL_4, "ts5_set_vsync_mode(%d)\n", mode);
1326 
1327  int retval = ts5_nextdisplay.vsync_mode;
1328 
1329  if (mode < TS5_VSYNC_WHATEVER || mode > TS5_VSYNC_OFF) {
1330  ts5_fatal("ts5_set_vsync_mode: mode should be 0, 1 or 2 (is %d)\n",
1331  mode);
1332  }
1333 
1334  ts5_nextdisplay.vsync_mode = mode;
1335 
1336  ts5_log(TS5_LOGLEVEL_4, "%s: %s %d (was %d)\n", "ts5_set_vsync_mode",
1337  "set vsync mode for next display to",
1338  ts5_nextdisplay.vsync_mode, retval);
1339 
1340  return retval;
1341 }
1342 
1343 
1344 ////////////////////////////////////////////////////////////////////////////////
1345 /// Get the vsync mode of a display.
1346 ///
1347 /// \param display Index of the display.
1348 ///
1349 /// \return The vsync mode of the display.
1350 ///
1351 /// Set display to 0 to get the requested vsync mode for the next display.
1352 ////////////////////////////////////////////////////////////////////////////////
1353 int ts5_get_vsync_mode(const int display)
1354 {
1355  ts5_check_display2("ts5_get_vsync_mode", display);
1356  ts5_log(TS5_LOGLEVEL_4, "ts5_get_vsync_mode(%d)\n", display);
1357 
1358  int retval;
1359 
1360  if (display == 0) {
1361  retval = ts5_nextdisplay.vsync_mode;
1362  }
1363  else {
1364  retval = _ts5_status.display[display-1].vsync_mode;
1365  }
1366 
1367  return retval;
1368 }
1369 
1370 
1371 ////////////////////////////////////////////////////////////////////////////////
1372 /// Set the multisampling mode for the next display.
1373 ///
1374 /// \param multisampling Multisampling mode.
1375 /// Can be TS5_MULTISAMPLING_OFF or TS5_MULTISAMPLING_ON.
1376 ///
1377 /// \return The previous multisampling mode.
1378 ///
1379 /// Turning multisampling on gives smoother pictures.
1380 ///
1381 /// On some older machines this should be turned off.
1382 ///
1383 /// The default multisampling mode is TS5_MULTISAMPLING_OFF.
1384 ////////////////////////////////////////////////////////////////////////////////
1385 int ts5_set_multisampling(const int multisampling)
1386 {
1387  ts5_check_display("ts5_set_multisampling");
1388  ts5_log(TS5_LOGLEVEL_4, "ts5_set_multisampling(%d)\n", multisampling);
1389 
1390  int retval = ts5_nextdisplay.multisampling;
1391 
1392  if (multisampling != TS5_MULTISAMPLING_OFF && multisampling != TS5_MULTISAMPLING_ON) {
1393  ts5_fatal("%s: %s (is %d)\n", "ts5_set_multisampling: ",
1394  "multisampling should be either TS5_MULTISAMPLING_OFF or TS5_MULTISAMPLING_ON ",
1395  multisampling);
1396  }
1397 
1398  ts5_nextdisplay.multisampling = multisampling;
1399  ts5_nextdisplay.sampling_factor = multisampling + 1;
1400 
1401  ts5_log(TS5_LOGLEVEL_4, "%s: %s %d (was %d)\n", "ts5_set_multisampling",
1402  "set multisampling level for next display to",
1403  ts5_nextdisplay.multisampling, retval);
1404 
1405  return retval;
1406 
1407 }
1408 
1409 
1410 ////////////////////////////////////////////////////////////////////////////////
1411 /// Get the multisampling mode of a display.
1412 ///
1413 /// \param display Index of the display.
1414 ///
1415 /// \return The multisampling mode of the display.
1416 ///
1417 /// Set display to 0 to get the requested multisampling mode for the next display.
1418 ////////////////////////////////////////////////////////////////////////////////
1419 int ts5_get_multisampling(const int display)
1420 {
1421  ts5_check_display2("ts5_get_multisampling", display);
1422  ts5_log(TS5_LOGLEVEL_4, "ts5_get_multisampling(%d)\n", display);
1423 
1424  int retval;
1425 
1426  if (display == 0) {
1427  retval = ts5_nextdisplay.multisampling;
1428  }
1429  else {
1430  retval = _ts5_status.display[display-1].multisampling;
1431  }
1432 
1433  return retval;
1434 }
1435 
1436 
1437 
1438 ////////////////////////////////////////////////////////////////////////////////
1439 //@}
1440 ////////////////////////////////////////////////////////////////////////////////
double ts5_get_display_adapter_width(const int adapter)
Get the width of the monitor attached to a display adapter.
Definition: display.c:758
int ts5_get_vsync_mode(const int display)
Get the vsync mode of a display.
Definition: display.c:1353
void ts5_check_display(char *calling_function)
Do some checks at the start of each display function.
int ts5_set_display_mode(const int mode)
Set the display mode for the next display.
Definition: display.c:1261
TS5_DISPLAY_STATUS ts5_nextdisplay
Settings for the next display that will be opened.
void ts5_check_display2(char *calling_function, const int display)
Do some checks at the start of each display function.
int ts5_get_num_display_adapters()
Get the number of display adapters that are connected to the system.
Definition: display.c:694
double ts5_flip_display()
Make what has been drawn visible on the screen.
Definition: display.c:539
int ts5_set_active_display(const int display)
Set the active display.
Definition: display.c:637
double ts5_get_bitmap_width(TS5_BITMAP *map)
Get the width of a bitmap in pixels.
Definition: bitmaps.c:233
int ts5_set_multisampling(const int multisampling)
Set the multisampling mode for the next display.
Definition: display.c:1385
int ts5_set_vsync_mode(const int mode)
Set the vsync mode for the next display.
Definition: display.c:1322
double ts5_get_bitmap_height(TS5_BITMAP *map)
Get the height of a bitmap in pixels.
Definition: bitmaps.c:252
void ts5_get_display_adapter_size(const int adapter, double *w, double *h)
Get the size of the monitor attached to a display adapter.
Definition: display.c:716
TS5_BITMAP * ts5_set_drawing_target(TS5_BITMAP *target)
Set the active drawing target.
Definition: bitmaps.c:285
void ts5_get_display_position(const int display, double *x, double *y)
Get the position of a display.
Definition: display.c:1055
int ts5_get_display_mode(const int display)
Get the display mode of a display.
Definition: display.c:1294
int ts5_install_display()
Open a new display.
Definition: display.c:84
void ts5_uninstall_displays()
Close all open displays.
double ts5_get_display_x(const int display)
Get the horizontal position of a display.
Definition: display.c:1143
void ts5_set_display_size(double w, double h)
Set the size of the next display.
Definition: display.c:875
int ts5_get_active_display()
Get the active display.
Definition: display.c:665
double ts5_get_display_adapter_height(const int adapter)
Get the heigth of the monitor attached to a display adapter.
Definition: display.c:779
void ts5_log(const unsigned int level, const char *format,...)
Send info to a logging window.
Definition: system.c:45
int ts5_get_refreshrate(const int display)
Get the refreshrate of a display.
Definition: display.c:1216
void ts5_clear_display()
Clear the current drawing target.
Definition: display.c:515
double ts5_get_display_width(const int display)
Get the width of a display.
Definition: display.c:945
void ts5_set_display_position(double x, double y)
Set the position of the next display.
Definition: display.c:992
int ts5_set_refreshrate(const int rate)
Set the requested refreshrate for the next display.
Definition: display.c:1190
double ts5_get_display_height(const int display)
Get the height of a display.
Definition: display.c:966
void ts5_fatal(const char *format,...)
Exit safely with an error message.
Definition: system.c:533
void ts5_get_display_size(const int display, double *w, double *h)
Get the size of a display.
Definition: display.c:910
double ts5_get_display_y(const int display)
Get the vertical position of a display.
Definition: display.c:1163
int ts5_get_multisampling(const int display)
Get the multisampling mode of a display.
Definition: display.c:1419
int ts5_set_display_adapter(const int adapter)
Set the display adapter for the next display that will be opened.
Definition: display.c:818
int ts5_get_display_adapter(const int display)
Get the index of the display adapter of a display.
Definition: display.c:849