|   |  | 
| 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 | 
|  |