|
Change adapter un runtime |
Silver Sthan
Member #4,585
April 2004
|
Is it possible to change the adapter of the display during runtime ? I have a dual screen and I want to switch between the two monitors, when I use : // FullScreen // Windowed in "ALLEGRO_FULLSCREEN_WINDOW", the window stay in the first defined monitor, even if I force it with "set_new_display_adapter(another_monitor)". |
Edgar Reynaldo
Major Reynaldo
May 2007
|
al_set_display_flag only modifies the current display. You'll want to set the new adapter and create a new window, or simply have one window on each that you modify the 'windowedness' of and then minimize. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Silver Sthan
Member #4,585
April 2004
|
I want a behavior like a "normal" window : |
Edgar Reynaldo
Major Reynaldo
May 2007
|
I don't think that Allegro detects which monitor it is over when going to fullscreen. The adapter you create the window on is the adapter it will be fullscreen on when you change the window. I can test this at home tonight, but I think that's how it works. Allegro could probably be patched to fix this, but I don't know how much work it would be. I don't think that (currently) you can 'go fullscreen' on any adapter but the original one it was created on. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Silver Sthan
Member #4,585
April 2004
|
There is an easy trick for that, just get the window position in the desktop, If the window Position is in "Monitor[i] zone" then the current adapter MUST be monitor[i] and when I want to go in fullscreen, just need to set the proper adapter. The problem is 'set_new_display_adapter()' of allegro 5.2.11 don't change/set/modify anything. We can use it only once time (at initialization before create display) ! |
Edgar Reynaldo
Major Reynaldo
May 2007
|
That's why it's called al_set_NEW_display_adapter", because it only affects the displays created AFTER it. Like I said, I don't know what the 'affinity' of a display is to an adapter. Right now it stays with the adapter it was created with. There would have to be a new function or new settings in order to create the behavior you're expecting. Like I said, I can look at this tonight, but not until I get home where I have a dual monitor setup. Regardless, you can work around this by creating a NEW display on the NEW adapter. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Silver Sthan
Member #4,585
April 2004
|
I've made a little program to test my Window manager, for my 2D Game Engine. I join a zip here, you can test it ! For this problem, maybe I need to make one display for each Monitor. I'll keep going to search a solution. |
Edgar Reynaldo
Major Reynaldo
May 2007
|
Your test program won't change back from a fullscreen window to a window. No matter what I press. I'm still not home, but I'm going to write a test program too. Source + Static binary here (7-zip format) I wrote up a simple test program. You can move and resize the window. You can press M to maximize and N to minimize (restore, actually) (al_set_display_flag(display , ALLEGRO_MAXIMIZED , false);). You can press F to toggle ALLEGRO_FULLSCREEN_WINDOW, but it always goes fullscreen on the adapter it was created with. You can press O for OpenGL and D for Direct3D. Press a number key to switch adapters. The program confirms what I thought before. The adapter you create the display on is the adapter that it will go fullscreen window on. There is some other behavior though, like toggling the ALLEGRO_MAXIMIZE flag. It maximizes on the monitor it is currently over. What with it being a window and all, it shouldn't be too hard to get the behavior you want. Perhaps a few functions like : or the like. Just ideas. I'll take a look at allegro over the next few days and see what I can dig up. Source code for my test program here : 1
2
3
4
5
6
7
8#include "allegro5/allegro.h"
9#include "allegro5/allegro_font.h"
10#include "allegro5/allegro_ttf.h"
11
12#include "allegro5/allegro_direct3d.h"
13
14
15#include <cstdio>
16
17
18
19class Display {
20protected:
21 ALLEGRO_DISPLAY* display;
22 ALLEGRO_EVENT_QUEUE* queue;
23 ALLEGRO_TIMER* timer;
24 ALLEGRO_FONT* verdana20;
25 int origw;
26 int origh;
27 int w;
28 int h;
29 int xpos;
30 int ypos;
31 int adapter;
32 bool opengl;
33 bool redraw;
34 bool quit;
35 bool fullscreen;
36
37
38
39public :
40
41 Display();
42
43 int Init();
44
45 bool Create(int width , int height , int adapter , bool use_opengl);
46 void Destroy();
47 void RefreshInfo();
48 void DisplayInfo();
49 void Register();
50
51 void ToggleFullscreen();
52
53 bool SetAdapter(int nadapter);
54 bool UseOpenGL();
55 bool UseDirect3D();
56
57 void CheckInput();
58
59 void Draw();
60
61 void Run();
62
63 bool Quit() {return quit;}
64};
65
66
67
68int main(int argc , char** argv) {
69
70
71
72 Display d;
73 int ret = d.Init();
74 if (ret != 0) {return ret;}
75
76 if (!d.Create(800 , 600 , 0 , true)) {
77 return 1;
78 }
79
80 d.Run();
81
82
83
84 return 0;
85}
86
87
88
89Display::Display() :
90 display(0),
91 queue(0),
92 timer(0),
93 verdana20(0),
94 origw(0),
95 origh(0),
96 w(0),
97 h(0),
98 xpos(0),
99 ypos(0),
100 adapter(0),
101 opengl(true),
102 redraw(true),
103 quit(false),
104 fullscreen(false)
105{}
106
107
108
109int Display::Init() {
110
111 if (!al_init()) {
112 return -1;
113 }
114 if (!al_init_font_addon() || !al_init_ttf_addon()) {
115 return -2;
116 }
117
118 if (!al_install_keyboard()) {
119 return -3;
120 }
121 if (!al_install_mouse()) {
122 return -4;
123 }
124
125 queue = al_create_event_queue();
126 if (!queue) {
127 return -6;
128 }
129
130 timer = al_create_timer(1.0/60.0);
131 if (!timer) {
132 return -7;
133 }
134
135 al_register_event_source(queue , al_get_keyboard_event_source());
136 al_register_event_source(queue , al_get_timer_event_source(timer));
137 al_register_event_source(queue , al_get_mouse_event_source());
138
139
140 verdana20 = al_load_ttf_font("Verdana.ttf" , -20 , 0);
141 if (!verdana20) {
142 return -10;
143 }
144
145 return 0;
146}
147
148
149
150bool Display::Create(int width , int height , int new_adapter , bool use_opengl) {
151 Destroy();
152 int ndflags = ALLEGRO_WINDOWED | ALLEGRO_RESIZABLE | (use_opengl?ALLEGRO_OPENGL:ALLEGRO_DIRECT3D);
153 al_set_new_display_flags(ndflags);
154 al_set_new_display_adapter(new_adapter);
155 origw = width;
156 origh = height;
157 display = al_create_display(origw,origh);
158 if (display) {
159 opengl = use_opengl;
160 adapter = new_adapter;
161 Register();
162 al_start_timer(timer);
163 }
164 redraw = true;
165 return display;
166}
167
168
169
170void Display::Destroy() {
171 if (display) {
172 al_stop_timer(timer);
173 al_destroy_display(display);
174 display = 0;
175 }
176}
177
178
179
180void Display::RefreshInfo() {
181 al_get_window_position(display , &xpos , &ypos);
182 w = al_get_display_width(display);
183 h = al_get_display_height(display);
184}
185
186
187
188void Display::DisplayInfo() {
189 RefreshInfo();
190 al_draw_textf(verdana20 , al_map_rgb(255,255,255) , 10 , 10 , 0 , "Window position <%d , %d>" , xpos , ypos);
191 al_draw_textf(verdana20 , al_map_rgb(255,255,255) , 10 , 40 , 0 , "Window dimensions <%d , %d>" , w , h);
192 al_draw_textf(verdana20 , al_map_rgb(255,255,255) , 10 , 70 , 0 , "Adapter #%d" , adapter);
193 al_draw_textf(verdana20 , al_map_rgb(255,255,255) , 10 , 100 , 0 , "%d Available adapters" , al_get_num_video_adapters());
194 al_draw_textf(verdana20 , al_map_rgb(255,255,255) , 10 , 130 , 0 , "Using %s" , opengl?"OpenGL":"Direct3D");
195}
196
197
198
199void Display::Register() {
200 al_register_event_source(queue , al_get_display_event_source(display));
201}
202
203
204
205void Display::ToggleFullscreen() {
206 fullscreen = !fullscreen;
207 al_set_display_flag(display , ALLEGRO_FULLSCREEN_WINDOW , fullscreen);
208}
209
210
211
212bool Display::SetAdapter(int nadapter) {
213 return Create(w , h , nadapter , opengl);
214}
215
216bool Display::UseOpenGL() {
217 return Create(w , h , adapter , true);
218}
219bool Display::UseDirect3D() {
220 return Create(w , h , adapter , false);
221}
222
223
224
225void Display::CheckInput() {
226 do {
227 ALLEGRO_EVENT ev;
228 al_wait_for_event(queue , &ev);
229 if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE || (ev.type == ALLEGRO_EVENT_KEY_DOWN && ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE)) {
230 quit = true;
231 break;
232 }
233 if (ev.type == ALLEGRO_EVENT_DISPLAY_RESIZE) {
234 al_acknowledge_resize(display);
235 }
236 if (ev.type == ALLEGRO_EVENT_KEY_DOWN) {
237 if (ev.keyboard.keycode == ALLEGRO_KEY_F) {
238 ToggleFullscreen();
239 }
240 if (ev.keyboard.keycode == ALLEGRO_KEY_M) {
241 al_set_display_flag(display , ALLEGRO_MAXIMIZED , true);
242 }
243 if (ev.keyboard.keycode == ALLEGRO_KEY_N) {
244 al_set_display_flag(display , ALLEGRO_MAXIMIZED , false);
245 }
246 if (ev.keyboard.keycode == ALLEGRO_KEY_O) {
247 if (!UseOpenGL()) {
248 printf("Failed to create an opengl context.\n");
249 quit = true;
250 break;
251 }
252 }
253 if (ev.keyboard.keycode == ALLEGRO_KEY_D) {
254 if (!UseDirect3D()) {
255 printf("Failed to create a Direct3D context.\n");
256 quit = true;
257 break;
258 }
259 }
260 for (int i = 0 ; i < al_get_num_video_adapters() ; ++i) {
261 if (ev.keyboard.keycode == ALLEGRO_KEY_1 + i) {
262 if (!SetAdapter(i)) {
263 printf("Failed to set adapter %d.\n" , i);
264 quit = true;
265 break;
266 }
267 }
268 }
269 }
270 if (ev.type == ALLEGRO_EVENT_TIMER) {
271 redraw = true;
272 }
273
274 } while (!al_is_event_queue_empty(queue));
275}
276
277
278
279
280void Display::Draw() {
281 if (redraw) {
282 al_set_target_backbuffer(display);
283 al_clear_to_color(al_map_rgb(0,0,0));
284
285 DisplayInfo();
286
287 al_flip_display();
288
289 redraw = false;
290 }
291}
292
293
294
295void Display::Run() {
296 while (!quit) {
297 Draw();
298 CheckInput();
299 }
300}
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Silver Sthan
Member #4,585
April 2004
|
Yes, new functions could be great !! I don't really like the idea to destroy/create display when you want to change adapter. not very elegant, but this is currently the only solution. Maybe a new minor release of Allegro5 soon ! |
Edgar Reynaldo
Major Reynaldo
May 2007
|
The majority of the work is done in the _al_win_set_display_flag function in allegro5/src/win/wwindow.c. The adapter there on line 1195 could easily be changed to affect which monitor the window goes fullscreen on. I dont' know how hard it would be to get allegro to do the same thing on other platforms. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
SilverTES
Member #16,572
October 2016
|
If it's work fine on Windows , I'll be already happy. It's possible to recompile this module, and add an argument like : ...(..,...,int monitor) 1 if (onoff) {
2 int adapter = monitor; <<---------------------------------------
3 al_get_monitor_info(adapter, &mi);
4 display->flags |= ALLEGRO_FULLSCREEN_WINDOW;
5 display->w = mi.x2 - mi.x1;
6 display->h = mi.y2 - mi.y1;
7 }
or something else. |
Edgar Reynaldo
Major Reynaldo
May 2007
|
_al_set_win_display_flag is probably part of the display driver, and if you change it's arguments then the ABI compatibility would be broken. It might be possible to add an element to the WIN_DISPLAY_DRIVER struct to store a preferred adapter, but that might end up doing the same thing. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
|