Tscope5
display.c
Go to the documentation of this file.
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 #include "../include/tscope5/display.h"
13 #include "../include/tscope5/graphics.h"
14 #include "../include/tscope5/bitmaps.h"
15 #include "../include/tscope5/display_internal.h"
16 #include "../include/tscope5/system_internal.h"
17 
18 
26 
27 
28 
29 
57 {
58  ts5_check_display("ts5_install_display");
59 
60  ts5_log(TS5_LOGLEVEL_1, "ts5_install_display: check settings\n");
61 
62  TS5_DISPLAY_STATUS request = ts5_nextdisplay;
63 
64  // TS5_FULLSCREEN_WINDOW
65  if (ts5_nextdisplay.display_mode == TS5_FULLSCREEN_WINDOW) {
66 
67  // the adapter cannot be in use by another tscope5 display
68  int i;
69  for (i = 0; i < _ts5_status.num_displays; i++) {
70 
71  if (_ts5_status.display_status[i].adapter == ts5_nextdisplay.adapter) {
72  ts5_fatal ("ts5_install_display: cannot open fullscreen display,",
73  " adapter already in use by another display (%d)\n", i);
74  }
75  }
76 
77  // copy relevant settings
78  request.w = 320;
79  request.h = 240;
80  request.x = -1;
81  request.y = -1;
82  request.refreshrate = -1;
83  request.display_mode = TS5_FULLSCREEN_WINDOW;
84  request.vsync_mode = ts5_nextdisplay.vsync_mode;
85  }
86 
87  // TS5_FULLSCREEN
88  if (ts5_nextdisplay.display_mode == TS5_FULLSCREEN) {
89 
90  // the adapter cannot be in use by another tscope5 display
91  int i;
92  for (i = 0; i < _ts5_status.num_displays; i++) {
93 
94  if (_ts5_status.display_status[i].adapter == ts5_nextdisplay.adapter) {
95  ts5_fatal ("ts5_install_display: cannot open fullscreen display,",
96  " adapter already in use by another display (%d)\n", i);
97  }
98  }
99 
100  // is the combination of display size and refresh rate supported by the adapter?
101  ALLEGRO_DISPLAY_MODE *mode;
102  mode = (ALLEGRO_DISPLAY_MODE *)al_malloc(sizeof(ALLEGRO_DISPLAY_MODE));
103  int nmodes = al_get_num_display_modes();
104  int found=0;
105 
106  for (i=0; i<nmodes; i++) {
107 
108  mode = al_get_display_mode(i, mode);
109 
110  if (mode->width==ts5_nextdisplay.w && mode->height==ts5_nextdisplay.h &&
111  (mode->refresh_rate==ts5_nextdisplay.refreshrate || mode->refresh_rate==0)) {
112  found=1;
113  }
114  }
115 
116  al_free(mode);
117 
118  if (!found) {
119  ts5_fatal ("ts5_install_display: the requested combination of size (%d,%d)",
120  " and refreshate (%d) is not supported by display adapter %d\n",
121  ts5_nextdisplay.w, ts5_nextdisplay.h,
122  ts5_nextdisplay.refreshrate, ts5_nextdisplay.adapter);
123  }
124 
125  // copy relevant settings
126  request.w = ts5_nextdisplay.w;
127  request.h = ts5_nextdisplay.h;
128  request.x = -1;
129  request.y = -1;
130  request.refreshrate = ts5_nextdisplay.refreshrate;
131  request.display_mode = TS5_FULLSCREEN;
132  request.vsync_mode = ts5_nextdisplay.vsync_mode;
133  }
134 
135  // TS5_WINDOWED
136  if (ts5_nextdisplay.display_mode == TS5_WINDOWED) {
137 
138  // the adapter cannot be in used by a TS5_FULLSCREEN_WINDOW or TS5_FULLSCREEN display
139  int i;
140  for (i = 0; i < _ts5_status.num_displays; i++) {
141 
142  if (_ts5_status.display_status[i].adapter == ts5_nextdisplay.adapter &&
143  (_ts5_status.display_status[i].display_mode == TS5_FULLSCREEN ||
144  _ts5_status.display_status[i].display_mode == TS5_FULLSCREEN_WINDOW)) {
145 
146  ts5_fatal ("ts5_install_display: cannot open display,",
147  " adapter already in use by a fullscreen display (%d)\n", i);
148  }
149  }
150 
151  // window should be at least 320 pixels wide and smaller than the width of the monitor
152  if (ts5_nextdisplay.w < 320 ) {
153  request.w = 320;
154  ts5_log(TS5_LOGLEVEL_1, "ts5_install_display: adjusting display width to %d (was %d)\n",
155  request.w, ts5_nextdisplay.w);
156  }
157  else if (ts5_nextdisplay.w > _ts5_status.display_adapter_status[ts5_nextdisplay.adapter].w) {
158  request.w = _ts5_status.display_adapter_status[ts5_nextdisplay.adapter].w;
159  ts5_log(TS5_LOGLEVEL_1, "ts5_install_display: adjusting display width to %d (was %d)\n",
160  request.w, ts5_nextdisplay.w);
161  }
162  else {
163  request.w = ts5_nextdisplay.w;
164  }
165 
166  // window should be at least 240 pixels high and smaller than the height of the monitor
167  if (ts5_nextdisplay.h < 240 ) {
168  request.h = 240;
169  ts5_log(TS5_LOGLEVEL_1, "ts5_install_display: adjusting display height to %d (was %d)\n",
170  request.h, ts5_nextdisplay.h);
171  }
172  else if (ts5_nextdisplay.h > _ts5_status.display_adapter_status[ts5_nextdisplay.adapter].h) {
173  request.h = _ts5_status.display_adapter_status[ts5_nextdisplay.adapter].h;
174  ts5_log(TS5_LOGLEVEL_1, "ts5_install_display: adjusting display height to %d (was %d)\n",
175  request.h, ts5_nextdisplay.h);
176  }
177  else {
178  request.h = ts5_nextdisplay.h;
179  }
180 
181  request.x = ts5_nextdisplay.x;
182  request.y = ts5_nextdisplay.y;
183 
184  if (request.x == -1) {
185 
186  if (_ts5_status.graphics_status.coordinate_system == TS5_CARTESIAN_COORDINATES) {
187  request.x = (_ts5_status.display_adapter_status[request.adapter].w - request.w)/2;
188  }
189  else {
190  request.x = 0;
191  }
192 
193  request.x += _ts5_status.display_adapter_status[request.adapter].x1;
194  }
195 
196  if (request.y == -1) {
197 
198  if (_ts5_status.graphics_status.coordinate_system == TS5_CARTESIAN_COORDINATES) {
199  request.y = (_ts5_status.display_adapter_status[request.adapter].h - request.h)/2;
200  }
201  else {
202  request.y = 0;
203  }
204 
205  request.y += _ts5_status.display_adapter_status[request.adapter].y1;
206  }
207 
208  // copy relevant settings
209  request.refreshrate = -1;
210  request.display_mode = TS5_WINDOWED;
211  request.vsync_mode = ts5_nextdisplay.vsync_mode;
212  }
213 
214 
215  // pass on display parameters to Allegro
216  ts5_log(TS5_LOGLEVEL_1, "ts5_install_display: request settings\n");
217  al_set_new_display_adapter(request.adapter);
218  al_set_new_display_refresh_rate(request.refreshrate);
219  al_set_new_display_option(ALLEGRO_VSYNC, (int)request.vsync_mode, ALLEGRO_SUGGEST);
220 
221  if (request.display_mode == TS5_WINDOWED) {
222  //al_set_new_window_position(request.x, request.y);
223  }
224 
225  if (request.display_mode == TS5_FULLSCREEN_WINDOW) {
226  al_set_new_window_position(INT_MAX, INT_MAX);
227  }
228 
229  al_set_new_display_flags(request.display_mode);
230 
231  // update counters
232  _ts5_status.num_displays++;
233  _ts5_status.active_display = _ts5_status.num_displays - 1;
234 
235  // try top open display
236  ts5_log(TS5_LOGLEVEL_1, "ts5_install_display: opening display\n");
237 
238  TS5_DISPLAY **display;
239  display = al_realloc(_ts5_status.display, _ts5_status.num_displays * sizeof(TS5_DISPLAY *));
240 
241  if (display == NULL) {
242  ts5_fatal("ts5_install_display: failed to allocate memory for display pointer\n");
243  }
244 
245  _ts5_status.display = (TS5_DISPLAY **) display;
246  _ts5_status.display[_ts5_status.active_display] = al_create_display(request.w, request.h);
247 
248  if (!_ts5_status.display[_ts5_status.active_display]) {
249  ts5_fatal("ts5_install_display: could not open display\n");
250  }
251 
252  if (ts5_nextdisplay.display_mode == TS5_FULLSCREEN_WINDOW) {
253  request.w = _ts5_status.display_adapter_status[request.adapter].w;
254  request.h = _ts5_status.display_adapter_status[request.adapter].h;
255  al_toggle_display_flag(_ts5_status.display[_ts5_status.active_display], TS5_FULLSCREEN_WINDOW, 0);
256  al_toggle_display_flag(_ts5_status.display[_ts5_status.active_display], TS5_FULLSCREEN_WINDOW, 1);
257  al_rest(0.1);
258  }
259 
260  // make a display buffer
261  TS5_BITMAP **display_buffer;
262  display_buffer = al_realloc(_ts5_status.display_buffer, _ts5_status.num_displays * sizeof(TS5_BITMAP *));
263 
264  if (display_buffer == NULL) {
265  ts5_fatal("ts5_install_display: failed to allocate memory for display buffer pointer\n");
266  }
267 
268  _ts5_status.display_buffer = (TS5_BITMAP **) display_buffer;
269  _ts5_status.display_buffer[_ts5_status.active_display] = al_create_bitmap(request.w, request.h);
270 
271  if (!_ts5_status.display_buffer[_ts5_status.active_display]) {
272  ts5_fatal("ts5_install_display: could not open display buffer\n");
273  }
274 
275  // set the new display as the drawing target and clear the display
276  ts5_set_drawing_target(_ts5_status.display_buffer[_ts5_status.active_display]);
279 
280  // copy the settings in the _ts5_status structure
281  ts5_log(TS5_LOGLEVEL_1, "ts5_install_display: copying settings\n");
282 
283  TS5_DISPLAY_STATUS *display_status;
284  display_status = al_realloc(_ts5_status.display_status, _ts5_status.num_displays * sizeof(TS5_DISPLAY_STATUS));
285 
286  if (display_status == NULL) {
287  ts5_fatal("ts5_install_display: failed to allocate memory for display settings\n");
288  }
289 
290  _ts5_status.display_status = (TS5_DISPLAY_STATUS *) display_status;
291  _ts5_status.display_status[_ts5_status.active_display].adapter = request.adapter;
292 
293  if (request.display_mode==TS5_WINDOWED) {
294 
295  al_get_window_position(_ts5_status.display[_ts5_status.active_display], &request.x, &request.y);
296 
297  if (request.x + request.w > _ts5_status.display_adapter_status[ts5_nextdisplay.adapter].x2) {
298 
299  int oldw = request.w;
300  request.w = _ts5_status.display_adapter_status[ts5_nextdisplay.adapter].x2 - request.x;
301  al_resize_display(_ts5_status.display[_ts5_status.active_display], request.w, request.h);
302  ts5_log(TS5_LOGLEVEL_1, "ts5_install_display: adjusting display width to %d (was %d)\n",
303  request.w, oldw);
304  }
305 
306  if (request.y + request.h > _ts5_status.display_adapter_status[ts5_nextdisplay.adapter].y2) {
307 
308  int oldh = request.h;
309  request.h = _ts5_status.display_adapter_status[ts5_nextdisplay.adapter].y2 - request.y;
310  al_resize_display(_ts5_status.display[_ts5_status.active_display], request.w, request.h);
311  al_set_window_position(_ts5_status.display[_ts5_status.active_display],
312  request.x, request.y + (request.h-oldh));
313 
314  ts5_log(TS5_LOGLEVEL_1, "ts5_install_display: adjusting display height to %d (was %d)\n",
315  request.h, oldh);
316 
317  al_get_window_position(_ts5_status.display[_ts5_status.active_display], &request.x, &request.y);
318  }
319 
320  request.x -= _ts5_status.display_adapter_status[request.adapter].x1;
321  request.y -= _ts5_status.display_adapter_status[request.adapter].y1;
322 
323  if (_ts5_status.graphics_status.coordinate_system == TS5_CARTESIAN_COORDINATES) {
324  request.x = request.x - (_ts5_status.display_adapter_status[request.adapter].w - request.w)/2;
325  request.y = (_ts5_status.display_adapter_status[request.adapter].h - request.h)/2 - request.y;
326  }
327  }
328 
329  _ts5_status.display_status[_ts5_status.active_display].x = request.x;
330  _ts5_status.display_status[_ts5_status.active_display].y = request.y;
331  _ts5_status.display_status[_ts5_status.active_display].w = request.w;
332  _ts5_status.display_status[_ts5_status.active_display].h = request.h;
333  _ts5_status.display_status[_ts5_status.active_display].refreshrate = request.refreshrate;
334  _ts5_status.display_status[_ts5_status.active_display].display_mode = request.display_mode;
335  _ts5_status.display_status[_ts5_status.active_display].vsync_mode = request.vsync_mode;
336 
337  atexit(ts5_uninstall_displays);
338 
339  // set icon
340  //TS5_BITMAP *icon;
341  //icon = ts5_read_bitmap("/usr/local/share/tscope5_data/tscope.tga");
342  //al_set_display_icon(_ts5_status.display[_ts5_status.active_display], icon);
343  //ts5_free_bitmap(icon);
344 
345  return _ts5_status.active_display;
346 }
347 
348 
358 {
359  ts5_check_display("ts5_clear_display");
360  ts5_log(TS5_LOGLEVEL_5, "ts5_clear_display()\n");
361 
362  if (_ts5_status.target == NULL) {
363  ts5_fatal("ts5_clear_display: target is a NULL pointer\n");
364  }
365 
366  al_clear_to_color(_ts5_status.graphics_status.background_color);
367 }
368 
369 
380 {
381  ts5_check_display("ts5_flip_display");
382  ts5_log(TS5_LOGLEVEL_5, "ts5_flip_display()\n");
383 
384  al_set_target_backbuffer(_ts5_status.display[_ts5_status.active_display]);
385  al_draw_bitmap(_ts5_status.display_buffer[_ts5_status.active_display], 0.0, 0.0, 0);
386  al_flip_display();
387  al_clear_to_color(_ts5_status.graphics_status.background_color);
388  al_set_target_bitmap(_ts5_status.display_buffer[_ts5_status.active_display]);
389 
390  return al_get_time();
391 }
392 
393 
395 
396 
397 
398 
406 
407 
408 
409 
419 int ts5_set_active_display(const int display)
420 {
421  ts5_check_display2("ts5_set_active_display", display);
422  ts5_log(TS5_LOGLEVEL_4, "ts5_set_active_display(%d)\n", display);
423 
424  int retval = _ts5_status.active_display + 1;
425  _ts5_status.active_display = display - 1;
426  _ts5_status.target = _ts5_status.display_buffer[_ts5_status.active_display];
427  al_set_target_bitmap(_ts5_status.target);
428 
429  _ts5_status.graphics_status.target_width = al_get_bitmap_width(_ts5_status.target);
430  _ts5_status.graphics_status.target_height = al_get_bitmap_height(_ts5_status.target);
431 
432  return retval;
433 }
434 
435 
444 {
445  ts5_check_display("ts5_get_active_display");
446  ts5_log(TS5_LOGLEVEL_4, "ts5_get_active_display()\n");
447 
448  return _ts5_status.active_display + 1;
449 }
450 
451 
459 TS5_BITMAP *ts5_set_drawing_target(TS5_BITMAP * target)
460 {
461  ts5_check_display("ts5_set_drawing_target");
462  ts5_log(TS5_LOGLEVEL_4, "ts5_set_drawing_target(%p)\n", target);
463 
464  if (target == NULL) {
465  ts5_fatal("ts5_set_drawing_target: target is a NULL pointer\n");
466  }
467 
468  TS5_BITMAP *retval = _ts5_status.target;
469  _ts5_status.target = target;
470  al_set_target_bitmap(_ts5_status.target);
471 
472  _ts5_status.graphics_status.target_width = al_get_bitmap_width(_ts5_status.target);
473  _ts5_status.graphics_status.target_height = al_get_bitmap_height(_ts5_status.target);
474 
475  return retval;
476 }
477 
478 
485 {
486  ts5_check_display("ts5_get_drawing_target");
487  ts5_log(TS5_LOGLEVEL_4, "ts5_get_drawing_target()\n");
488 
489  return _ts5_status.target;
490 }
491 
492 
494 
495 
496 
497 
503 
504 
505 
506 
513 {
514  ts5_check_display("ts5_get_num_display_adapters");
515  ts5_log(TS5_LOGLEVEL_4, "ts5_get_num_display_adapters()\n");
516 
517  return _ts5_status.num_display_adapters;
518 }
519 
520 
534 void ts5_get_display_adapter_size(const int adapter, double *w, double *h)
535 {
536  ts5_check_display("ts5_get_display_adapter_size");
537  ts5_log(TS5_LOGLEVEL_4, "ts5_get_display_adapter_size(%d,%f,%f)\n", adapter, w, h);
538 
539  double ww, hh;
540 
541  if (adapter < 0) {
542  ts5_fatal("ts5_get_display_adapter_size: adapter index not valid\n");
543  }
544  else if (adapter == 0) {
545  ww = _ts5_status.display_adapter_status[ts5_nextdisplay.adapter].w;
546  hh = _ts5_status.display_adapter_status[ts5_nextdisplay.adapter].h;
547  }
548  else if (adapter <= _ts5_status.num_display_adapters) {
549  ww = _ts5_status.display_adapter_status[adapter-1].w;
550  hh = _ts5_status.display_adapter_status[adapter-1].h;
551  }
552  else {
553  ts5_fatal("ts5_get_display_adapter_size: adapter index not valid\n");
554  }
555 
556  if (w) {
557  *w = ww;
558  }
559 
560  if (h) {
561  *h = hh;
562  }
563 }
564 
565 
575 double ts5_get_display_adapter_width(const int adapter)
576 {
577  ts5_check_display("ts5_get_display_adapter_width");
578  ts5_log(TS5_LOGLEVEL_4, "ts5_get_display_adapter_width(%d)\n", adapter);
579 
580  double w;
581  ts5_get_display_adapter_size(adapter, &w, NULL);
582 
583  return w;
584 }
585 
586 
596 double ts5_get_display_adapter_height(const int adapter)
597 {
598  ts5_check_display("ts5_get_display_adapter_height");
599  ts5_log(TS5_LOGLEVEL_4, "ts5_get_display_adapter_height(%d)\n", adapter);
600 
601  double h;
602  ts5_get_display_adapter_size(adapter, NULL, &h);
603 
604  return h;
605 }
606 
607 
609 
610 
611 
612 
617 
618 
619 
620 
633 int ts5_set_display_adapter(const int adapter)
634 {
635  ts5_check_display("ts5_set_display_adapter");
636  ts5_log(TS5_LOGLEVEL_4, "ts5_set_display_adapter(%d)\n", adapter);
637 
638  int retval = ts5_nextdisplay.adapter + 1;
639 
640  if (adapter > 0 && adapter <= _ts5_status.num_display_adapters) {
641  ts5_nextdisplay.adapter = adapter - 1;
642  ts5_log(TS5_LOGLEVEL_4, "ts5_set_display_adapter: set display adapter for next display to %d (was %d)\n",
643  retval-1, ts5_nextdisplay.adapter+1);
644  }
645  else {
646  ts5_fatal ("ts5_set_display_adapter: adapter index not valid\n");
647  }
648 
649  return retval;
650 }
651 
652 
662 int ts5_get_display_adapter(const int display)
663 {
664  ts5_check_display2("ts5_get_display_adapter", display);
665  ts5_log(TS5_LOGLEVEL_4, "ts5_get_display_adapter(%d)\n", display);
666 
667  int retval;
668 
669  if (display == 0) {
670  retval = ts5_nextdisplay.adapter + 1;
671  }
672  else {
673  retval = _ts5_status.display_status[display-1].adapter + 1;
674  }
675 
676  return retval;
677 }
678 
679 
688 void ts5_set_display_size(double w, double h)
689 {
690  ts5_check_display("ts5_set_display_size");
691  ts5_log(TS5_LOGLEVEL_4, "ts5_set_display_size(%f,%f)\n", w, h);
692 
693  int oldw = ts5_nextdisplay.w;
694  int oldh = ts5_nextdisplay.h;
695 
696  if (_ts5_status.graphics_status.coordinate_scale == TS5_RELATIVE_COORDINATES) {
697  w *= _ts5_status.display_adapter_status[ts5_nextdisplay.adapter].w;
698  h *= _ts5_status.display_adapter_status[ts5_nextdisplay.adapter].h;
699  }
700 
701  ts5_nextdisplay.w = w;
702  ts5_nextdisplay.h = h;
703 
704  ts5_log(TS5_LOGLEVEL_4, "ts5_set_display_size: set display size for next display to %d x %d (was %d x %d)\n",
705  ts5_nextdisplay.w, ts5_nextdisplay.h, oldw, oldh);
706 }
707 
708 
720 void ts5_get_display_size(const int display, double *w, double *h)
721 {
722  ts5_check_display2("ts5_get_display_size", display);
723  ts5_log(TS5_LOGLEVEL_4, "ts5_get_display_size(%d,%p,%p)\n", display, w, h);
724 
725  double ww, hh;
726 
727  if (display == 0) {
728 
729  ww = ts5_nextdisplay.w;
730  hh = ts5_nextdisplay.h;
731 
732  if (_ts5_status.graphics_status.coordinate_scale == TS5_RELATIVE_COORDINATES) {
733  ww /= _ts5_status.display_adapter_status[ts5_nextdisplay.adapter].w;
734  hh /= _ts5_status.display_adapter_status[ts5_nextdisplay.adapter].h;
735  }
736  }
737  else {
738 
739  ww = _ts5_status.display_status[display-1].w;
740  hh = _ts5_status.display_status[display-1].h;
741 
742  if (_ts5_status.graphics_status.coordinate_scale == TS5_RELATIVE_COORDINATES) {
743  ww /= _ts5_status.display_adapter_status[_ts5_status.display_status[display-1].adapter].w;
744  hh /= _ts5_status.display_adapter_status[_ts5_status.display_status[display-1].adapter].h;
745  }
746  }
747 
748  if (w) {
749  *w = ww;
750  }
751 
752  if (h) {
753  *h = hh;
754  }
755 }
756 
757 
767 double ts5_get_display_width(const int display)
768 {
769  ts5_check_display2("ts5_get_display_width", display);
770  ts5_log(TS5_LOGLEVEL_4, "ts5_get_display_width(%d)\n", display);
771 
772  double w;
773  ts5_get_display_size(display, &w, NULL);
774 
775  return w;
776 }
777 
778 
788 double ts5_get_display_height(const int display)
789 {
790  ts5_check_display2("ts5_get_display_height", display);
791  ts5_log(TS5_LOGLEVEL_4, "ts5_get_display_height(%d)\n", display);
792 
793  double h;
794  ts5_get_display_size(display, NULL, &h);
795 
796  return h;
797 }
798 
799 
812 void ts5_set_display_position(double x, double y)
813 {
814  ts5_check_display("ts5_set_display_position");
815  ts5_log(TS5_LOGLEVEL_4, "ts5_set_display_position(%f,%f)\n", x, y);
816 
817  int oldx = ts5_nextdisplay.x;
818  int oldy = ts5_nextdisplay.y;
819 
820  if (_ts5_status.graphics_status.coordinate_scale == TS5_RELATIVE_COORDINATES) {
821 
822  if (_ts5_status.graphics_status.coordinate_system == TS5_CARTESIAN_COORDINATES) {
823  x *= _ts5_status.display_adapter_status[ts5_nextdisplay.adapter].w/2.0;
824  y *= _ts5_status.display_adapter_status[ts5_nextdisplay.adapter].h/2.0;
825  }
826  else {
827  x *= _ts5_status.display_adapter_status[ts5_nextdisplay.adapter].w;
828  y *= _ts5_status.display_adapter_status[ts5_nextdisplay.adapter].h;
829  }
830  }
831 
832  if (_ts5_status.graphics_status.coordinate_system == TS5_CARTESIAN_COORDINATES) {
833 
834  x += _ts5_status.display_adapter_status[ts5_nextdisplay.adapter].w/2;
835  x -= ts5_nextdisplay.w/2;
836  y = -y;
837  y += _ts5_status.display_adapter_status[ts5_nextdisplay.adapter].h/2;
838  y -= ts5_nextdisplay.h/2;
839  }
840 
841  x += _ts5_status.display_adapter_status[ts5_nextdisplay.adapter].x1;
842  y += _ts5_status.display_adapter_status[ts5_nextdisplay.adapter].y1;
843 
844  ts5_nextdisplay.x = x;
845  ts5_nextdisplay.y = y;
846 
847  ts5_log(TS5_LOGLEVEL_4, "ts5_set_display_position: set display position for next display to (%d,%d) (was (%d,%d))\n",
848  ts5_nextdisplay.x, ts5_nextdisplay.y, oldx, oldy);
849 }
850 
851 
865 void ts5_get_display_position(const int display, double *x, double *y)
866 {
867  ts5_check_display2("ts5_get_display_position", display);
868  ts5_log(TS5_LOGLEVEL_4, "ts5_get_display_position(%d,%p,%p)\n", display, x, y);
869 
870  double xx, yy;
871  double dw, dh, aw, ah;
872 
873  // get the values we need
874  if (display != 0) {
875 
876  int adapter = ts5_get_display_adapter(display);
877  al_get_window_position(_ts5_status.display[display-1],
878  &_ts5_status.display_status[display-1].x,
879  &_ts5_status.display_status[display-1].y);
880 
881  xx = _ts5_status.display_status[display-1].x;
882  yy = _ts5_status.display_status[display-1].y;
883 
884  xx -= _ts5_status.display_adapter_status[adapter].x1;
885  yy -= _ts5_status.display_adapter_status[adapter].y1;
886 
887  dw = _ts5_status.display_status[display-1].w;
888  dh = _ts5_status.display_status[display-1].h;
889 
890  aw = _ts5_status.display_adapter_status[adapter].w;
891  ah = _ts5_status.display_adapter_status[adapter].h;
892  }
893  else {
894 
895  xx = ts5_nextdisplay.x;
896  yy = ts5_nextdisplay.y;
897 
898  dw = ts5_nextdisplay.w;
899  dh = ts5_nextdisplay.h;
900 
901  aw = _ts5_status.display_adapter_status[ts5_nextdisplay.adapter].w;
902  ah = _ts5_status.display_adapter_status[ts5_nextdisplay.adapter].h;
903  }
904 
905  // if the settings are not default, compute xx and yy
906  if (xx!=-1 && yy!=-1) {
907 
908  // convert to cartesian if necessary
909  if (_ts5_status.graphics_status.coordinate_system == TS5_CARTESIAN_COORDINATES) {
910  xx = xx + dw/2.0 - aw/ 2.0;
911  yy = ah/2.0 - yy - dh/2.0;
912  }
913 
914  // convert to relative if necessary
915  if (_ts5_status.graphics_status.coordinate_scale == TS5_RELATIVE_COORDINATES) {
916 
917  if (_ts5_status.graphics_status.coordinate_system == TS5_CARTESIAN_COORDINATES) {
918  xx /= aw/2.0;
919  yy /= ah/2.0;
920  }
921  else {
922  xx /= aw;
923  yy /= ah;
924  }
925  }
926  }
927 
928  if (x) {
929  *x = xx;
930  }
931 
932  if (y) {
933  *y = yy;
934  }
935 }
936 
937 
946 double ts5_get_display_x(const int display)
947 {
948  ts5_check_display2("ts5_get_display_x", display);
949  ts5_log(TS5_LOGLEVEL_4, "ts5_get_display_x(%d)\n", display);
950 
951  double x;
952  ts5_get_display_position(display, &x, NULL);
953 
954  return x;
955 }
956 
957 
966 double ts5_get_display_y(const int display)
967 {
968  ts5_check_display2("ts5_get_display_y", display);
969  ts5_log(TS5_LOGLEVEL_4, "ts5_get_display_y(%d)\n", display);
970 
971  double y;
972  ts5_get_display_position(display, NULL, &y);
973 
974  return y;
975 }
976 
977 
978 
979 
993 int ts5_set_refreshrate(const int rate)
994 {
995  ts5_check_display("ts5_set_refreshrate");
996  ts5_log(TS5_LOGLEVEL_4, "ts5_set_refreshrate(%d)\n", rate);
997 
998  int retval = ts5_nextdisplay.refreshrate;
999 
1000  ts5_nextdisplay.refreshrate = rate;
1001 
1002  ts5_log(TS5_LOGLEVEL_4, "ts5_set_refreshrate: set refreshrate for next display to %d (was %d)\n",
1003  ts5_nextdisplay.refreshrate, retval);
1004  return retval;
1005 }
1006 
1007 
1017 int ts5_get_refreshrate(const int display)
1018 {
1019  ts5_check_display2("ts5_get_refreshrate", display);
1020  ts5_log(TS5_LOGLEVEL_4, "ts5_get_refreshrate(%d)\n", display);
1021 
1022  int retval;
1023 
1024  if (display == 0) {
1025  retval = ts5_nextdisplay.refreshrate;
1026  }
1027  else {
1028  retval = _ts5_status.display_status[display-1].refreshrate;
1029  }
1030 
1031  return retval;
1032 }
1033 
1034 
1056 int ts5_set_display_mode(const int mode)
1057 {
1058  ts5_check_display("ts5_set_display_mode");
1059  ts5_log(TS5_LOGLEVEL_4, "ts5_set_display_mode(%d)\n", mode);
1060 
1061  int retval = ts5_nextdisplay.display_mode;
1062 
1063  if (mode != TS5_WINDOWED && mode != TS5_FULLSCREEN && mode != TS5_FULLSCREEN_WINDOW) {
1064  ts5_fatal ("ts5_set_display_mode: requested display mode not available (%d)\n", mode);
1065  }
1066 
1067 // char ts5_display_mode[3][TS5_MAX_CHAR] = {"TS5_WINDOWED", "TS5_FULLSCREEN", "TS5_FULLSCREEN_WINDOW"};
1068 
1069  ts5_nextdisplay.display_mode = mode;
1070 
1071  ts5_log(TS5_LOGLEVEL_4, "ts5_set_display_mode: set display mode for next display to %d (was %d)\n",
1072  ts5_nextdisplay.display_mode, retval);
1073 
1074  return retval;
1075 }
1076 
1077 
1087 int ts5_get_display_mode(const int display)
1088 {
1089  ts5_check_display2("ts5_get_display_mode", display);
1090  ts5_log(TS5_LOGLEVEL_4, "ts5_get_display_mode(%d)\n", display);
1091 
1092  int retval;
1093 
1094  if (display == 0) {
1095  retval = ts5_nextdisplay.display_mode;
1096  }
1097  else {
1098  retval = _ts5_status.display_status[display-1].display_mode;
1099  }
1100 
1101  return retval;
1102 }
1103 
1104 
1114 int ts5_set_vsync_mode(const int mode)
1115 {
1116  ts5_check_display("ts5_set_vsync_mode");
1117  ts5_log(TS5_LOGLEVEL_4, "ts5_set_vsync_mode(%d)\n", mode);
1118 
1119  int retval = ts5_nextdisplay.vsync_mode;
1120 
1121  if (mode < TS5_VSYNC_WHATEVER || mode > TS5_VSYNC_OFF) {
1122  ts5_fatal("ts5_set_vsync_mode: mode should be 0, 1 or 2 (is %d)\n", mode);
1123  }
1124 
1125  ts5_nextdisplay.vsync_mode = mode;
1126 
1127  ts5_log(TS5_LOGLEVEL_4, "ts5_set_vsync_mode: set vsync mode for next display to %d (was %d)\n",
1128  ts5_nextdisplay.vsync_mode, retval);
1129 
1130  return retval;
1131 }
1132 
1133 
1143 int ts5_get_vsync_mode(const int display)
1144 {
1145  ts5_check_display2("ts5_get_vsync_mode", display);
1146  ts5_log(TS5_LOGLEVEL_4, "ts5_get_vsync_mode(%d)\n", display);
1147 
1148  int retval;
1149 
1150  if (display == 0) {
1151  retval = ts5_nextdisplay.vsync_mode;
1152  }
1153  else {
1154  retval = _ts5_status.display_status[display-1].vsync_mode;
1155  }
1156 
1157  return retval;
1158 }
1159 
1160 
1162 
1163