21 #include "../include/tscope5/display.h"
22 #include "../include/tscope5/graphics.h"
23 #include "../include/tscope5/bitmaps.h"
24 #include "../include/tscope5/display_internal.h"
25 #include "../include/tscope5/system_internal.h"
26 #include "../include/tscope5/graphics_internal.h"
94 for (i = 0; i < _ts5_status.num_displays; i++) {
96 if (_ts5_status.display[i].adapter
98 ts5_fatal (
"%s: %s, %s (%d)\n",
"ts5_install_display",
99 "cannot open fullscreen display",
100 "adapter already in use by another display", i);
109 request.refreshrate = -1;
110 request.display_mode = TS5_FULLSCREEN_WINDOW;
113 #ifdef TS5_RASPBERRYPI
115 request.display_mode = TS5_FULLSCREEN;
129 for (i = 0; i < _ts5_status.num_displays; i++) {
131 if (_ts5_status.display[i].adapter
133 ts5_fatal (
"%s: %s, %s (%d)\n",
"ts5_install_display",
134 "cannot open fullscreen display",
135 " adapter already in use by another display", i);
141 ALLEGRO_DISPLAY_MODE *mode;
142 mode = (ALLEGRO_DISPLAY_MODE *)al_malloc(
sizeof(ALLEGRO_DISPLAY_MODE));
143 int nmodes = al_get_num_display_modes();
146 for (i=0; i<nmodes; i++) {
148 mode = al_get_display_mode(i, mode);
153 || mode->refresh_rate==0)) {
161 ts5_fatal (
"%s: %s (%d, %d) %s (%d) %s %d\n",
162 "ts5_install_display",
163 "the requested combination of size",
166 "is not supported by display adapter",
176 request.display_mode = TS5_FULLSCREEN;
186 for (i = 0; i < _ts5_status.num_displays; i++) {
188 if (_ts5_status.display[i].adapter
190 && (_ts5_status.display[i].display_mode
192 || _ts5_status.display[i].display_mode
193 == TS5_FULLSCREEN_WINDOW)) {
195 ts5_fatal (
"%s: %s, %s (%d)\n",
"ts5_install_display",
196 "cannot open display",
197 " adapter already in use by a fullscreen display",
206 ts5_log(TS5_LOGLEVEL_1,
"%s: %s %d (was %d)\n",
207 "ts5_install_display",
"adjusting display width to",
211 > _ts5_status.display_adapter
216 ts5_log(TS5_LOGLEVEL_1,
"%s: %s %d (was %d)\n",
217 "ts5_install_display",
"adjusting display width to",
228 ts5_log(TS5_LOGLEVEL_1,
"%s: %s %d (was %d)\n",
229 "ts5_install_display",
"adjusting display height to",
233 > _ts5_status.display_adapter
236 request.h = _ts5_status.display_adapter
239 ts5_log(TS5_LOGLEVEL_1,
"%s: %s %d (was %d)\n",
240 "ts5_install_display",
"adjusting display height to",
250 if (request.x == -1) {
252 if (_ts5_status.graphics.coordinate_system
253 == TS5_CARTESIAN_COORDINATES) {
255 request.x = (_ts5_status.display_adapter
256 [request.adapter].w - request.w)/2;
262 request.x += _ts5_status.display_adapter[request.adapter].x1;
265 if (request.y == -1) {
267 if (_ts5_status.graphics.coordinate_system
268 == TS5_CARTESIAN_COORDINATES) {
270 request.y = (_ts5_status.display_adapter
271 [request.adapter].h - request.h)/2;
277 request.y += _ts5_status.display_adapter[request.adapter].y1;
281 request.refreshrate = -1;
282 request.display_mode = TS5_WINDOWED;
288 al_set_new_display_adapter(request.adapter);
289 al_set_new_display_refresh_rate(request.refreshrate);
291 al_set_new_display_option(ALLEGRO_VSYNC, (
int)request.vsync_mode,
294 if (request.display_mode == TS5_WINDOWED) {
295 al_set_new_window_position(request.x, request.y);
298 if (request.display_mode == TS5_FULLSCREEN_WINDOW) {
299 al_set_new_window_position(INT_MAX, INT_MAX);
302 al_set_new_display_flags(request.display_mode);
305 _ts5_status.num_displays++;
306 _ts5_status.active_display = _ts5_status.num_displays - 1;
309 ts5_log(TS5_LOGLEVEL_1,
"ts5_install_display: Opening display\n");
311 TS5_DISPLAY **display;
312 display = al_realloc(_ts5_data.display,
313 _ts5_status.num_displays *
sizeof(TS5_DISPLAY *));
315 if (display == NULL) {
316 ts5_fatal(
"%s: %s\n",
"ts5_install_display",
317 "failed to allocate memory for display pointer");
320 _ts5_data.display = (TS5_DISPLAY **) display;
322 _ts5_data.display[_ts5_status.active_display] =
323 al_create_display(request.w, request.h);
325 if (!_ts5_data.display[_ts5_status.active_display]) {
326 ts5_fatal(
"ts5_install_display: could not open display\n");
330 request.w = _ts5_status.display_adapter[request.adapter].w;
331 request.h = _ts5_status.display_adapter[request.adapter].h;
335 TS5_BITMAP **display_buffer;
337 display_buffer = al_realloc(_ts5_data.display_buffer,
338 _ts5_status.num_displays *
sizeof(TS5_BITMAP *));
340 if (display_buffer == NULL) {
341 ts5_fatal(
"%s: %s\n",
"ts5_install_display",
342 "failed to allocate memory for display buffer pointer");
345 _ts5_data.display_buffer = (TS5_BITMAP **) display_buffer;
347 _ts5_data.display_buffer[_ts5_status.active_display] =
348 al_create_bitmap(request.w, request.h);
350 if (!_ts5_data.display_buffer[_ts5_status.active_display]) {
351 ts5_fatal(
"ts5_install_display: could not open display buffer\n");
356 TS5_BITMAP **display_backup;
358 display_backup = al_realloc(_ts5_data.display_backup,
359 _ts5_status.num_displays *
sizeof(TS5_BITMAP *));
361 if (display_backup == NULL) {
362 ts5_fatal(
"%s: %s\n",
"ts5_install_display",
363 "failed to allocate memory for display backup pointer");
366 _ts5_data.display_backup = (TS5_BITMAP **) display_backup;
368 _ts5_data.display_backup[_ts5_status.active_display] =
369 al_create_bitmap(request.w, request.h);
371 if (!_ts5_data.display_backup[_ts5_status.active_display]) {
372 ts5_fatal(
"ts5_install_display: could not open display backup\n");
377 TS5_DISPLAY_STATUS *display_status;
378 display_status = al_realloc(_ts5_status.display,
379 _ts5_status.num_displays *
sizeof(TS5_DISPLAY_STATUS));
381 if (display_status == NULL) {
382 ts5_fatal(
"%s: %s\n",
"ts5_install_display",
383 "failed to allocate memory for display settings");
386 _ts5_status.display = (TS5_DISPLAY_STATUS *) display_status;
388 _ts5_status.display[_ts5_status.active_display].adapter =
391 if (request.display_mode==TS5_WINDOWED) {
393 al_get_window_position(_ts5_data.display[_ts5_status.active_display],
394 &request.x, &request.y);
396 if (request.x + request.w
399 int oldw = request.w;
401 request.w = _ts5_status.display_adapter
404 al_resize_display(_ts5_data.display[_ts5_status.active_display],
405 request.w, request.h);
407 ts5_log(TS5_LOGLEVEL_1,
"%s: %s %d (was %d)\n",
408 "ts5_install_display",
"adjusting display width to",
412 if (request.y + request.h > _ts5_status.display_adapter
415 int oldh = request.h;
417 request.h = _ts5_status.display_adapter
420 al_resize_display(_ts5_data.display[_ts5_status.active_display],
421 request.w, request.h);
423 al_set_window_position(_ts5_data.display
424 [_ts5_status.active_display],
425 request.x, request.y + (request.h-oldh));
427 ts5_log(TS5_LOGLEVEL_1,
"%s: %s %d (was %d)\n",
428 "ts5_install_display",
"adjusting display height to",
431 al_get_window_position(
432 _ts5_data.display[_ts5_status.active_display],
433 &request.x, &request.y);
436 request.x -= _ts5_status.display_adapter[request.adapter].x1;
437 request.y -= _ts5_status.display_adapter[request.adapter].y1;
439 if (_ts5_status.graphics.coordinate_system
440 == TS5_CARTESIAN_COORDINATES) {
444 - (_ts5_status.display_adapter[request.adapter].w
448 (_ts5_status.display_adapter[request.adapter].h
454 _ts5_status.display[_ts5_status.active_display].x = request.x;
455 _ts5_status.display[_ts5_status.active_display].y = request.y;
456 _ts5_status.display[_ts5_status.active_display].w = request.w;
457 _ts5_status.display[_ts5_status.active_display].h = request.h;
459 _ts5_status.display[_ts5_status.active_display].refreshrate =
462 _ts5_status.display[_ts5_status.active_display].display_mode =
463 request.display_mode;
465 _ts5_status.display[_ts5_status.active_display].vsync_mode =
470 [_ts5_status.active_display]);
471 al_clear_to_color(_ts5_status.graphics.background_color);
474 [_ts5_status.active_display]);
482 _ts5_status.display[_ts5_status.active_display].last_sync = al_get_time();
489 return _ts5_status.active_display;
504 ts5_log(TS5_LOGLEVEL_5,
"ts5_clear_display()\n");
506 if (_ts5_data.target == NULL) {
507 ts5_fatal(
"ts5_clear_display: target is a NULL pointer\n");
510 al_clear_to_color(_ts5_status.graphics.background_color);
528 ts5_log(TS5_LOGLEVEL_5,
"ts5_flip_display()\n");
534 if (al_get_time() - _ts5_status.display[_ts5_status.active_display].last_sync >
535 1.0 / _ts5_status.display[_ts5_status.active_display].refreshrate + 0.003) {
544 if (al_get_time() - _ts5_status.display[_ts5_status.active_display].last_sync >
545 1.0 / _ts5_status.display[_ts5_status.active_display].refreshrate + 0.003) {
547 al_set_target_backbuffer(_ts5_data.display[_ts5_status.active_display]);
548 al_draw_bitmap(_ts5_data.display_backup[_ts5_status.active_display], 0.0, 0.0, 0);
552 al_set_target_bitmap(_ts5_data.display_backup[_ts5_status.active_display]);
553 al_clear_to_color(_ts5_status.graphics.background_color);
554 al_draw_bitmap(_ts5_data.display_buffer[_ts5_status.active_display], 0.0, 0.0, 0);
558 al_set_target_backbuffer(_ts5_data.display[_ts5_status.active_display]);
559 al_draw_bitmap(_ts5_data.display_buffer[_ts5_status.active_display], 0.0, 0.0, 0);
562 _ts5_status.display[_ts5_status.active_display].last_sync = al_get_time();
564 al_clear_to_color(_ts5_status.graphics.background_color);
566 al_set_target_bitmap(_ts5_data.display_buffer
567 [_ts5_status.active_display]);
569 return _ts5_status.display[_ts5_status.active_display].last_sync;
604 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_active_display(%d)\n", display);
606 int retval = _ts5_status.active_display + 1;
607 _ts5_status.active_display = display - 1;
608 _ts5_data.target = _ts5_data.display_buffer[_ts5_status.active_display];
609 al_set_target_bitmap(_ts5_data.target);
611 _ts5_status.graphics.target_width =
612 al_get_bitmap_width(_ts5_data.target);
614 _ts5_status.graphics.target_height =
615 al_get_bitmap_height(_ts5_data.target);
632 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_active_display()\n");
634 return _ts5_status.active_display + 1;
661 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_num_display_adapters()\n");
663 return _ts5_status.num_display_adapters;
683 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_display_adapter_size(%d,%f,%f)\n",
689 ts5_fatal(
"ts5_get_display_adapter_size: adapter index not valid\n");
691 else if (adapter == 0) {
695 else if (adapter <= _ts5_status.num_display_adapters) {
696 ww = _ts5_status.display_adapter[adapter-1].w;
697 hh = _ts5_status.display_adapter[adapter-1].h;
700 ts5_fatal(
"ts5_get_display_adapter_size: adapter index not valid\n");
725 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_display_adapter_width(%d)\n", adapter);
746 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_display_adapter_height(%d)\n", adapter);
785 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_display_adapter(%d)\n", adapter);
789 if (adapter > 0 && adapter <= _ts5_status.num_display_adapters) {
791 ts5_log(TS5_LOGLEVEL_4,
"%s: %s %d (was %d)\n",
792 "ts5_set_display_adapter",
793 "set display adapter for next display to",
797 ts5_fatal (
"ts5_set_display_adapter: adapter index not valid\n");
816 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_display_adapter(%d)\n", display);
824 retval = _ts5_status.display[display-1].adapter + 1;
842 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_display_size(%f,%f)\n", w, h);
847 if (_ts5_status.graphics.coordinate_scale
848 == TS5_RELATIVE_COORDINATES) {
856 ts5_log(TS5_LOGLEVEL_4,
"%s: %s %d x %d (was %d x %d)\n",
857 "ts5_set_display_size",
858 "set display size for next display to",
877 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_display_size(%d,%p,%p)\n", display, w, h);
886 ww = _ts5_status.display[display-1].w;
887 hh = _ts5_status.display[display-1].h;
912 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_display_width(%d)\n", display);
933 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_display_height(%d)\n", display);
959 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_display_position(%f,%f)\n", x, y);
964 if (_ts5_status.graphics.coordinate_scale
965 == TS5_RELATIVE_COORDINATES) {
967 if (_ts5_status.graphics.coordinate_system
968 == TS5_CARTESIAN_COORDINATES) {
982 if (_ts5_status.graphics.coordinate_system
983 == TS5_CARTESIAN_COORDINATES) {
998 ts5_log(TS5_LOGLEVEL_4,
"%s: %s (%d,%d) (was (%d,%d))\n",
999 "ts5_set_display_position",
1000 "set display position for next display to",
1022 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_display_position(%d,%p,%p)\n",
1026 double dw, dh, aw, ah;
1032 al_get_window_position(_ts5_data.display[display-1],
1033 &_ts5_status.display[display-1].x,
1034 &_ts5_status.display[display-1].y);
1036 xx = _ts5_status.display[display-1].x;
1037 yy = _ts5_status.display[display-1].y;
1039 xx -= _ts5_status.display_adapter[adapter-1].x1;
1040 yy -= _ts5_status.display_adapter[adapter-1].y1;
1042 dw = _ts5_status.display[display-1].w;
1043 dh = _ts5_status.display[display-1].h;
1045 aw = _ts5_status.display_adapter[adapter-1].w;
1046 ah = _ts5_status.display_adapter[adapter-1].h;
1061 if (xx!=-1 && yy!=-1) {
1065 if (_ts5_status.graphics.coordinate_system
1066 == TS5_CARTESIAN_COORDINATES) {
1067 xx = xx + dw/2.0 - aw/2.0;
1068 yy = ah/2.0 - yy - dh/2.0;
1072 if (_ts5_status.graphics.coordinate_scale
1073 == TS5_RELATIVE_COORDINATES) {
1075 if (_ts5_status.graphics.coordinate_system
1076 == TS5_CARTESIAN_COORDINATES) {
1110 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_display_x(%d)\n", display);
1130 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_display_y(%d)\n", display);
1157 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_refreshrate(%d)\n", rate);
1163 ts5_log(TS5_LOGLEVEL_4,
"%s: %s %d (was %d)\n",
"ts5_set_refreshrate",
1164 "set refreshrate for next display to",
1183 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_refreshrate(%d)\n", display);
1191 retval = _ts5_status.display[display-1].refreshrate;
1228 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_display_mode(%d)\n", mode);
1232 if (mode != TS5_WINDOWED
1233 && mode != TS5_FULLSCREEN
1234 && mode != TS5_FULLSCREEN_WINDOW) {
1235 ts5_fatal (
"%s: %s (%d)\n",
"ts5_set_display_mode",
1236 "requested display mode not available", mode);
1241 ts5_log(TS5_LOGLEVEL_4,
"%s: %s %d (was %d)\n",
"ts5_set_display_mode",
1242 "set display mode for next display to",
1261 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_display_mode(%d)\n", display);
1269 retval = _ts5_status.display[display-1].display_mode;
1289 ts5_log(TS5_LOGLEVEL_4,
"ts5_set_vsync_mode(%d)\n", mode);
1293 if (mode < TS5_VSYNC_WHATEVER || mode > TS5_VSYNC_OFF) {
1294 ts5_fatal(
"ts5_set_vsync_mode: mode should be 0, 1 or 2 (is %d)\n",
1300 ts5_log(TS5_LOGLEVEL_4,
"%s: %s %d (was %d)\n",
"ts5_set_vsync_mode",
1301 "set vsync mode for next display to",
1320 ts5_log(TS5_LOGLEVEL_4,
"ts5_get_vsync_mode(%d)\n", display);
1328 retval = _ts5_status.display[display-1].vsync_mode;
double ts5_get_display_adapter_width(const int adapter)
Get the width of the monitor attached to a display adapter.
int ts5_get_vsync_mode(const int display)
Get the vsync mode of a display.
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.
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.
double ts5_flip_display()
Make what has been drawn visible on the screen.
int ts5_set_active_display(const int display)
Set the active display.
int ts5_set_vsync_mode(const int mode)
Set the vsync mode for the next display.
void ts5_get_display_adapter_size(const int adapter, double *w, double *h)
Get the size of the monitor attached to a display adapter.
TS5_BITMAP * ts5_set_drawing_target(TS5_BITMAP *target)
Set the active drawing target.
void ts5_get_display_position(const int display, double *x, double *y)
Get the position of a display.
int ts5_get_display_mode(const int display)
Get the display mode of a display.
int ts5_install_display()
Open a new display.
void ts5_uninstall_displays()
Close all open displays.
double ts5_get_display_x(const int display)
Get the horizontal position of a display.
void ts5_set_display_size(double w, double h)
Set the size of the next display.
int ts5_get_active_display()
Get the active display.
double ts5_get_display_adapter_height(const int adapter)
Get the heigth of the monitor attached to a display adapter.
void ts5_log(const unsigned int level, const char *format,...)
Send info to a logging window.
int ts5_get_refreshrate(const int display)
Get the refreshrate of a display.
void ts5_clear_display()
Clear the current drawing target.
double ts5_get_display_width(const int display)
Get the width of a display.
void ts5_set_display_position(double x, double y)
Set the position of the next display.
int ts5_set_refreshrate(const int rate)
Set the requested refreshrate for the next display.
double ts5_get_display_height(const int display)
Get the height of a display.
void ts5_fatal(const char *format,...)
Exit safely with an error message.
void ts5_get_display_size(const int display, double *w, double *h)
Get the size of a display.
double ts5_get_display_y(const int display)
Get the vertical position of a display.
int ts5_set_display_adapter(const int adapter)
Set the display adapter for the next display that will be opened.
int ts5_get_display_adapter(const int display)
Get the index of the display adapter of a display.