Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2009, Google Inc. | 2 * Copyright 2009, Google Inc. |
| 3 * All rights reserved. | 3 * All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
| 7 * met: | 7 * met: |
| 8 * | 8 * |
| 9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 47 #include <AGL/aglRenderers.h> | 47 #include <AGL/aglRenderers.h> |
| 48 | 48 |
| 49 #include "core/cross/event.h" | 49 #include "core/cross/event.h" |
| 50 #include "statsreport/metrics.h" | 50 #include "statsreport/metrics.h" |
| 51 #include "plugin/cross/plugin_logging.h" | 51 #include "plugin/cross/plugin_logging.h" |
| 52 #include "plugin/cross/plugin_metrics.h" | 52 #include "plugin/cross/plugin_metrics.h" |
| 53 #include "plugin/cross/out_of_memory.h" | 53 #include "plugin/cross/out_of_memory.h" |
| 54 #include "plugin/mac/plugin_mac.h" | 54 #include "plugin/mac/plugin_mac.h" |
| 55 #include "plugin/mac/graphics_utils_mac.h" | 55 #include "plugin/mac/graphics_utils_mac.h" |
| 56 | 56 |
| 57 | 57 #if !defined(O3D_INTERNAL_PLUGIN) |
| 58 o3d::PluginLogging* g_logger = NULL; | 58 o3d::PluginLogging* g_logger = NULL; |
| 59 bool g_logging_initialized = false; | 59 bool g_logging_initialized = false; |
| 60 #endif | |
| 60 | 61 |
| 61 using glue::_o3d::PluginObject; | 62 using glue::_o3d::PluginObject; |
| 62 using glue::StreamManager; | 63 using glue::StreamManager; |
| 63 using o3d::DisplayWindowMac; | 64 using o3d::DisplayWindowMac; |
| 64 using o3d::Event; | 65 using o3d::Event; |
| 65 | 66 |
| 66 namespace { | 67 namespace { |
| 67 // We would normally make this a stack variable in main(), but in a | 68 // We would normally make this a stack variable in main(), but in a |
| 68 // plugin, that's not possible, so we allocate it dynamically and | 69 // plugin, that's not possible, so we allocate it dynamically and |
| 69 // destroy it explicitly. | 70 // destroy it explicitly. |
| 70 scoped_ptr<base::AtExitManager> g_at_exit_manager; | 71 scoped_ptr<base::AtExitManager> g_at_exit_manager; |
| 71 } // end anonymous namespace | |
| 72 | 72 |
| 73 // if defined, in AGL mode we do double buffered drawing | 73 // if defined, in AGL mode we do double buffered drawing |
| 74 // #define USE_AGL_DOUBLE_BUFFER | 74 // #define USE_AGL_DOUBLE_BUFFER |
| 75 | 75 |
| 76 #define CFTIMER | 76 #define CFTIMER |
| 77 // #define DEFERRED_DRAW_ON_NULLEVENTS | 77 // #define DEFERRED_DRAW_ON_NULLEVENTS |
| 78 | 78 |
| 79 // currently drawing with the timer doesn't play well with USE_AGL_DOUBLE_BUFFER | 79 // currently drawing with the timer doesn't play well with USE_AGL_DOUBLE_BUFFER |
| 80 #ifdef CFTIMER | 80 #ifdef CFTIMER |
| 81 #undef USE_AGL_DOUBLE_BUFFER | 81 #undef USE_AGL_DOUBLE_BUFFER |
| 82 #endif | 82 #endif |
| 83 | 83 |
| 84 static void DrawPlugin(PluginObject* obj) { | 84 void DrawPlugin(PluginObject* obj) { |
| 85 obj->client()->RenderClient(); | 85 obj->client()->RenderClient(); |
| 86 #ifdef USE_AGL_DOUBLE_BUFFER | 86 #ifdef USE_AGL_DOUBLE_BUFFER |
| 87 // In AGL mode, we have to call aglSwapBuffers to guarantee that our | 87 // In AGL mode, we have to call aglSwapBuffers to guarantee that our |
| 88 // pixels make it to the screen. | 88 // pixels make it to the screen. |
| 89 if (obj->mac_agl_context_ != NULL) | 89 if (obj->mac_agl_context_ != NULL) |
| 90 aglSwapBuffers(obj->mac_agl_context_); | 90 aglSwapBuffers(obj->mac_agl_context_); |
| 91 #endif | 91 #endif |
| 92 } | 92 } |
| 93 | 93 |
| 94 void RenderOnDemandCallbackHandler::Run() { | 94 unsigned char GetMacEventKeyChar(const EventRecord *the_event) { |
| 95 obj_->SetWantsRedraw(true); | |
| 96 } | |
| 97 | |
| 98 static unsigned char GetMacEventKeyChar(const EventRecord *the_event) { | |
| 99 unsigned char the_char = the_event->message & charCodeMask; | 95 unsigned char the_char = the_event->message & charCodeMask; |
| 100 return the_char; | 96 return the_char; |
| 101 } | 97 } |
| 102 | 98 |
| 103 static unsigned char GetMacEventKeyCode(const EventRecord *the_event) { | 99 unsigned char GetMacEventKeyCode(const EventRecord *the_event) { |
| 104 unsigned char the_key_code = (the_event->message & keyCodeMask) >> 8; | 100 unsigned char the_key_code = (the_event->message & keyCodeMask) >> 8; |
| 105 return the_key_code; | 101 return the_key_code; |
| 106 } | 102 } |
| 107 | 103 |
| 108 | 104 |
| 109 // Cocoa key events for things like arrow key presses can have strange unicode | 105 // Cocoa key events for things like arrow key presses can have strange unicode |
| 110 // values in the 0xF700-0xF747 range, eg NSUpArrowFunctionKey is 0xF700. | 106 // values in the 0xF700-0xF747 range, eg NSUpArrowFunctionKey is 0xF700. |
| 111 // These values are defined in NSEvent.h. | 107 // These values are defined in NSEvent.h. |
| 112 // Map the ones we care about to the more commonly understood values in | 108 // Map the ones we care about to the more commonly understood values in |
| 113 // the Mac system header Events.h, eg kUpArrowCharCode is 30. | 109 // the Mac system header Events.h, eg kUpArrowCharCode is 30. |
| 114 static int TranslateMacUnicodeControlChar(int theChar) { | 110 int TranslateMacUnicodeControlChar(int theChar) { |
| 115 switch(theChar) { | 111 switch(theChar) { |
| 116 case NSUpArrowFunctionKey: | 112 case NSUpArrowFunctionKey: |
| 117 return kUpArrowCharCode; | 113 return kUpArrowCharCode; |
| 118 case NSDownArrowFunctionKey: | 114 case NSDownArrowFunctionKey: |
| 119 return kDownArrowCharCode; | 115 return kDownArrowCharCode; |
| 120 case NSLeftArrowFunctionKey: | 116 case NSLeftArrowFunctionKey: |
| 121 return kLeftArrowCharCode; | 117 return kLeftArrowCharCode; |
| 122 case NSRightArrowFunctionKey: | 118 case NSRightArrowFunctionKey: |
| 123 return kRightArrowCharCode; | 119 return kRightArrowCharCode; |
| 124 } | 120 } |
| 125 return theChar; | 121 return theChar; |
| 126 } | 122 } |
| 127 | 123 |
| 128 | 124 |
| 129 // The Mac standard char codes for arrow keys are different from the | 125 // The Mac standard char codes for arrow keys are different from the |
| 130 // web standard. | 126 // web standard. |
| 131 // Also in the browser world the enter key gets mapped to be the same as the | 127 // Also in the browser world the enter key gets mapped to be the same as the |
| 132 // return key. | 128 // return key. |
| 133 static int TranslateMacControlCharToWebChar(int theChar) { | 129 int TranslateMacControlCharToWebChar(int theChar) { |
| 134 switch(theChar) { | 130 switch(theChar) { |
| 135 case kUpArrowCharCode: | 131 case kUpArrowCharCode: |
| 136 return 38; | 132 return 38; |
| 137 case kDownArrowCharCode: | 133 case kDownArrowCharCode: |
| 138 return 40; | 134 return 40; |
| 139 case kLeftArrowCharCode: | 135 case kLeftArrowCharCode: |
| 140 return 37; | 136 return 37; |
| 141 case kRightArrowCharCode: | 137 case kRightArrowCharCode: |
| 142 return 39; | 138 return 39; |
| 143 case kEnterCharCode: | 139 case kEnterCharCode: |
| 144 return kReturnCharCode; | 140 return kReturnCharCode; |
| 145 } | 141 } |
| 146 return theChar; | 142 return theChar; |
| 147 } | 143 } |
| 148 | 144 |
| 149 | 145 |
| 150 // Given an instance, and some event data, calls Javascript methods | 146 // Given an instance, and some event data, calls Javascript methods |
| 151 // placed on the object tag so that the keystrokes can be handled in | 147 // placed on the object tag so that the keystrokes can be handled in |
| 152 // Javascript. | 148 // Javascript. |
| 153 static void DispatchKeyboardEvent(PluginObject* obj, | 149 void DispatchKeyboardEvent(PluginObject* obj, |
| 154 EventKind kind, | 150 EventKind kind, |
| 155 int theChar, | 151 int theChar, |
| 156 int theKeyCode, | 152 int theKeyCode, |
| 157 EventModifiers mods) { | 153 EventModifiers mods) { |
| 158 theChar = TranslateMacUnicodeControlChar(theChar); | 154 theChar = TranslateMacUnicodeControlChar(theChar); |
| 159 theChar = TranslateMacControlCharToWebChar(theChar); | 155 theChar = TranslateMacControlCharToWebChar(theChar); |
| 160 int upperChar = (theChar >= 'a' && theChar <='z') ? theChar - 32 : theChar; | 156 int upperChar = (theChar >= 'a' && theChar <='z') ? theChar - 32 : theChar; |
| 161 | 157 |
| 162 Event::Type type; | 158 Event::Type type; |
| 163 switch (kind) { | 159 switch (kind) { |
| 164 case keyDown: | 160 case keyDown: |
| 165 // We'll also have to send a keypress below. | 161 // We'll also have to send a keypress below. |
| 166 type = Event::TYPE_KEYDOWN; | 162 type = Event::TYPE_KEYDOWN; |
| 167 break; | 163 break; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 205 event.clear_key_code(); | 201 event.clear_key_code(); |
| 206 event.set_char_code(theChar); | 202 event.set_char_code(theChar); |
| 207 event.set_type(Event::TYPE_KEYPRESS); | 203 event.set_type(Event::TYPE_KEYPRESS); |
| 208 obj->client()->AddEventToQueue(event); | 204 obj->client()->AddEventToQueue(event); |
| 209 } | 205 } |
| 210 } | 206 } |
| 211 | 207 |
| 212 // Given an instance, and a MacOS keyboard event, calls Javascript methods | 208 // Given an instance, and a MacOS keyboard event, calls Javascript methods |
| 213 // placed on the object tag so that the keystrokes can be handled in | 209 // placed on the object tag so that the keystrokes can be handled in |
| 214 // Javascript. | 210 // Javascript. |
| 215 static void DispatchMacKeyboardEvent(PluginObject* obj, | 211 void DispatchMacKeyboardEvent(PluginObject* obj, |
| 216 EventRecord* the_event) { | 212 EventRecord* the_event) { |
| 217 DispatchKeyboardEvent(obj, | 213 DispatchKeyboardEvent(obj, |
| 218 the_event->what, | 214 the_event->what, |
| 219 GetMacEventKeyChar(the_event), | 215 GetMacEventKeyChar(the_event), |
| 220 GetMacEventKeyCode(the_event), | 216 GetMacEventKeyCode(the_event), |
| 221 the_event->modifiers); | 217 the_event->modifiers); |
| 222 } | 218 } |
| 223 | 219 |
| 224 | 220 |
| 225 | 221 |
| 226 static void HandleMouseEvent(PluginObject* obj, | 222 void HandleMouseEvent(PluginObject* obj, |
| 227 EventRecord* the_event) { | 223 EventRecord* the_event) { |
| 228 DCHECK(obj); | 224 DCHECK(obj); |
| 229 DCHECK(obj->client()); | 225 DCHECK(obj->client()); |
| 230 int screen_x = the_event->where.h; | 226 int screen_x = the_event->where.h; |
| 231 int screen_y = the_event->where.v; | 227 int screen_y = the_event->where.v; |
| 232 static Point last_mouse_loc = {0,0}; | 228 static Point last_mouse_loc = {0,0}; |
| 233 | 229 |
| 234 o3d::Event::Type type; | 230 o3d::Event::Type type; |
| 235 switch (the_event->what) { | 231 switch (the_event->what) { |
| 236 case mouseDown: | 232 case mouseDown: |
| 237 type = o3d::Event::TYPE_MOUSEDOWN; | 233 type = o3d::Event::TYPE_MOUSEDOWN; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 298 if (in_plugin && type == Event::TYPE_MOUSEDOWN && | 294 if (in_plugin && type == Event::TYPE_MOUSEDOWN && |
| 299 obj->HitFullscreenClickRegion(x, y)) { | 295 obj->HitFullscreenClickRegion(x, y)) { |
| 300 obj->RequestFullscreenDisplay(); | 296 obj->RequestFullscreenDisplay(); |
| 301 } | 297 } |
| 302 } | 298 } |
| 303 | 299 |
| 304 // Handle a mouse-related NPCocoaEvent. | 300 // Handle a mouse-related NPCocoaEvent. |
| 305 // These events come from the new Cocoa revision of the NPAPI spec, | 301 // These events come from the new Cocoa revision of the NPAPI spec, |
| 306 // currently implemented only in Safari. | 302 // currently implemented only in Safari. |
| 307 // See https://wiki.mozilla.org/Mac:NPAPI_Event_Models | 303 // See https://wiki.mozilla.org/Mac:NPAPI_Event_Models |
| 308 static void HandleCocoaMouseEvent(PluginObject* obj, | 304 void HandleCocoaMouseEvent(PluginObject* obj, |
| 309 NPCocoaEvent* the_event) { | 305 NPCocoaEvent* the_event) { |
| 310 DCHECK(obj); | 306 DCHECK(obj); |
| 311 DCHECK(obj->client()); | 307 DCHECK(obj->client()); |
| 312 int screen_x = the_event->data.mouse.pluginX; | 308 int screen_x = the_event->data.mouse.pluginX; |
| 313 int screen_y = the_event->data.mouse.pluginY; | 309 int screen_y = the_event->data.mouse.pluginY; |
| 314 | 310 |
| 315 o3d::Event::Type type; | 311 o3d::Event::Type type; |
| 316 switch (the_event->type) { | 312 switch (the_event->type) { |
| 317 case NPCocoaEventMouseDown: | 313 case NPCocoaEventMouseDown: |
| 318 type = o3d::Event::TYPE_MOUSEDOWN; | 314 type = o3d::Event::TYPE_MOUSEDOWN; |
| 319 break; | 315 break; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 369 the_event->data.mouse.deltaX = 0; | 365 the_event->data.mouse.deltaX = 0; |
| 370 } | 366 } |
| 371 } | 367 } |
| 372 event.set_delta(the_event->data.mouse.deltaX * 10.0, | 368 event.set_delta(the_event->data.mouse.deltaX * 10.0, |
| 373 the_event->data.mouse.deltaY * 10.0); | 369 the_event->data.mouse.deltaY * 10.0); |
| 374 } | 370 } |
| 375 | 371 |
| 376 if ((the_event->type == NPCocoaEventMouseDown) || | 372 if ((the_event->type == NPCocoaEventMouseDown) || |
| 377 (the_event->type == NPCocoaEventMouseUp)) { | 373 (the_event->type == NPCocoaEventMouseUp)) { |
| 378 event.set_button( | 374 event.set_button( |
| 379 MacOSMouseButtonNumberToO3DButton( | 375 o3d::MacOSMouseButtonNumberToO3DButton( |
| 380 the_event->data.mouse.buttonNumber)); | 376 the_event->data.mouse.buttonNumber)); |
| 381 } | 377 } |
| 382 | 378 |
| 383 event.set_position(x, y, screen_x, screen_y, in_plugin); | 379 event.set_position(x, y, screen_x, screen_y, in_plugin); |
| 384 obj->client()->AddEventToQueue(event); | 380 obj->client()->AddEventToQueue(event); |
| 385 | 381 |
| 386 if (in_plugin && type == Event::TYPE_MOUSEDOWN && | 382 if (in_plugin && type == Event::TYPE_MOUSEDOWN && |
| 387 obj->HitFullscreenClickRegion(x, y)) { | 383 obj->HitFullscreenClickRegion(x, y)) { |
| 388 obj->RequestFullscreenDisplay(); | 384 obj->RequestFullscreenDisplay(); |
| 389 } | 385 } |
| 390 } | 386 } |
| 391 | 387 |
| 392 | 388 |
| 393 | 389 |
| 394 | 390 |
| 395 // Convert an NSEvent style modifiers field to an EventRecord style one. | 391 // Convert an NSEvent style modifiers field to an EventRecord style one. |
| 396 // Not all bits have a representation in the target type, eg NSFunctionKeyMask | 392 // Not all bits have a representation in the target type, eg NSFunctionKeyMask |
| 397 // but we just need to convert the basic modifiers that need to be passed on | 393 // but we just need to convert the basic modifiers that need to be passed on |
| 398 // to Javascript. | 394 // to Javascript. |
| 399 static EventModifiers CocoaToEventRecordModifiers(NSUInteger inMods) { | 395 EventModifiers CocoaToEventRecordModifiers(NSUInteger inMods) { |
| 400 EventModifiers outMods = 0; | 396 EventModifiers outMods = 0; |
| 401 | 397 |
| 402 // NSEvent distinuishes between the shift key being down and the capslock key, | 398 // NSEvent distinuishes between the shift key being down and the capslock key, |
| 403 // but the W3C event spec does not make this distinction. | 399 // but the W3C event spec does not make this distinction. |
| 404 if (inMods & (NSAlphaShiftKeyMask | NSShiftKeyMask)) | 400 if (inMods & (NSAlphaShiftKeyMask | NSShiftKeyMask)) |
| 405 outMods |= shiftKey; | 401 outMods |= shiftKey; |
| 406 if (inMods & NSControlKeyMask) | 402 if (inMods & NSControlKeyMask) |
| 407 outMods |= controlKey; | 403 outMods |= controlKey; |
| 408 if (inMods & NSAlternateKeyMask) | 404 if (inMods & NSAlternateKeyMask) |
| 409 outMods |= optionKey; | 405 outMods |= optionKey; |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 500 nsPluginEventType_GetFocusEvent = (osEvt + 16), | 496 nsPluginEventType_GetFocusEvent = (osEvt + 16), |
| 501 nsPluginEventType_LoseFocusEvent, | 497 nsPluginEventType_LoseFocusEvent, |
| 502 nsPluginEventType_AdjustCursorEvent, | 498 nsPluginEventType_AdjustCursorEvent, |
| 503 nsPluginEventType_MenuCommandEvent, | 499 nsPluginEventType_MenuCommandEvent, |
| 504 nsPluginEventType_ClippingChangedEvent, | 500 nsPluginEventType_ClippingChangedEvent, |
| 505 nsPluginEventType_ScrollingBeginsEvent, | 501 nsPluginEventType_ScrollingBeginsEvent, |
| 506 nsPluginEventType_ScrollingEndsEvent, | 502 nsPluginEventType_ScrollingEndsEvent, |
| 507 nsPluginEventType_Idle = 0 | 503 nsPluginEventType_Idle = 0 |
| 508 }; | 504 }; |
| 509 | 505 |
| 506 NPError InitializePlugin() { | |
| 507 #if !defined(O3D_INTERNAL_PLUGIN) | |
| 508 if (!o3d::SetupOutOfMemoryHandler()) | |
| 509 return NPERR_MODULE_LOAD_FAILED_ERROR; | |
| 510 | |
| 511 o3d::InitializeBreakpad(); | |
| 512 | |
| 513 #ifdef CFTIMER | |
| 514 o3d::gRenderTimer.Start(); | |
| 515 #endif // CFTIMER | |
| 516 | |
| 517 // Initialize the AtExitManager so that base singletons can be | |
| 518 // destroyed properly. | |
| 519 g_at_exit_manager.reset(new base::AtExitManager()); | |
| 520 | |
| 521 // Turn on the logging. | |
| 522 CommandLine::Init(0, NULL); | |
| 523 InitLogging("debug.log", | |
| 524 logging::LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG, | |
| 525 logging::DONT_LOCK_LOG_FILE, | |
| 526 logging::APPEND_TO_OLD_LOG_FILE); | |
| 527 | |
| 528 DLOG(INFO) << "NP_Initialize"; | |
| 529 | |
| 530 o3d::SetupOutOfMemoryHandler(); | |
| 531 #endif // O3D_INTERNAL_PLUGIN | |
| 532 | |
| 533 return NPERR_NO_ERROR; | |
| 534 } | |
| 535 | |
| 536 // Negotiates the best plugin event model, sets the browser to use that, | |
| 537 // and updates the PluginObject so we can remember which one we chose. | |
| 538 // We favor the newer Cocoa-based model, but can cope with browsers that | |
| 539 // only support the original event model, or indeed can't even understand | |
| 540 // what we are asking for. | |
| 541 // However, right at the minute, we shun the Cocoa event model because its | |
| 542 // NPP_SetWindow messages don't contain a WindowRef or NSWindow so we would | |
| 543 // not get enough info to create our AGL context. We'll go back to | |
| 544 // preferring Cocoa once we have worked out how to deal with that. | |
| 545 // Cannot actually fail - | |
| 546 void Mac_SetBestEventModel(NPP instance, PluginObject* obj) { | |
| 547 NPError err = NPERR_NO_ERROR; | |
| 548 NPEventModel event_model = NPEventModelCarbon; | |
| 549 NPBool supportsCocoaEventModel = FALSE; | |
| 550 NPBool supportsCarbonEventModel = FALSE; | |
| 551 | |
| 552 // See if browser supports Cocoa event model. | |
| 553 err = NPN_GetValue(instance, | |
| 554 NPNVsupportsCocoaBool, | |
| 555 &supportsCocoaEventModel); | |
| 556 if (err != NPERR_NO_ERROR) { | |
| 557 supportsCocoaEventModel = FALSE; | |
| 558 err = NPERR_NO_ERROR; // browser doesn't support switchable event models | |
| 559 } | |
| 560 | |
| 561 // See if browser supports Carbon event model. | |
| 562 err = NPN_GetValue(instance, | |
| 563 NPNVsupportsCarbonBool, | |
| 564 &supportsCarbonEventModel); | |
| 565 if (err != NPERR_NO_ERROR) { | |
| 566 supportsCarbonEventModel = FALSE; | |
| 567 err = NPERR_NO_ERROR; | |
| 568 } | |
| 569 | |
| 570 // Now we've collected our data, the decision phase begins. | |
| 571 | |
| 572 // If we didn't successfully get TRUE for either question, the browser | |
| 573 // just does not know about the new switchable event models, so must only | |
| 574 // support the old Carbon event model. | |
| 575 if (!(supportsCocoaEventModel || supportsCarbonEventModel)) { | |
| 576 supportsCarbonEventModel = TRUE; | |
| 577 obj->event_model_ = NPEventModelCarbon; | |
| 578 } | |
| 579 | |
| 580 // Default to Carbon event model, because the new version of the | |
| 581 // Cocoa event model spec does not supply sufficient window | |
| 582 // information in its Cocoa NPP_SetWindow calls for us to bind an | |
| 583 // AGL context to the browser window. | |
| 584 NPEventModel model_to_use = | |
| 585 (supportsCarbonEventModel) ? NPEventModelCarbon : NPEventModelCocoa; | |
| 586 NPN_SetValue(instance, NPPVpluginEventModel, | |
| 587 reinterpret_cast<void*>(model_to_use)); | |
| 588 obj->event_model_ = model_to_use; | |
| 589 } | |
| 590 | |
| 591 | |
| 592 // Negotiates the best plugin drawing model, sets the browser to use that, | |
| 593 // and updates the PluginObject so we can remember which one we chose. | |
| 594 // Returns NPERR_NO_ERROR (0) if successful, otherwise an NPError code. | |
| 595 NPError Mac_SetBestDrawingModel(NPP instance, PluginObject* obj) { | |
| 596 NPError err = NPERR_NO_ERROR; | |
| 597 NPBool supportsCoreGraphics = FALSE; | |
| 598 NPBool supportsOpenGL = FALSE; | |
| 599 NPBool supportsQuickDraw = FALSE; | |
| 600 NPDrawingModel drawing_model = NPDrawingModelQuickDraw; | |
| 601 | |
| 602 // test for direct OpenGL support | |
| 603 err = NPN_GetValue(instance, | |
| 604 NPNVsupportsOpenGLBool, | |
| 605 &supportsOpenGL); | |
| 606 if (err != NPERR_NO_ERROR) | |
| 607 supportsOpenGL = FALSE; | |
| 608 | |
| 609 // test for QuickDraw support | |
| 610 err = NPN_GetValue(instance, | |
| 611 NPNVsupportsQuickDrawBool, | |
| 612 &supportsQuickDraw); | |
| 613 if (err != NPERR_NO_ERROR) | |
| 614 supportsQuickDraw = FALSE; | |
| 615 | |
| 616 // Test for Core Graphics support | |
| 617 err = NPN_GetValue(instance, | |
| 618 NPNVsupportsCoreGraphicsBool, | |
| 619 &supportsCoreGraphics); | |
| 620 if (err != NPERR_NO_ERROR) | |
| 621 supportsCoreGraphics = FALSE; | |
| 622 | |
| 623 | |
| 624 // In order of preference. Preference is now determined by compatibility, | |
| 625 // not by modernity, and so is the opposite of the order I first used. | |
| 626 if (supportsQuickDraw && !(obj->event_model_ == NPEventModelCocoa)) { | |
| 627 drawing_model = NPDrawingModelQuickDraw; | |
| 628 } else if (supportsCoreGraphics) { | |
| 629 drawing_model = NPDrawingModelCoreGraphics; | |
| 630 } else if (supportsOpenGL) { | |
| 631 drawing_model = NPDrawingModelOpenGL; | |
| 632 } else { | |
| 633 // This case is for browsers that didn't even understand the question | |
| 634 // eg FF2, so drawing models are not supported, just assume QuickDraw. | |
| 635 obj->drawing_model_ = NPDrawingModelQuickDraw; | |
| 636 return NPERR_NO_ERROR; | |
| 637 } | |
| 638 | |
| 639 err = NPN_SetValue(instance, NPPVpluginDrawingModel, | |
| 640 reinterpret_cast<void*>(drawing_model)); | |
| 641 if (err != NPERR_NO_ERROR) | |
| 642 return err; | |
| 643 | |
| 644 obj->drawing_model_ = drawing_model; | |
| 645 | |
| 646 return NPERR_NO_ERROR; | |
| 647 } | |
| 648 } // end anonymous namespace | |
| 649 | |
| 650 #if defined(O3D_INTERNAL_PLUGIN) | |
| 651 namespace o3d { | |
| 652 #else | |
| 653 extern "C" { | |
| 654 #endif | |
| 655 | |
| 656 NPError OSCALL NP_Initialize(NPNetscapeFuncs* browserFuncs) { | |
| 657 HANDLE_CRASHES; | |
| 658 NPError retval = InitializeNPNApi(browserFuncs); | |
| 659 if (retval != NPERR_NO_ERROR) return retval; | |
| 660 return InitializePlugin(); | |
| 661 } | |
| 662 | |
| 663 #if !defined(O3D_INTERNAL_PLUGIN) | |
| 664 | |
| 665 // Wrapper that discards the return value to match the expected type of | |
| 666 // NPP_ShutdownUPP. | |
| 667 void NPP_ShutdownWrapper() { | |
| 668 NP_Shutdown(); | |
| 669 } | |
| 670 | |
| 671 // This code is needed to support browsers based on a slightly dated version | |
| 672 // of the NPAPI such as Firefox 2, and Camino 1.6. These browsers expect there | |
| 673 // to be a main() to call to do basic setup. | |
| 674 int main(NPNetscapeFuncs* browserFuncs, | |
| 675 NPPluginFuncs* pluginFuncs, | |
| 676 NPP_ShutdownUPP* shutdownProc) { | |
| 677 HANDLE_CRASHES; | |
| 678 NPError error = NP_Initialize(browserFuncs); | |
| 679 if (error == NPERR_NO_ERROR) | |
| 680 error = NP_GetEntryPoints(pluginFuncs); | |
| 681 *shutdownProc = NPP_ShutdownWrapper; | |
| 682 | |
| 683 return error; | |
| 684 } | |
| 685 | |
| 686 #endif // O3D_INTERNAL_PLUGIN | |
| 687 | |
| 688 NPError OSCALL NP_Shutdown(void) { | |
| 689 #if !defined(O3D_INTERNAL_PLUGIN) | |
| 690 HANDLE_CRASHES; | |
| 691 DLOG(INFO) << "NP_Shutdown"; | |
| 692 | |
| 693 if (g_logger) { | |
| 694 // Do a last sweep to aggregate metrics before we shut down | |
| 695 g_logger->ProcessMetrics(true, false); | |
| 696 delete g_logger; | |
| 697 g_logger = NULL; | |
| 698 g_logging_initialized = false; | |
| 699 stats_report::g_global_metrics.Uninitialize(); | |
| 700 } | |
| 701 | |
| 702 CommandLine::Terminate(); | |
| 703 | |
| 704 #ifdef CFTIMER | |
| 705 o3d::gRenderTimer.Stop(); | |
| 706 #endif | |
| 707 | |
| 708 // Force all base singletons to be destroyed. | |
| 709 g_at_exit_manager.reset(NULL); | |
| 710 | |
| 711 o3d::ShutdownBreakpad(); | |
| 712 #endif // O3D_INTERNAL_PLUGIN | |
| 713 | |
| 714 return NPERR_NO_ERROR; | |
| 715 } | |
| 716 | |
| 717 } // namespace o3d / extern "C" | |
| 718 | |
| 719 | |
| 720 namespace o3d { | |
| 721 | |
| 722 NPError PlatformNPPGetValue(NPP instance, NPPVariable variable, void *value) { | |
| 723 return NPERR_INVALID_PARAM; | |
| 724 } | |
| 510 | 725 |
| 511 bool HandleMacEvent(EventRecord* the_event, NPP instance) { | 726 bool HandleMacEvent(EventRecord* the_event, NPP instance) { |
| 512 PluginObject* obj = static_cast<PluginObject*>(instance->pdata); | 727 PluginObject* obj = static_cast<PluginObject*>(instance->pdata); |
| 513 bool handled = false; | 728 bool handled = false; |
| 514 WindowRef fullscreen_window = obj->GetFullscreenMacWindow(); | 729 WindowRef fullscreen_window = obj->GetFullscreenMacWindow(); |
| 515 | 730 |
| 516 if (g_logger) g_logger->UpdateLogging(); | 731 if (g_logger) g_logger->UpdateLogging(); |
| 517 | 732 |
| 518 // Help the plugin keep track of when we last saw an event so the CFTimer can | 733 // Help the plugin keep track of when we last saw an event so the CFTimer can |
| 519 // notice if we get cut off, eg by our tab being hidden by Safari, which there | 734 // notice if we get cut off, eg by our tab being hidden by Safari, which there |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 587 break; | 802 break; |
| 588 case nsPluginEventType_ScrollingEndsEvent: | 803 case nsPluginEventType_ScrollingEndsEvent: |
| 589 obj->SetScrollIsInProgress(false); | 804 obj->SetScrollIsInProgress(false); |
| 590 break; | 805 break; |
| 591 default: | 806 default: |
| 592 break; | 807 break; |
| 593 } | 808 } |
| 594 return handled; | 809 return handled; |
| 595 } | 810 } |
| 596 | 811 |
| 597 NPError PlatformNPPGetValue(NPP instance, NPPVariable variable, void *value) { | 812 void RenderOnDemandCallbackHandler::Run() { |
| 598 return NPERR_INVALID_PARAM; | 813 obj_->SetWantsRedraw(true); |
| 599 } | 814 } |
| 600 | 815 |
| 601 extern "C" { | 816 NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, |
| 602 NPError InitializePlugin() { | 817 char* argn[], char* argv[], NPSavedData* saved) { |
| 603 if (!o3d::SetupOutOfMemoryHandler()) | 818 HANDLE_CRASHES; |
| 604 return NPERR_MODULE_LOAD_FAILED_ERROR; | |
| 605 | 819 |
| 606 InitializeBreakpad(); | 820 NPError err = NPERR_NO_ERROR; |
| 607 | 821 |
|
vangelis
2009/07/09 02:14:11
g_logging_initialized won't be defined if defined(
| |
| 608 #ifdef CFTIMER | 822 if (!g_logging_initialized) { |
| 609 gRenderTimer.Start(); | 823 GetUserAgentMetrics(instance); |
| 610 #endif // CFTIMER | 824 GetUserConfigMetrics(); |
| 611 | 825 // Create usage stats logs object |
| 612 // Initialize the AtExitManager so that base singletons can be | 826 g_logger = o3d::PluginLogging::InitializeUsageStatsLogging(); |
| 613 // destroyed properly. | 827 g_logging_initialized = true; |
| 614 g_at_exit_manager.reset(new base::AtExitManager()); | |
| 615 | |
| 616 // Turn on the logging. | |
| 617 CommandLine::Init(0, NULL); | |
| 618 InitLogging("debug.log", | |
| 619 logging::LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG, | |
| 620 logging::DONT_LOCK_LOG_FILE, | |
| 621 logging::APPEND_TO_OLD_LOG_FILE); | |
| 622 | |
| 623 DLOG(INFO) << "NP_Initialize"; | |
| 624 | |
| 625 o3d::SetupOutOfMemoryHandler(); | |
| 626 | |
| 627 return NPERR_NO_ERROR; | |
| 628 } | 828 } |
| 629 | 829 |
| 630 NPError OSCALL NP_Initialize(NPNetscapeFuncs* browserFuncs) { | 830 PluginObject* pluginObject = glue::_o3d::PluginObject::Create( |
| 631 HANDLE_CRASHES; | 831 instance); |
| 632 NPError retval = InitializeNPNApi(browserFuncs); | 832 instance->pdata = pluginObject; |
| 633 if (retval != NPERR_NO_ERROR) return retval; | 833 glue::_o3d::InitializeGlue(instance); |
| 634 return InitializePlugin(); | 834 pluginObject->Init(argc, argn, argv); |
| 835 | |
| 836 Mac_SetBestEventModel(instance, | |
| 837 static_cast<PluginObject*>(instance->pdata)); | |
| 838 | |
| 839 err = Mac_SetBestDrawingModel( | |
| 840 instance, static_cast<PluginObject*>(instance->pdata)); | |
| 841 if (err != NPERR_NO_ERROR) | |
| 842 return err; | |
| 843 return NPERR_NO_ERROR; | |
| 844 } | |
| 845 | |
| 846 NPError NPP_Destroy(NPP instance, NPSavedData** save) { | |
| 847 HANDLE_CRASHES; | |
| 848 PluginObject* obj = static_cast<PluginObject*>(instance->pdata); | |
| 849 if (obj) { | |
| 850 #if defined(CFTIMER) | |
| 851 o3d::gRenderTimer.RemoveInstance(instance); | |
| 852 #endif | |
| 853 | |
| 854 obj->TearDown(); | |
| 855 NPN_ReleaseObject(obj); | |
| 856 instance->pdata = NULL; | |
| 635 } | 857 } |
| 636 | 858 |
| 637 // Wrapper that discards the return value to match the expected type of | 859 return NPERR_NO_ERROR; |
| 638 // NPP_ShutdownUPP. | 860 } |
| 639 void NPP_ShutdownWrapper() { | 861 |
| 640 NP_Shutdown(); | 862 bool CheckForAGLError() { |
| 863 return aglGetError() != AGL_NO_ERROR; | |
| 864 } | |
| 865 | |
| 866 | |
| 867 NPError NPP_SetWindow(NPP instance, NPWindow* window) { | |
| 868 HANDLE_CRASHES; | |
| 869 PluginObject* obj = static_cast<PluginObject*>(instance->pdata); | |
| 870 WindowRef new_window = NULL; | |
| 871 | |
| 872 assert(window != NULL); | |
| 873 | |
| 874 if (window->window == NULL) | |
| 875 return NPERR_NO_ERROR; | |
| 876 | |
| 877 obj->last_plugin_loc_.h = window->x; | |
| 878 obj->last_plugin_loc_.v = window->y; | |
| 879 | |
| 880 switch (obj->drawing_model_) { | |
| 881 case NPDrawingModelOpenGL: { | |
| 882 NP_GLContext* np_gl = reinterpret_cast<NP_GLContext*>(window->window); | |
| 883 if (obj->event_model_ == NPEventModelCocoa) { | |
| 884 NSWindow * ns_window = reinterpret_cast<NSWindow*>(np_gl->window); | |
| 885 new_window = reinterpret_cast<WindowRef>([ns_window windowRef]); | |
| 886 } else { | |
| 887 new_window = np_gl->window; | |
| 888 } | |
| 889 obj->mac_2d_context_ = NULL; | |
| 890 obj->mac_cgl_context_ = np_gl->context; | |
| 891 break; | |
| 892 } | |
| 893 case NPDrawingModelCoreGraphics: { | |
| 894 // Safari 4 sets window->window to NULL when in Cocoa event mode. | |
| 895 if (window->window != NULL) { | |
| 896 NP_CGContext* np_cg = reinterpret_cast<NP_CGContext*>(window->window); | |
| 897 if (obj->event_model_ == NPEventModelCocoa) { | |
| 898 NSWindow * ns_window = reinterpret_cast<NSWindow*>(np_cg->window); | |
| 899 new_window = reinterpret_cast<WindowRef>([ns_window windowRef]); | |
| 900 } else { | |
| 901 new_window = np_cg->window; | |
| 902 } | |
| 903 obj->mac_2d_context_ = np_cg->context; | |
| 904 } | |
| 905 break; | |
| 906 } | |
| 907 case NPDrawingModelQuickDraw: { | |
| 908 NP_Port* np_qd = reinterpret_cast<NP_Port*>(window->window); | |
| 909 obj->mac_2d_context_ = np_qd->port; | |
| 910 if (np_qd->port) | |
| 911 new_window = GetWindowFromPort(np_qd->port); | |
| 912 break; | |
| 913 } | |
| 914 default: | |
| 915 return NPERR_INCOMPATIBLE_VERSION_ERROR; | |
| 916 break; | |
| 641 } | 917 } |
| 642 | 918 |
| 643 // This code is needed to support browsers based on a slightly dated version | 919 // Whether the target window has changed. |
| 644 // of the NPAPI such as Firefox 2, and Camino 1.6. These browsers expect there | 920 bool window_changed = new_window != obj->mac_window_; |
| 645 // to be a main() to call to do basic setup. | |
| 646 int main(NPNetscapeFuncs* browserFuncs, | |
| 647 NPPluginFuncs* pluginFuncs, | |
| 648 NPP_ShutdownUPP* shutdownProc) { | |
| 649 HANDLE_CRASHES; | |
| 650 NPError error = NP_Initialize(browserFuncs); | |
| 651 if (error == NPERR_NO_ERROR) | |
| 652 error = NP_GetEntryPoints(pluginFuncs); | |
| 653 *shutdownProc = NPP_ShutdownWrapper; | |
| 654 | 921 |
| 655 return error; | 922 // Whether we already had a window before this call. |
| 656 } | 923 bool had_a_window = obj->mac_window_ != NULL; |
| 657 | 924 |
| 658 NPError OSCALL NP_Shutdown(void) { | 925 obj->mac_window_ = new_window; |
| 659 HANDLE_CRASHES; | |
| 660 DLOG(INFO) << "NP_Shutdown"; | |
| 661 | 926 |
| 662 if (g_logger) { | 927 if (obj->drawing_model_ == NPDrawingModelOpenGL) { |
| 663 // Do a last sweep to aggregate metrics before we shut down | 928 CGLSetCurrentContext(obj->mac_cgl_context_); |
| 664 g_logger->ProcessMetrics(true, false); | 929 } else if (!had_a_window && obj->mac_agl_context_ == NULL) { // setup AGL con text |
| 665 delete g_logger; | 930 AGLPixelFormat myAGLPixelFormat = NULL; |
| 666 g_logger = NULL; | |
| 667 g_logging_initialized = false; | |
| 668 stats_report::g_global_metrics.Uninitialize(); | |
| 669 } | |
| 670 | 931 |
| 671 CommandLine::Terminate(); | 932 // We need to spec out a few similar but different sets of renderer |
| 672 | 933 // specifications - define some macros to lessen the duplication. |
| 673 #ifdef CFTIMER | |
| 674 gRenderTimer.Stop(); | |
| 675 #endif | |
| 676 | |
| 677 // Force all base singletons to be destroyed. | |
| 678 g_at_exit_manager.reset(NULL); | |
| 679 | |
| 680 ShutdownBreakpad(); | |
| 681 | |
| 682 return NPERR_NO_ERROR; | |
| 683 } | |
| 684 | |
| 685 // Negotiates the best plugin event model, sets the browser to use that, | |
| 686 // and updates the PluginObject so we can remember which one we chose. | |
| 687 // We favor the newer Cocoa-based model, but can cope with browsers that | |
| 688 // only support the original event model, or indeed can't even understand | |
| 689 // what we are asking for. | |
| 690 // However, right at the minute, we shun the Cocoa event model because its | |
| 691 // NPP_SetWindow messages don't contain a WindowRef or NSWindow so we would | |
| 692 // not get enough info to create our AGL context. We'll go back to | |
| 693 // preferring Cocoa once we have worked out how to deal with that. | |
| 694 // Cannot actually fail - | |
| 695 static void Mac_SetBestEventModel(NPP instance, PluginObject* obj) { | |
| 696 NPError err = NPERR_NO_ERROR; | |
| 697 NPEventModel event_model = NPEventModelCarbon; | |
| 698 NPBool supportsCocoaEventModel = FALSE; | |
| 699 NPBool supportsCarbonEventModel = FALSE; | |
| 700 | |
| 701 // See if browser supports Cocoa event model. | |
| 702 err = NPN_GetValue(instance, | |
| 703 NPNVsupportsCocoaBool, | |
| 704 &supportsCocoaEventModel); | |
| 705 if (err != NPERR_NO_ERROR) { | |
| 706 supportsCocoaEventModel = FALSE; | |
| 707 err = NPERR_NO_ERROR; // browser doesn't support switchable event models | |
| 708 } | |
| 709 | |
| 710 // See if browser supports Carbon event model. | |
| 711 err = NPN_GetValue(instance, | |
| 712 NPNVsupportsCarbonBool, | |
| 713 &supportsCarbonEventModel); | |
| 714 if (err != NPERR_NO_ERROR) { | |
| 715 supportsCarbonEventModel = FALSE; | |
| 716 err = NPERR_NO_ERROR; | |
| 717 } | |
| 718 | |
| 719 // Now we've collected our data, the decision phase begins. | |
| 720 | |
| 721 // If we didn't successfully get TRUE for either question, the browser | |
| 722 // just does not know about the new switchable event models, so must only | |
| 723 // support the old Carbon event model. | |
| 724 if (!(supportsCocoaEventModel || supportsCarbonEventModel)) { | |
| 725 supportsCarbonEventModel = TRUE; | |
| 726 obj->event_model_ = NPEventModelCarbon; | |
| 727 } | |
| 728 | |
| 729 // Default to Carbon event model, because the new version of the | |
| 730 // Cocoa event model spec does not supply sufficient window | |
| 731 // information in its Cocoa NPP_SetWindow calls for us to bind an | |
| 732 // AGL context to the browser window. | |
| 733 NPEventModel model_to_use = | |
| 734 (supportsCarbonEventModel) ? NPEventModelCarbon : NPEventModelCocoa; | |
| 735 NPN_SetValue(instance, NPPVpluginEventModel, | |
| 736 reinterpret_cast<void*>(model_to_use)); | |
| 737 obj->event_model_ = model_to_use; | |
| 738 } | |
| 739 | |
| 740 | |
| 741 // Negotiates the best plugin drawing model, sets the browser to use that, | |
| 742 // and updates the PluginObject so we can remember which one we chose. | |
| 743 // Returns NPERR_NO_ERROR (0) if successful, otherwise an NPError code. | |
| 744 static NPError Mac_SetBestDrawingModel(NPP instance, PluginObject* obj) { | |
| 745 NPError err = NPERR_NO_ERROR; | |
| 746 NPBool supportsCoreGraphics = FALSE; | |
| 747 NPBool supportsOpenGL = FALSE; | |
| 748 NPBool supportsQuickDraw = FALSE; | |
| 749 NPDrawingModel drawing_model = NPDrawingModelQuickDraw; | |
| 750 | |
| 751 // test for direct OpenGL support | |
| 752 err = NPN_GetValue(instance, | |
| 753 NPNVsupportsOpenGLBool, | |
| 754 &supportsOpenGL); | |
| 755 if (err != NPERR_NO_ERROR) | |
| 756 supportsOpenGL = FALSE; | |
| 757 | |
| 758 // test for QuickDraw support | |
| 759 err = NPN_GetValue(instance, | |
| 760 NPNVsupportsQuickDrawBool, | |
| 761 &supportsQuickDraw); | |
| 762 if (err != NPERR_NO_ERROR) | |
| 763 supportsQuickDraw = FALSE; | |
| 764 | |
| 765 // Test for Core Graphics support | |
| 766 err = NPN_GetValue(instance, | |
| 767 NPNVsupportsCoreGraphicsBool, | |
| 768 &supportsCoreGraphics); | |
| 769 if (err != NPERR_NO_ERROR) | |
| 770 supportsCoreGraphics = FALSE; | |
| 771 | |
| 772 | |
| 773 // In order of preference. Preference is now determined by compatibility, | |
| 774 // not by modernity, and so is the opposite of the order I first used. | |
| 775 if (supportsQuickDraw && !(obj->event_model_ == NPEventModelCocoa)) { | |
| 776 drawing_model = NPDrawingModelQuickDraw; | |
| 777 } else if (supportsCoreGraphics) { | |
| 778 drawing_model = NPDrawingModelCoreGraphics; | |
| 779 } else if (supportsOpenGL) { | |
| 780 drawing_model = NPDrawingModelOpenGL; | |
| 781 } else { | |
| 782 // This case is for browsers that didn't even understand the question | |
| 783 // eg FF2, so drawing models are not supported, just assume QuickDraw. | |
| 784 obj->drawing_model_ = NPDrawingModelQuickDraw; | |
| 785 return NPERR_NO_ERROR; | |
| 786 } | |
| 787 | |
| 788 err = NPN_SetValue(instance, NPPVpluginDrawingModel, | |
| 789 reinterpret_cast<void*>(drawing_model)); | |
| 790 if (err != NPERR_NO_ERROR) | |
| 791 return err; | |
| 792 | |
| 793 obj->drawing_model_ = drawing_model; | |
| 794 | |
| 795 return NPERR_NO_ERROR; | |
| 796 } | |
| 797 | |
| 798 | |
| 799 NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, | |
| 800 char* argn[], char* argv[], NPSavedData* saved) { | |
| 801 HANDLE_CRASHES; | |
| 802 | |
| 803 NPError err = NPERR_NO_ERROR; | |
| 804 | |
| 805 if (!g_logging_initialized) { | |
| 806 GetUserAgentMetrics(instance); | |
| 807 GetUserConfigMetrics(); | |
| 808 // Create usage stats logs object | |
| 809 g_logger = o3d::PluginLogging::InitializeUsageStatsLogging(); | |
| 810 g_logging_initialized = true; | |
| 811 } | |
| 812 | |
| 813 PluginObject* pluginObject = glue::_o3d::PluginObject::Create( | |
| 814 instance); | |
| 815 instance->pdata = pluginObject; | |
| 816 glue::_o3d::InitializeGlue(instance); | |
| 817 pluginObject->Init(argc, argn, argv); | |
| 818 | |
| 819 Mac_SetBestEventModel(instance, | |
| 820 static_cast<PluginObject*>(instance->pdata)); | |
| 821 | |
| 822 err = Mac_SetBestDrawingModel( | |
| 823 instance, static_cast<PluginObject*>(instance->pdata)); | |
| 824 if (err != NPERR_NO_ERROR) | |
| 825 return err; | |
| 826 return NPERR_NO_ERROR; | |
| 827 } | |
| 828 | |
| 829 NPError NPP_Destroy(NPP instance, NPSavedData** save) { | |
| 830 HANDLE_CRASHES; | |
| 831 PluginObject* obj = static_cast<PluginObject*>(instance->pdata); | |
| 832 if (obj) { | |
| 833 #if defined(CFTIMER) | |
| 834 gRenderTimer.RemoveInstance(instance); | |
| 835 #endif | |
| 836 | |
| 837 obj->TearDown(); | |
| 838 NPN_ReleaseObject(obj); | |
| 839 instance->pdata = NULL; | |
| 840 } | |
| 841 | |
| 842 return NPERR_NO_ERROR; | |
| 843 } | |
| 844 | |
| 845 static bool CheckForAGLError() { | |
| 846 return aglGetError() != AGL_NO_ERROR; | |
| 847 } | |
| 848 | |
| 849 | |
| 850 NPError NPP_SetWindow(NPP instance, NPWindow* window) { | |
| 851 HANDLE_CRASHES; | |
| 852 PluginObject* obj = static_cast<PluginObject*>(instance->pdata); | |
| 853 WindowRef new_window = NULL; | |
| 854 | |
| 855 assert(window != NULL); | |
| 856 | |
| 857 if (window->window == NULL) | |
| 858 return NPERR_NO_ERROR; | |
| 859 | |
| 860 obj->last_plugin_loc_.h = window->x; | |
| 861 obj->last_plugin_loc_.v = window->y; | |
| 862 | |
| 863 switch (obj->drawing_model_) { | |
| 864 case NPDrawingModelOpenGL: { | |
| 865 NP_GLContext* np_gl = reinterpret_cast<NP_GLContext*>(window->window); | |
| 866 if (obj->event_model_ == NPEventModelCocoa) { | |
| 867 NSWindow * ns_window = reinterpret_cast<NSWindow*>(np_gl->window); | |
| 868 new_window = reinterpret_cast<WindowRef>([ns_window windowRef]); | |
| 869 } else { | |
| 870 new_window = np_gl->window; | |
| 871 } | |
| 872 obj->mac_2d_context_ = NULL; | |
| 873 obj->mac_cgl_context_ = np_gl->context; | |
| 874 break; | |
| 875 } | |
| 876 case NPDrawingModelCoreGraphics: { | |
| 877 // Safari 4 sets window->window to NULL when in Cocoa event mode. | |
| 878 if (window->window != NULL) { | |
| 879 NP_CGContext* np_cg = reinterpret_cast<NP_CGContext*>(window->window); | |
| 880 if (obj->event_model_ == NPEventModelCocoa) { | |
| 881 NSWindow * ns_window = reinterpret_cast<NSWindow*>(np_cg->window); | |
| 882 new_window = reinterpret_cast<WindowRef>([ns_window windowRef]); | |
| 883 } else { | |
| 884 new_window = np_cg->window; | |
| 885 } | |
| 886 obj->mac_2d_context_ = np_cg->context; | |
| 887 } | |
| 888 break; | |
| 889 } | |
| 890 case NPDrawingModelQuickDraw: { | |
| 891 NP_Port* np_qd = reinterpret_cast<NP_Port*>(window->window); | |
| 892 obj->mac_2d_context_ = np_qd->port; | |
| 893 if (np_qd->port) | |
| 894 new_window = GetWindowFromPort(np_qd->port); | |
| 895 break; | |
| 896 } | |
| 897 default: | |
| 898 return NPERR_INCOMPATIBLE_VERSION_ERROR; | |
| 899 break; | |
| 900 } | |
| 901 | |
| 902 // Whether the target window has changed. | |
| 903 bool window_changed = new_window != obj->mac_window_; | |
| 904 | |
| 905 // Whether we already had a window before this call. | |
| 906 bool had_a_window = obj->mac_window_ != NULL; | |
| 907 | |
| 908 obj->mac_window_ = new_window; | |
| 909 | |
| 910 if (obj->drawing_model_ == NPDrawingModelOpenGL) { | |
| 911 CGLSetCurrentContext(obj->mac_cgl_context_); | |
| 912 } else if (!had_a_window && obj->mac_agl_context_ == NULL) { // setup AGL c ontext | |
| 913 AGLPixelFormat myAGLPixelFormat = NULL; | |
| 914 | |
| 915 // We need to spec out a few similar but different sets of renderer | |
| 916 // specifications - define some macros to lessen the duplication. | |
| 917 #define O3D_DEPTH_SETTINGS AGL_RGBA, AGL_DEPTH_SIZE, 24, | 934 #define O3D_DEPTH_SETTINGS AGL_RGBA, AGL_DEPTH_SIZE, 24, |
| 918 #define O3D_STENCIL_SETTINGS AGL_STENCIL_SIZE, 8, | 935 #define O3D_STENCIL_SETTINGS AGL_STENCIL_SIZE, 8, |
| 919 #define O3D_HARDWARE_RENDERER AGL_ACCELERATED, AGL_NO_RECOVERY, | 936 #define O3D_HARDWARE_RENDERER AGL_ACCELERATED, AGL_NO_RECOVERY, |
| 920 #define O3D_SOFTWARE_RENDERER AGL_RENDERER_ID, AGL_RENDERER_GENERIC_FLOAT_ID, | 937 #define O3D_SOFTWARE_RENDERER AGL_RENDERER_ID, AGL_RENDERER_GENERIC_FLOAT_ID, |
| 921 #define O3D_MULTISAMPLE AGL_MULTISAMPLE, \ | 938 #define O3D_MULTISAMPLE AGL_MULTISAMPLE, \ |
| 922 AGL_SAMPLE_BUFFERS_ARB, 1, AGL_SAMPLES_ARB, 4, AGL_MULTISAMPLE, | 939 AGL_SAMPLE_BUFFERS_ARB, 1, AGL_SAMPLES_ARB, 4, AGL_MULTISAMPLE, |
| 923 #define O3D_END AGL_NONE | 940 #define O3D_END AGL_NONE |
| 924 | 941 |
| 925 #ifdef USE_AGL_DOUBLE_BUFFER | 942 #ifdef USE_AGL_DOUBLE_BUFFER |
| 926 #define O3D_DOUBLE_BUFFER_SETTINGS AGL_DOUBLEBUFFER, | 943 #define O3D_DOUBLE_BUFFER_SETTINGS AGL_DOUBLEBUFFER, |
| 927 #else | 944 #else |
| 928 #define O3D_DOUBLE_BUFFER_SETTINGS | 945 #define O3D_DOUBLE_BUFFER_SETTINGS |
| 929 #endif | 946 #endif |
| 930 | 947 |
| 931 if (!UseSoftwareRenderer()) { | 948 if (!UseSoftwareRenderer()) { |
| 932 // Try to create a hardware context with the following | 949 // Try to create a hardware context with the following |
| 933 // specification | 950 // specification |
| 934 GLint attributes[] = { | 951 GLint attributes[] = { |
| 952 O3D_DEPTH_SETTINGS | |
| 953 O3D_STENCIL_SETTINGS | |
| 954 O3D_DOUBLE_BUFFER_SETTINGS | |
| 955 O3D_HARDWARE_RENDERER | |
| 956 O3D_MULTISAMPLE | |
| 957 O3D_END | |
| 958 }; | |
| 959 myAGLPixelFormat = aglChoosePixelFormat(NULL, | |
| 960 0, | |
| 961 attributes); | |
| 962 | |
| 963 // If this fails, then don't try to be as ambitious | |
| 964 // (so don't ask for multi-sampling), but still require hardware | |
| 965 if (myAGLPixelFormat == NULL) { | |
| 966 GLint low_end_attributes[] = { | |
| 935 O3D_DEPTH_SETTINGS | 967 O3D_DEPTH_SETTINGS |
| 936 O3D_STENCIL_SETTINGS | 968 O3D_STENCIL_SETTINGS |
| 937 O3D_DOUBLE_BUFFER_SETTINGS | 969 O3D_DOUBLE_BUFFER_SETTINGS |
| 938 O3D_HARDWARE_RENDERER | 970 O3D_HARDWARE_RENDERER |
| 939 O3D_MULTISAMPLE | |
| 940 O3D_END | 971 O3D_END |
| 941 }; | 972 }; |
| 942 myAGLPixelFormat = aglChoosePixelFormat(NULL, | 973 myAGLPixelFormat = aglChoosePixelFormat(NULL, |
| 943 0, | 974 0, |
| 944 attributes); | 975 low_end_attributes); |
| 945 | |
| 946 // If this fails, then don't try to be as ambitious | |
| 947 // (so don't ask for multi-sampling), but still require hardware | |
| 948 if (myAGLPixelFormat == NULL) { | |
| 949 GLint low_end_attributes[] = { | |
| 950 O3D_DEPTH_SETTINGS | |
| 951 O3D_STENCIL_SETTINGS | |
| 952 O3D_DOUBLE_BUFFER_SETTINGS | |
| 953 O3D_HARDWARE_RENDERER | |
| 954 O3D_END | |
| 955 }; | |
| 956 myAGLPixelFormat = aglChoosePixelFormat(NULL, | |
| 957 0, | |
| 958 low_end_attributes); | |
| 959 } | |
| 960 } | 976 } |
| 961 | 977 } |
| 962 if (myAGLPixelFormat == NULL) { | 978 |
| 963 // Fallback to software renderer either if the vendorID/gpuID | 979 if (myAGLPixelFormat == NULL) { |
| 964 // is known to be problematic, or if the hardware context failed | 980 // Fallback to software renderer either if the vendorID/gpuID |
| 965 // to get created | 981 // is known to be problematic, or if the hardware context failed |
| 966 // | 982 // to get created |
| 967 // Note that we don't request multisampling since it's too slow. | 983 // |
| 968 GLint software_renderer_attributes[] = { | 984 // Note that we don't request multisampling since it's too slow. |
| 969 O3D_DEPTH_SETTINGS | 985 GLint software_renderer_attributes[] = { |
| 970 O3D_STENCIL_SETTINGS | 986 O3D_DEPTH_SETTINGS |
| 971 O3D_DOUBLE_BUFFER_SETTINGS | 987 O3D_STENCIL_SETTINGS |
| 972 O3D_SOFTWARE_RENDERER | 988 O3D_DOUBLE_BUFFER_SETTINGS |
| 973 O3D_END | 989 O3D_SOFTWARE_RENDERER |
| 974 }; | 990 O3D_END |
| 975 myAGLPixelFormat = aglChoosePixelFormat(NULL, | 991 }; |
| 976 0, | 992 myAGLPixelFormat = aglChoosePixelFormat(NULL, |
| 977 software_renderer_attributes); | 993 0, |
| 978 | 994 software_renderer_attributes); |
| 979 obj->SetRendererIsSoftware(true); | 995 |
| 980 } | 996 obj->SetRendererIsSoftware(true); |
| 981 | 997 } |
| 982 if (myAGLPixelFormat == NULL || CheckForAGLError()) | 998 |
| 983 return NPERR_MODULE_LOAD_FAILED_ERROR; | 999 if (myAGLPixelFormat == NULL || CheckForAGLError()) |
| 984 | 1000 return NPERR_MODULE_LOAD_FAILED_ERROR; |
| 985 obj->mac_agl_context_ = aglCreateContext(myAGLPixelFormat, NULL); | 1001 |
| 986 | 1002 obj->mac_agl_context_ = aglCreateContext(myAGLPixelFormat, NULL); |
| 987 if (CheckForAGLError()) | 1003 |
| 988 return NPERR_MODULE_LOAD_FAILED_ERROR; | 1004 if (CheckForAGLError()) |
| 989 | 1005 return NPERR_MODULE_LOAD_FAILED_ERROR; |
| 990 aglDestroyPixelFormat(myAGLPixelFormat); | 1006 |
| 991 | 1007 aglDestroyPixelFormat(myAGLPixelFormat); |
| 992 if (!SetWindowForAGLContext(obj->mac_agl_context_, obj->mac_window_)) | 1008 |
| 993 return NPERR_MODULE_LOAD_FAILED_ERROR; | 1009 if (!SetWindowForAGLContext(obj->mac_agl_context_, obj->mac_window_)) |
| 994 | 1010 return NPERR_MODULE_LOAD_FAILED_ERROR; |
| 995 aglSetCurrentContext(obj->mac_agl_context_); | 1011 |
| 996 | 1012 aglSetCurrentContext(obj->mac_agl_context_); |
| 997 GetOpenGLMetrics(); | 1013 |
| 1014 GetOpenGLMetrics(); | |
| 998 | 1015 |
| 999 #ifdef USE_AGL_DOUBLE_BUFFER | 1016 #ifdef USE_AGL_DOUBLE_BUFFER |
| 1000 GLint swapInterval = 1; // request synchronization | 1017 GLint swapInterval = 1; // request synchronization |
| 1001 aglSetInteger(obj->mac_agl_context_, AGL_SWAP_INTERVAL, &swapInterval); | 1018 aglSetInteger(obj->mac_agl_context_, AGL_SWAP_INTERVAL, &swapInterval); |
| 1002 #endif | 1019 #endif |
| 1003 } | 1020 } |
| 1004 | 1021 |
| 1005 int clipHeight = window->clipRect.bottom - window->clipRect.top; | 1022 int clipHeight = window->clipRect.bottom - window->clipRect.top; |
| 1006 int clipWidth = window->clipRect.right - window->clipRect.left; | 1023 int clipWidth = window->clipRect.right - window->clipRect.left; |
| 1007 | 1024 |
| 1008 int x_offset = window->clipRect.left - window->x; | 1025 int x_offset = window->clipRect.left - window->x; |
| 1009 int y_offset = window->clipRect.top - window->y; | 1026 int y_offset = window->clipRect.top - window->y; |
| 1010 int gl_x_origin = x_offset; | 1027 int gl_x_origin = x_offset; |
| 1011 int gl_y_origin = window->clipRect.bottom - (window->y + window->height); | 1028 int gl_y_origin = window->clipRect.bottom - (window->y + window->height); |
| 1012 | 1029 |
| 1013 // Firefox calls us with an empty cliprect all the time, toggling our | 1030 // Firefox calls us with an empty cliprect all the time, toggling our |
| 1014 // cliprect back and forth between empty and the normal value, particularly | 1031 // cliprect back and forth between empty and the normal value, particularly |
| 1015 // during scrolling. | 1032 // during scrolling. |
| 1016 // As we need to make our AGL surface track the clip rect, honoring all of | 1033 // As we need to make our AGL surface track the clip rect, honoring all of |
| 1017 // these calls would result in spectacular flashing. | 1034 // these calls would result in spectacular flashing. |
| 1018 // The goal here is to try to spot the calls we can safely ignore. | 1035 // The goal here is to try to spot the calls we can safely ignore. |
| 1019 // The bogus empty cliprects always have left and top of the real clip. | 1036 // The bogus empty cliprects always have left and top of the real clip. |
| 1020 // A null cliprect should always be honored ({0,0,0,0} means a hidden tab), | 1037 // A null cliprect should always be honored ({0,0,0,0} means a hidden tab), |
| 1021 // as should the first ever call to this function, | 1038 // as should the first ever call to this function, |
| 1022 // or an attempt to change the window. | 1039 // or an attempt to change the window. |
| 1023 // The call at the end of a scroll step is also honored. | 1040 // The call at the end of a scroll step is also honored. |
| 1024 // Otherwise, skip this change and do not hide our context. | 1041 // Otherwise, skip this change and do not hide our context. |
| 1025 bool is_empty_cliprect = (clipHeight <= 0 || clipWidth <= 0); | 1042 bool is_empty_cliprect = (clipHeight <= 0 || clipWidth <= 0); |
| 1026 bool is_null_cliprect = (window->clipRect.bottom == 0 && | 1043 bool is_null_cliprect = (window->clipRect.bottom == 0 && |
| 1027 window->clipRect.top == 0 && | 1044 window->clipRect.top == 0 && |
| 1028 window->clipRect.left == 0 && | 1045 window->clipRect.left == 0 && |
| 1029 window->clipRect.right == 0); | 1046 window->clipRect.right == 0); |
| 1030 | 1047 |
| 1031 if (is_empty_cliprect && (!is_null_cliprect) && | 1048 if (is_empty_cliprect && (!is_null_cliprect) && |
| 1032 had_a_window && (!window_changed) && !obj->ScrollIsInProgress()) { | 1049 had_a_window && (!window_changed) && !obj->ScrollIsInProgress()) { |
| 1050 return NPERR_NO_ERROR; | |
| 1051 } | |
| 1052 | |
| 1053 // Workaround - the Apple software renderer crashes if you set the drawing | |
| 1054 // area to 0x0, so use 1x1. | |
| 1055 if (is_empty_cliprect && obj->RendererIsSoftware()) | |
| 1056 clipWidth = clipHeight = 1; | |
| 1057 | |
| 1058 // update size and location of the agl context | |
| 1059 if (obj->mac_agl_context_) { | |
| 1060 | |
| 1061 // We already had a window, and now we've got a different window - | |
| 1062 // this can happen when the user drags out a tab in Safari into its own | |
| 1063 // window. | |
| 1064 if (had_a_window && window_changed) | |
| 1065 SetWindowForAGLContext(obj->mac_agl_context_, obj->mac_window_); | |
| 1066 | |
| 1067 aglSetCurrentContext(obj->mac_agl_context_); | |
| 1068 | |
| 1069 Rect windowRect = {0, 0, 0, 0}; | |
| 1070 if (obj->drawing_model_ == NPDrawingModelQuickDraw) | |
| 1071 GetWindowBounds(obj->mac_window_, kWindowContentRgn, &windowRect); | |
| 1072 else | |
| 1073 GetWindowBounds(obj->mac_window_, kWindowStructureRgn, &windowRect); | |
| 1074 | |
| 1075 int windowHeight = windowRect.bottom - windowRect.top; | |
| 1076 | |
| 1077 // These are in window coords, the weird bit being that agl wants the | |
| 1078 // location of the bottom of the GL context in y flipped coords, | |
| 1079 // eg 100 would mean the bottom of the GL context was 100 up from the | |
| 1080 // bottom of the window. | |
| 1081 obj->last_buffer_rect_[0] = window->x + x_offset; | |
| 1082 obj->last_buffer_rect_[1] = (windowHeight - (window->y + clipHeight)) | |
| 1083 - y_offset; // this param is y flipped | |
| 1084 obj->last_buffer_rect_[2] = clipWidth; | |
| 1085 obj->last_buffer_rect_[3] = clipHeight; | |
| 1086 obj->mac_surface_hidden_ = false; | |
| 1087 | |
| 1088 // If in fullscreen, just remember the desired change in geometry so | |
| 1089 // we restore to the right rectangle. | |
| 1090 if (obj->GetFullscreenMacWindow() != NULL) | |
| 1033 return NPERR_NO_ERROR; | 1091 return NPERR_NO_ERROR; |
| 1034 } | 1092 |
| 1035 | 1093 aglSetInteger(obj->mac_agl_context_, AGL_BUFFER_RECT, |
| 1036 // Workaround - the Apple software renderer crashes if you set the drawing | 1094 obj->last_buffer_rect_); |
| 1037 // area to 0x0, so use 1x1. | 1095 aglEnable(obj->mac_agl_context_, AGL_BUFFER_RECT); |
| 1038 if (is_empty_cliprect && obj->RendererIsSoftware()) | 1096 } |
| 1039 clipWidth = clipHeight = 1; | 1097 |
| 1040 | 1098 // Renderer is already initialized from a previous call to this function, |
| 1041 // update size and location of the agl context | 1099 // just update size and position and return. |
| 1042 if (obj->mac_agl_context_) { | 1100 if (had_a_window) { |
| 1043 | |
| 1044 // We already had a window, and now we've got a different window - | |
| 1045 // this can happen when the user drags out a tab in Safari into its own | |
| 1046 // window. | |
| 1047 if (had_a_window && window_changed) | |
| 1048 SetWindowForAGLContext(obj->mac_agl_context_, obj->mac_window_); | |
| 1049 | |
| 1050 aglSetCurrentContext(obj->mac_agl_context_); | |
| 1051 | |
| 1052 Rect windowRect = {0, 0, 0, 0}; | |
| 1053 if (obj->drawing_model_ == NPDrawingModelQuickDraw) | |
| 1054 GetWindowBounds(obj->mac_window_, kWindowContentRgn, &windowRect); | |
| 1055 else | |
| 1056 GetWindowBounds(obj->mac_window_, kWindowStructureRgn, &windowRect); | |
| 1057 | |
| 1058 int windowHeight = windowRect.bottom - windowRect.top; | |
| 1059 | |
| 1060 // These are in window coords, the weird bit being that agl wants the | |
| 1061 // location of the bottom of the GL context in y flipped coords, | |
| 1062 // eg 100 would mean the bottom of the GL context was 100 up from the | |
| 1063 // bottom of the window. | |
| 1064 obj->last_buffer_rect_[0] = window->x + x_offset; | |
| 1065 obj->last_buffer_rect_[1] = (windowHeight - (window->y + clipHeight)) | |
| 1066 - y_offset; // this param is y flipped | |
| 1067 obj->last_buffer_rect_[2] = clipWidth; | |
| 1068 obj->last_buffer_rect_[3] = clipHeight; | |
| 1069 obj->mac_surface_hidden_ = false; | |
| 1070 | |
| 1071 // If in fullscreen, just remember the desired change in geometry so | |
| 1072 // we restore to the right rectangle. | |
| 1073 if (obj->GetFullscreenMacWindow() != NULL) | |
| 1074 return NPERR_NO_ERROR; | |
| 1075 | |
| 1076 aglSetInteger(obj->mac_agl_context_, AGL_BUFFER_RECT, | |
| 1077 obj->last_buffer_rect_); | |
| 1078 aglEnable(obj->mac_agl_context_, AGL_BUFFER_RECT); | |
| 1079 } | |
| 1080 | |
| 1081 // Renderer is already initialized from a previous call to this function, | |
| 1082 // just update size and position and return. | |
| 1083 if (had_a_window) { | |
| 1084 if (obj->renderer()) { | |
| 1085 obj->renderer()->SetClientOriginOffset(gl_x_origin, gl_y_origin); | |
| 1086 obj->Resize(window->width, window->height); | |
| 1087 } | |
| 1088 return NPERR_NO_ERROR; | |
| 1089 } | |
| 1090 | |
| 1091 // Create and assign the graphics context. | |
| 1092 o3d::DisplayWindowMac default_display; | |
| 1093 default_display.set_agl_context(obj->mac_agl_context_); | |
| 1094 default_display.set_cgl_context(obj->mac_cgl_context_); | |
| 1095 | |
| 1096 obj->CreateRenderer(default_display); | |
| 1097 | |
| 1098 // if the renderer cannot be created (maybe the features are not supported) | |
| 1099 // then we can proceed no further | |
| 1100 if (!obj->renderer()) { | |
| 1101 if (obj->mac_agl_context_) { | |
| 1102 ::aglDestroyContext(obj->mac_agl_context_); | |
| 1103 obj->mac_agl_context_ = NULL; | |
| 1104 } | |
| 1105 } | |
| 1106 | |
| 1107 obj->client()->Init(); | |
| 1108 obj->client()->SetRenderOnDemandCallback( | |
| 1109 new RenderOnDemandCallbackHandler(obj)); | |
| 1110 | |
| 1111 if (obj->renderer()) { | 1101 if (obj->renderer()) { |
| 1112 obj->renderer()->SetClientOriginOffset(gl_x_origin, gl_y_origin); | 1102 obj->renderer()->SetClientOriginOffset(gl_x_origin, gl_y_origin); |
| 1113 obj->Resize(window->width, window->height); | 1103 obj->Resize(window->width, window->height); |
| 1104 } | |
| 1105 return NPERR_NO_ERROR; | |
| 1106 } | |
| 1107 | |
| 1108 // Create and assign the graphics context. | |
| 1109 o3d::DisplayWindowMac default_display; | |
| 1110 default_display.set_agl_context(obj->mac_agl_context_); | |
| 1111 default_display.set_cgl_context(obj->mac_cgl_context_); | |
| 1112 | |
| 1113 obj->CreateRenderer(default_display); | |
| 1114 | |
| 1115 // if the renderer cannot be created (maybe the features are not supported) | |
| 1116 // then we can proceed no further | |
| 1117 if (!obj->renderer()) { | |
| 1118 if (obj->mac_agl_context_) { | |
| 1119 ::aglDestroyContext(obj->mac_agl_context_); | |
| 1120 obj->mac_agl_context_ = NULL; | |
| 1121 } | |
| 1122 } | |
| 1123 | |
| 1124 obj->client()->Init(); | |
| 1125 obj->client()->SetRenderOnDemandCallback( | |
| 1126 new RenderOnDemandCallbackHandler(obj)); | |
| 1127 | |
| 1128 if (obj->renderer()) { | |
| 1129 obj->renderer()->SetClientOriginOffset(gl_x_origin, gl_y_origin); | |
| 1130 obj->Resize(window->width, window->height); | |
| 1114 | 1131 |
| 1115 #ifdef CFTIMER | 1132 #ifdef CFTIMER |
| 1116 // now that the grahics context is setup, add this instance to the timer | 1133 // now that the grahics context is setup, add this instance to the timer |
| 1117 // list so it gets drawn repeatedly | 1134 // list so it gets drawn repeatedly |
| 1118 gRenderTimer.AddInstance(instance); | 1135 gRenderTimer.AddInstance(instance); |
| 1119 #endif // CFTIMER | 1136 #endif // CFTIMER |
| 1120 } | 1137 } |
| 1121 | 1138 |
| 1122 return NPERR_NO_ERROR; | 1139 return NPERR_NO_ERROR; |
| 1123 } | 1140 } |
| 1124 | 1141 |
| 1125 // Called when the browser has finished attempting to stream data to | 1142 // Called when the browser has finished attempting to stream data to |
| 1126 // a file as requested. If fname == NULL the attempt was not successful. | 1143 // a file as requested. If fname == NULL the attempt was not successful. |
| 1127 void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname) { | 1144 void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname) { |
| 1128 HANDLE_CRASHES; | 1145 HANDLE_CRASHES; |
| 1129 PluginObject* obj = static_cast<PluginObject*>(instance->pdata); | 1146 PluginObject* obj = static_cast<PluginObject*>(instance->pdata); |
| 1130 StreamManager* stream_manager = obj->stream_manager(); | 1147 StreamManager* stream_manager = obj->stream_manager(); |
| 1131 | 1148 |
| 1132 // Some browsers give us an absolute HFS path in fname, some give us an | 1149 // Some browsers give us an absolute HFS path in fname, some give us an |
| 1133 // absolute Posix path, so convert to Posix if needed. | 1150 // absolute Posix path, so convert to Posix if needed. |
| 1134 if ((!fname) || (fname[0] == '/') || !fname[0]) { | 1151 if ((!fname) || (fname[0] == '/') || !fname[0]) { |
| 1135 stream_manager->SetStreamFile(stream, fname); | 1152 stream_manager->SetStreamFile(stream, fname); |
| 1136 } else { | 1153 } else { |
| 1137 const char* converted_fname = CreatePosixFilePathFromHFSFilePath(fname); | 1154 const char* converted_fname = CreatePosixFilePathFromHFSFilePath(fname); |
| 1138 if (converted_fname == NULL) | 1155 if (converted_fname == NULL) |
| 1139 return; // TODO should also log error if we ever get here | 1156 return; // TODO should also log error if we ever get here |
| 1140 stream_manager->SetStreamFile(stream, converted_fname); | 1157 stream_manager->SetStreamFile(stream, converted_fname); |
| 1141 delete converted_fname; | 1158 delete converted_fname; |
| 1142 } | 1159 } |
| 1143 } | 1160 } |
| 1144 | 1161 |
| 1145 int16 NPP_HandleEvent(NPP instance, void* event) { | 1162 int16 NPP_HandleEvent(NPP instance, void* event) { |
| 1146 HANDLE_CRASHES; | 1163 HANDLE_CRASHES; |
| 1147 PluginObject* obj = static_cast<PluginObject*>(instance->pdata); | 1164 PluginObject* obj = static_cast<PluginObject*>(instance->pdata); |
| 1148 if (obj->event_model_ == NPEventModelCarbon) { | 1165 if (obj->event_model_ == NPEventModelCarbon) { |
| 1149 EventRecord* theEvent = static_cast<EventRecord*>(event); | 1166 EventRecord* theEvent = static_cast<EventRecord*>(event); |
| 1150 return HandleMacEvent(theEvent, instance) ? 1 : 0; | 1167 return HandleMacEvent(theEvent, instance) ? 1 : 0; |
| 1151 } else if (obj->event_model_ == NPEventModelCocoa){ | 1168 } else if (obj->event_model_ == NPEventModelCocoa){ |
| 1152 return HandleCocoaEvent(instance, (NPCocoaEvent*)event) ? 1 : 0; | 1169 return HandleCocoaEvent(instance, (NPCocoaEvent*)event) ? 1 : 0; |
| 1153 } | 1170 } |
| 1154 return 0; | 1171 return 0; |
| 1155 } | 1172 } |
| 1156 }; // end extern "C" | 1173 |
| 1174 } // namespace o3d | |
| OLD | NEW |