Move fullscreen display resolution control to the GUI with the rest of the fullscreen...
[dolphin.git] / Source / Core / DolphinWX / Src / MainNoGUI.cpp
blobda15483f93488e8cef122efaa8ed00d787d03f8e
1 // Copyright (C) 2003 Dolphin Project.
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, version 2.0.
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 // GNU General Public License 2.0 for more details.
12 // A copy of the GPL 2.0 should have been included with the program.
13 // If not, see http://www.gnu.org/licenses/
15 // Official SVN repository and contact information can be found at
16 // http://code.google.com/p/dolphin-emu/
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <stdarg.h>
22 #ifndef _WIN32
23 #include <sys/param.h>
24 #else
26 #endif
28 #include "Common.h"
29 #include "FileUtil.h"
31 #ifdef __APPLE__
32 #include <sys/param.h>
33 #endif
35 #if defined HAVE_X11 && HAVE_X11
36 #include <X11/keysym.h>
37 #include "State.h"
38 #include "X11Utils.h"
39 #endif
41 #if defined(HAVE_COCOA) && HAVE_COCOA
42 #import "cocoaApp.h"
43 #endif
45 #include "Core.h"
46 #include "Globals.h"
47 #include "Host.h"
48 #include "ISOFile.h"
49 #include "CPUDetect.h"
50 #include "cmdline.h"
51 #include "Thread.h"
52 #include "PowerPC/PowerPC.h"
54 #include "PluginManager.h"
55 #include "ConfigManager.h"
56 #include "LogManager.h"
57 #include "BootManager.h"
59 #if defined HAVE_X11 && HAVE_X11
60 bool running = true;
61 bool rendererHasFocus = true;
62 #endif
64 void Host_NotifyMapLoaded(){}
66 void Host_ShowJitResults(unsigned int address){}
68 Common::Event updateMainFrameEvent;
69 void Host_Message(int Id)
71 #if defined(HAVE_X11) && HAVE_X11
72 switch (Id)
74 case WM_USER_STOP:
75 running = false;
76 break;
78 #endif
81 void Host_UpdateTitle(const char* title){};
83 void Host_UpdateLogDisplay(){}
86 void Host_UpdateDisasmDialog(){}
89 void Host_UpdateMainFrame()
91 updateMainFrameEvent.Set();
94 void Host_UpdateBreakPointView(){}
97 void Host_UpdateMemoryView(){}
100 void Host_SetDebugMode(bool){}
102 void Host_RequestWindowSize(int& x, int& y, int& width, int& height)
104 x = SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowXPos;
105 y = SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowYPos;
106 width = SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowWidth;
107 height = SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowHeight;
110 bool Host_RendererHasFocus()
112 return rendererHasFocus;
115 void Host_SetWaitCursor(bool enable){}
118 void Host_UpdateStatusBar(const char* _pText, int Filed){}
120 void Host_SysMessage(const char *fmt, ...)
122 va_list list;
123 char msg[512];
125 va_start(list, fmt);
126 vsprintf(msg, fmt, list);
127 va_end(list);
129 size_t len = strlen(msg);
130 if (msg[len - 1] != '\n') {
131 msg[len - 1] = '\n';
132 msg[len] = '\0';
134 fprintf(stderr, "%s", msg);
137 void Host_SetWiiMoteConnectionState(int _State) {}
139 #if defined(HAVE_X11) && HAVE_X11
140 void X11_MainLoop()
142 bool fullscreen = SConfig::GetInstance().m_LocalCoreStartupParameter.bFullscreen;
143 while (Core::GetState() == Core::CORE_UNINITIALIZED)
144 updateMainFrameEvent.Wait();
146 Display *dpy = XOpenDisplay(0);
147 Window win = *(Window *)Core::GetXWindow();
148 XSelectInput(dpy, win, KeyPressMask | KeyReleaseMask | FocusChangeMask);
150 #if defined(HAVE_XRANDR) && HAVE_XRANDR
151 X11Utils::XRRConfiguration *XRRConfig = new X11Utils::XRRConfiguration(dpy, win);
152 #endif
154 Cursor blankCursor = NULL;
155 if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor)
157 // make a blank cursor
158 Pixmap Blank;
159 XColor DummyColor;
160 char ZeroData[1] = {0};
161 Blank = XCreateBitmapFromData (dpy, win, ZeroData, 1, 1);
162 blankCursor = XCreatePixmapCursor(dpy, Blank, Blank, &DummyColor, &DummyColor, 0, 0);
163 XFreePixmap (dpy, Blank);
164 XDefineCursor(dpy, win, blankCursor);
167 if (fullscreen)
169 X11Utils::EWMH_Fullscreen(_NET_WM_STATE_TOGGLE);
170 #if defined(HAVE_XRANDR) && HAVE_XRANDR
171 XRRConfig->ToggleDisplayMode(True);
172 #endif
175 // The actual loop
176 while (running)
178 XEvent event;
179 KeySym key;
180 for (int num_events = XPending(dpy); num_events > 0; num_events--)
182 XNextEvent(dpy, &event);
183 switch(event.type)
185 case KeyPress:
186 key = XLookupKeysym((XKeyEvent*)&event, 0);
187 if (key == XK_Escape)
189 if (Core::GetState() == Core::CORE_RUN)
191 if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor)
192 XUndefineCursor(dpy, win);
193 Core::SetState(Core::CORE_PAUSE);
195 else
197 if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor)
198 XDefineCursor(dpy, win, blankCursor);
199 Core::SetState(Core::CORE_RUN);
202 else if ((key == XK_Return) && (event.xkey.state & Mod1Mask))
204 fullscreen = !fullscreen;
205 X11Utils::EWMH_Fullscreen(_NET_WM_STATE_TOGGLE);
206 #if defined(HAVE_XRANDR) && HAVE_XRANDR
207 XRRConfig->ToggleDisplayMode(fullscreen);
208 #endif
210 else if (key >= XK_F1 && key <= XK_F8)
212 int slot_number = key - XK_F1 + 1;
213 if (event.xkey.state & ShiftMask)
214 State_Save(slot_number);
215 else
216 State_Load(slot_number);
218 else if (key == XK_F9)
219 Core::ScreenShot();
220 else if (key == XK_F11)
221 State_LoadLastSaved();
222 else if (key == XK_F12)
224 if (event.xkey.state & ShiftMask)
225 State_UndoLoadState();
226 else
227 State_UndoSaveState();
229 break;
230 case FocusIn:
231 rendererHasFocus = true;
232 if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor &&
233 Core::GetState() != Core::CORE_PAUSE)
234 XDefineCursor(dpy, win, blankCursor);
235 break;
236 case FocusOut:
237 rendererHasFocus = false;
238 if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor)
239 XUndefineCursor(dpy, win);
240 break;
243 if (!fullscreen)
245 Window winDummy;
246 unsigned int borderDummy, depthDummy;
247 XGetGeometry(dpy, win, &winDummy,
248 &SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowXPos,
249 &SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowYPos,
250 (unsigned int *)&SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowWidth,
251 (unsigned int *)&SConfig::GetInstance().m_LocalCoreStartupParameter.iRenderWindowHeight,
252 &borderDummy, &depthDummy);
254 usleep(100000);
257 #if defined(HAVE_XRANDR) && HAVE_XRANDR
258 delete XRRConfig;
259 #endif
260 if (SConfig::GetInstance().m_LocalCoreStartupParameter.bHideCursor)
261 XFreeCursor(dpy, blankCursor);
262 XCloseDisplay(dpy);
263 Core::Stop();
265 #endif
267 //for cocoa we need to hijack the main to get event
268 #if defined(HAVE_COCOA) && HAVE_COCOA
270 @interface CocoaThread : NSObject
272 NSThread *Thread;
274 - (void)cocoaThreadStart;
275 - (void)cocoaThreadRun:(id)sender;
276 - (void)cocoaThreadQuit:(NSNotification*)note;
277 - (bool)cocoaThreadRunning;
278 @end
280 static NSString *CocoaThreadHaveFinish = @"CocoaThreadHaveFinish";
282 int cocoaArgc;
283 char **cocoaArgv;
284 int appleMain(int argc, char *argv[]);
286 @implementation CocoaThread
288 - (void)cocoaThreadStart
291 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(cocoaThreadQuit:) name:CocoaThreadHaveFinish object:nil];
292 [NSThread detachNewThreadSelector:@selector(cocoaThreadRun:) toTarget:self withObject:nil];
296 - (void)cocoaThreadRun:(id)sender
299 NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
300 Thread = [NSThread currentThread];
301 //launch main
302 appleMain(cocoaArgc,cocoaArgv);
304 [[NSNotificationCenter defaultCenter] postNotificationName:CocoaThreadHaveFinish object:nil];
306 [pool release];
310 - (void)cocoaThreadQuit:(NSNotification*)note
313 [[NSNotificationCenter defaultCenter] removeObserver:self];
317 - (bool)cocoaThreadRunning
319 if([Thread isFinished])
320 return false;
321 else
322 return true;
325 @end
328 int main(int argc, char *argv[])
331 cocoaArgc = argc;
332 cocoaArgv = argv;
334 cocoaCreateApp();
336 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
338 CocoaThread *thread = [[CocoaThread alloc] init];
339 NSEvent *event = [[NSEvent alloc] init];
341 [thread cocoaThreadStart];
343 //cocoa event loop
344 while(1)
346 event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES ];
347 if(cocoaSendEvent(event))
349 Core::Stop();
350 break;
352 if(![thread cocoaThreadRunning])
353 break;
357 [event release];
358 [thread release];
359 [pool release];
363 int appleMain(int argc, char *argv[])
364 #else
365 // Include SDL header so it can hijack main().
366 #if defined(USE_SDL) && USE_SDL
367 #include <SDL.h>
368 #endif
369 int main(int argc, char* argv[])
370 #endif
372 gengetopt_args_info args_info;
374 if (cmdline_parser(argc, argv, &args_info) != 0)
375 return(1);
377 if (args_info.inputs_num < 1)
379 fprintf(stderr, "Please supply at least one argument - the ISO to boot.\n");
380 return(1);
382 std::string bootFile(args_info.inputs[0]);
384 updateMainFrameEvent.Init();
386 LogManager::Init();
387 EventHandler::Init();
388 SConfig::Init();
389 CPluginManager::Init();
391 CPluginManager::GetInstance().ScanForPlugins();
393 #if defined HAVE_X11 && HAVE_X11
394 XInitThreads();
395 #endif
397 if (BootManager::BootCore(bootFile)) //no use running the loop when booting fails
399 #if defined(HAVE_X11) && HAVE_X11
400 X11_MainLoop();
401 #else
402 while (PowerPC::GetState() != PowerPC::CPU_POWERDOWN)
403 updateMainFrameEvent.Wait();
404 #endif
406 updateMainFrameEvent.Shutdown();
408 CPluginManager::Shutdown();
409 SConfig::Shutdown();
410 EventHandler::Shutdown();
411 LogManager::Shutdown();
413 cmdline_parser_free (&args_info);
414 return(0);