#include "qemu/cutils.h"
#include "qemu/main-loop.h"
#include "qemu/module.h"
+#include "qemu/error-report.h"
#include <Carbon/Carbon.h>
#include "hw/core/cpu.h"
static QemuClipboardInfo *cbinfo;
static QemuEvent cbevent;
-// Utility functions to run specified code block with iothread lock held
+// Utility functions to run specified code block with the BQL held
typedef void (^CodeBlock)(void);
typedef bool (^BoolCodeBlock)(void);
-static void with_iothread_lock(CodeBlock block)
+static void with_bql(CodeBlock block)
{
- bool locked = qemu_mutex_iothread_locked();
+ bool locked = bql_locked();
if (!locked) {
- qemu_mutex_lock_iothread();
+ bql_lock();
}
block();
if (!locked) {
- qemu_mutex_unlock_iothread();
+ bql_unlock();
}
}
-static bool bool_with_iothread_lock(BoolCodeBlock block)
+static bool bool_with_bql(BoolCodeBlock block)
{
- bool locked = qemu_mutex_iothread_locked();
+ bool locked = bql_locked();
bool val;
if (!locked) {
- qemu_mutex_lock_iothread();
+ bql_lock();
}
val = block();
if (!locked) {
- qemu_mutex_unlock_iothread();
+ bql_unlock();
}
return val;
}
static CGEventRef handleTapEvent(CGEventTapProxy proxy, CGEventType type, CGEventRef cgEvent, void *userInfo)
{
- QemuCocoaView *cocoaView = userInfo;
+ QemuCocoaView *view = userInfo;
NSEvent *event = [NSEvent eventWithCGEvent:cgEvent];
- if ([cocoaView isMouseGrabbed] && [cocoaView handleEvent:event]) {
+ if ([view isMouseGrabbed] && [view handleEvent:event]) {
COCOA_DEBUG("Global events tap: qemu handled the event, capturing!\n");
return NULL;
}
- (void) updateUIInfoLocked
{
- /* Must be called with the iothread lock, i.e. via updateUIInfo */
+ /* Must be called with the BQL, i.e. via updateUIInfo */
NSSize frameSize;
QemuUIInfo info;
return;
}
- with_iothread_lock(^{
+ with_bql(^{
[self updateUIInfoLocked];
});
}
}
if (keysym) {
- kbd_put_keysym(keysym);
+ qemu_text_console_put_keysym(NULL, keysym);
}
}
- (bool) handleEvent:(NSEvent *)event
{
- return bool_with_iothread_lock(^{
+ return bool_with_bql(^{
return [self handleEventLocked:event];
});
}
*/
- (void) raiseAllKeys
{
- with_iothread_lock(^{
+ with_bql(^{
qkbd_state_lift_all_keys(kbd);
});
}
[normalWindow makeKeyAndOrderFront:self];
[normalWindow center];
[normalWindow setDelegate: self];
- stretch_video = false;
/* Used for displaying pause on the screen */
pauseLabel = [NSTextField new];
{
COCOA_DEBUG("QemuCocoaAppController: applicationWillTerminate\n");
- with_iothread_lock(^{
+ with_bql(^{
shutdown_action = SHUTDOWN_ACTION_POWEROFF;
qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_UI);
});
/* Pause the guest */
- (void)pauseQEMU:(id)sender
{
- with_iothread_lock(^{
+ with_bql(^{
qmp_stop(NULL);
});
[sender setEnabled: NO];
/* Resume running the guest operating system */
- (void)resumeQEMU:(id) sender
{
- with_iothread_lock(^{
+ with_bql(^{
qmp_cont(NULL);
});
[sender setEnabled: NO];
/* Restarts QEMU */
- (void)restartQEMU:(id)sender
{
- with_iothread_lock(^{
+ with_bql(^{
qmp_system_reset(NULL);
});
}
/* Powers down QEMU */
- (void)powerDownQEMU:(id)sender
{
- with_iothread_lock(^{
+ with_bql(^{
qmp_system_powerdown(NULL);
});
}
}
__block Error *err = NULL;
- with_iothread_lock(^{
+ with_bql(^{
qmp_eject([drive cStringUsingEncoding: NSASCIIStringEncoding],
NULL, false, false, &err);
});
}
__block Error *err = NULL;
- with_iothread_lock(^{
+ with_bql(^{
qmp_blockdev_change_medium([drive cStringUsingEncoding:
NSASCIIStringEncoding],
NULL,
// get the throttle percentage
throttle_pct = [sender tag];
- with_iothread_lock(^{
+ with_bql(^{
cpu_throttle_set(throttle_pct);
});
COCOA_DEBUG("cpu throttling at %d%c\n", cpu_throttle_get_percentage(), '%');
// View menu
menu = [[NSMenu alloc] initWithTitle:@"View"];
[menu addItem: [[[NSMenuItem alloc] initWithTitle:@"Enter Fullscreen" action:@selector(doToggleFullScreen:) keyEquivalent:@"f"] autorelease]]; // Fullscreen
- [menu addItem: [[[NSMenuItem alloc] initWithTitle:@"Zoom To Fit" action:@selector(zoomToFit:) keyEquivalent:@""] autorelease]];
+ menuItem = [[[NSMenuItem alloc] initWithTitle:@"Zoom To Fit" action:@selector(zoomToFit:) keyEquivalent:@""] autorelease];
+ [menuItem setState: stretch_video ? NSControlStateValueOn : NSControlStateValueOff];
+ [menu addItem: menuItem];
menuItem = [[[NSMenuItem alloc] initWithTitle:@"View" action:nil keyEquivalent:@""] autorelease];
[menuItem setSubmenu:menu];
[[NSApp mainMenu] addItem:menuItem];
return;
}
- with_iothread_lock(^{
+ with_bql(^{
QemuClipboardInfo *info = qemu_clipboard_info_ref(cbinfo);
qemu_event_reset(&cbevent);
qemu_clipboard_request(info, QEMU_CLIPBOARD_TYPE_TEXT);
while (info == cbinfo &&
info->types[QEMU_CLIPBOARD_TYPE_TEXT].available &&
info->types[QEMU_CLIPBOARD_TYPE_TEXT].data == NULL) {
- qemu_mutex_unlock_iothread();
+ bql_unlock();
qemu_event_wait(&cbevent);
- qemu_mutex_lock_iothread();
+ bql_lock();
}
if (info == cbinfo) {
int status;
COCOA_DEBUG("Second thread: calling qemu_default_main()\n");
- qemu_mutex_lock_iothread();
+ bql_lock();
status = qemu_default_main();
- qemu_mutex_unlock_iothread();
+ bql_unlock();
COCOA_DEBUG("Second thread: qemu_default_main() returned, exiting\n");
[cbowner release];
exit(status);
}
-static int cocoa_main()
+static int cocoa_main(void)
{
QemuThread thread;
COCOA_DEBUG("Entered %s()\n", __func__);
- qemu_mutex_unlock_iothread();
+ bql_unlock();
qemu_thread_create(&thread, "qemu_main", call_qemu_main,
NULL, QEMU_THREAD_DETACHED);
COCOA_DEBUG("qemu_cocoa: cocoa_refresh\n");
graphic_hw_update(NULL);
- if (qemu_input_is_absolute()) {
+ if (qemu_input_is_absolute(dcl->con)) {
dispatch_async(dispatch_get_main_queue(), ^{
if (![cocoaView isAbsoluteEnabled]) {
if ([cocoaView isMouseGrabbed]) {
[QemuApplication sharedApplication];
- create_initial_menus();
-
- /*
- * Create the menu entries which depend on QEMU state (for consoles
- * and removeable devices). These make calls back into QEMU functions,
- * which is OK because at this point we know that the second thread
- * holds the iothread lock and is synchronously waiting for us to
- * finish.
- */
- add_console_menu_entries();
- addRemovableDevicesMenuItems();
-
// Create an Application controller
QemuCocoaAppController *controller = [[QemuCocoaAppController alloc] init];
[NSApp setDelegate:controller];
left_command_key_enabled = 0;
}
+ if (opts->u.cocoa.has_zoom_to_fit && opts->u.cocoa.zoom_to_fit) {
+ stretch_video = true;
+ }
+
+ create_initial_menus();
+ /*
+ * Create the menu entries which depend on QEMU state (for consoles
+ * and removable devices). These make calls back into QEMU functions,
+ * which is OK because at this point we know that the second thread
+ * holds the BQL and is synchronously waiting for us to
+ * finish.
+ */
+ add_console_menu_entries();
+ addRemovableDevicesMenuItems();
+
// register vga output callbacks
register_displaychangelistener(&dcl);