@@ -151,6 +151,93 @@ void projectMSDL::maximize() {
151151 resize (dm.w , dm.h );
152152}
153153
154+ /* Stretch projectM across multiple monitors */
155+ void projectMSDL::stretchMonitors ()
156+ {
157+ int displayCount = SDL_GetNumVideoDisplays ();
158+ if (displayCount >= 2 )
159+ {
160+ std::vector<SDL_Rect> displayBounds;
161+ for (int i = 0 ; i < displayCount; i++)
162+ {
163+ displayBounds.push_back (SDL_Rect ());
164+ SDL_GetDisplayBounds (i, &displayBounds.back ());
165+ }
166+
167+ int furthestX = 0 ;
168+ int furthestY = 0 ;
169+ int widest = 0 ;
170+ int highest = 0 ;
171+ int spanX = 0 ;
172+ int spanY = 0 ;
173+ int spanWidth = 0 ;
174+ int spanHeight = 0 ;
175+
176+ bool horizontal = true ;
177+ bool vertical = true ;
178+
179+ for (int i = 0 ; i < displayCount; i++)
180+ {
181+ if (displayBounds[0 ].x != displayBounds[i].x ) vertical = false ;
182+ if (displayBounds[0 ].y != displayBounds[i].y ) horizontal = false ;
183+ }
184+
185+ if (!vertical && !horizontal)
186+ {
187+ // If multiple montors are not perfectly aligned it's a bit of work to get the correct x,y and
188+ // dimensions But in my testing on Windows 10 even with the screen did not render correctly.
189+ // @todo more testing and make it work.
190+ SDL_Log (
191+ " SDL currently only supports multiple monitors that are aligned evenly in a vertical or "
192+ " horizontal position." );
193+ }
194+ else
195+ {
196+ for (int i = 0 ; i < displayCount; i++)
197+ {
198+ if (displayBounds[i].x < furthestX) spanX = displayBounds[i].x ; // X furthest left device
199+ if (displayBounds[i].y < furthestY) spanY = displayBounds[i].y ; // Y highest device
200+ if (displayBounds[i].h > highest) highest = displayBounds[i].h ; // highest resolution Height
201+ if (displayBounds[i].h > widest) widest = displayBounds[i].w ; // highest resolution Width
202+ if (horizontal) // perfectly aligned horizonal monitors.
203+ {
204+ spanHeight = highest;
205+ spanWidth = spanWidth + displayBounds[i].w ;
206+ }
207+ else if (vertical) // perfectly aligned vertical monitors.
208+ {
209+ spanHeight = spanHeight + displayBounds[i].h ;
210+ spanWidth = widest;
211+ }
212+ }
213+ SDL_SetWindowPosition (win, spanX, spanY);
214+ SDL_SetWindowSize (win, spanWidth, spanHeight);
215+ }
216+ }
217+ }
218+
219+ /* Moves projectM to the next monitor */
220+ void projectMSDL::nextMonitor ()
221+ {
222+ int displayCount = SDL_GetNumVideoDisplays ();
223+ int currentWindowIndex = SDL_GetWindowDisplayIndex (win);
224+ if (displayCount >= 2 )
225+ {
226+ std::vector<SDL_Rect> displayBounds;
227+ int nextWindow = currentWindowIndex + 1 ;
228+ if (nextWindow > displayCount) nextWindow = 0 ;
229+
230+ for (int i = 0 ; i < displayCount; i++)
231+ {
232+ displayBounds.push_back (SDL_Rect ());
233+ SDL_GetDisplayBounds (i, &displayBounds.back ());
234+ }
235+ SDL_SetWindowPosition (win, displayBounds[nextWindow].x , displayBounds[nextWindow].y );
236+ SDL_SetWindowSize (win, displayBounds[nextWindow].w , displayBounds[nextWindow].h );
237+ maximize ();
238+ }
239+ }
240+
154241void projectMSDL::toggleFullScreen () {
155242 maximize ();
156243 if (isFullScreen) {
@@ -180,8 +267,26 @@ void projectMSDL::keyHandler(SDL_Event *sdl_evt) {
180267 return ;
181268 }
182269 break ;
183-
184-
270+ case SDLK_s:
271+ if (sdl_mod & KMOD_LGUI || sdl_mod & KMOD_RGUI || sdl_mod & KMOD_LCTRL)
272+ {
273+ // command-s: [s]tretch monitors
274+ // Stereo requires fullscreen
275+ #if !STEREOSCOPIC_SBS
276+ stretchMonitors ();
277+ #endif
278+ return ; // handled
279+ }
280+ case SDLK_m:
281+ if (sdl_mod & KMOD_LGUI || sdl_mod & KMOD_RGUI || sdl_mod & KMOD_LCTRL)
282+ {
283+ // command-m: change [m]onitor
284+ // Stereo requires fullscreen
285+ #if !STEREOSCOPIC_SBS
286+ nextMonitor ();
287+ #endif
288+ return ; // handled
289+ }
185290 case SDLK_f:
186291 if (sdl_mod & KMOD_LGUI || sdl_mod & KMOD_RGUI || sdl_mod & KMOD_LCTRL) {
187292 // command-f: fullscreen
@@ -298,9 +403,12 @@ void projectMSDL::pollEvent() {
298403 switch (evt.type ) {
299404 case SDL_WINDOWEVENT:
300405 switch (evt.window .event ) {
301- case SDL_WINDOWEVENT_RESIZED:
302- resize (evt.window .data1 , evt.window .data2 );
303- break ;
406+ case SDL_WINDOWEVENT_RESIZED:
407+ resize (evt.window .data1 , evt.window .data2 );
408+ break ;
409+ case SDL_WINDOWEVENT_SIZE_CHANGED:
410+ resize (evt.window .data1 , evt.window .data2 );
411+ break ;
304412 }
305413 break ;
306414 case SDL_KEYDOWN:
0 commit comments