1 #include <QtGui>
2 #include <QDesktopWidget>
3 #include "macros.h"
4 
5 #if (defined(QMC2_OS_UNIX) && QT_VERSION < 0x050000) || defined(QMC2_OS_WIN)
6 
7 #if defined(QMC2_OS_UNIX)
8 #include <QX11Info>
9 #include <X11/Xlib.h>
10 #include <X11/keysym.h>
11 #elif defined(QMC2_OS_WIN)
12 #include <QTest>
13 #include "windows_tools.h"
14 #include "processmanager.h"
15 #endif
16 #include "embedder.h"
17 #include "qmc2main.h"
18 #include "options.h"
19 #include "macros.h"
20 
21 extern MainWindow *qmc2MainWindow;
22 extern Settings *qmc2Config;
23 extern Options *qmc2Options;
24 
25 #if defined(QMC2_OS_WIN)
26 #define QMC2_EMBEDDED_STYLE		(LONG)(WS_VISIBLE | WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_MAXIMIZE)
27 #define QMC2_RELEASED_STYLE		(LONG)(WS_VISIBLE | WS_OVERLAPPEDWINDOW)
28 extern ProcessManager *qmc2ProcessManager;
29 #endif
30 
Embedder(QString name,QString id,WId wid,bool currentlyPaused,QWidget * parent,QIcon icon)31 Embedder::Embedder(QString name, QString id, WId wid, bool currentlyPaused, QWidget *parent, QIcon icon)
32 	: QWidget(parent)
33 {
34 	setAttribute(Qt::WA_NativeWindow);
35 	setAttribute(Qt::WA_DontCreateNativeAncestors);
36 	createWinId();
37 
38 	machineName = name;
39 	machineId = id;
40 	embeddedWinId = wid;
41 #if defined(QMC2_OS_UNIX)
42 	embedded = pauseKeyPressed = pausing = resuming = false;
43 	isPaused = currentlyPaused;
44 	embedContainer = new QX11EmbedContainer(this);
45 #elif defined(QMC2_OS_WIN)
46 	embedContainer = new QWidget(this);
47 	isPaused = currentlyPaused;
48 #endif
49 
50 	embedContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
51 	embedContainer->setObjectName("QMC2_EMBED_CONTAINER");
52 	embedContainer->setAutoFillBackground(true);
53 	QPalette pal = embedContainer->palette();
54 	pal.setColor(QPalette::Window, Qt::black);
55 	embedContainer->setPalette(pal);
56 
57 	setFocusPolicy(Qt::WheelFocus);
58 	setFocusProxy(embedContainer);
59 
60 	gridLayout = new QGridLayout(this);
61 	gridLayout->getContentsMargins(&cmLeft, &cmTop, &cmRight, &cmBottom);
62 	gridLayout->setContentsMargins(0, 0, 0, 0);
63 	gridLayout->setRowStretch(0, 0);
64 	gridLayout->setRowStretch(1, 4);
65 	gridLayout->setColumnStretch(0, 4);
66 	gridLayout->addWidget(embedContainer, 1, 0);
67 	setLayout(gridLayout);
68 
69 	if ( icon.isNull() ) {
70 		iconRunning = QIcon(QString::fromUtf8(":/data/img/trafficlight_green.png"));
71 		iconPaused = QIcon(QString::fromUtf8(":/data/img/trafficlight_yellow.png"));
72 		iconStopped = QIcon(QString::fromUtf8(":/data/img/trafficlight_red.png"));
73 		iconUnknown = QIcon(QString::fromUtf8(":/data/img/trafficlight_off.png"));
74 	} else {
75 		QPainter p;
76 		QPixmap pm(128, 64);
77 		QPixmap pmStatus;
78 		QPixmap pmIcon = icon.pixmap(icon.actualSize(QSize(64, 64))).scaled(64, 64, Qt::KeepAspectRatioByExpanding);
79 		pmIcon.setMask(pmIcon.createMaskFromColor(QColor(255, 255, 255), Qt::MaskInColor));
80 
81 		pmStatus = QIcon(QString::fromUtf8(":/data/img/trafficlight_green.png")).pixmap(64, 64);
82 		pm.fill(Qt::transparent);
83 		p.begin(&pm);
84 		p.setBackgroundMode(Qt::TransparentMode);
85 		p.drawPixmap(0, 0, pmStatus);
86 		p.drawPixmap(64, 0, pmIcon);
87 		p.end();
88 		iconRunning = QIcon(pm);
89 
90 		pmStatus = QIcon(QString::fromUtf8(":/data/img/trafficlight_yellow.png")).pixmap(64, 64);
91 		pm.fill(Qt::transparent);
92 		p.begin(&pm);
93 		p.setBackgroundMode(Qt::TransparentMode);
94 		p.drawPixmap(0, 0, pmStatus);
95 		p.drawPixmap(64, 0, pmIcon);
96 		p.end();
97 		iconPaused = QIcon(pm);
98 
99 		pmStatus = QIcon(QString::fromUtf8(":/data/img/trafficlight_red.png")).pixmap(64, 64);
100 		pm.fill(Qt::transparent);
101 		p.begin(&pm);
102 		p.setBackgroundMode(Qt::TransparentMode);
103 		p.drawPixmap(0, 0, pmStatus);
104 		p.drawPixmap(64, 0, pmIcon);
105 		p.end();
106 		iconStopped = QIcon(pm);
107 
108 		pmStatus = QIcon(QString::fromUtf8(":/data/img/trafficlight_off.png")).pixmap(64, 64);
109 		pm.fill(Qt::transparent);
110 		p.begin(&pm);
111 		p.setBackgroundMode(Qt::TransparentMode);
112 		p.drawPixmap(0, 0, pmStatus);
113 		p.drawPixmap(64, 0, pmIcon);
114 		p.end();
115 		iconUnknown = QIcon(pm);
116 	}
117 	iconUnknown = icon;
118 
119 #if defined(QMC2_OS_UNIX)
120 	connect(embedContainer, SIGNAL(clientIsEmbedded()), SLOT(clientEmbedded()));
121 	connect(embedContainer, SIGNAL(clientClosed()), SLOT(clientClosed()));
122 	connect(embedContainer, SIGNAL(error(QX11EmbedContainer::Error)), SLOT(clientError(QX11EmbedContainer::Error)));
123 #elif defined(QMC2_OS_WIN)
124 	windowHandle = (HWND)embeddedWinId;
125 	embeddingWindow = releasingWindow = checkingWindow = updatingWindow = fullScreen = false;
126 	connect(&checkTimer, SIGNAL(timeout()), this, SLOT(checkWindow()));
127 	RECT wR, cR;
128 	GetWindowRect(windowHandle, &wR);
129 	GetClientRect(windowHandle, &cR);
130 	SetWindowPos(windowHandle, HWND_BOTTOM, 0, 0, embedContainer->width(), embedContainer->height(), SWP_HIDEWINDOW);
131 	originalRect = QRect(wR.left, wR.top, wR.right - wR.left, wR.bottom - wR.top);
132 	nativeResolution = QRect(cR.left, cR.top, cR.right - cR.left, cR.bottom - cR.top).size();
133 #endif
134 
135 	embedderOptions = 0;
136 	optionsShown = false;
137 }
138 
embed()139 void Embedder::embed()
140 {
141 #if defined(QMC2_OS_WIN)
142 	if ( embeddingWindow || releasingWindow )
143 		return;
144 
145 	embeddingWindow = true;
146 #endif
147 
148 	// serious hack to access the tab bar without sub-classing from QTabWidget ;)
149 	QTabBar *tabBar = qmc2MainWindow->tabWidgetEmbeddedEmulators->findChild<QTabBar *>();
150 	int index = qmc2MainWindow->tabWidgetEmbeddedEmulators->indexOf(this);
151 	if ( tabBar )
152 		if ( !iconUnknown.isNull() )
153 			tabBar->setTabIcon(index, iconUnknown);
154 
155 #if defined(QMC2_OS_UNIX)
156 	nativeResolution = QPixmap::grabWindow(embeddedWinId).size();
157   	embedContainer->embedClient(embeddedWinId);
158 #elif defined(QMC2_OS_WIN)
159 	fullScreen = false;
160 	embedded = true;
161 	embeddingWindow = false;
162 	qmc2MainWindow->log(QMC2_LOG_FRONTEND, tr("emulator #%1 embedded, window ID = %2").arg(machineId).arg("0x" + QString::number((qulonglong)windowHandle, 16)));
163 	SetParent(windowHandle, (HWND)embedContainer->winId());
164 	QTimer::singleShot(0, this, SLOT(updateWindow()));
165 	checkTimer.start(250);
166 #endif
167 	QTimer::singleShot(0, this, SLOT(adjustIconSizes()));
168 }
169 
release()170 void Embedder::release()
171 {
172 #if defined(QMC2_OS_WIN)
173 	SetWindowPos(windowHandle, HWND_BOTTOM, originalRect.x(), originalRect.y(), originalRect.width(), originalRect.height(), SWP_HIDEWINDOW);
174 #endif
175 	embedded = false;
176 	embedContainer->clearFocus();
177 #if defined(QMC2_OS_UNIX)
178 	embedContainer->discardClient();
179 	qmc2MainWindow->log(QMC2_LOG_FRONTEND, tr("emulator #%1 released, window ID = %2").arg(machineId).arg("0x" + QString::number(embeddedWinId, 16)));
180 	qApp->syncX();
181 	XUnmapWindow(QX11Info::display(), embeddedWinId);
182 	XMapWindow(QX11Info::display(), embeddedWinId);
183 	QTimer::singleShot(QMC2_EMBED_RELEASE_DELAY, qmc2MainWindow, SLOT(raise()));
184 #elif defined(QMC2_OS_WIN)
185 	checkTimer.stop();
186 	releasingWindow = true;
187 	if ( checkingWindow || updatingWindow ) {
188 		QTimer::singleShot(10, this, SLOT(release()));
189 		return;
190 	}
191 	SetParent(windowHandle, 0);
192 	SetWindowLong(windowHandle, GWL_STYLE, QMC2_RELEASED_STYLE);
193 	SetWindowPos(windowHandle, HWND_NOTOPMOST, originalRect.x(), originalRect.y(), originalRect.width(), originalRect.height(), SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_DRAWFRAME);
194 	UpdateWindow(windowHandle);
195 	qmc2MainWindow->raise();
196 	qmc2MainWindow->activateWindow();
197 	qmc2MainWindow->log(QMC2_LOG_FRONTEND, tr("emulator #%1 released, window ID = %2").arg(machineId).arg("0x" + QString::number((qulonglong)windowHandle, 16)));
198 	windowHandle = 0;
199 	embeddedWinId = 0;
200 	releasingWindow = false;
201 #endif
202 }
203 
clientClosed()204 void Embedder::clientClosed()
205 {
206 	embedded = false;
207 
208 	emit closing();
209 }
210 
closeEvent(QCloseEvent * e)211 void Embedder::closeEvent(QCloseEvent *e)
212 {
213 	if ( embedded )
214 		release();
215 
216 	if ( embedderOptions )
217 		delete embedderOptions;
218 
219 	QWidget::closeEvent(e);
220 }
221 
showEvent(QShowEvent * e)222 void Embedder::showEvent(QShowEvent *e)
223 {
224 	if ( qmc2MainWindow->toolButtonEmbedderMaximizeToggle->isChecked() )
225 		QTimer::singleShot(0, qmc2MainWindow->menuBar(), SLOT(hide()));
226 
227 #if defined(QMC2_OS_WIN)
228 	QTimer::singleShot(QMC2_EMBED_FOCUS_DELAY, this, SLOT(forceFocus()));
229 #endif
230 
231 #if defined(QMC2_OS_UNIX)
232 	if ( embedded )
233 		QTimer::singleShot(QMC2_EMBED_PAUSERESUME_DELAY, this, SLOT(showEventDelayed()));
234 #endif
235 
236 	int myIndex = qmc2MainWindow->tabWidgetEmbeddedEmulators->indexOf(this);
237 	if ( qmc2Options->outputNotifiersEnabled() ) {
238 		if ( isPaused )
239 			qmc2MainWindow->tabWidgetEmbeddedEmulators->setTabIcon(myIndex, iconPaused);
240 		else
241 			qmc2MainWindow->tabWidgetEmbeddedEmulators->setTabIcon(myIndex, iconRunning);
242 	} else
243 		qmc2MainWindow->tabWidgetEmbeddedEmulators->setTabIcon(myIndex, iconUnknown);
244 
245 	QWidget::showEvent(e);
246 }
247 
hideEvent(QHideEvent * e)248 void Embedder::hideEvent(QHideEvent *e)
249 {
250 #if defined(QMC2_OS_UNIX)
251 	if ( embedded )
252 		QTimer::singleShot(QMC2_EMBED_PAUSERESUME_DELAY, this, SLOT(hideEventDelayed()));
253 #endif
254 
255 	QWidget::hideEvent(e);
256 }
257 
resizeEvent(QResizeEvent * e)258 void Embedder::resizeEvent(QResizeEvent *e)
259 {
260 	QWidget::resizeEvent(e);
261 	embedContainer->resize(size());
262 
263 #if defined(QMC2_OS_WIN)
264 	if ( embedded ) {
265 		embedContainer->resize(size());
266 		if ( windowHandle && !updatingWindow )
267 			SetWindowPos(windowHandle, HWND_TOPMOST, 0, 0, embedContainer->width(), embedContainer->height(), SWP_SHOWWINDOW);
268 	}
269 #endif
270 }
271 
272 #if defined(QMC2_OS_UNIX)
showEventDelayed()273 void Embedder::showEventDelayed()
274 {
275 	if ( !qmc2Options->outputNotifiersEnabled() )
276 		return;
277 	if ( isVisible() ) {
278   		// gain focus
279 		QTimer::singleShot(QMC2_EMBED_FOCUS_DELAY, this, SLOT(forceFocus()));
280 		if ( qmc2MainWindow->toolButtonEmbedderAutoPause->isChecked() ) {
281 			resuming = true;
282 			resume();
283 		}
284 	}
285 }
286 
hideEventDelayed()287 void Embedder::hideEventDelayed()
288 {
289 	if ( !qmc2Options->outputNotifiersEnabled() )
290 		return;
291 	if ( !isVisible() ) {
292 		if ( qmc2MainWindow->toolButtonEmbedderAutoPause->isChecked() ) {
293 			pausing = true;
294 			pause();
295 		}
296 	}
297 }
298 #endif
299 
toggleOptions()300 void Embedder::toggleOptions()
301 {
302 	optionsShown = !optionsShown;
303 	if ( optionsShown ) {
304 		if ( !embedderOptions ) {
305 			embedderOptions = new EmbedderOptions(this);
306 			embedderOptions->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
307 			gridLayout->addWidget(embedderOptions, 0, 0);
308 		}
309 		gridLayout->setContentsMargins(cmLeft, cmTop, cmRight, cmBottom);
310 		gridLayout->setRowStretch(0, 1);
311 		gridLayout->setRowStretch(1, 4);
312 		embedderOptions->show();
313 	} else {
314 		gridLayout->setContentsMargins(0, 0, 0, 0);
315 		gridLayout->setRowStretch(0, 0);
316 		gridLayout->setRowStretch(1, 4);
317 		if ( embedderOptions )
318 			embedderOptions->hide();
319 	}
320 #if defined(QMC2_OS_WIN)
321 	QTimer::singleShot(0, this, SLOT(updateWindow()));
322 #endif
323 }
324 
adjustIconSizes()325 void Embedder::adjustIconSizes()
326 {
327 	// serious hack to access the tab bar without sub-classing from QTabWidget ;)
328 	QTabBar *tabBar = qmc2MainWindow->tabWidgetEmbeddedEmulators->findChild<QTabBar *>();
329 	int index = qmc2MainWindow->tabWidgetEmbeddedEmulators->indexOf(this);
330 	QFont f;
331 	f.fromString(qmc2Config->value(QMC2_FRONTEND_PREFIX + "GUI/Font").toString());
332 	QFontMetrics fm(f);
333 	QToolButton *optionsButton = (QToolButton *)tabBar->tabButton(index, QTabBar::LeftSide);
334 	QToolButton *releaseButton = (QToolButton *)tabBar->tabButton(index, QTabBar::RightSide);
335 	int baseSize = fm.height() + 2;
336 	QSize optionsButtonSize(2 * baseSize, baseSize + 2);
337 	QSize releaseButtonSize(baseSize, baseSize);
338 	if ( optionsButton )
339 		optionsButton->setFixedSize(optionsButtonSize);
340 	if ( releaseButton )
341 		releaseButton->setFixedSize(releaseButtonSize);
342 	tabBar->setIconSize(optionsButtonSize);
343 }
344 
forceFocus()345 void Embedder::forceFocus()
346 {
347 	if ( embedded ) {
348 #if defined(QMC2_OS_WIN)
349 		if ( !updatingWindow ) {
350   			SetWindowPos(windowHandle, HWND_TOPMOST, 0, 0, embedContainer->width(), embedContainer->height(), SWP_HIDEWINDOW);
351 			SetParent(windowHandle, (HWND)embedContainer->winId());
352 			MoveWindow(windowHandle, 0, 0, embedContainer->width(), embedContainer->height(), true);
353   			SetWindowPos(windowHandle, HWND_TOPMOST, 0, 0, embedContainer->width(), embedContainer->height(), SWP_SHOWWINDOW);
354 			SetWindowLong(windowHandle, GWL_STYLE, QMC2_EMBEDDED_STYLE);
355 			UpdateWindow(windowHandle);
356 			EnableWindow(windowHandle, true);
357 			SetFocus(windowHandle);
358 			setUpdatesEnabled(true);
359 		}
360 #elif defined(QMC2_OS_UNIX)
361 		embedContainer->activateWindow();
362 		embedContainer->setFocus();
363 #endif
364 	} else {
365 		activateWindow();
366 		setFocus();
367 	}
368 }
369 
370 #if defined(QMC2_OS_UNIX)
371 
pause()372 void Embedder::pause()
373 {
374 	if ( !isPaused ) {
375 		if ( resuming ) {
376 			// retry soon...
377 			QTimer::singleShot(QMC2_XKEYEVENT_TRANSITION_TIME, this, SLOT(pause()));
378 			return;
379 		}
380 		simulatePauseKey();
381 		QTimer::singleShot(2 * QMC2_XKEYEVENT_TRANSITION_TIME, this, SLOT(pause()));
382 	} else
383 		pausing = false;
384 }
385 
resume()386 void Embedder::resume()
387 {
388 	if ( isPaused ) {
389 		if ( pausing ) {
390 			// retry soon...
391 			QTimer::singleShot(QMC2_XKEYEVENT_TRANSITION_TIME, this, SLOT(resume()));
392 			return;
393 		}
394 		simulatePauseKey();
395 		QTimer::singleShot(2 * QMC2_XKEYEVENT_TRANSITION_TIME, this, SLOT(resume()));
396 	} else
397 		resuming = false;
398 }
399 
simulatePauseKey()400 void Embedder::simulatePauseKey()
401 {
402 	XKeyEvent xev;
403 	xev.display = QX11Info::display();
404 	xev.window = embeddedWinId;
405 	xev.root = qApp->desktop()->winId();
406 	xev.subwindow = 0;
407 	xev.time = QX11Info::appTime();
408 	xev.x = xev.y = xev.x_root = xev.y_root = 1;
409 	xev.same_screen = true;
410 	xev.keycode = XKeysymToKeycode(xev.display, qmc2Config->value(QMC2_FRONTEND_PREFIX + "Embedder/PauseKey", Qt::Key_P).toInt());
411 	xev.state = 0;
412 
413 	if ( pauseKeyPressed ) {
414 		xev.type = KeyRelease;
415 		XSendEvent(xev.display, xev.window, true, KeyReleaseMask, (XEvent *)&xev);
416 		pauseKeyPressed = false;
417 		XFlush(QX11Info::display());
418 	} else {
419 		xev.type = KeyPress;
420 		XSendEvent(xev.display, xev.window, true, KeyPressMask, (XEvent *)&xev);
421 		pauseKeyPressed = true;
422 		QTimer::singleShot(QMC2_XKEYEVENT_TRANSITION_TIME, this, SLOT(simulatePauseKey()));
423 	}
424 }
425 
clientEmbedded()426 void Embedder::clientEmbedded()
427 {
428 	embedded = true;
429 	qmc2MainWindow->log(QMC2_LOG_FRONTEND, tr("emulator #%1 embedded, window ID = %2").arg(machineId).arg("0x" + QString::number(embeddedWinId, 16)));
430 
431 	// this works around a Qt bug when the tool bar is vertical and obscured by the emulator window before embedding
432 	QTimer::singleShot(0, qmc2MainWindow->toolbar, SLOT(update()));
433 
434 	int myIndex = qmc2MainWindow->tabWidgetEmbeddedEmulators->indexOf(this);
435 	if ( qmc2Options->outputNotifiersEnabled() ) {
436 		if ( isPaused )
437 			qmc2MainWindow->tabWidgetEmbeddedEmulators->setTabIcon(myIndex, iconPaused);
438 		else
439 			qmc2MainWindow->tabWidgetEmbeddedEmulators->setTabIcon(myIndex, iconRunning);
440 	} else
441 		qmc2MainWindow->tabWidgetEmbeddedEmulators->setTabIcon(myIndex, iconUnknown);
442 
443 	forceFocus();
444 }
445 
clientError(QX11EmbedContainer::Error error)446 void Embedder::clientError(QX11EmbedContainer::Error error)
447 {
448 	switch ( error ) {
449 		case QX11EmbedContainer::InvalidWindowID:
450 			qmc2MainWindow->log(QMC2_LOG_FRONTEND, tr("WARNING: invalid window ID %1").arg("0x" + QString::number(embeddedWinId, 16)));
451 			break;
452 		case QX11EmbedContainer::Unknown:
453 		default:
454 			qmc2MainWindow->log(QMC2_LOG_FRONTEND, tr("WARNING: unknown error, window ID = %1").arg("0x" + QString::number(embeddedWinId, 16)));
455 			break;
456 	}
457 
458 	emit closing();
459 }
460 
461 #elif defined(QMC2_OS_WIN)
462 
checkWindow()463 void Embedder::checkWindow()
464 {
465 	if ( embeddingWindow || releasingWindow || updatingWindow )
466 		return;
467 
468 	if ( !embedded || !windowHandle )
469 		return;
470 
471 	checkingWindow = true;
472 
473 	LONG currentStyle = GetWindowLong(windowHandle, GWL_STYLE);
474 	if ( currentStyle == 0 ) {
475 		qmc2MainWindow->log(QMC2_LOG_FRONTEND, tr("window ID for emulator #%1 lost, looking for replacement").arg(machineId));
476 		qApp->processEvents();
477 		HWND hwnd = 0;
478 		int retries = 0;
479 		Q_PID gamePid = qmc2ProcessManager->getPid(machineId.toInt());
480 		while ( gamePid && !hwnd && retries++ < QMC2_MAX_WININFO_RETRIES ) {
481 			hwnd = winFindWindowHandleOfProcess(gamePid, "MAME:");
482 			if ( !hwnd )
483 				QTest::qWait(QMC2_WININFO_DELAY);
484 		}
485 		if ( releasingWindow || !embedded ) {
486 			checkingWindow = false;
487 			return;
488 		}
489 		if ( hwnd && hwnd != windowHandle ) {
490 			windowHandle = hwnd;
491 			embeddedWinId = (WId)hwnd;
492   			SetWindowPos(windowHandle, HWND_BOTTOM, 0, 0, embedContainer->width(), embedContainer->height(), SWP_HIDEWINDOW);
493 			SetParent(windowHandle, (HWND)embedContainer->winId());
494 			SetWindowLong(windowHandle, GWL_STYLE, QMC2_EMBEDDED_STYLE);
495 			MoveWindow(windowHandle, 0, 0, embedContainer->width(), embedContainer->height(), true);
496 			qmc2MainWindow->log(QMC2_LOG_FRONTEND, tr("using replacement window ID %1 for emulator #%2").arg((qulonglong)windowHandle).arg(machineId));
497 			UpdateWindow(windowHandle);
498   			SetWindowPos(windowHandle, HWND_TOPMOST, 0, 0, embedContainer->width(), embedContainer->height(), SWP_SHOWWINDOW);
499 			EnableWindow(windowHandle, true);
500 			SetFocus(windowHandle);
501 			checkingWindow = false;
502 			return;
503 		} else {
504 			qmc2MainWindow->log(QMC2_LOG_FRONTEND, tr("no replacement window ID found for emulator #%1, closing embedder").arg(machineId));
505 			checkTimer.stop();
506 			windowHandle = 0;
507 			embeddedWinId = 0;
508 			QTimer::singleShot(0, this, SLOT(clientClosed()));
509 			checkingWindow = false;
510 			return;
511 		}
512 		fullScreen = false;
513 	} else if ( currentStyle != QMC2_EMBEDDED_STYLE ) {
514 		if ( currentStyle & WS_OVERLAPPEDWINDOW ) {
515 			qmc2MainWindow->log(QMC2_LOG_FRONTEND, tr("embedded emulator #%1 is returning from full-screen").arg(machineId));
516 			fullScreen = false;
517 			QTimer::singleShot(0, this, SLOT(updateWindow()));
518 			checkingWindow = false;
519 			return;
520 		} else {
521 			if ( !fullScreen ) {
522 				int desktopWidth, desktopHeight;
523 				desktopWidth = qApp->desktop()->width();
524 				desktopHeight = qApp->desktop()->height();
525 				qmc2MainWindow->log(QMC2_LOG_FRONTEND, tr("embedded emulator #%1 is switching to full-screen, using desktop-resolution %2x%3").arg(machineId).arg(desktopWidth).arg(desktopHeight));
526   				SetWindowPos(windowHandle, HWND_BOTTOM, 0, 0, desktopWidth, desktopHeight, SWP_HIDEWINDOW);
527 				SetParent(windowHandle, 0);
528 				SetWindowLong(windowHandle, GWL_STYLE, currentStyle | WS_POPUP);
529   				SetWindowPos(windowHandle, HWND_TOPMOST, 0, 0, desktopWidth, desktopHeight, SWP_SHOWWINDOW);
530 				EnableWindow(windowHandle, true);
531 				SetFocus(windowHandle);
532 			}
533 			fullScreen = true;
534 		}
535 	} else if ( GetFocus() != windowHandle ) {
536 		if ( QApplication::activeWindow() == qmc2MainWindow && qmc2MainWindow->tabWidgetMachineList->currentIndex() == QMC2_EMBED_INDEX )
537 			if ( qmc2MainWindow->tabWidgetEmbeddedEmulators->currentWidget() == this ) {
538 				QTimer::singleShot(0, this, SLOT(updateWindow()));
539 				checkingWindow = false;
540 				return;
541 			}
542 	}
543 
544 	if ( !fullScreen ) {
545 		RECT wR;
546 		GetWindowRect(windowHandle, &wR);
547 		QRect windowRect(wR.left, wR.top, wR.right - wR.left, wR.bottom - wR.top);
548 		if ( windowRect.size() != embedContainer->rect().size() )
549 			QTimer::singleShot(0, this, SLOT(updateWindow()));
550 	}
551 
552 	checkingWindow = false;
553 }
554 
updateWindow()555 void Embedder::updateWindow()
556 {
557 	if ( embeddingWindow || releasingWindow || updatingWindow )
558 		return;
559 
560 	updatingWindow = true;
561 	if ( GetWindowLong(windowHandle, GWL_STYLE) != QMC2_EMBEDDED_STYLE )
562 		SetWindowLong(windowHandle, GWL_STYLE, QMC2_EMBEDDED_STYLE);
563 	MoveWindow(windowHandle, 0, 0, embedContainer->width(), embedContainer->height(), true);
564 	UpdateWindow(windowHandle);
565 	updatingWindow = false;
566 }
567 
568 #endif
569 
570 #endif
571