/* * Copyright 2011 Sven Weidauer * * This file is part of NetSurf, http://www.netsurf-browser.org/ * * NetSurf is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License. * * NetSurf is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #import #import "utils/nsoption.h" #import "utils/utils.h" #import "utils/log.h" #import "utils/nsurl.h" #import "netsurf/mouse.h" #import "netsurf/window.h" #import "netsurf/misc.h" #import "netsurf/browser_window.h" #import "netsurf/content.h" #import "cocoa/gui.h" #import "cocoa/coordinates.h" #import "cocoa/plotter.h" #import "cocoa/BrowserView.h" #import "cocoa/BrowserViewController.h" #import "cocoa/BrowserWindowController.h" #import "cocoa/FormSelectMenu.h" #import "cocoa/fetch.h" #import "cocoa/schedule.h" NSString *const kCookiesFileOption = @"CookiesFile"; NSString *const kURLsFileOption = @"URLsFile"; NSString *const kHotlistFileOption = @"Hotlist"; NSString *const kHomepageURLOption = @"HomepageURL"; NSString *const kOptionsFileOption = @"ClassicOptionsFile"; NSString *const kAlwaysCancelDownload = @"AlwaysCancelDownload"; NSString *const kAlwaysCloseMultipleTabs = @"AlwaysCloseMultipleTabs"; #define UNIMPL() NSLog(@"Function '%s' unimplemented", __func__) struct browser_window; /* exported function docuemnted in cocoa/gui.h */ nserror cocoa_warning(const char *warning, const char *detail) { NSAlert *alert = [[NSAlert alloc] init]; alert.messageText = NSLocalizedString(@"Warning", @"Warning title"); alert.informativeText = [NSString localizedStringWithFormat:NSLocalizedString(@"Warning %s%s%s", @"Warning message"), warning, detail != NULL ? ": " : "", detail != NULL ? detail : ""]; [alert addButtonWithTitle:NSLocalizedString(@"OK", @"")]; [alert runModal]; return NSERROR_OK; } static struct gui_window * gui_window_create(struct browser_window *bw, struct gui_window *existing, gui_window_create_flags flags) { BrowserWindowController *window = nil; BrowserViewController *result; browser_window_set_scale(bw, (float)nsoption_int(scale) / 100, false); if (existing != NULL) { window = [(__bridge BrowserViewController *)(existing)windowController]; } result = [[BrowserViewController alloc] initWithBrowser:bw]; if (!(flags & GW_CREATE_TAB) || nil == window) { window = [[BrowserWindowController alloc] init]; [[window window] makeKeyAndOrderFront:nil]; } [window addTab:result]; return (__bridge_retained struct gui_window *)result; } static void gui_window_destroy(struct gui_window *g) { BrowserViewController *vc = (__bridge_transfer BrowserViewController *)g; vc = nil; } static void gui_window_set_title(struct gui_window *g, const char *title) { [(__bridge BrowserViewController *)g setTitle:[NSString stringWithUTF8String:title]]; } static nserror gui_window_update_box(struct gui_window *g, const struct rect *rect) { if (rect == NULL) { [[(__bridge BrowserViewController *)g browserView] setNeedsDisplay:YES]; return NSERROR_OK; } const NSRect nsrect = cocoa_scaled_rect_wh( browser_window_get_scale([(__bridge BrowserViewController *)g browser]), rect->x0, rect->y0, rect->x1 - rect->x0, rect->y1 - rect->y0); [[(__bridge BrowserViewController *)g browserView] setNeedsDisplayInRect:nsrect]; return NSERROR_OK; } static bool gui_window_get_scroll(struct gui_window *g, int *sx, int *sy) { NSCParameterAssert(g != NULL && sx != NULL && sy != NULL); NSRect visible = [[(__bridge BrowserViewController *)g browserView] visibleRect]; *sx = cocoa_pt_to_px(NSMinX(visible)); *sy = cocoa_pt_to_px(NSMinY(visible)); return true; } static nserror gui_window_set_scroll(struct gui_window *g, const struct rect *rect) { [[(__bridge BrowserViewController *)g browserView] scrollPoint:cocoa_point(rect->x0, rect->y0)]; return NSERROR_OK; } /** * Find the current dimensions of a cocoa browser window content area. * * \param g The gui window to measure content area of. * \param width receives width of window * \param height receives height of window * \param scaled whether to return scaled values * \return NSERROR_OK on sucess and width and height updated * else error code. */ static nserror gui_window_get_dimensions(struct gui_window *g, int *width, int *height, bool scaled) { NSCParameterAssert(width != NULL && height != NULL); NSRect frame = [[[(__bridge BrowserViewController *)g browserView] superview] frame]; if (scaled) { const CGFloat scale = browser_window_get_scale([(__bridge BrowserViewController *)g browser]); frame.size.width /= scale; frame.size.height /= scale; } *width = cocoa_pt_to_px(NSWidth(frame)); *height = cocoa_pt_to_px(NSHeight(frame)); return NSERROR_OK; } static void gui_window_update_extent(struct gui_window *g) { BrowserViewController *const window = (__bridge BrowserViewController *)g; int width; int height; struct browser_window *browser = [window browser]; browser_window_get_extents(browser, false, &width, &height); [[window browserView] setMinimumSize: cocoa_scaled_size(browser_window_get_scale(browser), width, height)]; } static void gui_window_set_status(struct gui_window *g, const char *text) { [(__bridge BrowserViewController *)g setStatus:[NSString stringWithUTF8String:text]]; } static void gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape) { switch (shape) { case GUI_POINTER_DEFAULT: case GUI_POINTER_WAIT: case GUI_POINTER_PROGRESS: [[NSCursor arrowCursor] set]; break; case GUI_POINTER_CROSS: [[NSCursor crosshairCursor] set]; break; case GUI_POINTER_POINT: case GUI_POINTER_MENU: [[NSCursor pointingHandCursor] set]; break; case GUI_POINTER_CARET: [[NSCursor IBeamCursor] set]; break; case GUI_POINTER_MOVE: [[NSCursor closedHandCursor] set]; break; default: NSLog(@"Other cursor %d requested", shape); [[NSCursor arrowCursor] set]; break; } } static nserror gui_window_set_url(struct gui_window *g, struct nsurl *url) { [(__bridge BrowserViewController *)g setUrl:[NSString stringWithUTF8String:nsurl_access(url)]]; return NSERROR_OK; } static void gui_window_start_throbber(struct gui_window *g) { [(__bridge BrowserViewController *)g setIsProcessing:YES]; [(__bridge BrowserViewController *)g updateBackForward]; } static void gui_window_stop_throbber(struct gui_window *g) { [(__bridge BrowserViewController *)g setIsProcessing:NO]; [(__bridge BrowserViewController *)g updateBackForward]; } static void gui_window_set_icon(struct gui_window *g, struct hlcache_handle *icon) { NSBitmapImageRep *bmp = NULL; NSImage *image = nil; if (icon != NULL) { bmp = (__bridge NSBitmapImageRep *)content_get_bitmap(icon); } if (bmp != nil) { image = [[NSImage alloc] initWithSize:NSMakeSize(32, 32)]; [image addRepresentation:bmp]; } else { image = [[NSImage imageNamed:@"NetSurf"] copy]; } [image setFlipped:YES]; [(__bridge BrowserViewController *)g setFavicon:image]; } static void gui_window_place_caret(struct gui_window *g, int x, int y, int height, const struct rect *clip) { [[(__bridge BrowserViewController *)g browserView] addCaretAt:cocoa_point(x, y) height:cocoa_px_to_pt(height)]; } static void gui_window_remove_caret(struct gui_window *g) { [[(__bridge BrowserViewController *)g browserView] removeCaret]; } static void gui_window_new_content(struct gui_window *g) { [(__bridge BrowserViewController *)g contentUpdated]; } static void gui_create_form_select_menu(struct gui_window *g, struct form_control *control) { BrowserViewController *const window = (__bridge BrowserViewController *)g; FormSelectMenu *menu = [[FormSelectMenu alloc] initWithControl:control forWindow:[window browser]]; [menu runInView:[window browserView]]; } static nserror gui_launch_url(nsurl *url) { [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:[NSString stringWithUTF8String:nsurl_access(url)]]]; return NSERROR_OK; } struct ssl_cert_info; static nserror gui_cert_verify(nsurl *url, const struct ssl_cert_info *certs, unsigned long num, nserror (*cb)(bool proceed, void *pw), void *cbpw) { return NSERROR_NOT_IMPLEMENTED; } static struct gui_window_table window_table = { .create = gui_window_create, .destroy = gui_window_destroy, .invalidate = gui_window_update_box, .get_scroll = gui_window_get_scroll, .set_scroll = gui_window_set_scroll, .get_dimensions = gui_window_get_dimensions, .update_extent = gui_window_update_extent, .set_title = gui_window_set_title, .set_url = gui_window_set_url, .set_icon = gui_window_set_icon, .set_status = gui_window_set_status, .set_pointer = gui_window_set_pointer, .place_caret = gui_window_place_caret, .remove_caret = gui_window_remove_caret, .new_content = gui_window_new_content, .start_throbber = gui_window_start_throbber, .stop_throbber = gui_window_stop_throbber, .create_form_select_menu = gui_create_form_select_menu, }; struct gui_window_table *cocoa_window_table = &window_table; static struct gui_misc_table browser_table = { .schedule = cocoa_schedule, .warning = cocoa_warning, .launch_url = gui_launch_url, .cert_verify = gui_cert_verify, }; struct gui_misc_table *cocoa_misc_table = &browser_table;