1/* 2 * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 14 * its contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#if ENABLE(NETSCAPE_PLUGIN_API) 30 31#import "WebBaseNetscapePluginView.h" 32 33#import "WebFrameInternal.h" 34#import "WebKitLogging.h" 35#import "WebKitNSStringExtras.h" 36#import "WebKitSystemInterface.h" 37#import "WebPluginContainerCheck.h" 38#import "WebNetscapeContainerCheckContextInfo.h" 39#import "WebNSURLExtras.h" 40#import "WebNSURLRequestExtras.h" 41#import "WebView.h" 42#import "WebViewInternal.h" 43 44#import <WebCore/WebCoreObjCExtras.h> 45#import <WebCore/AuthenticationMac.h> 46#import <WebCore/CString.h> 47#import <WebCore/Document.h> 48#import <WebCore/Element.h> 49#import <WebCore/Frame.h> 50#import <WebCore/FrameLoader.h> 51#import <WebCore/HTMLPlugInElement.h> 52#import <WebCore/Page.h> 53#import <WebCore/RenderView.h> 54#import <WebKit/DOMPrivate.h> 55#import <runtime/InitializeThreading.h> 56#import <wtf/Assertions.h> 57 58#define LoginWindowDidSwitchFromUserNotification @"WebLoginWindowDidSwitchFromUserNotification" 59#define LoginWindowDidSwitchToUserNotification @"WebLoginWindowDidSwitchToUserNotification" 60 61using namespace WebCore; 62 63@implementation WebBaseNetscapePluginView 64 65+ (void)initialize 66{ 67 JSC::initializeThreading(); 68#ifndef BUILDING_ON_TIGER 69 WebCoreObjCFinalizeOnMainThread(self); 70#endif 71 WKSendUserChangeNotifications(); 72} 73 74- (id)initWithFrame:(NSRect)frame 75 pluginPackage:(WebNetscapePluginPackage *)pluginPackage 76 URL:(NSURL *)URL 77 baseURL:(NSURL *)baseURL 78 MIMEType:(NSString *)MIME 79 attributeKeys:(NSArray *)keys 80 attributeValues:(NSArray *)values 81 loadManually:(BOOL)loadManually 82 element:(PassRefPtr<WebCore::HTMLPlugInElement>)element 83{ 84 self = [super initWithFrame:frame]; 85 if (!self) 86 return nil; 87 88 _pluginPackage = pluginPackage; 89 _element = element; 90 _sourceURL.adoptNS([URL copy]); 91 _baseURL.adoptNS([baseURL copy]); 92 _MIMEType.adoptNS([MIME copy]); 93 94#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) 95 // Enable "kiosk mode" when instantiating the QT plug-in inside of Dashboard. See <rdar://problem/6878105> 96 if ([[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.dashboard.client"] && 97 [[[_pluginPackage.get() bundle] bundleIdentifier] isEqualToString:@"com.apple.QuickTime Plugin.plugin"]) { 98 RetainPtr<NSMutableArray> mutableKeys(AdoptNS, [keys mutableCopy]); 99 RetainPtr<NSMutableArray> mutableValues(AdoptNS, [values mutableCopy]); 100 101 [mutableKeys.get() addObject:@"kioskmode"]; 102 [mutableValues.get() addObject:@"true"]; 103 [self setAttributeKeys:mutableKeys.get() andValues:mutableValues.get()]; 104 } else 105#endif 106 [self setAttributeKeys:keys andValues:values]; 107 108 if (loadManually) 109 _mode = NP_FULL; 110 else 111 _mode = NP_EMBED; 112 113 _loadManually = loadManually; 114 115 return self; 116} 117 118- (void)dealloc 119{ 120 ASSERT(!_isStarted); 121 122 [super dealloc]; 123} 124 125- (void)finalize 126{ 127 ASSERT_MAIN_THREAD(); 128 ASSERT(!_isStarted); 129 130 [super finalize]; 131} 132 133- (WebNetscapePluginPackage *)pluginPackage 134{ 135 return _pluginPackage.get(); 136} 137 138- (BOOL)isFlipped 139{ 140 return YES; 141} 142 143- (NSURL *)URLWithCString:(const char *)URLCString 144{ 145 if (!URLCString) 146 return nil; 147 148 CFStringRef string = CFStringCreateWithCString(kCFAllocatorDefault, URLCString, kCFStringEncodingISOLatin1); 149 ASSERT(string); // All strings should be representable in ISO Latin 1 150 151 NSString *URLString = [(NSString *)string _web_stringByStrippingReturnCharacters]; 152 NSURL *URL = [NSURL _web_URLWithDataAsString:URLString relativeToURL:_baseURL.get()]; 153 CFRelease(string); 154 if (!URL) 155 return nil; 156 157 return URL; 158} 159 160- (NSMutableURLRequest *)requestWithURLCString:(const char *)URLCString 161{ 162 NSURL *URL = [self URLWithCString:URLCString]; 163 if (!URL) 164 return nil; 165 166 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL]; 167 Frame* frame = core([self webFrame]); 168 if (!frame) 169 return nil; 170 [request _web_setHTTPReferrer:frame->loader()->outgoingReferrer()]; 171 return request; 172} 173 174// Methods that subclasses must override 175- (void)setAttributeKeys:(NSArray *)keys andValues:(NSArray *)values 176{ 177 ASSERT_NOT_REACHED(); 178} 179 180- (void)handleMouseMoved:(NSEvent *)event 181{ 182 ASSERT_NOT_REACHED(); 183} 184 185- (void)focusChanged 186{ 187 ASSERT_NOT_REACHED(); 188} 189 190- (void)windowFocusChanged:(BOOL)hasFocus 191{ 192 ASSERT_NOT_REACHED(); 193} 194 195- (BOOL)createPlugin 196{ 197 ASSERT_NOT_REACHED(); 198 return NO; 199} 200 201- (void)loadStream 202{ 203 ASSERT_NOT_REACHED(); 204} 205 206- (BOOL)shouldStop 207{ 208 ASSERT_NOT_REACHED(); 209 return YES; 210} 211 212- (void)destroyPlugin 213{ 214 ASSERT_NOT_REACHED(); 215} 216 217- (void)updateAndSetWindow 218{ 219 ASSERT_NOT_REACHED(); 220} 221 222- (void)sendModifierEventWithKeyCode:(int)keyCode character:(char)character 223{ 224 ASSERT_NOT_REACHED(); 225} 226 227- (void)removeTrackingRect 228{ 229 if (_trackingTag) { 230 [self removeTrackingRect:_trackingTag]; 231 _trackingTag = 0; 232 233 // Do the following after setting trackingTag to 0 so we don't re-enter. 234 235 // Balance the retain in resetTrackingRect. Use autorelease in case we hold 236 // the last reference to the window during tear-down, to avoid crashing AppKit. 237 [[self window] autorelease]; 238 } 239} 240 241- (void)resetTrackingRect 242{ 243 [self removeTrackingRect]; 244 if (_isStarted) { 245 // Retain the window so that removeTrackingRect can work after the window is closed. 246 [[self window] retain]; 247 _trackingTag = [self addTrackingRect:[self bounds] owner:self userData:nil assumeInside:NO]; 248 } 249} 250 251- (void)stopTimers 252{ 253 _shouldFireTimers = NO; 254} 255 256- (void)startTimers 257{ 258 _shouldFireTimers = YES; 259} 260 261- (void)restartTimers 262{ 263 ASSERT([self window]); 264 265 [self stopTimers]; 266 267 if (!_isStarted || [[self window] isMiniaturized]) 268 return; 269 270 [self startTimers]; 271} 272 273- (NSRect)_windowClipRect 274{ 275 RenderObject* renderer = _element->renderer(); 276 277 if (renderer && renderer->view()) { 278 if (FrameView* frameView = renderer->view()->frameView()) 279 return frameView->windowClipRectForLayer(renderer->enclosingLayer(), true); 280 } 281 282 return NSZeroRect; 283} 284 285- (NSRect)visibleRect 286{ 287 // WebCore may impose an additional clip (via CSS overflow or clip properties). Fetch 288 // that clip now. 289 return NSIntersectionRect([self convertRect:[self _windowClipRect] fromView:nil], [super visibleRect]); 290} 291 292- (BOOL)acceptsFirstResponder 293{ 294 return YES; 295} 296 297- (void)sendActivateEvent:(BOOL)activate 298{ 299 if (!_isStarted) 300 return; 301 302 [self windowFocusChanged:activate]; 303} 304 305- (void)setHasFocus:(BOOL)flag 306{ 307 if (!_isStarted) 308 return; 309 310 if (_hasFocus == flag) 311 return; 312 313 _hasFocus = flag; 314 315 [self focusChanged]; 316} 317 318- (void)addWindowObservers 319{ 320 ASSERT([self window]); 321 322 NSWindow *theWindow = [self window]; 323 324 NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; 325 [notificationCenter addObserver:self selector:@selector(windowWillClose:) 326 name:NSWindowWillCloseNotification object:theWindow]; 327 [notificationCenter addObserver:self selector:@selector(windowBecameKey:) 328 name:NSWindowDidBecomeKeyNotification object:theWindow]; 329 [notificationCenter addObserver:self selector:@selector(windowResignedKey:) 330 name:NSWindowDidResignKeyNotification object:theWindow]; 331 [notificationCenter addObserver:self selector:@selector(windowDidMiniaturize:) 332 name:NSWindowDidMiniaturizeNotification object:theWindow]; 333 [notificationCenter addObserver:self selector:@selector(windowDidDeminiaturize:) 334 name:NSWindowDidDeminiaturizeNotification object:theWindow]; 335 336 [notificationCenter addObserver:self selector:@selector(loginWindowDidSwitchFromUser:) 337 name:LoginWindowDidSwitchFromUserNotification object:nil]; 338 [notificationCenter addObserver:self selector:@selector(loginWindowDidSwitchToUser:) 339 name:LoginWindowDidSwitchToUserNotification object:nil]; 340} 341 342- (void)removeWindowObservers 343{ 344 NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; 345 [notificationCenter removeObserver:self name:NSWindowWillCloseNotification object:nil]; 346 [notificationCenter removeObserver:self name:NSWindowDidBecomeKeyNotification object:nil]; 347 [notificationCenter removeObserver:self name:NSWindowDidResignKeyNotification object:nil]; 348 [notificationCenter removeObserver:self name:NSWindowDidMiniaturizeNotification object:nil]; 349 [notificationCenter removeObserver:self name:NSWindowDidDeminiaturizeNotification object:nil]; 350 [notificationCenter removeObserver:self name:LoginWindowDidSwitchFromUserNotification object:nil]; 351 [notificationCenter removeObserver:self name:LoginWindowDidSwitchToUserNotification object:nil]; 352} 353 354- (void)start 355{ 356 ASSERT([self currentWindow]); 357 358 if (_isStarted) 359 return; 360 361 if (_triedAndFailedToCreatePlugin) 362 return; 363 364 ASSERT([self webView]); 365 366 if (![[[self webView] preferences] arePlugInsEnabled]) 367 return; 368 369 Frame* frame = core([self webFrame]); 370 if (!frame) 371 return; 372 Page* page = frame->page(); 373 if (!page) 374 return; 375 376 bool wasDeferring = page->defersLoading(); 377 if (!wasDeferring) 378 page->setDefersLoading(true); 379 380 BOOL result = [self createPlugin]; 381 382 if (!wasDeferring) 383 page->setDefersLoading(false); 384 385 if (!result) { 386 _triedAndFailedToCreatePlugin = YES; 387 return; 388 } 389 390 _isStarted = YES; 391 [[self webView] addPluginInstanceView:self]; 392 393 [self updateAndSetWindow]; 394 395 if ([self window]) { 396 [self addWindowObservers]; 397 if ([[self window] isKeyWindow]) { 398 [self sendActivateEvent:YES]; 399 } 400 [self restartTimers]; 401 } 402 403 [self resetTrackingRect]; 404 405 [self loadStream]; 406} 407 408- (void)stop 409{ 410 if (![self shouldStop]) 411 return; 412 413 [self removeTrackingRect]; 414 415 if (!_isStarted) 416 return; 417 418 _isStarted = NO; 419 420 [[self webView] removePluginInstanceView:self]; 421 422 // Stop the timers 423 [self stopTimers]; 424 425 // Stop notifications and callbacks. 426 [self removeWindowObservers]; 427 428 [self destroyPlugin]; 429} 430 431- (void)viewWillMoveToWindow:(NSWindow *)newWindow 432{ 433 // We must remove the tracking rect before we move to the new window. 434 // Once we move to the new window, it will be too late. 435 [self removeTrackingRect]; 436 [self removeWindowObservers]; 437 438 // Workaround for: <rdar://problem/3822871> resignFirstResponder is not sent to first responder view when it is removed from the window 439 [self setHasFocus:NO]; 440 441 if (!newWindow) { 442 if ([[self webView] hostWindow]) { 443 // View will be moved out of the actual window but it still has a host window. 444 [self stopTimers]; 445 } else { 446 // View will have no associated windows. 447 [self stop]; 448 449 // Stop observing WebPreferencesChangedNotification -- we only need to observe this when installed in the view hierarchy. 450 // When not in the view hierarchy, -viewWillMoveToWindow: and -viewDidMoveToWindow will start/stop the plugin as needed. 451 [[NSNotificationCenter defaultCenter] removeObserver:self name:WebPreferencesChangedNotification object:nil]; 452 } 453 } 454} 455 456- (void)viewWillMoveToSuperview:(NSView *)newSuperview 457{ 458 if (!newSuperview) { 459 // Stop the plug-in when it is removed from its superview. It is not sufficient to do this in -viewWillMoveToWindow:nil, because 460 // the WebView might still has a hostWindow at that point, which prevents the plug-in from being destroyed. 461 // There is no need to start the plug-in when moving into a superview. -viewDidMoveToWindow takes care of that. 462 [self stop]; 463 464 // Stop observing WebPreferencesChangedNotification -- we only need to observe this when installed in the view hierarchy. 465 // When not in the view hierarchy, -viewWillMoveToWindow: and -viewDidMoveToWindow will start/stop the plugin as needed. 466 [[NSNotificationCenter defaultCenter] removeObserver:self name:WebPreferencesChangedNotification object:nil]; 467 } 468} 469 470- (void)viewDidMoveToWindow 471{ 472 [self resetTrackingRect]; 473 474 if ([self window]) { 475 // While in the view hierarchy, observe WebPreferencesChangedNotification so that we can start/stop depending 476 // on whether plugins are enabled. 477 [[NSNotificationCenter defaultCenter] addObserver:self 478 selector:@selector(preferencesHaveChanged:) 479 name:WebPreferencesChangedNotification 480 object:nil]; 481 482 // View moved to an actual window. Start it if not already started. 483 [self start]; 484 [self restartTimers]; 485 [self addWindowObservers]; 486 } else if ([[self webView] hostWindow]) { 487 // View moved out of an actual window, but still has a host window. 488 // Call setWindow to explicitly "clip out" the plug-in from sight. 489 // FIXME: It would be nice to do this where we call stopNullEvents in viewWillMoveToWindow. 490 [self updateAndSetWindow]; 491 } 492} 493 494- (void)viewWillMoveToHostWindow:(NSWindow *)hostWindow 495{ 496 if (!hostWindow && ![self window]) { 497 // View will have no associated windows. 498 [self stop]; 499 500 // Remove WebPreferencesChangedNotification observer -- we will observe once again when we move back into the window 501 [[NSNotificationCenter defaultCenter] removeObserver:self name:WebPreferencesChangedNotification object:nil]; 502 } 503} 504 505- (void)viewDidMoveToHostWindow 506{ 507 if ([[self webView] hostWindow]) { 508 // View now has an associated window. Start it if not already started. 509 [self start]; 510 } 511} 512 513#pragma mark NOTIFICATIONS 514 515- (void)windowWillClose:(NSNotification *)notification 516{ 517 [self stop]; 518} 519 520- (void)windowBecameKey:(NSNotification *)notification 521{ 522 [self sendActivateEvent:YES]; 523 [self invalidatePluginContentRect:[self bounds]]; 524 [self restartTimers]; 525} 526 527- (void)windowResignedKey:(NSNotification *)notification 528{ 529 [self sendActivateEvent:NO]; 530 [self invalidatePluginContentRect:[self bounds]]; 531 [self restartTimers]; 532} 533 534- (void)windowDidMiniaturize:(NSNotification *)notification 535{ 536 [self stopTimers]; 537} 538 539- (void)windowDidDeminiaturize:(NSNotification *)notification 540{ 541 [self restartTimers]; 542} 543 544- (void)loginWindowDidSwitchFromUser:(NSNotification *)notification 545{ 546 [self stopTimers]; 547} 548 549-(void)loginWindowDidSwitchToUser:(NSNotification *)notification 550{ 551 [self restartTimers]; 552} 553 554- (void)preferencesHaveChanged:(NSNotification *)notification 555{ 556 WebPreferences *preferences = [[self webView] preferences]; 557 BOOL arePlugInsEnabled = [preferences arePlugInsEnabled]; 558 559 if ([notification object] == preferences && _isStarted != arePlugInsEnabled) { 560 if (arePlugInsEnabled) { 561 if ([self currentWindow]) { 562 [self start]; 563 } 564 } else { 565 [self stop]; 566 [self invalidatePluginContentRect:[self bounds]]; 567 } 568 } 569} 570 571- (void)renewGState 572{ 573 [super renewGState]; 574 575 // -renewGState is called whenever the view's geometry changes. It's a little hacky to override this method, but 576 // much safer than walking up the view hierarchy and observing frame/bounds changed notifications, since you don't 577 // have to track subsequent changes to the view hierarchy and add/remove notification observers. 578 // NSOpenGLView uses the exact same technique to reshape its OpenGL surface. 579 580 // All of the work this method does may safely be skipped if the view is not in a window. When the view 581 // is moved back into a window, everything should be set up correctly. 582 if (![self window]) 583 return; 584 585 [self updateAndSetWindow]; 586 587 [self resetTrackingRect]; 588 589 // Check to see if the plugin view is completely obscured (scrolled out of view, for example). 590 // For performance reasons, we send null events at a lower rate to plugins which are obscured. 591 BOOL oldIsObscured = _isCompletelyObscured; 592 _isCompletelyObscured = NSIsEmptyRect([self visibleRect]); 593 if (_isCompletelyObscured != oldIsObscured) 594 [self restartTimers]; 595} 596 597- (BOOL)becomeFirstResponder 598{ 599 [self setHasFocus:YES]; 600 return YES; 601} 602 603- (BOOL)resignFirstResponder 604{ 605 [self setHasFocus:NO]; 606 return YES; 607} 608 609- (WebDataSource *)dataSource 610{ 611 WebFrame *webFrame = kit(_element->document()->frame()); 612 return [webFrame _dataSource]; 613} 614 615- (WebFrame *)webFrame 616{ 617 return [[self dataSource] webFrame]; 618} 619 620- (WebView *)webView 621{ 622 return [[self webFrame] webView]; 623} 624 625- (NSWindow *)currentWindow 626{ 627 return [self window] ? [self window] : [[self webView] hostWindow]; 628} 629 630- (WebCore::HTMLPlugInElement*)element 631{ 632 return _element.get(); 633} 634 635- (void)cut:(id)sender 636{ 637 [self sendModifierEventWithKeyCode:7 character:'x']; 638} 639 640- (void)copy:(id)sender 641{ 642 [self sendModifierEventWithKeyCode:8 character:'c']; 643} 644 645- (void)paste:(id)sender 646{ 647 [self sendModifierEventWithKeyCode:9 character:'v']; 648} 649 650- (void)selectAll:(id)sender 651{ 652 [self sendModifierEventWithKeyCode:0 character:'a']; 653} 654 655// AppKit doesn't call mouseDown or mouseUp on right-click. Simulate control-click 656// mouseDown and mouseUp so plug-ins get the right-click event as they do in Carbon (3125743). 657- (void)rightMouseDown:(NSEvent *)theEvent 658{ 659 [self mouseDown:theEvent]; 660} 661 662- (void)rightMouseUp:(NSEvent *)theEvent 663{ 664 [self mouseUp:theEvent]; 665} 666 667 668- (BOOL)convertFromX:(double)sourceX andY:(double)sourceY space:(NPCoordinateSpace)sourceSpace 669 toX:(double *)destX andY:(double *)destY space:(NPCoordinateSpace)destSpace 670{ 671 // Nothing to do 672 if (sourceSpace == destSpace) 673 return TRUE; 674 675 NSPoint sourcePoint = NSMakePoint(sourceX, sourceY); 676 677 NSPoint sourcePointInScreenSpace; 678 679 // First convert to screen space 680 switch (sourceSpace) { 681 case NPCoordinateSpacePlugin: 682 sourcePointInScreenSpace = [self convertPoint:sourcePoint toView:nil]; 683 sourcePointInScreenSpace = [[self currentWindow] convertBaseToScreen:sourcePointInScreenSpace]; 684 break; 685 686 case NPCoordinateSpaceWindow: 687 sourcePointInScreenSpace = [[self currentWindow] convertBaseToScreen:sourcePoint]; 688 break; 689 690 case NPCoordinateSpaceFlippedWindow: 691 sourcePoint.y = [[self currentWindow] frame].size.height - sourcePoint.y; 692 sourcePointInScreenSpace = [[self currentWindow] convertBaseToScreen:sourcePoint]; 693 break; 694 695 case NPCoordinateSpaceScreen: 696 sourcePointInScreenSpace = sourcePoint; 697 break; 698 699 case NPCoordinateSpaceFlippedScreen: 700 sourcePoint.y = [[[NSScreen screens] objectAtIndex:0] frame].size.height - sourcePoint.y; 701 sourcePointInScreenSpace = sourcePoint; 702 break; 703 default: 704 return FALSE; 705 } 706 707 NSPoint destPoint; 708 709 // Then convert back to the destination space 710 switch (destSpace) { 711 case NPCoordinateSpacePlugin: 712 destPoint = [[self currentWindow] convertScreenToBase:sourcePointInScreenSpace]; 713 destPoint = [self convertPoint:destPoint fromView:nil]; 714 break; 715 716 case NPCoordinateSpaceWindow: 717 destPoint = [[self currentWindow] convertScreenToBase:sourcePointInScreenSpace]; 718 break; 719 720 case NPCoordinateSpaceFlippedWindow: 721 destPoint = [[self currentWindow] convertScreenToBase:sourcePointInScreenSpace]; 722 destPoint.y = [[self currentWindow] frame].size.height - destPoint.y; 723 break; 724 725 case NPCoordinateSpaceScreen: 726 destPoint = sourcePointInScreenSpace; 727 break; 728 729 case NPCoordinateSpaceFlippedScreen: 730 destPoint = sourcePointInScreenSpace; 731 destPoint.y = [[[NSScreen screens] objectAtIndex:0] frame].size.height - destPoint.y; 732 break; 733 734 default: 735 return FALSE; 736 } 737 738 if (destX) 739 *destX = destPoint.x; 740 if (destY) 741 *destY = destPoint.y; 742 743 return TRUE; 744} 745 746 747- (CString)resolvedURLStringForURL:(const char*)url target:(const char*)target; 748{ 749 String relativeURLString = String::fromUTF8(url); 750 if (relativeURLString.isNull()) 751 return CString(); 752 753 Frame* frame = core([self webFrame]); 754 if (!frame) 755 return CString(); 756 757 Frame* targetFrame = frame->tree()->find(String::fromUTF8(target)); 758 if (!targetFrame) 759 return CString(); 760 761 if (!frame->document()->securityOrigin()->canAccess(targetFrame->document()->securityOrigin())) 762 return CString(); 763 764 KURL absoluteURL = targetFrame->loader()->completeURL(relativeURLString); 765 return absoluteURL.string().utf8(); 766} 767 768- (void)invalidatePluginContentRect:(NSRect)rect 769{ 770 if (RenderBoxModelObject *renderer = toRenderBoxModelObject(_element->renderer())) { 771 IntRect contentRect(rect); 772 contentRect.move(renderer->borderLeft() + renderer->paddingLeft(), renderer->borderTop() + renderer->paddingTop()); 773 774 renderer->repaintRectangle(contentRect); 775 } 776} 777 778@end 779 780namespace WebKit { 781 782#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) 783CString proxiesForURL(NSURL *url) 784{ 785 RetainPtr<CFDictionaryRef> systemProxies(AdoptCF, CFNetworkCopySystemProxySettings()); 786 if (!systemProxies) 787 return "DIRECT"; 788 789 RetainPtr<CFArrayRef> proxiesForURL(AdoptCF, CFNetworkCopyProxiesForURL((CFURLRef)url, systemProxies.get())); 790 CFIndex proxyCount = proxiesForURL ? CFArrayGetCount(proxiesForURL.get()) : 0; 791 if (!proxyCount) 792 return "DIRECT"; 793 794 // proxiesForURL is a CFArray of CFDictionaries. Each dictionary represents a proxy. 795 // The format of the result should be: 796 // "PROXY host[:port]" (for HTTP proxy) or 797 // "SOCKS host[:port]" (for SOCKS proxy) or 798 // A combination of the above, separated by semicolon, in the order that they should be tried. 799 String proxies; 800 for (CFIndex i = 0; i < proxyCount; ++i) { 801 CFDictionaryRef proxy = static_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(proxiesForURL.get(), i)); 802 if (!proxy) 803 continue; 804 805 CFStringRef type = static_cast<CFStringRef>(CFDictionaryGetValue(proxy, kCFProxyTypeKey)); 806 bool isHTTP = type == kCFProxyTypeHTTP || type == kCFProxyTypeHTTPS; 807 bool isSOCKS = type == kCFProxyTypeSOCKS; 808 809 // We can only report HTTP and SOCKS proxies. 810 if (!isHTTP && !isSOCKS) 811 continue; 812 813 CFStringRef host = static_cast<CFStringRef>(CFDictionaryGetValue(proxy, kCFProxyHostNameKey)); 814 CFNumberRef port = static_cast<CFNumberRef>(CFDictionaryGetValue(proxy, kCFProxyPortNumberKey)); 815 816 // If we are inserting multiple entries, add a separator 817 if (!proxies.isEmpty()) 818 proxies += ";"; 819 820 if (isHTTP) 821 proxies += "PROXY "; 822 else if (isSOCKS) 823 proxies += "SOCKS "; 824 825 proxies += host; 826 827 if (port) { 828 SInt32 intPort; 829 CFNumberGetValue(port, kCFNumberSInt32Type, &intPort); 830 831 proxies += ":" + String::number(intPort); 832 } 833 } 834 835 if (proxies.isEmpty()) 836 return "DIRECT"; 837 838 return proxies.utf8(); 839} 840#endif 841 842bool getAuthenticationInfo(const char* protocolStr, const char* hostStr, int32_t port, const char* schemeStr, const char* realmStr, 843 CString& username, CString& password) 844{ 845 if (strcasecmp(protocolStr, "http") != 0 && 846 strcasecmp(protocolStr, "https") != 0) 847 return false; 848 849 NSString *host = [NSString stringWithUTF8String:hostStr]; 850 if (!hostStr) 851 return false; 852 853 NSString *protocol = [NSString stringWithUTF8String:protocolStr]; 854 if (!protocol) 855 return false; 856 857 NSString *realm = [NSString stringWithUTF8String:realmStr]; 858 if (!realm) 859 return NPERR_GENERIC_ERROR; 860 861 NSString *authenticationMethod = NSURLAuthenticationMethodDefault; 862 if (!strcasecmp(protocolStr, "http")) { 863 if (!strcasecmp(schemeStr, "basic")) 864 authenticationMethod = NSURLAuthenticationMethodHTTPBasic; 865 else if (!strcasecmp(schemeStr, "digest")) 866 authenticationMethod = NSURLAuthenticationMethodHTTPDigest; 867 } 868 869 RetainPtr<NSURLProtectionSpace> protectionSpace(AdoptNS, [[NSURLProtectionSpace alloc] initWithHost:host port:port protocol:protocol realm:realm authenticationMethod:authenticationMethod]); 870 871 NSURLCredential *credential = WebCoreCredentialStorage::get(protectionSpace.get()); 872 if (!credential) 873 credential = [[NSURLCredentialStorage sharedCredentialStorage] defaultCredentialForProtectionSpace:protectionSpace.get()]; 874 if (!credential) 875 return false; 876 877 if (![credential hasPassword]) 878 return false; 879 880 username = [[credential user] UTF8String]; 881 password = [[credential password] UTF8String]; 882 883 return true; 884} 885 886} // namespace WebKit 887 888#endif // ENABLE(NETSCAPE_PLUGIN_API) 889 890