mirror of
				https://bitbucket.org/chromiumembedded/cef
				synced 2025-06-05 21:39:12 +02:00 
			
		
		
		
	- Add off-screen rendering support for Mac OS-X (issue #540).
- Add patch for ninja build support on Mac OS-X. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@624 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
		| @@ -212,6 +212,7 @@ | |||||||
|           'link_settings': { |           'link_settings': { | ||||||
|             'libraries': [ |             'libraries': [ | ||||||
|               '$(SDKROOT)/System/Library/Frameworks/AppKit.framework', |               '$(SDKROOT)/System/Library/Frameworks/AppKit.framework', | ||||||
|  |               '$(SDKROOT)/System/Library/Frameworks/OpenGL.framework', | ||||||
|             ], |             ], | ||||||
|           }, |           }, | ||||||
|           'sources': [ |           'sources': [ | ||||||
| @@ -490,6 +491,7 @@ | |||||||
|       ], |       ], | ||||||
|       'xcode_settings': { |       'xcode_settings': { | ||||||
|         'INSTALL_PATH': '@executable_path', |         'INSTALL_PATH': '@executable_path', | ||||||
|  |         'DYLIB_INSTALL_NAME_BASE': '@executable_path', | ||||||
|         # The libcef_static target contains ObjC categories. Passing the -ObjC flag |         # The libcef_static target contains ObjC categories. Passing the -ObjC flag | ||||||
|         # is necessary to properly load them and avoid a "selector not recognized" |         # is necessary to properly load them and avoid a "selector not recognized" | ||||||
|         # runtime error. See http://developer.apple.com/library/mac/#qa/qa1490/_index.html |         # runtime error. See http://developer.apple.com/library/mac/#qa/qa1490/_index.html | ||||||
|   | |||||||
| @@ -111,6 +111,8 @@ | |||||||
|       'tests/cefclient/client_handler_win.cpp', |       'tests/cefclient/client_handler_win.cpp', | ||||||
|       'tests/cefclient/clientplugin.cpp', |       'tests/cefclient/clientplugin.cpp', | ||||||
|       'tests/cefclient/clientplugin.h', |       'tests/cefclient/clientplugin.h', | ||||||
|  |       'tests/cefclient/osrenderer.cpp', | ||||||
|  |       'tests/cefclient/osrenderer.h', | ||||||
|       'tests/cefclient/osrplugin.cpp', |       'tests/cefclient/osrplugin.cpp', | ||||||
|       'tests/cefclient/osrplugin.h', |       'tests/cefclient/osrplugin.h', | ||||||
|       'tests/cefclient/osrplugin_test.cpp', |       'tests/cefclient/osrplugin_test.cpp', | ||||||
| @@ -135,6 +137,10 @@ | |||||||
|     'cefclient_sources_mac': [ |     'cefclient_sources_mac': [ | ||||||
|       'tests/cefclient/cefclient_mac.mm', |       'tests/cefclient/cefclient_mac.mm', | ||||||
|       'tests/cefclient/client_handler_mac.mm', |       'tests/cefclient/client_handler_mac.mm', | ||||||
|  |       'tests/cefclient/osrenderer.cpp', | ||||||
|  |       'tests/cefclient/osrenderer.h', | ||||||
|  |       'tests/cefclient/osrtest_mac.h', | ||||||
|  |       'tests/cefclient/osrtest_mac.mm', | ||||||
|       'tests/cefclient/resource_util_mac.mm', |       'tests/cefclient/resource_util_mac.mm', | ||||||
|     ], |     ], | ||||||
|     'cefclient_bundle_resources_mac': [ |     'cefclient_bundle_resources_mac': [ | ||||||
| @@ -146,6 +152,9 @@ | |||||||
|       'tests/cefclient/res/extensionperf.html', |       'tests/cefclient/res/extensionperf.html', | ||||||
|       'tests/cefclient/res/localstorage.html', |       'tests/cefclient/res/localstorage.html', | ||||||
|       'tests/cefclient/res/logo.png', |       'tests/cefclient/res/logo.png', | ||||||
|  |       'tests/cefclient/res/logoball.png', | ||||||
|  |       'tests/cefclient/res/osrtest.html', | ||||||
|  |       'tests/cefclient/res/transparency.html', | ||||||
|       'tests/cefclient/res/xmlhttprequest.html', |       'tests/cefclient/res/xmlhttprequest.html', | ||||||
|     ], |     ], | ||||||
|     'cefclient_sources_linux': [ |     'cefclient_sources_linux': [ | ||||||
|   | |||||||
| @@ -259,8 +259,8 @@ typedef struct _cef_browser_t { | |||||||
|   // Send a key event to the browser. |   // Send a key event to the browser. | ||||||
|   /// |   /// | ||||||
|   void (CEF_CALLBACK *send_key_event)(struct _cef_browser_t* self, |   void (CEF_CALLBACK *send_key_event)(struct _cef_browser_t* self, | ||||||
|       enum cef_key_type_t type, int key, int modifiers, int sysChar, |       enum cef_key_type_t type, const struct _cef_key_info_t* keyInfo, | ||||||
|       int imeChar); |       int modifiers); | ||||||
|  |  | ||||||
|   /// |   /// | ||||||
|   // Send a mouse click event to the browser. The |x| and |y| coordinates are |   // Send a mouse click event to the browser. The |x| and |y| coordinates are | ||||||
| @@ -279,10 +279,11 @@ typedef struct _cef_browser_t { | |||||||
|  |  | ||||||
|   /// |   /// | ||||||
|   // Send a mouse wheel event to the browser. The |x| and |y| coordinates are |   // Send a mouse wheel event to the browser. The |x| and |y| coordinates are | ||||||
|   // relative to the upper-left corner of the view. |   // relative to the upper-left corner of the view. The |deltaX| and |deltaY| | ||||||
|  |   // values represent the movement delta in the X and Y directions respectively. | ||||||
|   /// |   /// | ||||||
|   void (CEF_CALLBACK *send_mouse_wheel_event)(struct _cef_browser_t* self, |   void (CEF_CALLBACK *send_mouse_wheel_event)(struct _cef_browser_t* self, | ||||||
|       int x, int y, int delta); |       int x, int y, int deltaX, int deltaY); | ||||||
|  |  | ||||||
|   /// |   /// | ||||||
|   // Send a focus event to the browser. |   // Send a focus event to the browser. | ||||||
|   | |||||||
| @@ -294,8 +294,8 @@ class CefBrowser : public virtual CefBase { | |||||||
|   // Send a key event to the browser. |   // Send a key event to the browser. | ||||||
|   /// |   /// | ||||||
|   /*--cef()--*/ |   /*--cef()--*/ | ||||||
|   virtual void SendKeyEvent(KeyType type, int key, int modifiers, bool sysChar, |   virtual void SendKeyEvent(KeyType type, const CefKeyInfo& keyInfo, | ||||||
|                             bool imeChar) =0; |                             int modifiers) =0; | ||||||
|  |  | ||||||
|   /// |   /// | ||||||
|   // Send a mouse click event to the browser. The |x| and |y| coordinates are |   // Send a mouse click event to the browser. The |x| and |y| coordinates are | ||||||
| @@ -314,10 +314,11 @@ class CefBrowser : public virtual CefBase { | |||||||
|  |  | ||||||
|   /// |   /// | ||||||
|   // Send a mouse wheel event to the browser. The |x| and |y| coordinates are |   // Send a mouse wheel event to the browser. The |x| and |y| coordinates are | ||||||
|   // relative to the upper-left corner of the view. |   // relative to the upper-left corner of the view. The |deltaX| and |deltaY| | ||||||
|  |   // values represent the movement delta in the X and Y directions respectively. | ||||||
|   /// |   /// | ||||||
|   /*--cef()--*/ |   /*--cef()--*/ | ||||||
|   virtual void SendMouseWheelEvent(int x, int y, int delta) =0; |   virtual void SendMouseWheelEvent(int x, int y, int deltaX, int deltaY) =0; | ||||||
|  |  | ||||||
|   /// |   /// | ||||||
|   // Send a focus event to the browser. |   // Send a focus event to the browser. | ||||||
|   | |||||||
| @@ -37,7 +37,9 @@ | |||||||
| #include "include/internal/cef_types_linux.h" | #include "include/internal/cef_types_linux.h" | ||||||
| #include "include/internal/cef_types_wrappers.h" | #include "include/internal/cef_types_wrappers.h" | ||||||
|  |  | ||||||
|  | /// | ||||||
| // Atomic increment and decrement. | // Atomic increment and decrement. | ||||||
|  | /// | ||||||
| inline long CefAtomicIncrement(long volatile *pDest) {  // NOLINT(runtime/int) | inline long CefAtomicIncrement(long volatile *pDest) {  // NOLINT(runtime/int) | ||||||
|   return __sync_add_and_fetch(pDest, 1); |   return __sync_add_and_fetch(pDest, 1); | ||||||
| } | } | ||||||
| @@ -45,7 +47,9 @@ inline long CefAtomicDecrement(long volatile *pDest) {  // NOLINT(runtime/int) | |||||||
|   return __sync_sub_and_fetch(pDest, 1); |   return __sync_sub_and_fetch(pDest, 1); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// | ||||||
| // Critical section wrapper. | // Critical section wrapper. | ||||||
|  | /// | ||||||
| class CefCriticalSection { | class CefCriticalSection { | ||||||
|  public: |  public: | ||||||
|   CefCriticalSection() { |   CefCriticalSection() { | ||||||
| @@ -68,10 +72,13 @@ class CefCriticalSection { | |||||||
|   pthread_mutexattr_t attr_; |   pthread_mutexattr_t attr_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | /// | ||||||
| // Handle types. | // Handle types. | ||||||
|  | /// | ||||||
| #define CefWindowHandle cef_window_handle_t | #define CefWindowHandle cef_window_handle_t | ||||||
| #define CefCursorHandle cef_cursor_handle_t | #define CefCursorHandle cef_cursor_handle_t | ||||||
|  |  | ||||||
|  |  | ||||||
| struct CefWindowInfoTraits { | struct CefWindowInfoTraits { | ||||||
|   typedef cef_window_info_t struct_type; |   typedef cef_window_info_t struct_type; | ||||||
|  |  | ||||||
| @@ -85,7 +92,9 @@ struct CefWindowInfoTraits { | |||||||
|   } |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | /// | ||||||
| // Class representing window information. | // Class representing window information. | ||||||
|  | /// | ||||||
| class CefWindowInfo : public CefStructBase<CefWindowInfoTraits> { | class CefWindowInfo : public CefStructBase<CefWindowInfoTraits> { | ||||||
|  public: |  public: | ||||||
|   typedef CefStructBase<CefWindowInfoTraits> parent; |   typedef CefStructBase<CefWindowInfoTraits> parent; | ||||||
| @@ -99,6 +108,7 @@ class CefWindowInfo : public CefStructBase<CefWindowInfoTraits> { | |||||||
|   } |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  |  | ||||||
| struct CefPrintInfoTraits { | struct CefPrintInfoTraits { | ||||||
|   typedef cef_print_info_t struct_type; |   typedef cef_print_info_t struct_type; | ||||||
|  |  | ||||||
| @@ -111,9 +121,29 @@ struct CefPrintInfoTraits { | |||||||
|   } |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | /// | ||||||
| // Class representing print context information. | // Class representing print context information. | ||||||
|  | /// | ||||||
| typedef CefStructBase<CefPrintInfoTraits> CefPrintInfo; | typedef CefStructBase<CefPrintInfoTraits> CefPrintInfo; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | struct CefKeyInfoTraits { | ||||||
|  |   typedef cef_key_info_t struct_type; | ||||||
|  |  | ||||||
|  |   static inline void init(struct_type* s) {} | ||||||
|  |   static inline void clear(struct_type* s) {} | ||||||
|  |  | ||||||
|  |   static inline void set(const struct_type* src, struct_type* target, | ||||||
|  |       bool copy) { | ||||||
|  |     target->key = src->key; | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /// | ||||||
|  | // Class representing key information. | ||||||
|  | /// | ||||||
|  | typedef CefStructBase<CefKeyInfoTraits> CefKeyInfo; | ||||||
|  |  | ||||||
| #endif  // OS_LINUX | #endif  // OS_LINUX | ||||||
|  |  | ||||||
| #endif  // CEF_INCLUDE_INTERNAL_CEF_LINUX_H_ | #endif  // CEF_INCLUDE_INTERNAL_CEF_LINUX_H_ | ||||||
|   | |||||||
| @@ -37,7 +37,9 @@ | |||||||
| #include "include/internal/cef_types_mac.h" | #include "include/internal/cef_types_mac.h" | ||||||
| #include "include/internal/cef_types_wrappers.h" | #include "include/internal/cef_types_wrappers.h" | ||||||
|  |  | ||||||
|  | /// | ||||||
| // Atomic increment and decrement. | // Atomic increment and decrement. | ||||||
|  | /// | ||||||
| inline long CefAtomicIncrement(long volatile *pDest) {  // NOLINT(runtime/int) | inline long CefAtomicIncrement(long volatile *pDest) {  // NOLINT(runtime/int) | ||||||
|   return __sync_add_and_fetch(pDest, 1); |   return __sync_add_and_fetch(pDest, 1); | ||||||
| } | } | ||||||
| @@ -45,11 +47,15 @@ inline long CefAtomicDecrement(long volatile *pDest) {  // NOLINT(runtime/int) | |||||||
|   return __sync_sub_and_fetch(pDest, 1); |   return __sync_sub_and_fetch(pDest, 1); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// | ||||||
| // Handle types. | // Handle types. | ||||||
|  | /// | ||||||
| #define CefWindowHandle cef_window_handle_t | #define CefWindowHandle cef_window_handle_t | ||||||
| #define CefCursorHandle cef_cursor_handle_t | #define CefCursorHandle cef_cursor_handle_t | ||||||
|  |  | ||||||
|  | /// | ||||||
| // Critical section wrapper. | // Critical section wrapper. | ||||||
|  | /// | ||||||
| class CefCriticalSection { | class CefCriticalSection { | ||||||
|  public: |  public: | ||||||
|   CefCriticalSection() { |   CefCriticalSection() { | ||||||
| @@ -72,6 +78,7 @@ class CefCriticalSection { | |||||||
|   pthread_mutexattr_t attr_; |   pthread_mutexattr_t attr_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  |  | ||||||
| struct CefWindowInfoTraits { | struct CefWindowInfoTraits { | ||||||
|   typedef cef_window_info_t struct_type; |   typedef cef_window_info_t struct_type; | ||||||
|  |  | ||||||
| @@ -92,10 +99,14 @@ struct CefWindowInfoTraits { | |||||||
|     target->m_nWidth = src->m_nWidth; |     target->m_nWidth = src->m_nWidth; | ||||||
|     target->m_nHeight = src->m_nHeight; |     target->m_nHeight = src->m_nHeight; | ||||||
|     target->m_bHidden = src->m_bHidden; |     target->m_bHidden = src->m_bHidden; | ||||||
|  |     target->m_bWindowRenderingDisabled = src->m_bWindowRenderingDisabled; | ||||||
|  |     target->m_bTransparentPainting = src->m_bTransparentPainting; | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | /// | ||||||
| // Class representing window information. | // Class representing window information. | ||||||
|  | /// | ||||||
| class CefWindowInfo : public CefStructBase<CefWindowInfoTraits> { | class CefWindowInfo : public CefStructBase<CefWindowInfoTraits> { | ||||||
|  public: |  public: | ||||||
|   typedef CefStructBase<CefWindowInfoTraits> parent; |   typedef CefStructBase<CefWindowInfoTraits> parent; | ||||||
| @@ -113,8 +124,18 @@ class CefWindowInfo : public CefStructBase<CefWindowInfoTraits> { | |||||||
|     m_nHeight = height; |     m_nHeight = height; | ||||||
|     m_bHidden = false; |     m_bHidden = false; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   void SetAsOffScreen(NSView* parent) { | ||||||
|  |     m_bWindowRenderingDisabled = true; | ||||||
|  |     m_ParentView = parent; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void SetTransparentPainting(int transparentPainting) { | ||||||
|  |     m_bTransparentPainting = transparentPainting; | ||||||
|  |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  |  | ||||||
| struct CefPrintInfoTraits { | struct CefPrintInfoTraits { | ||||||
|   typedef cef_print_info_t struct_type; |   typedef cef_print_info_t struct_type; | ||||||
|  |  | ||||||
| @@ -127,9 +148,31 @@ struct CefPrintInfoTraits { | |||||||
|   } |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | /// | ||||||
| // Class representing print context information. | // Class representing print context information. | ||||||
|  | /// | ||||||
| typedef CefStructBase<CefPrintInfoTraits> CefPrintInfo; | typedef CefStructBase<CefPrintInfoTraits> CefPrintInfo; | ||||||
|  |  | ||||||
|  | struct CefKeyInfoTraits { | ||||||
|  |   typedef cef_key_info_t struct_type; | ||||||
|  |  | ||||||
|  |   static inline void init(struct_type* s) {} | ||||||
|  |   static inline void clear(struct_type* s) {} | ||||||
|  |  | ||||||
|  |   static inline void set(const struct_type* src, struct_type* target, | ||||||
|  |       bool copy) { | ||||||
|  |     target->keyCode = src->keyCode; | ||||||
|  |     target->character = src->character; | ||||||
|  |     target->characterNoModifiers = src->characterNoModifiers; | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /// | ||||||
|  | // Class representing key information. | ||||||
|  | /// | ||||||
|  | typedef CefStructBase<CefKeyInfoTraits> CefKeyInfo; | ||||||
|  |  | ||||||
|  |  | ||||||
| #endif  // OS_MACOSX | #endif  // OS_MACOSX | ||||||
|  |  | ||||||
| #endif  // CEF_INCLUDE_INTERNAL_CEF_MAC_H_ | #endif  // CEF_INCLUDE_INTERNAL_CEF_MAC_H_ | ||||||
|   | |||||||
| @@ -856,10 +856,11 @@ enum cef_handler_keyevent_type_t { | |||||||
| // Key event modifiers. | // Key event modifiers. | ||||||
| /// | /// | ||||||
| enum cef_handler_keyevent_modifiers_t { | enum cef_handler_keyevent_modifiers_t { | ||||||
|   KEY_SHIFT = 1 << 0, |   KEY_SHIFT  = 1 << 0, | ||||||
|   KEY_CTRL  = 1 << 1, |   KEY_CTRL   = 1 << 1, | ||||||
|   KEY_ALT   = 1 << 2, |   KEY_ALT    = 1 << 2, | ||||||
|   KEY_META  = 1 << 3 |   KEY_META   = 1 << 3, | ||||||
|  |   KEY_KEYPAD = 1 << 4,  // Only used on Mac OS-X | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /// | /// | ||||||
|   | |||||||
| @@ -72,6 +72,13 @@ typedef struct _cef_print_info_t { | |||||||
|   double m_Scale; |   double m_Scale; | ||||||
| } cef_print_info_t; | } cef_print_info_t; | ||||||
|  |  | ||||||
|  | /// | ||||||
|  | // Class representing key information. | ||||||
|  | /// | ||||||
|  | typedef struct _cef_key_info_t { | ||||||
|  |   int key; | ||||||
|  | } cef_key_info_t; | ||||||
|  |  | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -40,15 +40,18 @@ | |||||||
| // Window handle. | // Window handle. | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| #ifdef __OBJC__ | #ifdef __OBJC__ | ||||||
|  | @class NSCursor; | ||||||
| @class NSView; | @class NSView; | ||||||
| #else | #else | ||||||
|  | class NSCursor; | ||||||
| struct NSView; | struct NSView; | ||||||
| #endif | #endif | ||||||
| #define cef_window_handle_t NSView* | #define cef_window_handle_t NSView* | ||||||
|  | #define cef_cursor_handle_t NSCursor* | ||||||
| #else | #else | ||||||
| #define cef_window_handle_t void* | #define cef_window_handle_t void* | ||||||
| #endif |  | ||||||
| #define cef_cursor_handle_t void* | #define cef_cursor_handle_t void* | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| extern "C" { | extern "C" { | ||||||
| @@ -76,6 +79,14 @@ typedef struct _cef_window_info_t { | |||||||
|   // NSView pointer for the parent view. |   // NSView pointer for the parent view. | ||||||
|   cef_window_handle_t m_ParentView; |   cef_window_handle_t m_ParentView; | ||||||
|  |  | ||||||
|  |   // If window rendering is disabled no browser window will be created. Set | ||||||
|  |   // |m_ParentView| to the window that will act as the parent for popup menus, | ||||||
|  |   // dialog boxes, etc. | ||||||
|  |   int m_bWindowRenderingDisabled; | ||||||
|  |  | ||||||
|  |   // Set to true to enable transparent painting. | ||||||
|  |   int m_bTransparentPainting; | ||||||
|  |  | ||||||
|   // NSView pointer for the new browser view. |   // NSView pointer for the new browser view. | ||||||
|   cef_window_handle_t m_View; |   cef_window_handle_t m_View; | ||||||
| } cef_window_info_t; | } cef_window_info_t; | ||||||
| @@ -87,6 +98,15 @@ typedef struct _cef_print_info_t { | |||||||
|   double m_Scale; |   double m_Scale; | ||||||
| } cef_print_info_t; | } cef_print_info_t; | ||||||
|  |  | ||||||
|  | /// | ||||||
|  | // Class representing key information. | ||||||
|  | /// | ||||||
|  | typedef struct _cef_key_info_t { | ||||||
|  |   int keyCode; | ||||||
|  |   int character; | ||||||
|  |   int characterNoModifiers; | ||||||
|  | } cef_key_info_t; | ||||||
|  |  | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -92,6 +92,15 @@ typedef struct _cef_print_info_t { | |||||||
|   double m_Scale; |   double m_Scale; | ||||||
| } cef_print_info_t; | } cef_print_info_t; | ||||||
|  |  | ||||||
|  | /// | ||||||
|  | // Class representing key information. | ||||||
|  | /// | ||||||
|  | typedef struct _cef_key_info_t { | ||||||
|  |   int key; | ||||||
|  |   BOOL sysChar; | ||||||
|  |   BOOL imeChar; | ||||||
|  | } cef_key_info_t; | ||||||
|  |  | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -71,7 +71,6 @@ class CefCriticalSection { | |||||||
| #define CefWindowHandle cef_window_handle_t | #define CefWindowHandle cef_window_handle_t | ||||||
| #define CefCursorHandle cef_cursor_handle_t | #define CefCursorHandle cef_cursor_handle_t | ||||||
|  |  | ||||||
|  |  | ||||||
| struct CefWindowInfoTraits { | struct CefWindowInfoTraits { | ||||||
|   typedef cef_window_info_t struct_type; |   typedef cef_window_info_t struct_type; | ||||||
|  |  | ||||||
| @@ -162,6 +161,26 @@ struct CefPrintInfoTraits { | |||||||
| /// | /// | ||||||
| typedef CefStructBase<CefPrintInfoTraits> CefPrintInfo; | typedef CefStructBase<CefPrintInfoTraits> CefPrintInfo; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | struct CefKeyInfoTraits { | ||||||
|  |   typedef cef_key_info_t struct_type; | ||||||
|  |  | ||||||
|  |   static inline void init(struct_type* s) {} | ||||||
|  |   static inline void clear(struct_type* s) {} | ||||||
|  |  | ||||||
|  |   static inline void set(const struct_type* src, struct_type* target, | ||||||
|  |       bool copy) { | ||||||
|  |     target->key = src->key; | ||||||
|  |     target->sysChar = src->sysChar; | ||||||
|  |     target->imeChar = src->imeChar; | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /// | ||||||
|  | // Class representing key information. | ||||||
|  | /// | ||||||
|  | typedef CefStructBase<CefKeyInfoTraits> CefKeyInfo; | ||||||
|  |  | ||||||
| #endif  // OS_WIN | #endif  // OS_WIN | ||||||
|  |  | ||||||
| #endif  // CEF_INCLUDE_INTERNAL_CEF_WIN_H_ | #endif  // CEF_INCLUDE_INTERNAL_CEF_WIN_H_ | ||||||
|   | |||||||
| @@ -440,13 +440,13 @@ bool CefBrowserImpl::GetImage(PaintElementType type, int width, int height, | |||||||
|   return false; |   return false; | ||||||
| } | } | ||||||
|  |  | ||||||
| void CefBrowserImpl::SendKeyEvent(KeyType type, int key, int modifiers, | void CefBrowserImpl::SendKeyEvent(KeyType type, const CefKeyInfo& keyInfo, | ||||||
|                                   bool sysChar, bool imeChar) { |                                   int modifiers) { | ||||||
|   // Intentially post event tasks in all cases so that painting tasks can be |   // Intentially post event tasks in all cases so that painting tasks can be | ||||||
|   // handled at sane times. |   // handled at sane times. | ||||||
|   CefThread::PostTask(CefThread::UI, FROM_HERE, |   CefThread::PostTask(CefThread::UI, FROM_HERE, | ||||||
|       base::Bind(&CefBrowserImpl::UIT_SendKeyEvent, this, type, key, modifiers, |       base::Bind(&CefBrowserImpl::UIT_SendKeyEvent, this, type, keyInfo, | ||||||
|                  sysChar, imeChar)); |                  modifiers)); | ||||||
| } | } | ||||||
|  |  | ||||||
| void CefBrowserImpl::SendMouseClickEvent(int x, int y, MouseButtonType type, | void CefBrowserImpl::SendMouseClickEvent(int x, int y, MouseButtonType type, | ||||||
| @@ -466,11 +466,12 @@ void CefBrowserImpl::SendMouseMoveEvent(int x, int y, bool mouseLeave) { | |||||||
|                  mouseLeave)); |                  mouseLeave)); | ||||||
| } | } | ||||||
|  |  | ||||||
| void CefBrowserImpl::SendMouseWheelEvent(int x, int y, int delta) { | void CefBrowserImpl::SendMouseWheelEvent(int x, int y, int deltaX, int deltaY) { | ||||||
|   // Intentially post event tasks in all cases so that painting tasks can be |   // Intentially post event tasks in all cases so that painting tasks can be | ||||||
|   // handled at sane times. |   // handled at sane times. | ||||||
|   CefThread::PostTask(CefThread::UI, FROM_HERE, |   CefThread::PostTask(CefThread::UI, FROM_HERE, | ||||||
|       base::Bind(&CefBrowserImpl::UIT_SendMouseWheelEvent, this, x, y, delta)); |       base::Bind(&CefBrowserImpl::UIT_SendMouseWheelEvent, this, x, y, deltaX, | ||||||
|  |                  deltaY)); | ||||||
| } | } | ||||||
|  |  | ||||||
| void CefBrowserImpl::SendFocusEvent(bool setFocus) { | void CefBrowserImpl::SendFocusEvent(bool setFocus) { | ||||||
| @@ -1051,16 +1052,16 @@ void CefBrowserImpl::UIT_Invalidate(const CefRect& dirtyRect) { | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void CefBrowserImpl::UIT_SendKeyEvent(KeyType type, int key, int modifiers, | void CefBrowserImpl::UIT_SendKeyEvent(KeyType type, const CefKeyInfo& keyInfo, | ||||||
|                                       bool sysChar, bool imeChar) { |                                       int modifiers) { | ||||||
|   REQUIRE_UIT(); |   REQUIRE_UIT(); | ||||||
|   if (popuphost_) { |   if (popuphost_) { | ||||||
|     // Send the event to the popup. |     // Send the event to the popup. | ||||||
|     popuphost_->SendKeyEvent(type, key, modifiers, sysChar, imeChar); |     popuphost_->SendKeyEvent(type, keyInfo, modifiers); | ||||||
|   } else { |   } else { | ||||||
|     WebViewHost* host = UIT_GetWebViewHost(); |     WebViewHost* host = UIT_GetWebViewHost(); | ||||||
|     if (host) |     if (host) | ||||||
|       host->SendKeyEvent(type, key, modifiers, sysChar, imeChar); |       host->SendKeyEvent(type, keyInfo, modifiers); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1091,16 +1092,17 @@ void CefBrowserImpl::UIT_SendMouseMoveEvent(int x, int y, bool mouseLeave) { | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void CefBrowserImpl::UIT_SendMouseWheelEvent(int x, int y, int delta) { | void CefBrowserImpl::UIT_SendMouseWheelEvent(int x, int y, int deltaX, | ||||||
|  |                                              int deltaY) { | ||||||
|   REQUIRE_UIT(); |   REQUIRE_UIT(); | ||||||
|   if (popuphost_ && popup_rect_.Contains(x, y)) { |   if (popuphost_ && popup_rect_.Contains(x, y)) { | ||||||
|     // Send the event to the popup. |     // Send the event to the popup. | ||||||
|     popuphost_->SendMouseWheelEvent(x - popup_rect_.x(), y - popup_rect_.y(), |     popuphost_->SendMouseWheelEvent(x - popup_rect_.x(), y - popup_rect_.y(), | ||||||
|         delta); |         deltaX, deltaY); | ||||||
|   } else { |   } else { | ||||||
|     WebViewHost* host = UIT_GetWebViewHost(); |     WebViewHost* host = UIT_GetWebViewHost(); | ||||||
|     if (host) |     if (host) | ||||||
|       host->SendMouseWheelEvent(x, y, delta); |       host->SendMouseWheelEvent(x, y, deltaX, deltaY); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -106,12 +106,13 @@ class CefBrowserImpl : public CefBrowser { | |||||||
|   virtual void Invalidate(const CefRect& dirtyRect) OVERRIDE; |   virtual void Invalidate(const CefRect& dirtyRect) OVERRIDE; | ||||||
|   virtual bool GetImage(PaintElementType type, int width, int height, |   virtual bool GetImage(PaintElementType type, int width, int height, | ||||||
|                         void* buffer) OVERRIDE; |                         void* buffer) OVERRIDE; | ||||||
|   virtual void SendKeyEvent(KeyType type, int key, int modifiers, bool sysChar, |   virtual void SendKeyEvent(KeyType type, const CefKeyInfo& keyInfo, | ||||||
|                             bool imeChar) OVERRIDE; |                             int modifiers) OVERRIDE; | ||||||
|   virtual void SendMouseClickEvent(int x, int y, MouseButtonType type, |   virtual void SendMouseClickEvent(int x, int y, MouseButtonType type, | ||||||
|                                    bool mouseUp, int clickCount) OVERRIDE; |                                    bool mouseUp, int clickCount) OVERRIDE; | ||||||
|   virtual void SendMouseMoveEvent(int x, int y, bool mouseLeave) OVERRIDE; |   virtual void SendMouseMoveEvent(int x, int y, bool mouseLeave) OVERRIDE; | ||||||
|   virtual void SendMouseWheelEvent(int x, int y, int delta) OVERRIDE; |   virtual void SendMouseWheelEvent(int x, int y, int deltaX, int deltaY) | ||||||
|  |       OVERRIDE; | ||||||
|   virtual void SendFocusEvent(bool setFocus) OVERRIDE; |   virtual void SendFocusEvent(bool setFocus) OVERRIDE; | ||||||
|   virtual void SendCaptureLostEvent() OVERRIDE; |   virtual void SendCaptureLostEvent() OVERRIDE; | ||||||
|  |  | ||||||
| @@ -269,12 +270,11 @@ class CefBrowserImpl : public CefBrowser { | |||||||
|   void UIT_SetFocus(WebWidgetHost* host, bool enable); |   void UIT_SetFocus(WebWidgetHost* host, bool enable); | ||||||
|   void UIT_SetSize(PaintElementType type, int width, int height); |   void UIT_SetSize(PaintElementType type, int width, int height); | ||||||
|   void UIT_Invalidate(const CefRect& dirtyRect); |   void UIT_Invalidate(const CefRect& dirtyRect); | ||||||
|   void UIT_SendKeyEvent(KeyType type, int key, int modifiers, bool sysChar, |   void UIT_SendKeyEvent(KeyType type, const CefKeyInfo& keyInfo, int modifiers); | ||||||
|                         bool imeChar); |  | ||||||
|   void UIT_SendMouseClickEvent(int x, int y, MouseButtonType type, |   void UIT_SendMouseClickEvent(int x, int y, MouseButtonType type, | ||||||
|                                bool mouseUp, int clickCount); |                                bool mouseUp, int clickCount); | ||||||
|   void UIT_SendMouseMoveEvent(int x, int y, bool mouseLeave); |   void UIT_SendMouseMoveEvent(int x, int y, bool mouseLeave); | ||||||
|   void UIT_SendMouseWheelEvent(int x, int y, int delta); |   void UIT_SendMouseWheelEvent(int x, int y, int deltaX, int deltaY); | ||||||
|   void UIT_SendFocusEvent(bool setFocus); |   void UIT_SendFocusEvent(bool setFocus); | ||||||
|   void UIT_SendCaptureLostEvent(); |   void UIT_SendCaptureLostEvent(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -29,18 +29,19 @@ CefWindowHandle CefBrowserImpl::GetWindowHandle() { | |||||||
| } | } | ||||||
|  |  | ||||||
| bool CefBrowserImpl::IsWindowRenderingDisabled() { | bool CefBrowserImpl::IsWindowRenderingDisabled() { | ||||||
|   // TODO(port): Add support for off-screen rendering. |   return (window_info_.m_bWindowRenderingDisabled ? true : false); | ||||||
|   return false; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| gfx::NativeView CefBrowserImpl::UIT_GetMainWndHandle() { | gfx::NativeView CefBrowserImpl::UIT_GetMainWndHandle() { | ||||||
|   REQUIRE_UIT(); |   REQUIRE_UIT(); | ||||||
|   return window_info_.m_View; |   return window_info_.m_bWindowRenderingDisabled ? | ||||||
|  |       window_info_.m_ParentView : window_info_.m_View; | ||||||
| } | } | ||||||
|  |  | ||||||
| void CefBrowserImpl::UIT_ClearMainWndHandle() { | void CefBrowserImpl::UIT_ClearMainWndHandle() { | ||||||
|   REQUIRE_UIT(); |   REQUIRE_UIT(); | ||||||
|   window_info_.m_View = NULL; |   if (!window_info_.m_bWindowRenderingDisabled) | ||||||
|  |     window_info_.m_View = NULL; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool CefBrowserImpl::UIT_CreateBrowser(const CefString& url) { | bool CefBrowserImpl::UIT_CreateBrowser(const CefString& url) { | ||||||
| @@ -61,29 +62,35 @@ bool CefBrowserImpl::UIT_CreateBrowser(const CefString& url) { | |||||||
|   NSView* parentView = window_info_.m_ParentView; |   NSView* parentView = window_info_.m_ParentView; | ||||||
|   gfx::Rect contentRect(window_info_.m_x, window_info_.m_y, |   gfx::Rect contentRect(window_info_.m_x, window_info_.m_y, | ||||||
|                         window_info_.m_nWidth, window_info_.m_nHeight); |                         window_info_.m_nWidth, window_info_.m_nHeight); | ||||||
|   if (parentView == nil) { |   if (!window_info_.m_bWindowRenderingDisabled) { | ||||||
|     // Create a new window. |     if (parentView == nil) { | ||||||
|     NSRect screen_rect = [[NSScreen mainScreen] visibleFrame]; |       // Create a new window. | ||||||
|     NSRect window_rect = {{window_info_.m_x, |       NSRect screen_rect = [[NSScreen mainScreen] visibleFrame]; | ||||||
|                            screen_rect.size.height - window_info_.m_y}, |       NSRect window_rect = {{window_info_.m_x, | ||||||
|                           {window_info_.m_nWidth, window_info_.m_nHeight}}; |                              screen_rect.size.height - window_info_.m_y}, | ||||||
|     if (window_rect.size.width == 0) |                             {window_info_.m_nWidth, window_info_.m_nHeight}}; | ||||||
|       window_rect.size.width = 750; |       if (window_rect.size.width == 0) | ||||||
|     if (window_rect.size.height == 0) |         window_rect.size.width = 750; | ||||||
|       window_rect.size.height = 750; |       if (window_rect.size.height == 0) | ||||||
|     contentRect.SetRect(0, 0, window_rect.size.width, window_rect.size.height); |         window_rect.size.height = 750; | ||||||
|  |       contentRect.SetRect(0, 0, window_rect.size.width, | ||||||
|  |                           window_rect.size.height); | ||||||
|  |  | ||||||
|     newWnd = [[NSWindow alloc] |       newWnd = [[NSWindow alloc] | ||||||
|               initWithContentRect:window_rect |                 initWithContentRect:window_rect | ||||||
|               styleMask:(NSTitledWindowMask | |                 styleMask:(NSTitledWindowMask | | ||||||
|                          NSClosableWindowMask | |                            NSClosableWindowMask | | ||||||
|                          NSMiniaturizableWindowMask | |                            NSMiniaturizableWindowMask | | ||||||
|                          NSResizableWindowMask | |                            NSResizableWindowMask | | ||||||
|                          NSUnifiedTitleAndToolbarWindowMask ) |                            NSUnifiedTitleAndToolbarWindowMask ) | ||||||
|               backing:NSBackingStoreBuffered |                 backing:NSBackingStoreBuffered | ||||||
|               defer:NO]; |                 defer:NO]; | ||||||
|     parentView = [newWnd contentView]; |       parentView = [newWnd contentView]; | ||||||
|     window_info_.m_ParentView = parentView; |       window_info_.m_ParentView = parentView; | ||||||
|  |     } | ||||||
|  |   } else { | ||||||
|  |     // Create a new paint delegate. | ||||||
|  |     paint_delegate_.reset(new PaintDelegate(this)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   WebPreferences prefs; |   WebPreferences prefs; | ||||||
| @@ -92,7 +99,11 @@ bool CefBrowserImpl::UIT_CreateBrowser(const CefString& url) { | |||||||
|   // Create the webview host object |   // Create the webview host object | ||||||
|   webviewhost_.reset( |   webviewhost_.reset( | ||||||
|       WebViewHost::Create(parentView, contentRect, delegate_.get(), |       WebViewHost::Create(parentView, contentRect, delegate_.get(), | ||||||
|                           NULL, dev_tools_agent_.get(), prefs)); |                           paint_delegate_.get(), dev_tools_agent_.get(), | ||||||
|  |                           prefs)); | ||||||
|  |  | ||||||
|  |   if (window_info_.m_bTransparentPainting) | ||||||
|  |     webviewhost_->webview()->setIsTransparent(true); | ||||||
|  |  | ||||||
|   if (!settings_.developer_tools_disabled) |   if (!settings_.developer_tools_disabled) | ||||||
|     dev_tools_agent_->SetWebView(webviewhost_->webview()); |     dev_tools_agent_->SetWebView(webviewhost_->webview()); | ||||||
| @@ -101,8 +112,10 @@ bool CefBrowserImpl::UIT_CreateBrowser(const CefString& url) { | |||||||
|   browserView.browser = this; |   browserView.browser = this; | ||||||
|   window_info_.m_View = browserView; |   window_info_.m_View = browserView; | ||||||
|  |  | ||||||
|   if (!settings_.drag_drop_disabled) |   if (!window_info_.m_bWindowRenderingDisabled) { | ||||||
|     [browserView registerDragDrop]; |     if (!settings_.drag_drop_disabled) | ||||||
|  |       [browserView registerDragDrop]; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   Unlock(); |   Unlock(); | ||||||
|  |  | ||||||
| @@ -142,11 +155,24 @@ void CefBrowserImpl::UIT_SetFocus(WebWidgetHost* host, bool enable) { | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| bool CefBrowserImpl::UIT_ViewDocumentString(WebKit::WebFrame *frame) { | bool CefBrowserImpl::UIT_ViewDocumentString(WebKit::WebFrame* frame) { | ||||||
|   REQUIRE_UIT(); |   REQUIRE_UIT(); | ||||||
|  |  | ||||||
|   // TODO(port): Add implementation. |   char sztmp[L_tmpnam+4]; | ||||||
|   NOTIMPLEMENTED(); |   if (tmpnam(sztmp)) { | ||||||
|  |     strcat(sztmp, ".txt"); | ||||||
|  |  | ||||||
|  |     FILE* fp = fopen(sztmp, "wb"); | ||||||
|  |     if (fp) { | ||||||
|  |       std::string markup = frame->contentAsMarkup().utf8(); | ||||||
|  |       fwrite(markup.c_str(), 1, markup.size(), fp); | ||||||
|  |       fclose(fp); | ||||||
|  |  | ||||||
|  |       char szopen[L_tmpnam + 14]; | ||||||
|  |       snprintf(szopen, sizeof(szopen), "open -t \"%s\"", sztmp); | ||||||
|  |       return (system(szopen) >= 0); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|   return false; |   return false; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -48,6 +48,7 @@ namespace { | |||||||
| void AddMenuItem(CefRefPtr<CefBrowser> browser, | void AddMenuItem(CefRefPtr<CefBrowser> browser, | ||||||
|                  CefRefPtr<CefMenuHandler> handler, |                  CefRefPtr<CefMenuHandler> handler, | ||||||
|                  NSMenu* menu, |                  NSMenu* menu, | ||||||
|  |                  id target, | ||||||
|                  cef_menu_id_t menuId, |                  cef_menu_id_t menuId, | ||||||
|                  const std::string& label, |                  const std::string& label, | ||||||
|                  bool enabled) { |                  bool enabled) { | ||||||
| @@ -65,7 +66,8 @@ void AddMenuItem(CefRefPtr<CefBrowser> browser, | |||||||
|   NSMenuItem* item = |   NSMenuItem* item = | ||||||
|       [[[NSMenuItem alloc] initWithTitle:str |       [[[NSMenuItem alloc] initWithTitle:str | ||||||
|                                  action:enabled?@selector(menuItemSelected:):nil |                                  action:enabled?@selector(menuItemSelected:):nil | ||||||
|                            keyEquivalent:@""] autorelease];  |                            keyEquivalent:@""] autorelease]; | ||||||
|  |   [item setTarget:target]; | ||||||
|   [item setTag:menuId]; |   [item setTag:menuId]; | ||||||
|   [menu addItem:item]; |   [menu addItem:item]; | ||||||
| } | } | ||||||
| @@ -77,6 +79,46 @@ void AddMenuSeparator(NSMenu* menu) { | |||||||
|  |  | ||||||
| } // namespace | } // namespace | ||||||
|  |  | ||||||
|  | @interface BrowserMenuDelegate : NSObject <NSMenuDelegate> { | ||||||
|  |  @private | ||||||
|  |   CefRefPtr<CefBrowserImpl> browser_; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (id)initWithBrowser:(CefBrowserImpl*)browser; | ||||||
|  | - (void)menuItemSelected:(id)sender; | ||||||
|  | @end | ||||||
|  |  | ||||||
|  | @implementation BrowserMenuDelegate | ||||||
|  |  | ||||||
|  | - (id)initWithBrowser:(CefBrowserImpl*)browser { | ||||||
|  |   self = [super init]; | ||||||
|  |   if (self) | ||||||
|  |     browser_ = browser; | ||||||
|  |   return self; | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Called when a context menu item is selected by the user. | ||||||
|  | - (void)menuItemSelected:(id)sender { | ||||||
|  |   cef_menu_id_t menuId = static_cast<cef_menu_id_t>([sender tag]); | ||||||
|  |   bool handled = false; | ||||||
|  |  | ||||||
|  |   CefRefPtr<CefClient> client = browser_->GetClient(); | ||||||
|  |   if (client.get()) { | ||||||
|  |     CefRefPtr<CefMenuHandler> handler = client->GetMenuHandler(); | ||||||
|  |     if (handler.get()) { | ||||||
|  |       // Ask the handler if it wants to handle the action. | ||||||
|  |       handled = handler->OnMenuAction(browser_.get(), menuId); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if(!handled) { | ||||||
|  |     // Execute the action. | ||||||
|  |     browser_->UIT_HandleAction(menuId, browser_->GetFocusedFrame()); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @end | ||||||
|  |  | ||||||
| // WebViewClient -------------------------------------------------------------- | // WebViewClient -------------------------------------------------------------- | ||||||
|  |  | ||||||
| @@ -102,12 +144,21 @@ void BrowserWebViewDelegate::showContextMenu( | |||||||
|   if (!host) |   if (!host) | ||||||
|     return; |     return; | ||||||
|  |  | ||||||
|   BrowserWebView *view = static_cast<BrowserWebView*>(host->view_handle()); |   NSView *view = browser_->UIT_GetMainWndHandle(); | ||||||
|   if (!view) |   if (!view) | ||||||
|     return; |     return; | ||||||
|  |  | ||||||
|   NSWindow* window = [view window]; |   NSWindow* window = [view window]; | ||||||
|   NSPoint position = [window mouseLocationOutsideOfEventStream]; |  | ||||||
|  |   int screenX = -1; | ||||||
|  |   int screenY = -1;  | ||||||
|  |   NSPoint mouse_pt = {data.mousePosition.x, data.mousePosition.y}; | ||||||
|  |   if (!browser_->IsWindowRenderingDisabled()) { | ||||||
|  |     mouse_pt = [window mouseLocationOutsideOfEventStream]; | ||||||
|  |     NSPoint screen_pt = [window convertBaseToScreen:mouse_pt]; | ||||||
|  |     screenX = screen_pt.x; | ||||||
|  |     screenY = screen_pt.y; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   int edit_flags = 0; |   int edit_flags = 0; | ||||||
|   int type_flags = 0; |   int type_flags = 0; | ||||||
| @@ -117,7 +168,7 @@ void BrowserWebViewDelegate::showContextMenu( | |||||||
|   MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current()); |   MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current()); | ||||||
|  |  | ||||||
|   // Give the client a chance to handle the menu. |   // Give the client a chance to handle the menu. | ||||||
|   if (OnBeforeMenu(data, position.x, position.y, edit_flags, type_flags)) |   if (OnBeforeMenu(data, mouse_pt.x, mouse_pt.y, edit_flags, type_flags)) | ||||||
|     return; |     return; | ||||||
|  |  | ||||||
|   CefRefPtr<CefClient> client = browser_->GetClient(); |   CefRefPtr<CefClient> client = browser_->GetClient(); | ||||||
| @@ -125,43 +176,57 @@ void BrowserWebViewDelegate::showContextMenu( | |||||||
|   if (client.get()) |   if (client.get()) | ||||||
|     handler = client->GetMenuHandler(); |     handler = client->GetMenuHandler(); | ||||||
|  |  | ||||||
|  |   if (client.get() && browser_->IsWindowRenderingDisabled()) { | ||||||
|  |     // Retrieve the screen coordinates. | ||||||
|  |     CefRefPtr<CefRenderHandler> render_handler = client->GetRenderHandler(); | ||||||
|  |     if (!render_handler.get() || | ||||||
|  |         !render_handler->GetScreenPoint(browser_, mouse_pt.x, mouse_pt.y, | ||||||
|  |                                         screenX, screenY)) { | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   BrowserMenuDelegate* delegate = | ||||||
|  |      [[[BrowserMenuDelegate alloc] initWithBrowser:browser_] autorelease]; | ||||||
|  |  | ||||||
|   // Build the correct default context menu |   // Build the correct default context menu | ||||||
|   if (type_flags &  MENUTYPE_EDITABLE) { |   if (type_flags &  MENUTYPE_EDITABLE) { | ||||||
|     menu = [[[NSMenu alloc] initWithTitle:@""] autorelease]; |     menu = [[[NSMenu alloc] initWithTitle:@""] autorelease]; | ||||||
|  |  | ||||||
|     AddMenuItem(browser_, handler, menu, MENU_ID_UNDO, "Undo", |     AddMenuItem(browser_, handler, menu, delegate, MENU_ID_UNDO, "Undo", | ||||||
|                 !!(edit_flags & MENU_CAN_UNDO)); |                 !!(edit_flags & MENU_CAN_UNDO)); | ||||||
|     AddMenuItem(browser_, handler, menu, MENU_ID_REDO, "Redo", |     AddMenuItem(browser_, handler, menu, delegate, MENU_ID_REDO, "Redo", | ||||||
|                 !!(edit_flags & MENU_CAN_REDO)); |                 !!(edit_flags & MENU_CAN_REDO)); | ||||||
|     AddMenuSeparator(menu); |     AddMenuSeparator(menu); | ||||||
|     AddMenuItem(browser_, handler, menu, MENU_ID_CUT, "Cut", |     AddMenuItem(browser_, handler, menu, delegate, MENU_ID_CUT, "Cut", | ||||||
|                 !!(edit_flags & MENU_CAN_CUT)); |                 !!(edit_flags & MENU_CAN_CUT)); | ||||||
|     AddMenuItem(browser_, handler, menu, MENU_ID_COPY, "Copy", |     AddMenuItem(browser_, handler, menu, delegate, MENU_ID_COPY, "Copy", | ||||||
|                 !!(edit_flags & MENU_CAN_COPY)); |                 !!(edit_flags & MENU_CAN_COPY)); | ||||||
|     AddMenuItem(browser_, handler, menu, MENU_ID_PASTE, "Paste", |     AddMenuItem(browser_, handler, menu, delegate, MENU_ID_PASTE, "Paste", | ||||||
|                 !!(edit_flags & MENU_CAN_PASTE)); |                 !!(edit_flags & MENU_CAN_PASTE)); | ||||||
|     AddMenuItem(browser_, handler, menu, MENU_ID_DELETE, "Delete", |     AddMenuItem(browser_, handler, menu, delegate, MENU_ID_DELETE, "Delete", | ||||||
|                 !!(edit_flags & MENU_CAN_DELETE)); |                 !!(edit_flags & MENU_CAN_DELETE)); | ||||||
|     AddMenuSeparator(menu); |     AddMenuSeparator(menu); | ||||||
|     AddMenuItem(browser_, handler, menu, MENU_ID_SELECTALL, "Select All", |     AddMenuItem(browser_, handler, menu, delegate, MENU_ID_SELECTALL, | ||||||
|                 !!(edit_flags & MENU_CAN_SELECT_ALL)); |                 "Select All", !!(edit_flags & MENU_CAN_SELECT_ALL)); | ||||||
|   } else if(type_flags & MENUTYPE_SELECTION) { |   } else if(type_flags & MENUTYPE_SELECTION) { | ||||||
|     menu = [[[NSMenu alloc] initWithTitle:@""] autorelease]; |     menu = [[[NSMenu alloc] initWithTitle:@""] autorelease]; | ||||||
|  |  | ||||||
|     AddMenuItem(browser_, handler, menu, MENU_ID_COPY, "Copy", |     AddMenuItem(browser_, handler, menu, delegate, MENU_ID_COPY, "Copy", | ||||||
|                 !!(edit_flags & MENU_CAN_COPY)); |                 !!(edit_flags & MENU_CAN_COPY)); | ||||||
|   } else if(type_flags & (MENUTYPE_PAGE | MENUTYPE_FRAME)) { |   } else if(type_flags & (MENUTYPE_PAGE | MENUTYPE_FRAME)) { | ||||||
|     menu = [[[NSMenu alloc] initWithTitle:@""] autorelease]; |     menu = [[[NSMenu alloc] initWithTitle:@""] autorelease]; | ||||||
|  |  | ||||||
|     AddMenuItem(browser_, handler, menu, MENU_ID_NAV_BACK, "Back", |     AddMenuItem(browser_, handler, menu, delegate, MENU_ID_NAV_BACK, "Back", | ||||||
|                 !!(edit_flags & MENU_CAN_GO_BACK)); |                 !!(edit_flags & MENU_CAN_GO_BACK)); | ||||||
|     AddMenuItem(browser_, handler, menu, MENU_ID_NAV_FORWARD, "Forward", |     AddMenuItem(browser_, handler, menu, delegate, MENU_ID_NAV_FORWARD, | ||||||
|                 !!(edit_flags & MENU_CAN_GO_FORWARD)); |                 "Forward", !!(edit_flags & MENU_CAN_GO_FORWARD)); | ||||||
|     // TODO(port): Enable the below menu items when supported. |     // TODO(port): Enable the below menu items when supported. | ||||||
|     //AddMenuSeparator(menu); |     //AddMenuSeparator(menu); | ||||||
|     //AddMenuItem(browser_, handler, menu, MENU_ID_PRINT, "Print", true); |     //AddMenuItem(browser_, handler, menu, delegate, MENU_ID_PRINT, "Print", | ||||||
|     //AddMenuItem(browser_, handler, menu, MENU_ID_VIEWSOURCE, "View Source", |     //           true); | ||||||
|     //            true); |     //AddMenuItem(browser_, handler, menu, delegate, MENU_ID_VIEWSOURCE, | ||||||
|  |     //            "View Source", true); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if (!menu) |   if (!menu) | ||||||
| @@ -169,21 +234,24 @@ void BrowserWebViewDelegate::showContextMenu( | |||||||
|  |  | ||||||
|   // Synthesize an event for the click, as there is no certainty that |   // Synthesize an event for the click, as there is no certainty that | ||||||
|   // [NSApp currentEvent] will return a valid event. |   // [NSApp currentEvent] will return a valid event. | ||||||
|  |   NSPoint screen_pt = {screenX, screenY}; | ||||||
|  |   NSPoint window_pt = [window convertScreenToBase:screen_pt]; | ||||||
|  |  | ||||||
|   NSEvent* currentEvent = [NSApp currentEvent]; |   NSEvent* currentEvent = [NSApp currentEvent]; | ||||||
|   NSTimeInterval eventTime = [currentEvent timestamp]; |   NSTimeInterval eventTime = [currentEvent timestamp]; | ||||||
|   NSEvent* clickEvent = [NSEvent mouseEventWithType:NSRightMouseDown |   NSEvent* clickEvent = [NSEvent mouseEventWithType:NSRightMouseDown | ||||||
|                                           location:position |                                            location:window_pt | ||||||
|                                      modifierFlags:NSRightMouseDownMask |                                       modifierFlags:NSRightMouseDownMask | ||||||
|                                          timestamp:eventTime |                                           timestamp:eventTime | ||||||
|                                       windowNumber:[window windowNumber] |                                        windowNumber:[window windowNumber] | ||||||
|                                            context:nil |                                             context:nil | ||||||
|                                        eventNumber:0 |                                         eventNumber:0 | ||||||
|                                         clickCount:1 |                                          clickCount:1 | ||||||
|                                           pressure:1.0]; |                                            pressure:1.0]; | ||||||
|      |      | ||||||
|  |  | ||||||
|   // Menu selection events go to the BrowserWebView. |   // Menu selection events go to the BrowserMenuDelegate. | ||||||
|   [menu setDelegate:view]; |   [menu setDelegate:delegate]; | ||||||
|  |  | ||||||
|   // Show the menu. |   // Show the menu. | ||||||
|   [NSMenu popUpContextMenu:menu |   [NSMenu popUpContextMenu:menu | ||||||
| @@ -194,18 +262,43 @@ void BrowserWebViewDelegate::showContextMenu( | |||||||
| // WebWidgetClient ------------------------------------------------------------ | // WebWidgetClient ------------------------------------------------------------ | ||||||
|  |  | ||||||
| void BrowserWebViewDelegate::show(WebNavigationPolicy policy) { | void BrowserWebViewDelegate::show(WebNavigationPolicy policy) { | ||||||
|  |   DCHECK(this != browser_->UIT_GetPopupDelegate()); | ||||||
| } | } | ||||||
|  |  | ||||||
| void BrowserWebViewDelegate::didChangeCursor(const WebCursorInfo& cursor_info) { | void BrowserWebViewDelegate::didChangeCursor(const WebCursorInfo& cursor_info) { | ||||||
|   NSCursor* ns_cursor = WebCursor(cursor_info).GetNativeCursor(); |   NSCursor* ns_cursor = WebCursor(cursor_info).GetNativeCursor(); | ||||||
|   [ns_cursor set]; |  | ||||||
|  |   if (!browser_->IsWindowRenderingDisabled()) { | ||||||
|  |     [ns_cursor set]; | ||||||
|  |   } else { | ||||||
|  |     // Notify the handler of cursor change. | ||||||
|  |     CefRefPtr<CefClient> client = browser_->GetClient(); | ||||||
|  |     if (client.get()) { | ||||||
|  |       CefRefPtr<CefRenderHandler> handler = client->GetRenderHandler(); | ||||||
|  |       if (handler.get()) | ||||||
|  |         handler->OnCursorChange(browser_, ns_cursor); | ||||||
|  |     } | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| WebRect BrowserWebViewDelegate::windowRect() { | WebRect BrowserWebViewDelegate::windowRect() { | ||||||
|   if (WebWidgetHost* host = GetWidgetHost()) { |   if (WebWidgetHost* host = GetWidgetHost()) { | ||||||
|     NSView *view = host->view_handle(); |     if (!browser_->IsWindowRenderingDisabled()) { | ||||||
|     NSRect rect = [view frame]; |       NSView *view = host->view_handle(); | ||||||
|     return gfx::Rect(NSRectToCGRect(rect)); |       NSRect rect = [view frame]; | ||||||
|  |       return gfx::Rect(NSRectToCGRect(rect)); | ||||||
|  |     } else { | ||||||
|  |       // Retrieve the view rectangle from the handler. | ||||||
|  |       CefRefPtr<CefClient> client = browser_->GetClient(); | ||||||
|  |       if (client.get()) { | ||||||
|  |         CefRefPtr<CefRenderHandler> handler = client->GetRenderHandler(); | ||||||
|  |         if (handler.get()) { | ||||||
|  |           CefRect rect(0, 0, 0, 0); | ||||||
|  |           if (handler->GetViewRect(browser_, rect)) | ||||||
|  |             return WebRect(rect.x, rect.y, rect.width, rect.height); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|   return WebRect(); |   return WebRect(); | ||||||
| } | } | ||||||
| @@ -213,6 +306,8 @@ WebRect BrowserWebViewDelegate::windowRect() { | |||||||
| void BrowserWebViewDelegate::setWindowRect(const WebRect& rect) { | void BrowserWebViewDelegate::setWindowRect(const WebRect& rect) { | ||||||
|   if (this == browser_->UIT_GetWebViewDelegate()) { |   if (this == browser_->UIT_GetWebViewDelegate()) { | ||||||
|     // TODO(port): Set the window rectangle. |     // TODO(port): Set the window rectangle. | ||||||
|  |   } else if (this == browser_->UIT_GetPopupDelegate()) { | ||||||
|  |     NOTREACHED(); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -257,7 +352,8 @@ void BrowserWebViewDelegate::startDragging(const WebDragData& data, | |||||||
|                                            WebDragOperationsMask mask, |                                            WebDragOperationsMask mask, | ||||||
|                                            const WebImage& image, |                                            const WebImage& image, | ||||||
|                                            const WebPoint& image_offset) { |                                            const WebPoint& image_offset) { | ||||||
|   if (browser_->settings().drag_drop_disabled) { |   if (browser_->settings().drag_drop_disabled || | ||||||
|  |       browser_->IsWindowRenderingDisabled()) { | ||||||
|     browser_->UIT_GetWebView()->dragSourceSystemDragEnded(); |     browser_->UIT_GetWebView()->dragSourceSystemDragEnded(); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
| @@ -332,15 +428,30 @@ webkit::npapi::WebPluginDelegate* BrowserWebViewDelegate::CreatePluginDelegate( | |||||||
|  |  | ||||||
| void BrowserWebViewDelegate::CreatedPluginWindow( | void BrowserWebViewDelegate::CreatedPluginWindow( | ||||||
|     gfx::PluginWindowHandle handle) { |     gfx::PluginWindowHandle handle) { | ||||||
|  |   if (browser_->IsWindowRenderingDisabled()) { | ||||||
|  |     WebViewHost* host = browser_->UIT_GetWebViewHost(); | ||||||
|  |     if (host) | ||||||
|  |       host->AddWindowedPlugin(handle); | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void BrowserWebViewDelegate::WillDestroyPluginWindow( | void BrowserWebViewDelegate::WillDestroyPluginWindow( | ||||||
|     gfx::PluginWindowHandle handle) { |     gfx::PluginWindowHandle handle) { | ||||||
|  |   if (browser_->IsWindowRenderingDisabled()) { | ||||||
|  |     WebViewHost* host = browser_->UIT_GetWebViewHost(); | ||||||
|  |     if (host) | ||||||
|  |       host->RemoveWindowedPlugin(handle); | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void BrowserWebViewDelegate::DidMovePlugin( | void BrowserWebViewDelegate::DidMovePlugin( | ||||||
|     const webkit::npapi::WebPluginGeometry& move) { |     const webkit::npapi::WebPluginGeometry& move) { | ||||||
|   // TODO(port): add me once plugins work. |   if (browser_->IsWindowRenderingDisabled()) { | ||||||
|  |     WebViewHost* host = browser_->UIT_GetWebViewHost(); | ||||||
|  |     if (host) { | ||||||
|  |       host->MoveWindowedPlugin(move); | ||||||
|  |     } | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| // Protected methods ---------------------------------------------------------- | // Protected methods ---------------------------------------------------------- | ||||||
|   | |||||||
| @@ -448,7 +448,7 @@ void BrowserWebViewDelegate::showContextMenu( | |||||||
|   if (client.get() && browser_->IsWindowRenderingDisabled()) { |   if (client.get() && browser_->IsWindowRenderingDisabled()) { | ||||||
|     // Retrieve the screen coordinates. |     // Retrieve the screen coordinates. | ||||||
|     CefRefPtr<CefRenderHandler> render_handler = client->GetRenderHandler(); |     CefRefPtr<CefRenderHandler> render_handler = client->GetRenderHandler(); | ||||||
|     if (render_handler.get() && |     if (!render_handler.get() || | ||||||
|         !render_handler->GetScreenPoint(browser_, mouse_pt.x, mouse_pt.y, |         !render_handler->GetScreenPoint(browser_, mouse_pt.x, mouse_pt.y, | ||||||
|                                         screenX, screenY)) { |                                         screenX, screenY)) { | ||||||
|       return; |       return; | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ struct WebDropData; | |||||||
| // A view to wrap the WebCore view and help it live in a Cocoa world. The | // A view to wrap the WebCore view and help it live in a Cocoa world. The | ||||||
| // (rough) equivalent of Apple's WebView. | // (rough) equivalent of Apple's WebView. | ||||||
|  |  | ||||||
| @interface BrowserWebView : NSView <NSMenuDelegate> { | @interface BrowserWebView : NSView { | ||||||
|  @private |  @private | ||||||
|   CefBrowserImpl* browser_;  // weak |   CefBrowserImpl* browser_;  // weak | ||||||
|   NSTrackingArea* trackingArea_; |   NSTrackingArea* trackingArea_; | ||||||
| @@ -46,9 +46,6 @@ struct WebDropData; | |||||||
| - (BOOL)isOpaque; | - (BOOL)isOpaque; | ||||||
| - (void)setFrame:(NSRect)frameRect; | - (void)setFrame:(NSRect)frameRect; | ||||||
|  |  | ||||||
| // Called when a context menu item is selected by the user. |  | ||||||
| - (void)menuItemSelected:(id)sender; |  | ||||||
|  |  | ||||||
| // Register this WebView as a drag/drop target. | // Register this WebView as a drag/drop target. | ||||||
| - (void)registerDragDrop; | - (void)registerDragDrop; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -239,25 +239,6 @@ | |||||||
|     browser_->GetFocusedFrame()->SelectAll(); |     browser_->GetFocusedFrame()->SelectAll(); | ||||||
| } | } | ||||||
|  |  | ||||||
| - (void)menuItemSelected:(id)sender { |  | ||||||
|   cef_menu_id_t menuId = static_cast<cef_menu_id_t>([sender tag]); |  | ||||||
|   bool handled = false; |  | ||||||
|  |  | ||||||
|   CefRefPtr<CefClient> client = browser_->GetClient(); |  | ||||||
|   if (client.get()) { |  | ||||||
|     CefRefPtr<CefMenuHandler> handler = client->GetMenuHandler(); |  | ||||||
|     if (handler.get()) { |  | ||||||
|       // Ask the handler if it wants to handle the action. |  | ||||||
|       handled = handler->OnMenuAction(browser_, menuId); |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if(!handled) { |  | ||||||
|     // Execute the action. |  | ||||||
|     browser_->UIT_HandleAction(menuId, browser_->GetFocusedFrame()); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| - (void)registerDragDrop { | - (void)registerDragDrop { | ||||||
|   dropTarget_.reset([[WebDropTarget alloc] initWithWebView:self]); |   dropTarget_.reset([[WebDropTarget alloc] initWithWebView:self]); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -33,9 +33,35 @@ void ExternalPopupMenu::show(const WebKit::WebRect& bounds) { | |||||||
|  |  | ||||||
|   CefBrowserImpl* browser = delegate_->GetBrowser(); |   CefBrowserImpl* browser = delegate_->GetBrowser(); | ||||||
|  |  | ||||||
|  |   NSView* view = nil; | ||||||
|  |   NSRect view_rect; | ||||||
|  |   | ||||||
|  |   if (!browser->IsWindowRenderingDisabled()) { | ||||||
|  |     view = browser->UIT_GetWebViewWndHandle(); | ||||||
|  |     view_rect = [view bounds]; | ||||||
|  |   } else { | ||||||
|  |     view = browser->UIT_GetMainWndHandle(); | ||||||
|  |     if (view != nil) { | ||||||
|  |       CefRefPtr<CefClient> client = browser->GetClient(); | ||||||
|  |       if (client.get()) { | ||||||
|  |         // Retrieve the view rect. | ||||||
|  |         CefRect rect; | ||||||
|  |         CefRefPtr<CefRenderHandler> render_handler = client->GetRenderHandler(); | ||||||
|  |         if (render_handler.get() && | ||||||
|  |             render_handler->GetViewRect(browser, rect)) { | ||||||
|  |           view_rect = NSMakeRect(rect.x, rect.y, rect.width, rect.height); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (view == nil || view_rect.size.width == 0 || view_rect.size.height == 0) { | ||||||
|  |     popup_menu_client_->didCancel(); | ||||||
|  |     delegate_->ClosePopupMenu(); | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   // Set up the menu position. |   // Set up the menu position. | ||||||
|   NSView* web_view = browser->UIT_GetWebViewWndHandle(); |  | ||||||
|   NSRect view_rect = [web_view bounds]; |  | ||||||
|   int y_offset = bounds.y + bounds.height; |   int y_offset = bounds.y + bounds.height; | ||||||
|   NSRect position = NSMakeRect(bounds.x, view_rect.size.height - y_offset, |   NSRect position = NSMakeRect(bounds.x, view_rect.size.height - y_offset, | ||||||
|                                bounds.width, bounds.height); |                                bounds.width, bounds.height); | ||||||
| @@ -46,7 +72,7 @@ void ExternalPopupMenu::show(const WebKit::WebRect& bounds) { | |||||||
|                                                 fontSize:font_size |                                                 fontSize:font_size | ||||||
|                                             rightAligned:right_aligned]); |                                             rightAligned:right_aligned]); | ||||||
|  |  | ||||||
|   [menu_runner runMenuInView:browser->UIT_GetWebViewWndHandle() |   [menu_runner runMenuInView:view | ||||||
|                   withBounds:position |                   withBounds:position | ||||||
|                 initialIndex:selected_index]; |                 initialIndex:selected_index]; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -35,10 +35,15 @@ WebViewHost* WebViewHost::Create(NSView* parent_view, | |||||||
|   WebViewHost* host = new WebViewHost(delegate); |   WebViewHost* host = new WebViewHost(delegate); | ||||||
|  |  | ||||||
|   NSRect content_rect = {{rect.x(), rect.y()}, {rect.width(), rect.height()}}; |   NSRect content_rect = {{rect.x(), rect.y()}, {rect.width(), rect.height()}}; | ||||||
|   host->view_ = [[BrowserWebView alloc] initWithFrame:content_rect]; |   if (!paint_delegate) { | ||||||
|   [host->view_ setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; |     host->view_ = [[BrowserWebView alloc] initWithFrame:content_rect]; | ||||||
|   [parent_view addSubview:host->view_]; |     [host->view_ setAutoresizingMask:(NSViewWidthSizable | | ||||||
|   [host->view_ release]; |                                       NSViewHeightSizable)]; | ||||||
|  |     [parent_view addSubview:host->view_]; | ||||||
|  |     [host->view_ release]; | ||||||
|  |   } else { | ||||||
|  |     host->paint_delegate_ = paint_delegate; | ||||||
|  |   } | ||||||
|  |  | ||||||
| #if defined(WEBKIT_HAS_WEB_AUTO_FILL_CLIENT) | #if defined(WEBKIT_HAS_WEB_AUTO_FILL_CLIENT) | ||||||
|   host->webwidget_ = WebView::create(delegate, NULL); |   host->webwidget_ = WebView::create(delegate, NULL); | ||||||
|   | |||||||
| @@ -106,21 +106,18 @@ gfx::PluginWindowHandle WebWidgetHost::GetWindowedPluginAt(int x, int y) { | |||||||
| } | } | ||||||
|  |  | ||||||
| void WebWidgetHost::DoPaint() { | void WebWidgetHost::DoPaint() { | ||||||
|   // TODO(cef): The below code is cross-platform but the IsIdle() method |  if (MessageLoop::current()->IsIdle()) { | ||||||
|   // currently requires patches to Chromium. Since this code is only executed |  | ||||||
|   // on Windows it's been stuck behind an #ifdef for now to avoid having to |  | ||||||
|   // patch Chromium code on other platforms. |  | ||||||
| #if defined(OS_WIN) |  | ||||||
|   if (MessageLoop::current()->IsIdle()) { |  | ||||||
|     has_update_task_ = false; |     has_update_task_ = false; | ||||||
|     // Paint to the delegate. |     // Paint to the delegate. | ||||||
|  | #if defined(OS_MACOSX) | ||||||
|  |     SkRegion region; | ||||||
|  |     Paint(region); | ||||||
|  | #else | ||||||
|     Paint(); |     Paint(); | ||||||
|  | #endif | ||||||
|   } else { |   } else { | ||||||
|     // Try again later. |     // Try again later. | ||||||
|     CefThread::PostTask(CefThread::UI, FROM_HERE, |     CefThread::PostTask(CefThread::UI, FROM_HERE, | ||||||
|         base::Bind(&WebWidgetHost::DoPaint, weak_factory_.GetWeakPtr())); |         base::Bind(&WebWidgetHost::DoPaint, weak_factory_.GetWeakPtr())); | ||||||
|   } |   } | ||||||
| #else |  | ||||||
|   NOTIMPLEMENTED(); |  | ||||||
| #endif |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -123,12 +123,12 @@ class WebWidgetHost { | |||||||
|  |  | ||||||
|   void SetTooltipText(const CefString& tooltip_text); |   void SetTooltipText(const CefString& tooltip_text); | ||||||
|  |  | ||||||
|   void SendKeyEvent(cef_key_type_t type, int key, int modifiers, bool sysChar, |   void SendKeyEvent(cef_key_type_t type, const cef_key_info_t& keyInfo, | ||||||
|                     bool imeChar); |                     int modifiers); | ||||||
|   void SendMouseClickEvent(int x, int y, cef_mouse_button_type_t type, |   void SendMouseClickEvent(int x, int y, cef_mouse_button_type_t type, | ||||||
|                            bool mouseUp, int clickCount); |                            bool mouseUp, int clickCount); | ||||||
|   void SendMouseMoveEvent(int x, int y, bool mouseLeave); |   void SendMouseMoveEvent(int x, int y, bool mouseLeave); | ||||||
|   void SendMouseWheelEvent(int x, int y, int delta); |   void SendMouseWheelEvent(int x, int y, int deltaX, int deltaY); | ||||||
|   void SendFocusEvent(bool setFocus); |   void SendFocusEvent(bool setFocus); | ||||||
|   void SendCaptureLostEvent(); |   void SendCaptureLostEvent(); | ||||||
|  |  | ||||||
| @@ -284,6 +284,11 @@ class WebWidgetHost { | |||||||
|   WebKit::WebRect caret_bounds_; |   WebKit::WebRect caret_bounds_; | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | #if defined(OS_MACOSX) | ||||||
|  |   int mouse_modifiers_; | ||||||
|  |   WebKit::WebMouseEvent::Button mouse_button_down_; | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #if defined(TOOLKIT_GTK) | #if defined(TOOLKIT_GTK) | ||||||
|   // Since GtkWindow resize is asynchronous, we have to stash the dimensions, |   // Since GtkWindow resize is asynchronous, we have to stash the dimensions, | ||||||
|   // so that the backing store doesn't have to wait for sizing to take place. |   // so that the backing store doesn't have to wait for sizing to take place. | ||||||
|   | |||||||
| @@ -440,8 +440,9 @@ void WebWidgetHost::PaintRect(const gfx::Rect& rect) { | |||||||
|   set_painting(false); |   set_painting(false); | ||||||
| } | } | ||||||
|  |  | ||||||
| void WebWidgetHost::SendKeyEvent(cef_key_type_t type, int key, int modifiers, | void WebWidgetHost::SendKeyEvent(cef_key_type_t type, | ||||||
|                                  bool sysChar, bool imeChar) { |                                  const cef_key_info_t& keyInfo, | ||||||
|  |                                  int modifiers) { | ||||||
|   // TODO(port): Implement this method as part of off-screen rendering support. |   // TODO(port): Implement this method as part of off-screen rendering support. | ||||||
|   NOTIMPLEMENTED(); |   NOTIMPLEMENTED(); | ||||||
| } | } | ||||||
| @@ -458,7 +459,7 @@ void WebWidgetHost::SendMouseMoveEvent(int x, int y, bool mouseLeave) { | |||||||
|   NOTIMPLEMENTED(); |   NOTIMPLEMENTED(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void WebWidgetHost::SendMouseWheelEvent(int x, int y, int delta) { | void WebWidgetHost::SendMouseWheelEvent(int x, int y, int deltaX, int deltaY) { | ||||||
|   // TODO(port): Implement this method as part of off-screen rendering support. |   // TODO(port): Implement this method as part of off-screen rendering support. | ||||||
|   NOTIMPLEMENTED(); |   NOTIMPLEMENTED(); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -3,7 +3,18 @@ | |||||||
| // found in the LICENSE file. | // found in the LICENSE file. | ||||||
|  |  | ||||||
| #import <Cocoa/Cocoa.h> | #import <Cocoa/Cocoa.h> | ||||||
|  |  | ||||||
|  | #include "base/compiler_specific.h" | ||||||
|  | #include "third_party/WebKit/Source/WebCore/config.h" | ||||||
|  | MSVC_PUSH_WARNING_LEVEL(0); | ||||||
|  | #include "KeyEventCocoa.h"  // NOLINT(build/include) | ||||||
|  | MSVC_POP_WARNING(); | ||||||
|  |  | ||||||
|  | #undef LOG | ||||||
| #import "libcef/webwidget_host.h" | #import "libcef/webwidget_host.h" | ||||||
|  | #include "libcef/cef_thread.h" | ||||||
|  |  | ||||||
|  | #include "base/bind.h" | ||||||
| #import "base/logging.h" | #import "base/logging.h" | ||||||
| #import "skia/ext/platform_canvas.h" | #import "skia/ext/platform_canvas.h" | ||||||
| #import "third_party/WebKit/Source/WebKit/chromium/public/mac/WebInputEventFactory.h" | #import "third_party/WebKit/Source/WebKit/chromium/public/mac/WebInputEventFactory.h" | ||||||
| @@ -11,12 +22,14 @@ | |||||||
| #import "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" | #import "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" | ||||||
| #import "third_party/WebKit/Source/WebKit/chromium/public/WebPopupMenu.h" | #import "third_party/WebKit/Source/WebKit/chromium/public/WebPopupMenu.h" | ||||||
| #import "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h" | #import "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h" | ||||||
|  | #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" | ||||||
| #import "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h" | #import "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h" | ||||||
| #import "third_party/skia/include/core/SkRegion.h" | #import "third_party/skia/include/core/SkRegion.h" | ||||||
| #import "ui/gfx/rect.h" | #import "ui/gfx/rect.h" | ||||||
| #import "ui/gfx/size.h" | #import "ui/gfx/size.h" | ||||||
| #import "webkit/glue/webkit_glue.h" | #import "webkit/glue/webkit_glue.h" | ||||||
|  |  | ||||||
|  | using webkit::npapi::WebPluginGeometry; | ||||||
| using WebKit::WebInputEvent; | using WebKit::WebInputEvent; | ||||||
| using WebKit::WebInputEventFactory; | using WebKit::WebInputEventFactory; | ||||||
| using WebKit::WebKeyboardEvent; | using WebKit::WebKeyboardEvent; | ||||||
| @@ -46,14 +59,19 @@ WebWidgetHost* WebWidgetHost::Create(NSView* parent_view, | |||||||
|                                      PaintDelegate* paint_delegate) { |                                      PaintDelegate* paint_delegate) { | ||||||
|   WebWidgetHost* host = new WebWidgetHost(); |   WebWidgetHost* host = new WebWidgetHost(); | ||||||
|  |  | ||||||
|   const NSRect bounds = [parent_view bounds]; |   if (!paint_delegate) { | ||||||
|   host->view_ = [[NSView alloc] initWithFrame:bounds]; |     const NSRect bounds = [parent_view bounds]; | ||||||
|   [parent_view addSubview:host->view_]; |     host->view_ = [[NSView alloc] initWithFrame:bounds]; | ||||||
|  |     [parent_view addSubview:host->view_]; | ||||||
|  |  | ||||||
|  |     host->webwidget_ = WebPopupMenu::create(client); | ||||||
|  |     host->webwidget_->resize(WebSize(NSWidth(bounds), NSHeight(bounds))); | ||||||
|  |   } else { | ||||||
|  |     host->paint_delegate_ = paint_delegate; | ||||||
|  |     host->view_ = nil; | ||||||
|  |     host->webwidget_ = WebPopupMenu::create(client); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   host->painting_  = false; |  | ||||||
|   host->layouting_ = false; |  | ||||||
|   host->webwidget_ = WebPopupMenu::create(client); |  | ||||||
|   host->webwidget_->resize(WebSize(NSWidth(bounds), NSHeight(bounds))); |  | ||||||
|   return host; |   return host; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -66,6 +84,9 @@ WebWidgetHost::WebWidgetHost() | |||||||
|       popup_(false), |       popup_(false), | ||||||
|       has_update_task_(false), |       has_update_task_(false), | ||||||
|       has_invalidate_task_(false), |       has_invalidate_task_(false), | ||||||
|  |       mouse_modifiers_(0), | ||||||
|  |       painting_(false), | ||||||
|  |       layouting_(false), | ||||||
|       ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { |       ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { | ||||||
|   set_painting(false); |   set_painting(false); | ||||||
| } | } | ||||||
| @@ -74,21 +95,38 @@ WebWidgetHost::~WebWidgetHost() { | |||||||
| } | } | ||||||
|  |  | ||||||
| void WebWidgetHost::DidInvalidateRect(const gfx::Rect& damaged_rect) { | void WebWidgetHost::DidInvalidateRect(const gfx::Rect& damaged_rect) { | ||||||
|   const gfx::Rect client_rect(NSRectToCGRect([view_ bounds])); |   int width, height; | ||||||
|  |   GetSize(width, height); | ||||||
|  |   const gfx::Rect client_rect(width, height); | ||||||
|  |  | ||||||
|   const gfx::Rect damaged_rect_in_client = client_rect.Intersect(damaged_rect); |   const gfx::Rect damaged_rect_in_client = client_rect.Intersect(damaged_rect); | ||||||
|  |  | ||||||
|   if (!damaged_rect_in_client.IsEmpty()) { |   if (!damaged_rect_in_client.IsEmpty()) { | ||||||
|     UpdatePaintRect(damaged_rect_in_client); |     UpdatePaintRect(damaged_rect_in_client); | ||||||
|     NSRect cocoa_rect = NSRectFromCGRect(damaged_rect_in_client.ToCGRect()); |  | ||||||
|     cocoa_rect.origin.y = client_rect.height() - NSMaxY(cocoa_rect); |     if (view_) { | ||||||
|     [view_ setNeedsDisplayInRect:cocoa_rect]; |       NSRect cocoa_rect = NSRectFromCGRect(damaged_rect_in_client.ToCGRect()); | ||||||
|  |       cocoa_rect.origin.y = client_rect.height() - NSMaxY(cocoa_rect); | ||||||
|  |       [view_ setNeedsDisplayInRect:cocoa_rect]; | ||||||
|  |     } else { | ||||||
|  |       // Don't post a paint task if this invalidation occurred during layout or | ||||||
|  |       // if a paint task is already pending. Paint() will be called by | ||||||
|  |       // DoPaint(). | ||||||
|  |       if (!layouting_ && !has_update_task_) { | ||||||
|  |         has_update_task_ = true; | ||||||
|  |         CefThread::PostTask(CefThread::UI, FROM_HERE, | ||||||
|  |             base::Bind(&WebWidgetHost::DoPaint, weak_factory_.GetWeakPtr())); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void WebWidgetHost::DidScrollRect(int dx, int dy, const gfx::Rect& clip_rect) { | void WebWidgetHost::DidScrollRect(int dx, int dy, const gfx::Rect& clip_rect) { | ||||||
|   DCHECK(dx || dy); |   DCHECK(dx || dy); | ||||||
|  |  | ||||||
|   const gfx::Rect client_rect(NSRectToCGRect([view_ bounds])); |   int width, height; | ||||||
|  |   GetSize(width, height); | ||||||
|  |   const gfx::Rect client_rect(width, height); | ||||||
|   gfx::Rect rect = clip_rect.Intersect(client_rect); |   gfx::Rect rect = clip_rect.Intersect(client_rect); | ||||||
|  |  | ||||||
|   const int x = rect.x(); |   const int x = rect.x(); | ||||||
| @@ -106,7 +144,8 @@ void WebWidgetHost::DidScrollRect(int dx, int dy, const gfx::Rect& clip_rect) { | |||||||
|   // needs to be laid out; calling scrollRect:by: in this situation leads to |   // needs to be laid out; calling scrollRect:by: in this situation leads to | ||||||
|   // unwanted behavior. Finally, scrolling the rectangle by more than the size |   // unwanted behavior. Finally, scrolling the rectangle by more than the size | ||||||
|   // of the view means we can just invalidate the entire scroll rect. |   // of the view means we can just invalidate the entire scroll rect. | ||||||
|   if (![view_ canDraw] || painting_ || layouting_ || Dx >= w || Dy >= h) { |   if (!view_ || [view_ canDraw] || painting_ || layouting_ || Dx >= w || | ||||||
|  |       Dy >= h) { | ||||||
|     DidInvalidateRect(clip_rect); |     DidInvalidateRect(clip_rect); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
| @@ -144,36 +183,56 @@ void WebWidgetHost::DidScrollRect(int dx, int dy, const gfx::Rect& clip_rect) { | |||||||
| } | } | ||||||
|  |  | ||||||
| void WebWidgetHost::Paint(SkRegion& update_rgn) { | void WebWidgetHost::Paint(SkRegion& update_rgn) { | ||||||
|   gfx::Rect client_rect(NSRectToCGRect([view_ bounds])); |   int width, height; | ||||||
|  |   GetSize(width, height); | ||||||
|  |   gfx::Rect client_rect(width, height); | ||||||
|  |  | ||||||
|   // Union the rectangle that WebKit think needs repainting with the rectangle |   SkRegion damaged_rgn; | ||||||
|   // of the view that must be painted now. In most situations this will not |   if (!view_ && !redraw_rect_.IsEmpty()) { | ||||||
|   // affect the painted rectangle. In some situations we could end up re- |     // At a minimum we need to send the delegate the rectangle that was | ||||||
|   // painting areas that are already in the canvas and only dirty in the view |     // requested by calling CefBrowser::InvalidateRect(). | ||||||
|   // itself. However, if we don't do this we can get artifacts when scrolling |     damaged_rgn.setRect(convertToSkiaRect(redraw_rect_)); | ||||||
|   // because contents of the canvas are no longer correct after scrolling only |     redraw_rect_ = gfx::Rect(); | ||||||
|   // in the view. |   } | ||||||
|   paint_rgn_.op(update_rgn, SkRegion::kUnion_Op); |  | ||||||
|  |  | ||||||
|   // When we are not using accelerated compositing the canvas area is allowed |   if (view_) { | ||||||
|   // to differ in size from the client by a certain number of pixels (128 in |     // Union the rectangle that WebKit think needs repainting with the rectangle | ||||||
|   // this case). When accelerated compositing is in effect the size must match |     // of the view that must be painted now. In most situations this will not | ||||||
|   // exactly. |     // affect the painted rectangle. In some situations we could end up re- | ||||||
|   const int extra_w = (webwidget_->isAcceleratedCompositingActive()? 0: 128); |     // painting areas that are already in the canvas and only dirty in the view | ||||||
|   const int extra_h = (webwidget_->isAcceleratedCompositingActive()? 0: 128); |     // itself. However, if we don't do this we can get artifacts when scrolling | ||||||
|   const int min_w = client_rect.width(); |     // because contents of the canvas are no longer correct after scrolling only | ||||||
|   const int min_h = client_rect.height(); |     // in the view. | ||||||
|   const int max_w = client_rect.width()  + extra_w * 2; |     paint_rgn_.op(update_rgn, SkRegion::kUnion_Op); | ||||||
|   const int max_h = client_rect.height() + extra_h * 2; |  | ||||||
|  |  | ||||||
|   const bool too_small = (canvas_w_ < min_w || canvas_h_ < min_h); |     // When we are not using accelerated compositing the canvas area is allowed | ||||||
|   const bool too_large = (canvas_w_ > max_w || canvas_h_ > max_h); |     // to differ in size from the client by a certain number of pixels (128 in | ||||||
|  |     // this case). When accelerated compositing is in effect the size must match | ||||||
|  |     // exactly. | ||||||
|  |     const int extra_w = (webwidget_->isAcceleratedCompositingActive()? 0: 128); | ||||||
|  |     const int extra_h = (webwidget_->isAcceleratedCompositingActive()? 0: 128); | ||||||
|  |     const int min_w = client_rect.width(); | ||||||
|  |     const int min_h = client_rect.height(); | ||||||
|  |     const int max_w = client_rect.width()  + extra_w * 2; | ||||||
|  |     const int max_h = client_rect.height() + extra_h * 2; | ||||||
|  |  | ||||||
|   if (!canvas_.get() || too_small || too_large) { |     const bool too_small = (canvas_w_ < min_w || canvas_h_ < min_h); | ||||||
|     canvas_w_ = client_rect.width()  + extra_w; |     const bool too_large = (canvas_w_ > max_w || canvas_h_ > max_h); | ||||||
|     canvas_h_ = client_rect.height() + extra_h; |  | ||||||
|     canvas_.reset(new skia::PlatformCanvas(canvas_w_, canvas_h_, true)); |     if (!canvas_.get() || too_small || too_large) { | ||||||
|  |       canvas_w_ = client_rect.width()  + extra_w; | ||||||
|  |       canvas_h_ = client_rect.height() + extra_h; | ||||||
|  |       canvas_.reset(new skia::PlatformCanvas(canvas_w_, canvas_h_, true)); | ||||||
|  |       paint_rgn_.setRect(convertToSkiaRect(client_rect)); | ||||||
|  |     } | ||||||
|  |   } else if (!canvas_.get() || canvas_w_ != client_rect.width() || | ||||||
|  |              canvas_h_ != client_rect.height()) { | ||||||
|     paint_rgn_.setRect(convertToSkiaRect(client_rect)); |     paint_rgn_.setRect(convertToSkiaRect(client_rect)); | ||||||
|  |  | ||||||
|  |     // The canvas must be the exact size of the client area. | ||||||
|  |     canvas_w_ = client_rect.width(); | ||||||
|  |     canvas_h_ = client_rect.height(); | ||||||
|  |     canvas_.reset(new skia::PlatformCanvas(canvas_w_, canvas_h_, true)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   webwidget_->animate(0.0); |   webwidget_->animate(0.0); | ||||||
| @@ -202,28 +261,69 @@ void WebWidgetHost::Paint(SkRegion& update_rgn) { | |||||||
|     draw_rgn.swap(paint_rgn_); |     draw_rgn.swap(paint_rgn_); | ||||||
|  |  | ||||||
|     SkRegion::Cliperator iterator(draw_rgn, convertToSkiaRect(client_rect)); |     SkRegion::Cliperator iterator(draw_rgn, convertToSkiaRect(client_rect)); | ||||||
|     for (; !iterator.done(); iterator.next()) |     for (; !iterator.done(); iterator.next()) { | ||||||
|       PaintRect(convertFromSkiaRect(iterator.rect())); |       const SkIRect& r = iterator.rect(); | ||||||
|  |       PaintRect(convertFromSkiaRect(r)); | ||||||
|  |  | ||||||
|     // If any more rectangles were made dirty during the paint operation, make |       if (!view_) | ||||||
|     // sure they are copied to the window buffer, by including the paint region. |         damaged_rgn.op(r, SkRegion::kUnion_Op); | ||||||
|     // If nothing needs additional painting, this is a no-op. |     } | ||||||
|     update_rgn.op(paint_rgn_, SkRegion::kUnion_Op); |  | ||||||
|  |     if (view_) { | ||||||
|  |       // If any more rectangles were made dirty during the paint operation, make | ||||||
|  |       // sure they are copied to the window buffer, by including the paint | ||||||
|  |       // region. If nothing needs additional painting, this is a no-op. | ||||||
|  |       update_rgn.op(paint_rgn_, SkRegion::kUnion_Op); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   if (!view_ && plugin_map_.size() > 0) { | ||||||
|  |     // Flash seems to stop calling NPN_InvalidateRect, which means we stop | ||||||
|  |     // painting. If we've got a plugin make sure we paint its rect each time. | ||||||
|  |  | ||||||
|  |     PluginMap::const_iterator it = plugin_map_.begin(); | ||||||
|  |     for (; it != plugin_map_.end(); ++it) { | ||||||
|  |       if (it->second.visible && | ||||||
|  |           client_rect.Intersects(it->second.window_rect)) { | ||||||
|  |         const WebPluginGeometry* geom = &it->second; | ||||||
|  |         damaged_rgn.op(convertToSkiaRect(geom->window_rect), | ||||||
|  |                        SkRegion::kUnion_Op); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // Set the context back to our view and copy the bitmap that we just painted |   if (view_) { | ||||||
|   // into to the view. Only the regions that were updated are copied. |     // Set the context back to our view and copy the bitmap that we just painted | ||||||
|   [NSGraphicsContext restoreGraphicsState]; |     // into to the view. Only the regions that were updated are copied. | ||||||
|   NSGraphicsContext* view_context = [NSGraphicsContext currentContext]; |     [NSGraphicsContext restoreGraphicsState]; | ||||||
|   CGContextRef context = static_cast<CGContextRef>([view_context graphicsPort]); |     NSGraphicsContext* view_context = [NSGraphicsContext currentContext]; | ||||||
|  |     CGContextRef context = | ||||||
|  |         static_cast<CGContextRef>([view_context graphicsPort]); | ||||||
|  |  | ||||||
|   SkRegion::Cliperator iterator(update_rgn, convertToSkiaRect(client_rect)); |     SkRegion::Cliperator iterator(update_rgn, convertToSkiaRect(client_rect)); | ||||||
|   for (; !iterator.done(); iterator.next()) { |     for (; !iterator.done(); iterator.next()) { | ||||||
|     const SkIRect& r = iterator.rect(); |       const SkIRect& r = iterator.rect(); | ||||||
|     CGRect copy_rect = { { r.x(), r.y() }, { r.width(), r.height() } }; |       CGRect copy_rect = { { r.x(), r.y() }, { r.width(), r.height() } }; | ||||||
|     const float x = r.x(); |       const float x = r.x(); | ||||||
|     const float y = client_rect.height() - r.bottom(); |       const float y = client_rect.height() - r.bottom(); | ||||||
|     skia::DrawToNativeContext(canvas_.get(), context, x, y, ©_rect); |       skia::DrawToNativeContext(canvas_.get(), context, x, y, ©_rect); | ||||||
|  |     } | ||||||
|  |   } else { | ||||||
|  |     // Paint to the delegate. | ||||||
|  |     DCHECK(paint_delegate_); | ||||||
|  |     const SkBitmap& bitmap = canvas_->getDevice()->accessBitmap(false); | ||||||
|  |     DCHECK(bitmap.config() == SkBitmap::kARGB_8888_Config); | ||||||
|  |     const void* pixels = bitmap.getPixels(); | ||||||
|  |  | ||||||
|  |     std::vector<CefRect> damaged_rects; | ||||||
|  |     SkRegion::Cliperator iterator(damaged_rgn, convertToSkiaRect(client_rect)); | ||||||
|  |     for (; !iterator.done(); iterator.next()) { | ||||||
|  |       const SkIRect& r = iterator.rect(); | ||||||
|  |       damaged_rects.push_back( | ||||||
|  |           CefRect(r.left(), r.top(), r.width(), r.height())); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     paint_delegate_->Paint(popup_, damaged_rects, pixels); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // Used with scheduled invalidation to maintain a consistent frame rate. |   // Used with scheduled invalidation to maintain a consistent frame rate. | ||||||
| @@ -233,7 +333,12 @@ void WebWidgetHost::Paint(SkRegion& update_rgn) { | |||||||
| } | } | ||||||
|  |  | ||||||
| void WebWidgetHost::Invalidate() { | void WebWidgetHost::Invalidate() { | ||||||
|   [view_ setNeedsDisplay:YES]; |   if (view_) { | ||||||
|  |     [view_ setNeedsDisplay:YES]; | ||||||
|  |   } else if (webwidget_) { | ||||||
|  |     WebSize size = webwidget_->size(); | ||||||
|  |     InvalidateRect(gfx::Rect(0, 0, size.width, size.height)); | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void WebWidgetHost::SetTooltipText(const CefString& tooltip_text) { | void WebWidgetHost::SetTooltipText(const CefString& tooltip_text) { | ||||||
| @@ -241,17 +346,50 @@ void WebWidgetHost::SetTooltipText(const CefString& tooltip_text) { | |||||||
| } | } | ||||||
|  |  | ||||||
| void WebWidgetHost::InvalidateRect(const gfx::Rect& rect) { | void WebWidgetHost::InvalidateRect(const gfx::Rect& rect) { | ||||||
|   // TODO(port): Implement this method as part of off-screen rendering support. |   if (rect.IsEmpty()) | ||||||
|   NOTIMPLEMENTED(); |     return; | ||||||
|  |  | ||||||
|  |   if (!view_) { | ||||||
|  |     // Don't post a paint task if this invalidation occurred during layout or if | ||||||
|  |     // a paint task is already pending. Paint() will be called by DoPaint(). | ||||||
|  |     if (!layouting_ && !has_update_task_) { | ||||||
|  |       has_update_task_ = true; | ||||||
|  |       CefThread::PostTask(CefThread::UI, FROM_HERE, | ||||||
|  |           base::Bind(&WebWidgetHost::DoPaint, weak_factory_.GetWeakPtr())); | ||||||
|  |     } | ||||||
|  |   } else { | ||||||
|  |     NOTIMPLEMENTED(); | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| bool WebWidgetHost::GetImage(int width, int height, void* rgba_buffer) { | bool WebWidgetHost::GetImage(int width, int height, void* rgba_buffer) { | ||||||
|   if (!canvas_.get()) |   if (!canvas_.get()) | ||||||
|     return false; |     return false; | ||||||
|  |  | ||||||
|   // TODO(port): Implement this method as part of off-screen rendering support. |   const SkBitmap& bitmap = canvas_->getDevice()->accessBitmap(false); | ||||||
|   NOTIMPLEMENTED(); |   DCHECK(bitmap.config() == SkBitmap::kARGB_8888_Config); | ||||||
|   return false; |  | ||||||
|  |   if (width == canvas_->getDevice()->width() && | ||||||
|  |       height == canvas_->getDevice()->height()) { | ||||||
|  |     // The specified width and height values are the same as the canvas size. | ||||||
|  |     // Return the existing canvas contents. | ||||||
|  |     const void* pixels = bitmap.getPixels(); | ||||||
|  |     memcpy(rgba_buffer, pixels, width * height * 4); | ||||||
|  |     return true; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Create a new canvas of the requested size. | ||||||
|  |   scoped_ptr<skia::PlatformCanvas> new_canvas( | ||||||
|  |       new skia::PlatformCanvas(width, height, true)); | ||||||
|  |  | ||||||
|  |   new_canvas->writePixels(bitmap, 0, 0); | ||||||
|  |   const SkBitmap& new_bitmap = new_canvas->getDevice()->accessBitmap(false); | ||||||
|  |   DCHECK(new_bitmap.config() == SkBitmap::kARGB_8888_Config); | ||||||
|  |  | ||||||
|  |   // Return the new canvas contents. | ||||||
|  |   const void* pixels = new_bitmap.getPixels(); | ||||||
|  |   memcpy(rgba_buffer, pixels, width * height * 4); | ||||||
|  |   return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| WebScreenInfo WebWidgetHost::GetScreenInfo() { | WebScreenInfo WebWidgetHost::GetScreenInfo() { | ||||||
| @@ -326,44 +464,213 @@ void WebWidgetHost::PaintRect(const gfx::Rect& rect) { | |||||||
| #endif | #endif | ||||||
|   DCHECK(canvas_.get()); |   DCHECK(canvas_.get()); | ||||||
|  |  | ||||||
|   if (!rect.IsEmpty()) { |   if (rect.IsEmpty()) | ||||||
|     set_painting(true); |     return; | ||||||
|     webwidget_->paint(webkit_glue::ToWebCanvas(canvas_.get()), rect); |  | ||||||
|     set_painting(false); |   if (!popup() && ((WebKit::WebView*)webwidget_)->isTransparent()) { | ||||||
|  |     // When using transparency mode clear the rectangle before painting. | ||||||
|  |     SkPaint clearpaint; | ||||||
|  |     clearpaint.setARGB(0, 0, 0, 0); | ||||||
|  |     clearpaint.setXfermodeMode(SkXfermode::kClear_Mode); | ||||||
|  |  | ||||||
|  |     SkRect skrc; | ||||||
|  |     skrc.set(rect.x(), rect.y(), rect.right(), rect.bottom()); | ||||||
|  |     canvas_->drawRect(skrc, clearpaint); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   set_painting(true); | ||||||
|  |   webwidget_->paint(webkit_glue::ToWebCanvas(canvas_.get()), rect); | ||||||
|  |   set_painting(false); | ||||||
| } | } | ||||||
|  |  | ||||||
| void WebWidgetHost::SendKeyEvent(cef_key_type_t type, int key, int modifiers, | void WebWidgetHost::SendKeyEvent(cef_key_type_t type, | ||||||
|                                  bool sysChar, bool imeChar) { |                                  const cef_key_info_t& keyInfo, | ||||||
|   // TODO(port): Implement this method as part of off-screen rendering support. |                                  int modifiers) { | ||||||
|   NOTIMPLEMENTED(); |   WebKeyboardEvent event; | ||||||
|  |  | ||||||
|  |   switch (type) { | ||||||
|  |     case KT_KEYUP: | ||||||
|  |     default: | ||||||
|  |       event.type = WebInputEvent::KeyUp; | ||||||
|  |       break; | ||||||
|  |     case KT_KEYDOWN: | ||||||
|  |       event.type = WebInputEvent::RawKeyDown; | ||||||
|  |       break; | ||||||
|  |     case KT_CHAR: | ||||||
|  |       event.type = WebInputEvent::Char; | ||||||
|  |       break; | ||||||
|  |   } | ||||||
|  |   event.timeStampSeconds = TickCount();	 | ||||||
|  |  | ||||||
|  |   if (modifiers & KEY_SHIFT) | ||||||
|  |     event.modifiers |= WebInputEvent::ShiftKey; | ||||||
|  |   if (modifiers & KEY_ALT) | ||||||
|  |     event.modifiers |= WebInputEvent::AltKey; | ||||||
|  |   if (modifiers & KEY_CTRL) | ||||||
|  |     event.modifiers |= WebInputEvent::ControlKey; | ||||||
|  |   if (modifiers & KEY_META) | ||||||
|  |     event.modifiers |= WebInputEvent::MetaKey; | ||||||
|  |   if (modifiers & KEY_KEYPAD) | ||||||
|  |     event.modifiers |= WebInputEvent::IsKeyPad; | ||||||
|  |  | ||||||
|  |   // There are several kinds of characters for which we produce key code from | ||||||
|  |   // char code: | ||||||
|  |   // 1. Roman letters. Windows keyboard layouts affect both virtual key codes | ||||||
|  |   //    and character codes for these, so e.g. 'A' gets the same keyCode on | ||||||
|  |   //    QWERTY, AZERTY or Dvorak layouts. | ||||||
|  |   // 2. Keys for which there is no known Mac virtual key codes, like | ||||||
|  |   //    PrintScreen. | ||||||
|  |   // 3. Certain punctuation keys. On Windows, these are also remapped depending | ||||||
|  |   //    on current keyboard layout, but see comment in | ||||||
|  |   //    windowsKeyCodeForCharCode(). | ||||||
|  |  | ||||||
|  |   if (type == KT_KEYUP || type == KT_KEYDOWN) { | ||||||
|  |     if (keyInfo.character != 0) { | ||||||
|  |       // Cmd switches Roman letters for Dvorak-QWERTY layout, so try modified | ||||||
|  |       // characters first. | ||||||
|  |       event.windowsKeyCode = | ||||||
|  |           WebCore::windowsKeyCodeForCharCode(keyInfo.character); | ||||||
|  |     } | ||||||
|  |     if (event.windowsKeyCode == 0 && keyInfo.characterNoModifiers != 0) { | ||||||
|  |       // Ctrl+A on an AZERTY keyboard would get VK_Q keyCode if we relied on | ||||||
|  |       // keyInfo.keyCode below. | ||||||
|  |       event.windowsKeyCode = | ||||||
|  |           WebCore::windowsKeyCodeForCharCode(keyInfo.characterNoModifiers); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (event.windowsKeyCode == 0) { | ||||||
|  |     // Map Mac virtual key code directly to Windows one for any keys not handled | ||||||
|  |     // above. E.g. the key next to Caps Lock has the same Event.keyCode on U.S. | ||||||
|  |     // keyboard ('A') and on Russian keyboard (CYRILLIC LETTER EF). | ||||||
|  |     event.windowsKeyCode = WebCore::windowsKeyCodeForKeyCode(keyInfo.keyCode); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   event.nativeKeyCode = keyInfo.keyCode; | ||||||
|  |  | ||||||
|  |   int textChar = keyInfo.character; | ||||||
|  |   int unmodifiedChar = keyInfo.characterNoModifiers; | ||||||
|  |  | ||||||
|  |   // Always use 13 for Enter/Return -- we don't want to use AppKit's | ||||||
|  |   // different character for Enter. | ||||||
|  |   if (event.windowsKeyCode == '\r') { | ||||||
|  |     textChar = '\r'; | ||||||
|  |     unmodifiedChar = '\r'; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // The adjustments below are only needed in backward compatibility mode, | ||||||
|  |   // but we cannot tell what mode we are in from here. | ||||||
|  |  | ||||||
|  |   // Turn 0x7F into 8, because backspace needs to always be 8. | ||||||
|  |   if (textChar == '\x7F') | ||||||
|  |     textChar = '\x8'; | ||||||
|  |   if (unmodifiedChar == '\x7F') | ||||||
|  |     unmodifiedChar = '\x8'; | ||||||
|  |   // Always use 9 for tab -- we don't want to use AppKit's different character | ||||||
|  |   // for shift-tab. | ||||||
|  |   if (event.windowsKeyCode == 9) { | ||||||
|  |     textChar = '\x9'; | ||||||
|  |     unmodifiedChar = '\x9'; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   event.text[0] = textChar; | ||||||
|  |   event.unmodifiedText[0] = unmodifiedChar; | ||||||
|  |  | ||||||
|  |   event.setKeyIdentifierFromWindowsKeyCode(); | ||||||
|  |  | ||||||
|  |   event.isSystemKey = !!(modifiers & KEY_META); | ||||||
|  |  | ||||||
|  |   last_key_event_ = event; | ||||||
|  |  | ||||||
|  |   webwidget_->handleInputEvent(event); | ||||||
| } | } | ||||||
|  |  | ||||||
| void WebWidgetHost::SendMouseClickEvent(int x, int y, | void WebWidgetHost::SendMouseClickEvent(int x, int y, | ||||||
|                                         cef_mouse_button_type_t type, |                                         cef_mouse_button_type_t type, | ||||||
|                                         bool mouseUp, int clickCount) { |                                         bool mouseUp, int clickCount) { | ||||||
|   // TODO(port): Implement this method as part of off-screen rendering support. |   WebMouseEvent event; | ||||||
|   NOTIMPLEMENTED(); |  | ||||||
|  |   switch(type) { | ||||||
|  |     case MBT_LEFT: | ||||||
|  |       event.button = WebMouseEvent::ButtonLeft; | ||||||
|  |       event.modifiers |= WebInputEvent::LeftButtonDown; | ||||||
|  |       break; | ||||||
|  |     case MBT_MIDDLE: | ||||||
|  |       event.button = WebMouseEvent::ButtonMiddle; | ||||||
|  |       event.modifiers |= WebInputEvent::MiddleButtonDown; | ||||||
|  |       break; | ||||||
|  |     case MBT_RIGHT: | ||||||
|  |       event.button = WebMouseEvent::ButtonRight; | ||||||
|  |       event.modifiers |= WebInputEvent::RightButtonDown; | ||||||
|  |       break; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (mouseUp) | ||||||
|  |     event.type = WebInputEvent::MouseUp; | ||||||
|  |   else | ||||||
|  |     event.type = WebInputEvent::MouseDown; | ||||||
|  |  | ||||||
|  |   event.clickCount = clickCount; | ||||||
|  |   event.timeStampSeconds = TickCount();	 | ||||||
|  |   event.x = x; | ||||||
|  |   event.y = y; | ||||||
|  |   event.windowX = event.x; | ||||||
|  |   event.windowY = event.y; | ||||||
|  |  | ||||||
|  |   if (mouseUp) { | ||||||
|  |     mouse_button_down_ = WebMouseEvent::ButtonNone; | ||||||
|  |     mouse_modifiers_ &= ~event.modifiers; | ||||||
|  |   } else { | ||||||
|  |     mouse_modifiers_ |= event.modifiers; | ||||||
|  |     mouse_button_down_ = event.button; | ||||||
|  |   } | ||||||
|  |   event.modifiers = mouse_modifiers_; | ||||||
|  |  | ||||||
|  |   webwidget_->handleInputEvent(event); | ||||||
| } | } | ||||||
|  |  | ||||||
| void WebWidgetHost::SendMouseMoveEvent(int x, int y, bool mouseLeave) { | void WebWidgetHost::SendMouseMoveEvent(int x, int y, bool mouseLeave) { | ||||||
|   // TODO(port): Implement this method as part of off-screen rendering support. |   WebMouseEvent event; | ||||||
|   NOTIMPLEMENTED(); |  | ||||||
|  |   event.type = WebInputEvent::MouseMove; | ||||||
|  |   event.timeStampSeconds = TickCount(); | ||||||
|  |   event.button = mouse_button_down_; | ||||||
|  |   event.x = x; | ||||||
|  |   event.y = y; | ||||||
|  |   event.windowX = event.x; | ||||||
|  |   event.windowY = event.y; | ||||||
|  |   event.modifiers = mouse_modifiers_; | ||||||
|  |  | ||||||
|  |   webwidget_->handleInputEvent(event); | ||||||
| } | } | ||||||
|  |  | ||||||
| void WebWidgetHost::SendMouseWheelEvent(int x, int y, int delta) { | void WebWidgetHost::SendMouseWheelEvent(int x, int y, int deltaX, int deltaY) { | ||||||
|   // TODO(port): Implement this method as part of off-screen rendering support. |   WebMouseWheelEvent event; | ||||||
|   NOTIMPLEMENTED(); |  | ||||||
|  |   // Conversion between wheel delta amounts and number of pixels to scroll. | ||||||
|  |   static const double scrollbarPixelsPerCocoaTick = 40.0; | ||||||
|  |  | ||||||
|  |   event.type = WebInputEvent::MouseWheel; | ||||||
|  |   event.timeStampSeconds = TickCount(); | ||||||
|  |   event.button = WebMouseEvent::ButtonNone; | ||||||
|  |   event.deltaX = static_cast<float>(deltaX); | ||||||
|  |   event.deltaY = static_cast<float>(deltaY); | ||||||
|  |   event.wheelTicksX = static_cast<float>(deltaX/scrollbarPixelsPerCocoaTick); | ||||||
|  |   event.wheelTicksY = static_cast<float>(deltaY/scrollbarPixelsPerCocoaTick); | ||||||
|  |   event.hasPreciseScrollingDeltas = true; | ||||||
|  |   event.x = x; | ||||||
|  |   event.y = y; | ||||||
|  |   event.windowX = event.x; | ||||||
|  |   event.windowY = event.y; | ||||||
|  |  | ||||||
|  |   webwidget_->handleInputEvent(event); | ||||||
| } | } | ||||||
|  |  | ||||||
| void WebWidgetHost::SendFocusEvent(bool setFocus) { | void WebWidgetHost::SendFocusEvent(bool setFocus) { | ||||||
|   // TODO(port): Implement this method as part of off-screen rendering support. |   SetFocus(setFocus); | ||||||
|   NOTIMPLEMENTED(); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void WebWidgetHost::SendCaptureLostEvent() { | void WebWidgetHost::SendCaptureLostEvent() { | ||||||
|   // TODO(port): Implement this method as part of off-screen rendering support. |  | ||||||
|   NOTIMPLEMENTED(); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void WebWidgetHost::EnsureTooltip() { | void WebWidgetHost::EnsureTooltip() { | ||||||
|   | |||||||
| @@ -777,30 +777,31 @@ void WebWidgetHost::PaintRect(const gfx::Rect& rect) { | |||||||
|   set_painting(false); |   set_painting(false); | ||||||
| } | } | ||||||
|  |  | ||||||
| void WebWidgetHost::SendKeyEvent(cef_key_type_t type, int key, int modifiers, | void WebWidgetHost::SendKeyEvent(cef_key_type_t type, | ||||||
|                                  bool sysChar, bool imeChar) { |                                  const cef_key_info_t& keyInfo, | ||||||
|  |                                  int modifiers) { | ||||||
|   UINT message = 0; |   UINT message = 0; | ||||||
|   WPARAM wparam = key; |   WPARAM wparam = keyInfo.key; | ||||||
|   LPARAM lparam = modifiers; |   LPARAM lparam = modifiers; | ||||||
|  |  | ||||||
|   if (type == KT_KEYUP) { |   if (type == KT_KEYUP) { | ||||||
|     if (sysChar) |     if (keyInfo.sysChar) | ||||||
|       message = WM_SYSKEYUP; |       message = WM_SYSKEYUP; | ||||||
|     else if (imeChar) |     else if (keyInfo.imeChar) | ||||||
|       message = WM_IME_KEYUP; |       message = WM_IME_KEYUP; | ||||||
|     else |     else | ||||||
|       message = WM_KEYUP; |       message = WM_KEYUP; | ||||||
|   } else if (type == KT_KEYDOWN) { |   } else if (type == KT_KEYDOWN) { | ||||||
|     if (sysChar) |     if (keyInfo.sysChar) | ||||||
|       message = WM_SYSKEYDOWN; |       message = WM_SYSKEYDOWN; | ||||||
|     else if (imeChar) |     else if (keyInfo.imeChar) | ||||||
|       message = WM_IME_KEYDOWN; |       message = WM_IME_KEYDOWN; | ||||||
|     else |     else | ||||||
|       message = WM_KEYDOWN; |       message = WM_KEYDOWN; | ||||||
|   } else if (type == KT_CHAR) { |   } else if (type == KT_CHAR) { | ||||||
|     if (sysChar) |     if (keyInfo.sysChar) | ||||||
|       message = WM_SYSCHAR; |       message = WM_SYSCHAR; | ||||||
|     else if (imeChar) |     else if (keyInfo.imeChar) | ||||||
|       message = WM_IME_CHAR; |       message = WM_IME_CHAR; | ||||||
|     else |     else | ||||||
|       message = WM_CHAR; |       message = WM_CHAR; | ||||||
| @@ -903,8 +904,8 @@ void WebWidgetHost::SendMouseMoveEvent(int x, int y, bool mouseLeave) { | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| void WebWidgetHost::SendMouseWheelEvent(int x, int y, int delta) { | void WebWidgetHost::SendMouseWheelEvent(int x, int y, int deltaX, int deltaY) { | ||||||
|   WPARAM wparam = MAKEWPARAM(0, delta); |   WPARAM wparam = MAKEWPARAM(0, deltaY); | ||||||
|   LPARAM lparam = MAKELPARAM(x, y); |   LPARAM lparam = MAKELPARAM(x, y); | ||||||
|  |  | ||||||
|   if (GetKeyState(VK_CONTROL) & 0x8000) |   if (GetKeyState(VK_CONTROL) & 0x8000) | ||||||
|   | |||||||
| @@ -606,21 +606,28 @@ int CEF_CALLBACK browser_get_image(struct _cef_browser_t* self, | |||||||
| } | } | ||||||
|  |  | ||||||
| void CEF_CALLBACK browser_send_key_event(struct _cef_browser_t* self, | void CEF_CALLBACK browser_send_key_event(struct _cef_browser_t* self, | ||||||
|     enum cef_key_type_t type, int key, int modifiers, int sysChar, |     enum cef_key_type_t type, const struct _cef_key_info_t* keyInfo, | ||||||
|     int imeChar) { |     int modifiers) { | ||||||
|   // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING |   // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING | ||||||
|  |  | ||||||
|   DCHECK(self); |   DCHECK(self); | ||||||
|   if (!self) |   if (!self) | ||||||
|     return; |     return; | ||||||
|  |   // Verify param: keyInfo; type: struct_byref_const | ||||||
|  |   DCHECK(keyInfo); | ||||||
|  |   if (!keyInfo) | ||||||
|  |     return; | ||||||
|  |  | ||||||
|  |   // Translate param: keyInfo; type: struct_byref_const | ||||||
|  |   CefKeyInfo keyInfoObj; | ||||||
|  |   if (keyInfo) | ||||||
|  |     keyInfoObj.Set(*keyInfo, false); | ||||||
|  |  | ||||||
|   // Execute |   // Execute | ||||||
|   CefBrowserCppToC::Get(self)->SendKeyEvent( |   CefBrowserCppToC::Get(self)->SendKeyEvent( | ||||||
|       type, |       type, | ||||||
|       key, |       keyInfoObj, | ||||||
|       modifiers, |       modifiers); | ||||||
|       sysChar?true:false, |  | ||||||
|       imeChar?true:false); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void CEF_CALLBACK browser_send_mouse_click_event(struct _cef_browser_t* self, | void CEF_CALLBACK browser_send_mouse_click_event(struct _cef_browser_t* self, | ||||||
| @@ -657,7 +664,7 @@ void CEF_CALLBACK browser_send_mouse_move_event(struct _cef_browser_t* self, | |||||||
| } | } | ||||||
|  |  | ||||||
| void CEF_CALLBACK browser_send_mouse_wheel_event(struct _cef_browser_t* self, | void CEF_CALLBACK browser_send_mouse_wheel_event(struct _cef_browser_t* self, | ||||||
|     int x, int y, int delta) { |     int x, int y, int deltaX, int deltaY) { | ||||||
|   // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING |   // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING | ||||||
|  |  | ||||||
|   DCHECK(self); |   DCHECK(self); | ||||||
| @@ -668,7 +675,8 @@ void CEF_CALLBACK browser_send_mouse_wheel_event(struct _cef_browser_t* self, | |||||||
|   CefBrowserCppToC::Get(self)->SendMouseWheelEvent( |   CefBrowserCppToC::Get(self)->SendMouseWheelEvent( | ||||||
|       x, |       x, | ||||||
|       y, |       y, | ||||||
|       delta); |       deltaX, | ||||||
|  |       deltaY); | ||||||
| } | } | ||||||
|  |  | ||||||
| void CEF_CALLBACK browser_send_focus_event(struct _cef_browser_t* self, | void CEF_CALLBACK browser_send_focus_event(struct _cef_browser_t* self, | ||||||
|   | |||||||
| @@ -491,8 +491,8 @@ bool CefBrowserCToCpp::GetImage(PaintElementType type, int width, int height, | |||||||
|   return _retval?true:false; |   return _retval?true:false; | ||||||
| } | } | ||||||
|  |  | ||||||
| void CefBrowserCToCpp::SendKeyEvent(KeyType type, int key, int modifiers, | void CefBrowserCToCpp::SendKeyEvent(KeyType type, const CefKeyInfo& keyInfo, | ||||||
|     bool sysChar, bool imeChar) { |     int modifiers) { | ||||||
|   if (CEF_MEMBER_MISSING(struct_, send_key_event)) |   if (CEF_MEMBER_MISSING(struct_, send_key_event)) | ||||||
|     return; |     return; | ||||||
|  |  | ||||||
| @@ -501,10 +501,8 @@ void CefBrowserCToCpp::SendKeyEvent(KeyType type, int key, int modifiers, | |||||||
|   // Execute |   // Execute | ||||||
|   struct_->send_key_event(struct_, |   struct_->send_key_event(struct_, | ||||||
|       type, |       type, | ||||||
|       key, |       &keyInfo, | ||||||
|       modifiers, |       modifiers); | ||||||
|       sysChar, |  | ||||||
|       imeChar); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void CefBrowserCToCpp::SendMouseClickEvent(int x, int y, MouseButtonType type, | void CefBrowserCToCpp::SendMouseClickEvent(int x, int y, MouseButtonType type, | ||||||
| @@ -536,7 +534,8 @@ void CefBrowserCToCpp::SendMouseMoveEvent(int x, int y, bool mouseLeave) { | |||||||
|       mouseLeave); |       mouseLeave); | ||||||
| } | } | ||||||
|  |  | ||||||
| void CefBrowserCToCpp::SendMouseWheelEvent(int x, int y, int delta) { | void CefBrowserCToCpp::SendMouseWheelEvent(int x, int y, int deltaX, | ||||||
|  |     int deltaY) { | ||||||
|   if (CEF_MEMBER_MISSING(struct_, send_mouse_wheel_event)) |   if (CEF_MEMBER_MISSING(struct_, send_mouse_wheel_event)) | ||||||
|     return; |     return; | ||||||
|  |  | ||||||
| @@ -546,7 +545,8 @@ void CefBrowserCToCpp::SendMouseWheelEvent(int x, int y, int delta) { | |||||||
|   struct_->send_mouse_wheel_event(struct_, |   struct_->send_mouse_wheel_event(struct_, | ||||||
|       x, |       x, | ||||||
|       y, |       y, | ||||||
|       delta); |       deltaX, | ||||||
|  |       deltaY); | ||||||
| } | } | ||||||
|  |  | ||||||
| void CefBrowserCToCpp::SendFocusEvent(bool setFocus) { | void CefBrowserCToCpp::SendFocusEvent(bool setFocus) { | ||||||
|   | |||||||
| @@ -70,12 +70,13 @@ class CefBrowserCToCpp | |||||||
|   virtual void Invalidate(const CefRect& dirtyRect) OVERRIDE; |   virtual void Invalidate(const CefRect& dirtyRect) OVERRIDE; | ||||||
|   virtual bool GetImage(PaintElementType type, int width, int height, |   virtual bool GetImage(PaintElementType type, int width, int height, | ||||||
|       void* buffer) OVERRIDE; |       void* buffer) OVERRIDE; | ||||||
|   virtual void SendKeyEvent(KeyType type, int key, int modifiers, bool sysChar, |   virtual void SendKeyEvent(KeyType type, const CefKeyInfo& keyInfo, | ||||||
|       bool imeChar) OVERRIDE; |       int modifiers) OVERRIDE; | ||||||
|   virtual void SendMouseClickEvent(int x, int y, MouseButtonType type, |   virtual void SendMouseClickEvent(int x, int y, MouseButtonType type, | ||||||
|       bool mouseUp, int clickCount) OVERRIDE; |       bool mouseUp, int clickCount) OVERRIDE; | ||||||
|   virtual void SendMouseMoveEvent(int x, int y, bool mouseLeave) OVERRIDE; |   virtual void SendMouseMoveEvent(int x, int y, bool mouseLeave) OVERRIDE; | ||||||
|   virtual void SendMouseWheelEvent(int x, int y, int delta) OVERRIDE; |   virtual void SendMouseWheelEvent(int x, int y, int deltaX, | ||||||
|  |       int deltaY) OVERRIDE; | ||||||
|   virtual void SendFocusEvent(bool setFocus) OVERRIDE; |   virtual void SendFocusEvent(bool setFocus) OVERRIDE; | ||||||
|   virtual void SendCaptureLostEvent() OVERRIDE; |   virtual void SendCaptureLostEvent() OVERRIDE; | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -18,6 +18,7 @@ patches = [ | |||||||
|   }, |   }, | ||||||
|   { |   { | ||||||
|     # http://code.google.com/p/gyp/issues/detail?id=223 |     # http://code.google.com/p/gyp/issues/detail?id=223 | ||||||
|  |     # http://codereview.chromium.org/10383117/ | ||||||
|     'name': 'tools_gyp', |     'name': 'tools_gyp', | ||||||
|     'path': '../tools/gyp/', |     'path': '../tools/gyp/', | ||||||
|   }, |   }, | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| Index: pylib/gyp/input.py | Index: pylib/gyp/input.py | ||||||
| =================================================================== | =================================================================== | ||||||
| --- pylib/gyp/input.py	(revision 1107) | --- pylib/gyp/input.py	(revision 1323) | ||||||
| +++ pylib/gyp/input.py	(working copy) | +++ pylib/gyp/input.py	(working copy) | ||||||
| @@ -666,7 +666,8 @@ | @@ -666,7 +666,8 @@ | ||||||
|              # that don't load quickly, this can be faster than |              # that don't load quickly, this can be faster than | ||||||
| @@ -12,3 +12,25 @@ Index: pylib/gyp/input.py | |||||||
|   |   | ||||||
|              parsed_contents = shlex.split(contents) |              parsed_contents = shlex.split(contents) | ||||||
|              py_module = __import__(parsed_contents[0]) |              py_module = __import__(parsed_contents[0]) | ||||||
|  | Index: pylib/gyp/mac_tool.py | ||||||
|  | =================================================================== | ||||||
|  | --- pylib/gyp/mac_tool.py	(revision 1323) | ||||||
|  | +++ pylib/gyp/mac_tool.py	(working copy) | ||||||
|  | @@ -54,16 +54,8 @@ | ||||||
|  |        return self._CopyXIBFile(source, dest) | ||||||
|  |      elif extension == '.strings': | ||||||
|  |        self._CopyStringsFile(source, dest) | ||||||
|  | -    # TODO: Given that files with arbitrary extensions can be copied to the | ||||||
|  | -    # bundle, we will want to get rid of this whitelist eventually. | ||||||
|  | -    elif extension in [ | ||||||
|  | -        '.icns', '.manifest', '.pak', '.pdf', '.png', '.sb', '.sh', | ||||||
|  | -        '.ttf', '.sdef']: | ||||||
|  | -      shutil.copyfile(source, dest) | ||||||
|  |      else: | ||||||
|  | -      raise NotImplementedError( | ||||||
|  | -          "Don't know how to copy bundle resources of type %s while copying " | ||||||
|  | -          "%s to %s)" % (extension, source, dest)) | ||||||
|  | +      shutil.copyfile(source, dest) | ||||||
|  |   | ||||||
|  |    def _CopyXIBFile(self, source, dest): | ||||||
|  |      """Compiles a XIB file with ibtool into a binary plist in the bundle.""" | ||||||
|   | |||||||
| @@ -14,6 +14,7 @@ | |||||||
| #include "cefclient/binding_test.h" | #include "cefclient/binding_test.h" | ||||||
| #include "cefclient/client_handler.h" | #include "cefclient/client_handler.h" | ||||||
| #include "cefclient/extension_test.h" | #include "cefclient/extension_test.h" | ||||||
|  | #include "cefclient/osrtest_mac.h" | ||||||
| #include "cefclient/resource_util.h" | #include "cefclient/resource_util.h" | ||||||
| #include "cefclient/scheme_test.h" | #include "cefclient/scheme_test.h" | ||||||
| #include "cefclient/string_util.h" | #include "cefclient/string_util.h" | ||||||
| @@ -212,6 +213,8 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) { | |||||||
| - (IBAction)testDevToolsShow:(id)sender; | - (IBAction)testDevToolsShow:(id)sender; | ||||||
| - (IBAction)testDevToolsClose:(id)sender; | - (IBAction)testDevToolsClose:(id)sender; | ||||||
| - (IBAction)testPluginInfo:(id)sender; | - (IBAction)testPluginInfo:(id)sender; | ||||||
|  | - (IBAction)testOffscreenRendering:(id)sender; | ||||||
|  | - (IBAction)testTransparentOffscreenRendering:(id)sender; | ||||||
| @end | @end | ||||||
|  |  | ||||||
| @implementation ClientAppDelegate | @implementation ClientAppDelegate | ||||||
| @@ -305,6 +308,12 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) { | |||||||
|   [testMenu addItemWithTitle:@"Plugin Info" |   [testMenu addItemWithTitle:@"Plugin Info" | ||||||
|                       action:@selector(testPluginInfo:) |                       action:@selector(testPluginInfo:) | ||||||
|                keyEquivalent:@""]; |                keyEquivalent:@""]; | ||||||
|  |   [testMenu addItemWithTitle:@"Offscreen Rendering" | ||||||
|  |                       action:@selector(testOffscreenRendering:) | ||||||
|  |                keyEquivalent:@""]; | ||||||
|  |   [testMenu addItemWithTitle:@"Transparent Offscreen Rendering" | ||||||
|  |                       action:@selector(testTransparentOffscreenRendering:) | ||||||
|  |                keyEquivalent:@""]; | ||||||
|   [testItem setSubmenu:testMenu]; |   [testItem setSubmenu:testMenu]; | ||||||
|   [menubar addItem:testItem]; |   [menubar addItem:testItem]; | ||||||
|    |    | ||||||
| @@ -531,6 +540,14 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) { | |||||||
|     RunPluginInfoTest(g_handler->GetBrowser()); |     RunPluginInfoTest(g_handler->GetBrowser()); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | - (IBAction)testOffscreenRendering:(id)sender { | ||||||
|  |   osrtest::RunTest(false); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (IBAction)testTransparentOffscreenRendering:(id)sender { | ||||||
|  |   osrtest::RunTest(true); | ||||||
|  | } | ||||||
|  |  | ||||||
| // Sent by the default notification center immediately before the application | // Sent by the default notification center immediately before the application | ||||||
| // terminates. | // terminates. | ||||||
| - (void)applicationWillTerminate:(NSNotification *)aNotification { | - (void)applicationWillTerminate:(NSNotification *)aNotification { | ||||||
|   | |||||||
							
								
								
									
										410
									
								
								cef1/tests/cefclient/osrenderer.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										410
									
								
								cef1/tests/cefclient/osrenderer.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,410 @@ | |||||||
|  | // Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights | ||||||
|  | // reserved. Use of this source code is governed by a BSD-style license | ||||||
|  | // that can be found in the LICENSE file. | ||||||
|  |  | ||||||
|  | #include "cefclient/osrenderer.h" | ||||||
|  | #include "cefclient/util.h" | ||||||
|  |  | ||||||
|  | #if defined(OS_WIN) | ||||||
|  | #include <gl/gl.h> | ||||||
|  | #include <gl/glu.h> | ||||||
|  | #elif defined(OS_MACOSX) | ||||||
|  | #include <OpenGL/gl.h> | ||||||
|  | #else | ||||||
|  | #error Platform is not supported. | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | namespace { | ||||||
|  |  | ||||||
|  | // Convert from BGRA to RGBA format and from upper-left to lower-left origin. | ||||||
|  | void ConvertToRGBA(const unsigned char* src, unsigned char* dst, | ||||||
|  |                    int width, int height) { | ||||||
|  |   int sp = 0, dp = (height-1) * width * 4; | ||||||
|  |   for (int i = 0; i < height; i++) { | ||||||
|  |     for (int j = 0; j < width; j++, dp += 4, sp += 4) { | ||||||
|  |       dst[dp] = src[sp+2];  // R | ||||||
|  |       dst[dp+1] = src[sp+1];  // G | ||||||
|  |       dst[dp+2] = src[sp];  // B | ||||||
|  |       dst[dp+3] = src[sp+3];  // A | ||||||
|  |     } | ||||||
|  |     dp -= width * 8; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ConvertToRGBARect(const CefRect& clipRect, | ||||||
|  |                        const unsigned char* src, unsigned char* dst, | ||||||
|  |                        int width, int height) { | ||||||
|  |   int sp = 0, dp = (height-1) * width * 4; | ||||||
|  |   for (int i = 0; i < height; i++) { | ||||||
|  |     for (int j = 0; j < width; j++, dp += 4, sp += 4) { | ||||||
|  |       if ((clipRect.x <= j) && (clipRect.x + clipRect.width > j) && | ||||||
|  |           (clipRect.y <= i) && (clipRect.y + clipRect.height > i)) { | ||||||
|  |         dst[dp] = src[sp+2];  // R | ||||||
|  |         dst[dp+1] = src[sp+1];  // G | ||||||
|  |         dst[dp+2] = src[sp];  // B | ||||||
|  |         dst[dp+3] = src[sp+3];  // A | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     dp -= width * 8; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Convert from BGRA to RGB format and from upper-left to lower-left origin. | ||||||
|  | void ConvertToRGB(const unsigned char* src, unsigned char* dst, | ||||||
|  |                   int width, int height) { | ||||||
|  |   int sp = 0, dp = (height-1) * width * 3; | ||||||
|  |   for (int i = 0; i < height; i++) { | ||||||
|  |     for (int j = 0; j < width; j++, dp += 3, sp += 4) { | ||||||
|  |       dst[dp] = src[sp+2];  // R | ||||||
|  |       dst[dp+1] = src[sp+1];  // G | ||||||
|  |       dst[dp+2] = src[sp];  // B | ||||||
|  |     } | ||||||
|  |     dp -= width * 6; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ConvertToRGBRect(const CefRect& clipRect, | ||||||
|  |                       const unsigned char* src, unsigned char* dst, | ||||||
|  |                       int width, int height) { | ||||||
|  |   int sp = 0, dp = (height-1) * width * 3; | ||||||
|  |   for (int i = 0; i < height; i++) { | ||||||
|  |     for (int j = 0; j < width; j++, dp += 3, sp += 4) { | ||||||
|  |       if ((clipRect.x <= j) && (clipRect.x + clipRect.width > j) && | ||||||
|  |           (clipRect.y <= i) && (clipRect.y + clipRect.height > i)) { | ||||||
|  |         dst[dp] = src[sp+2];  // R | ||||||
|  |         dst[dp+1] = src[sp+1];  // G | ||||||
|  |         dst[dp+2] = src[sp];  // B | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     dp -= width * 6; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | }  // namespace | ||||||
|  |  | ||||||
|  | ClientOSRenderer::ClientOSRenderer(bool transparent) | ||||||
|  |   : transparent_(transparent), | ||||||
|  |     initialized_(false), | ||||||
|  |     texture_id_(0), | ||||||
|  |     view_buffer_(NULL), | ||||||
|  |     view_buffer_size_(0), | ||||||
|  |     popup_buffer_(NULL), | ||||||
|  |     popup_buffer_size_(0), | ||||||
|  |     view_width_(0), | ||||||
|  |     view_height_(0), | ||||||
|  |     spin_x_(0), | ||||||
|  |     spin_y_(0) { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | ClientOSRenderer::~ClientOSRenderer() { | ||||||
|  |   Cleanup(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ClientOSRenderer::Initialize() { | ||||||
|  |   if (initialized_) | ||||||
|  |     return; | ||||||
|  |  | ||||||
|  |   glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | ||||||
|  |  | ||||||
|  |   // Necessary for non-power-of-2 textures to render correctly. | ||||||
|  |   glPixelStorei(GL_UNPACK_ALIGNMENT, 1); | ||||||
|  |  | ||||||
|  |   if (transparent_) { | ||||||
|  |     // Alpha blending style. | ||||||
|  |     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   initialized_ = true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ClientOSRenderer::Cleanup() { | ||||||
|  |   if (view_buffer_) { | ||||||
|  |     delete [] view_buffer_; | ||||||
|  |     view_buffer_ = NULL; | ||||||
|  |     view_buffer_size_ = 0; | ||||||
|  |   } | ||||||
|  |   if (popup_buffer_) { | ||||||
|  |     delete [] popup_buffer_; | ||||||
|  |     popup_buffer_ = NULL; | ||||||
|  |     popup_buffer_size_ = 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (texture_id_ != 0) | ||||||
|  |     glDeleteTextures(1, &texture_id_); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ClientOSRenderer::SetSize(int width, int height) { | ||||||
|  |   if (!initialized_) | ||||||
|  |     Initialize(); | ||||||
|  |  | ||||||
|  |   // Match GL units to screen coordinates. | ||||||
|  |   glViewport(0, 0, width, height); | ||||||
|  |   glMatrixMode(GL_PROJECTION); | ||||||
|  |   glLoadIdentity(); | ||||||
|  |   glOrtho(0, 0, width, height, 0.1, 100.0); | ||||||
|  |  | ||||||
|  |   if (transparent_) { | ||||||
|  |     // Enable alpha blending. | ||||||
|  |     glEnable(GL_BLEND); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Enable 2D textures. | ||||||
|  |   glEnable(GL_TEXTURE_2D); | ||||||
|  |  | ||||||
|  |   GLuint new_texture_id = 0; | ||||||
|  |  | ||||||
|  |   // Create a new texture. | ||||||
|  |   glGenTextures(1, &new_texture_id); | ||||||
|  |   ASSERT(new_texture_id != 0); | ||||||
|  |   glBindTexture(GL_TEXTURE_2D, new_texture_id); | ||||||
|  |   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||||||
|  |   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||||||
|  |  | ||||||
|  |   // Start with all white contents. | ||||||
|  |   { | ||||||
|  |     int size = width * height * (transparent_?4:3); | ||||||
|  |     unsigned char* buffer = new unsigned char[size]; | ||||||
|  |     memset(buffer, 255, size); | ||||||
|  |  | ||||||
|  |     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, | ||||||
|  |         transparent_?GL_RGBA:GL_RGB, GL_UNSIGNED_BYTE, buffer); | ||||||
|  |  | ||||||
|  |     delete [] buffer; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (texture_id_ != 0) { | ||||||
|  |     // Draw the existing view buffer to the new texture. | ||||||
|  |     DrawViewBuffer(width, height); | ||||||
|  |  | ||||||
|  |     // Delete the old texture. | ||||||
|  |     glDeleteTextures(1, &texture_id_); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   texture_id_ = new_texture_id; | ||||||
|  |  | ||||||
|  |   // Disable 2D textures. | ||||||
|  |   glDisable(GL_TEXTURE_2D); | ||||||
|  |  | ||||||
|  |   if (transparent_) { | ||||||
|  |     // Disable alpha blending. | ||||||
|  |     glDisable(GL_BLEND); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ClientOSRenderer::Render() { | ||||||
|  |   ASSERT(initialized_); | ||||||
|  |  | ||||||
|  |   struct { | ||||||
|  |     float tu, tv; | ||||||
|  |     float x, y, z; | ||||||
|  |   } static vertices[] = { | ||||||
|  |     {0.0f, 0.0f, -1.0f, -1.0f, 0.0f}, | ||||||
|  |     {1.0f, 0.0f,  1.0f, -1.0f, 0.0f}, | ||||||
|  |     {1.0f, 1.0f,  1.0f,  1.0f, 0.0f}, | ||||||
|  |     {0.0f, 1.0f, -1.0f,  1.0f, 0.0f} | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | ||||||
|  |  | ||||||
|  |   glMatrixMode(GL_MODELVIEW); | ||||||
|  |   glLoadIdentity(); | ||||||
|  |  | ||||||
|  |   // Draw the background gradient. | ||||||
|  |   glPushAttrib(GL_ALL_ATTRIB_BITS); | ||||||
|  |   glBegin(GL_QUADS); | ||||||
|  |   glColor4f(1.0, 0.0, 0.0, 1.0);  // red | ||||||
|  |   glVertex2f(-1.0, -1.0); | ||||||
|  |   glVertex2f(1.0, -1.0); | ||||||
|  |   glColor4f(0.0, 0.0, 1.0, 1.0);  // blue | ||||||
|  |   glVertex2f(1.0, 1.0); | ||||||
|  |   glVertex2f(-1.0, 1.0); | ||||||
|  |   glEnd(); | ||||||
|  |   glPopAttrib(); | ||||||
|  |  | ||||||
|  |   // Rotate the view based on the mouse spin. | ||||||
|  |   glRotatef(-spin_x_, 1.0f, 0.0f, 0.0f); | ||||||
|  |   glRotatef(-spin_y_, 0.0f, 1.0f, 0.0f); | ||||||
|  |  | ||||||
|  |   if (transparent_) { | ||||||
|  |     // Enable alpha blending. | ||||||
|  |     glEnable(GL_BLEND); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Enable 2D textures. | ||||||
|  |   glEnable(GL_TEXTURE_2D); | ||||||
|  |  | ||||||
|  |   // Draw the facets with the texture. | ||||||
|  |   ASSERT(texture_id_ != 0); | ||||||
|  |   glBindTexture(GL_TEXTURE_2D, texture_id_); | ||||||
|  |   glInterleavedArrays(GL_T2F_V3F, 0, vertices); | ||||||
|  |   glDrawArrays(GL_QUADS, 0, 4); | ||||||
|  |  | ||||||
|  |   // Disable 2D textures. | ||||||
|  |   glDisable(GL_TEXTURE_2D); | ||||||
|  |  | ||||||
|  |   if (transparent_) { | ||||||
|  |     // Disable alpha blending. | ||||||
|  |     glDisable(GL_BLEND); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   glFlush(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ClientOSRenderer::OnPopupShow(CefRefPtr<CefBrowser> browser, | ||||||
|  |                                    bool show) { | ||||||
|  |   if (!show) { | ||||||
|  |     // Clear the popup buffer. | ||||||
|  |     popup_rect_.Set(0, 0, 0, 0); | ||||||
|  |     if (popup_buffer_) { | ||||||
|  |       delete [] popup_buffer_; | ||||||
|  |       popup_buffer_ = NULL; | ||||||
|  |       popup_buffer_size_ = 0; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ClientOSRenderer::OnPopupSize(CefRefPtr<CefBrowser> browser, | ||||||
|  |                                    const CefRect& rect) { | ||||||
|  |   if (rect.width > 0) { | ||||||
|  |     // Update the popup rectange. It should always be inside the view. | ||||||
|  |     ASSERT(rect.x + rect.width < view_width_ && | ||||||
|  |           rect.y + rect.height < view_height_); | ||||||
|  |     popup_rect_ = rect; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ClientOSRenderer::OnPaint(CefRefPtr<CefBrowser> browser, | ||||||
|  |                                CefRenderHandler::PaintElementType type, | ||||||
|  |                                const CefRenderHandler::RectList& dirtyRects, | ||||||
|  |                                const void* buffer) { | ||||||
|  |   ASSERT(initialized_); | ||||||
|  |  | ||||||
|  |   // Retrieve the current size of the browser view. | ||||||
|  |   browser->GetSize(type, view_width_, view_height_); | ||||||
|  |  | ||||||
|  |   if (transparent_) { | ||||||
|  |     // Enable alpha blending. | ||||||
|  |     glEnable(GL_BLEND); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Enable 2D textures. | ||||||
|  |   glEnable(GL_TEXTURE_2D); | ||||||
|  |  | ||||||
|  |   ASSERT(texture_id_ != 0); | ||||||
|  |   glBindTexture(GL_TEXTURE_2D, texture_id_); | ||||||
|  |  | ||||||
|  |   if (type == PET_VIEW) { | ||||||
|  |     SetBufferSize(view_width_, view_height_, true); | ||||||
|  |  | ||||||
|  |     // Paint the view. | ||||||
|  |     if (transparent_) { | ||||||
|  |       CefRenderHandler::RectList::const_iterator i = dirtyRects.begin(); | ||||||
|  |       for (; i != dirtyRects.end(); ++i) { | ||||||
|  |         ConvertToRGBARect(*i, (unsigned char*)buffer, view_buffer_, | ||||||
|  |                           view_width_, view_height_); | ||||||
|  |       } | ||||||
|  |     } else { | ||||||
|  |       CefRenderHandler::RectList::const_iterator i = dirtyRects.begin(); | ||||||
|  |       for (; i != dirtyRects.end(); ++i) { | ||||||
|  |         ConvertToRGBRect(*i, (unsigned char*)buffer, view_buffer_, | ||||||
|  |                           view_width_, view_height_); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Update the whole texture. This is done for simplicity instead of | ||||||
|  |     // updating just the dirty region. | ||||||
|  |     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, view_width_, view_height_, | ||||||
|  |       transparent_?GL_RGBA:GL_RGB, GL_UNSIGNED_BYTE, view_buffer_); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (popup_rect_.width > 0) { | ||||||
|  |     if (type == PET_POPUP) { | ||||||
|  |       // Paint the popup. | ||||||
|  |       if (transparent_) | ||||||
|  |         SetRGBA(buffer, popup_rect_.width, popup_rect_.height, false); | ||||||
|  |       else | ||||||
|  |         SetRGB(buffer, popup_rect_.width, popup_rect_.height, false); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (popup_buffer_) { | ||||||
|  |       // Update the popup region. | ||||||
|  |       glTexSubImage2D(GL_TEXTURE_2D, 0, popup_rect_.x, | ||||||
|  |           view_height_ - popup_rect_.y - popup_rect_.height, | ||||||
|  |           popup_rect_.width, popup_rect_.height, | ||||||
|  |           transparent_?GL_RGBA:GL_RGB, | ||||||
|  |           GL_UNSIGNED_BYTE, popup_buffer_); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Disable 2D textures. | ||||||
|  |   glDisable(GL_TEXTURE_2D); | ||||||
|  |  | ||||||
|  |   if (transparent_) { | ||||||
|  |     // Disable alpha blending. | ||||||
|  |     glDisable(GL_BLEND); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ClientOSRenderer::SetSpin(float spinX, float spinY) { | ||||||
|  |   spin_x_ = spinX; | ||||||
|  |   spin_y_ = spinY; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ClientOSRenderer::IncrementSpin(float spinDX, float spinDY) { | ||||||
|  |   spin_x_ -= spinDX; | ||||||
|  |   spin_y_ -= spinDY; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ClientOSRenderer::SetBufferSize(int width, int height, bool view) { | ||||||
|  |   int dst_size = width * height * (transparent_?4:3); | ||||||
|  |  | ||||||
|  |   // Allocate a new buffer if necesary. | ||||||
|  |   if (view) { | ||||||
|  |     if (dst_size > view_buffer_size_) { | ||||||
|  |       if (view_buffer_) | ||||||
|  |         delete [] view_buffer_; | ||||||
|  |       view_buffer_ = new unsigned char[dst_size]; | ||||||
|  |       view_buffer_size_ = dst_size; | ||||||
|  |     } | ||||||
|  |   } else { | ||||||
|  |     if (dst_size > popup_buffer_size_) { | ||||||
|  |       if (popup_buffer_) | ||||||
|  |         delete [] popup_buffer_; | ||||||
|  |       popup_buffer_ = new unsigned char[dst_size]; | ||||||
|  |       popup_buffer_size_ = dst_size; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Set the contents of the RGBA buffer. | ||||||
|  | void ClientOSRenderer::SetRGBA(const void* src, int width, int height, | ||||||
|  |                                bool view) { | ||||||
|  |   SetBufferSize(width, height, view); | ||||||
|  |   ConvertToRGBA((unsigned char*)src, view?view_buffer_:popup_buffer_, width, | ||||||
|  |       height); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Set the contents of the RGB buffer. | ||||||
|  | void ClientOSRenderer::SetRGB(const void* src, int width, int height, | ||||||
|  |                               bool view) { | ||||||
|  |   SetBufferSize(width, height, view); | ||||||
|  |   ConvertToRGB((unsigned char*)src, view?view_buffer_:popup_buffer_, width, | ||||||
|  |       height); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ClientOSRenderer::DrawViewBuffer(int max_width, int max_height) { | ||||||
|  |   if (max_width < view_width_ || max_height < view_height_) { | ||||||
|  |     // The requested max size is smaller than the current view buffer. | ||||||
|  |     int width = std::min(max_width, view_width_); | ||||||
|  |     int height = std::min(max_height, view_height_); | ||||||
|  |  | ||||||
|  |     glPixelStorei(GL_UNPACK_ROW_LENGTH, view_width_); | ||||||
|  |     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, | ||||||
|  |                     transparent_?GL_RGBA:GL_RGB, GL_UNSIGNED_BYTE, | ||||||
|  |                     view_buffer_); | ||||||
|  |     glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); | ||||||
|  |   } else { | ||||||
|  |     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, view_width_, view_height_, | ||||||
|  |         transparent_?GL_RGBA:GL_RGB, GL_UNSIGNED_BYTE, view_buffer_); | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										64
									
								
								cef1/tests/cefclient/osrenderer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								cef1/tests/cefclient/osrenderer.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | |||||||
|  | // Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights | ||||||
|  | // reserved. Use of this source code is governed by a BSD-style license | ||||||
|  | // that can be found in the LICENSE file. | ||||||
|  |  | ||||||
|  | #ifndef CEF_TESTS_CEFCLIENT_OSRENDERER_H_ | ||||||
|  | #define CEF_TESTS_CEFCLIENT_OSRENDERER_H_ | ||||||
|  |  | ||||||
|  | #include "include/cef_browser.h" | ||||||
|  | #include "include/cef_render_handler.h" | ||||||
|  |  | ||||||
|  | class ClientOSRenderer { | ||||||
|  |  public: | ||||||
|  |   // The context must outlive this object. | ||||||
|  |   explicit ClientOSRenderer(bool transparent); | ||||||
|  |   virtual ~ClientOSRenderer(); | ||||||
|  |  | ||||||
|  |   // Initialize the OpenGL environment. | ||||||
|  |   void Initialize(); | ||||||
|  |  | ||||||
|  |   // Clean up the OpenGL environment. | ||||||
|  |   void Cleanup(); | ||||||
|  |  | ||||||
|  |   // Set the size of the viewport. | ||||||
|  |   void SetSize(int width, int height); | ||||||
|  |  | ||||||
|  |   // Render to the screen. | ||||||
|  |   void Render(); | ||||||
|  |  | ||||||
|  |   // Forwarded from CefRenderHandler callbacks. | ||||||
|  |   void OnPopupShow(CefRefPtr<CefBrowser> browser, | ||||||
|  |                    bool show); | ||||||
|  |   void OnPopupSize(CefRefPtr<CefBrowser> browser, | ||||||
|  |                    const CefRect& rect); | ||||||
|  |   void OnPaint(CefRefPtr<CefBrowser> browser, | ||||||
|  |                CefRenderHandler::PaintElementType type, | ||||||
|  |                const CefRenderHandler::RectList& dirtyRects, | ||||||
|  |                const void* buffer); | ||||||
|  |  | ||||||
|  |   // Apply spin. | ||||||
|  |   void SetSpin(float spinX, float spinY); | ||||||
|  |   void IncrementSpin(float spinDX, float spinDY); | ||||||
|  |  | ||||||
|  |  private: | ||||||
|  |   void SetBufferSize(int width, int height, bool view); | ||||||
|  |   void SetRGBA(const void* src, int width, int height, bool view); | ||||||
|  |   void SetRGB(const void* src, int width, int height, bool view); | ||||||
|  |   void DrawViewBuffer(int max_width, int max_height); | ||||||
|  |   | ||||||
|  |   bool transparent_; | ||||||
|  |   bool initialized_; | ||||||
|  |   unsigned int texture_id_; | ||||||
|  |   unsigned char* view_buffer_; | ||||||
|  |   int view_buffer_size_; | ||||||
|  |   unsigned char* popup_buffer_; | ||||||
|  |   int popup_buffer_size_; | ||||||
|  |   CefRect popup_rect_; | ||||||
|  |   int view_width_; | ||||||
|  |   int view_height_; | ||||||
|  |   float spin_x_; | ||||||
|  |   float spin_y_; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #endif  // CEF_TESTS_CEFCLIENT_OSR_RENDERER_H_ | ||||||
|  |  | ||||||
| @@ -4,6 +4,7 @@ | |||||||
| // found in the LICENSE file. | // found in the LICENSE file. | ||||||
|  |  | ||||||
| #include "cefclient/osrplugin.h" | #include "cefclient/osrplugin.h" | ||||||
|  | #include "cefclient/osrenderer.h" | ||||||
|  |  | ||||||
| #if defined(OS_WIN) | #if defined(OS_WIN) | ||||||
|  |  | ||||||
| @@ -28,27 +29,22 @@ NPNetscapeFuncs* g_osrbrowser = NULL; | |||||||
|  |  | ||||||
| namespace { | namespace { | ||||||
|  |  | ||||||
| GLuint g_textureID = -1; |  | ||||||
| float g_spinX = 0.0f; |  | ||||||
| float g_spinY = 0.0f; |  | ||||||
| int g_width = -1, g_height = -1; |  | ||||||
| CefRefPtr<CefBrowser> g_offscreenBrowser; | CefRefPtr<CefBrowser> g_offscreenBrowser; | ||||||
|  |  | ||||||
| // If set to true alpha transparency will be used. | // If set to true alpha transparency will be used. | ||||||
| bool g_offscreenTransparent = false; | bool g_offscreenTransparent = false; | ||||||
|  |  | ||||||
| #define GL_IMAGE_FORMAT (g_offscreenTransparent?GL_RGBA:GL_RGB) |  | ||||||
| #define GL_BYTE_COUNT (g_offscreenTransparent?4:3) |  | ||||||
|  |  | ||||||
| // Class holding pointers for the client plugin window. | // Class holding pointers for the client plugin window. | ||||||
| class ClientPlugin { | class ClientPlugin { | ||||||
|  public: |  public: | ||||||
|   ClientPlugin()  { |   ClientPlugin(bool transparent) | ||||||
|     hWnd = NULL; |     : renderer(transparent), | ||||||
|     hDC = NULL; |       hWnd(NULL), | ||||||
|     hRC = NULL; |       hDC(NULL), | ||||||
|  |       hRC(NULL) { | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   ClientOSRenderer renderer; | ||||||
|   HWND hWnd; |   HWND hWnd; | ||||||
|   HDC hDC; |   HDC hDC; | ||||||
|   HGLRC hRC; |   HGLRC hRC; | ||||||
| @@ -63,17 +59,9 @@ class ClientOSRHandler : public CefClient, | |||||||
|                          public CefRenderHandler { |                          public CefRenderHandler { | ||||||
|  public: |  public: | ||||||
|   explicit ClientOSRHandler(ClientPlugin* plugin) |   explicit ClientOSRHandler(ClientPlugin* plugin) | ||||||
|     : plugin_(plugin), |     : plugin_(plugin) { | ||||||
|       view_buffer_(NULL), |  | ||||||
|       view_buffer_size_(0), |  | ||||||
|       popup_buffer_(NULL), |  | ||||||
|       popup_buffer_size_(0) { |  | ||||||
|   } |   } | ||||||
|   ~ClientOSRHandler() { |   ~ClientOSRHandler() { | ||||||
|     if (view_buffer_) |  | ||||||
|       delete [] view_buffer_; |  | ||||||
|     if (popup_buffer_) |  | ||||||
|       delete [] popup_buffer_; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // CefClient methods |   // CefClient methods | ||||||
| @@ -111,10 +99,12 @@ class ClientOSRHandler : public CefClient, | |||||||
|   virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE { |   virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE { | ||||||
|     REQUIRE_UI_THREAD(); |     REQUIRE_UI_THREAD(); | ||||||
|  |  | ||||||
|     // Set the view size to match the plugin window size. |  | ||||||
|     browser->SetSize(PET_VIEW, g_width, g_height); |  | ||||||
|  |  | ||||||
|     g_offscreenBrowser = browser; |     g_offscreenBrowser = browser; | ||||||
|  |  | ||||||
|  |     // Set the off-screen browser size to match the plugin window size. | ||||||
|  |     RECT clientRect; | ||||||
|  |     ::GetClientRect(plugin_->hWnd, &clientRect); | ||||||
|  |     g_offscreenBrowser->SetSize(PET_VIEW, clientRect.right, clientRect.bottom); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser)  OVERRIDE { |   virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser)  OVERRIDE { | ||||||
| @@ -214,9 +204,12 @@ class ClientOSRHandler : public CefClient, | |||||||
|  |  | ||||||
|     // The simulated screen and view rectangle are the same. This is necessary |     // The simulated screen and view rectangle are the same. This is necessary | ||||||
|     // for popup menus to be located and sized inside the view. |     // for popup menus to be located and sized inside the view. | ||||||
|  |     RECT clientRect; | ||||||
|  |     ::GetClientRect(plugin_->hWnd, &clientRect); | ||||||
|  |  | ||||||
|     rect.x = rect.y = 0; |     rect.x = rect.y = 0; | ||||||
|     rect.width = g_width; |     rect.width = clientRect.right; | ||||||
|     rect.height = g_height; |     rect.height = clientRect.bottom; | ||||||
|     return true; |     return true; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -243,29 +236,13 @@ class ClientOSRHandler : public CefClient, | |||||||
|   virtual void OnPopupShow(CefRefPtr<CefBrowser> browser, |   virtual void OnPopupShow(CefRefPtr<CefBrowser> browser, | ||||||
|                            bool show) OVERRIDE { |                            bool show) OVERRIDE { | ||||||
|     REQUIRE_UI_THREAD(); |     REQUIRE_UI_THREAD(); | ||||||
|  |     plugin_->renderer.OnPopupShow(browser, show); | ||||||
|     if (!show) { |  | ||||||
|       // Clear the popup buffer. |  | ||||||
|       popup_rect_.Set(0, 0, 0, 0); |  | ||||||
|       if (popup_buffer_) { |  | ||||||
|         delete [] popup_buffer_; |  | ||||||
|         popup_buffer_ = NULL; |  | ||||||
|         popup_buffer_size_ = 0; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   virtual void OnPopupSize(CefRefPtr<CefBrowser> browser, |   virtual void OnPopupSize(CefRefPtr<CefBrowser> browser, | ||||||
|                            const CefRect& rect) OVERRIDE { |                            const CefRect& rect) OVERRIDE { | ||||||
|     REQUIRE_UI_THREAD(); |     REQUIRE_UI_THREAD(); | ||||||
|  |     plugin_->renderer.OnPopupSize(browser, rect); | ||||||
|     if (rect.width > 0) { |  | ||||||
|       // Update the popup rectange. It will always be inside the view due to |  | ||||||
|       // HandleGetRect(). |  | ||||||
|       ASSERT(rect.x + rect.width < g_width && |  | ||||||
|              rect.y + rect.height < g_height); |  | ||||||
|       popup_rect_ = rect; |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   virtual void OnPaint(CefRefPtr<CefBrowser> browser, |   virtual void OnPaint(CefRefPtr<CefBrowser> browser, | ||||||
| @@ -275,65 +252,7 @@ class ClientOSRHandler : public CefClient, | |||||||
|     REQUIRE_UI_THREAD(); |     REQUIRE_UI_THREAD(); | ||||||
|  |  | ||||||
|     wglMakeCurrent(plugin_->hDC, plugin_->hRC); |     wglMakeCurrent(plugin_->hDC, plugin_->hRC); | ||||||
|  |     plugin_->renderer.OnPaint(browser, type, dirtyRects, buffer); | ||||||
|     if (g_offscreenTransparent) { |  | ||||||
|       // Enable alpha blending. |  | ||||||
|       glEnable(GL_BLEND); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // Enable 2D textures. |  | ||||||
|     glEnable(GL_TEXTURE_2D); |  | ||||||
|  |  | ||||||
|     glBindTexture(GL_TEXTURE_2D, g_textureID); |  | ||||||
|  |  | ||||||
|     if (type == PET_VIEW) { |  | ||||||
|       SetBufferSize(g_width, g_height, true); |  | ||||||
|       // Paint the view. |  | ||||||
|       if (g_offscreenTransparent) { |  | ||||||
|         RectList::const_iterator i = dirtyRects.begin(); |  | ||||||
|         for (; i != dirtyRects.end(); ++i) { |  | ||||||
|           ConvertToRGBARect(*i, (unsigned char*)buffer, view_buffer_, g_width, |  | ||||||
|                             g_height); |  | ||||||
|         } |  | ||||||
|       } else { |  | ||||||
|         RectList::const_iterator i = dirtyRects.begin(); |  | ||||||
|         for (i; i != dirtyRects.end(); ++i) { |  | ||||||
|           ConvertToRGBRect(*i, (unsigned char*)buffer, view_buffer_, g_width, |  | ||||||
|                            g_height); |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       // Update the whole texture. This is done for simplicity instead of |  | ||||||
|       // updating just the dirty region. |  | ||||||
|       glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, g_width, g_height, |  | ||||||
|           GL_IMAGE_FORMAT, GL_UNSIGNED_BYTE, view_buffer_); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if (popup_rect_.width > 0) { |  | ||||||
|       if (type == PET_POPUP) { |  | ||||||
|         // Paint the popup. |  | ||||||
|         if (g_offscreenTransparent) |  | ||||||
|           SetRGBA(buffer, popup_rect_.width, popup_rect_.height, false); |  | ||||||
|         else |  | ||||||
|           SetRGB(buffer, popup_rect_.width, popup_rect_.height, false); |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       if (popup_buffer_) { |  | ||||||
|         // Update the popup region. |  | ||||||
|         glTexSubImage2D(GL_TEXTURE_2D, 0, popup_rect_.x, |  | ||||||
|             g_height-popup_rect_.y-popup_rect_.height, popup_rect_.width, |  | ||||||
|             popup_rect_.height, GL_IMAGE_FORMAT, GL_UNSIGNED_BYTE, |  | ||||||
|             popup_buffer_); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // Disable 2D textures. |  | ||||||
|     glDisable(GL_TEXTURE_2D); |  | ||||||
|  |  | ||||||
|     if (g_offscreenTransparent) { |  | ||||||
|       // Disable alpha blending. |  | ||||||
|       glDisable(GL_BLEND); |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   virtual void OnCursorChange(CefRefPtr<CefBrowser> browser, |   virtual void OnCursorChange(CefRefPtr<CefBrowser> browser, | ||||||
| @@ -357,112 +276,7 @@ class ClientOSRHandler : public CefClient, | |||||||
|     AppGetBrowser()->GetMainFrame()->ExecuteJavaScript(ss.str(), "", 0); |     AppGetBrowser()->GetMainFrame()->ExecuteJavaScript(ss.str(), "", 0); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // Size the RGB buffer. |  | ||||||
|   void SetBufferSize(int width, int height, bool view) { |  | ||||||
|     int dst_size = width * height * GL_BYTE_COUNT; |  | ||||||
|  |  | ||||||
|     // Allocate a new buffer if necesary. |  | ||||||
|     if (view) { |  | ||||||
|       if (dst_size > view_buffer_size_) { |  | ||||||
|         if (view_buffer_) |  | ||||||
|           delete [] view_buffer_; |  | ||||||
|         view_buffer_ = new unsigned char[dst_size]; |  | ||||||
|         view_buffer_size_ = dst_size; |  | ||||||
|       } |  | ||||||
|     } else { |  | ||||||
|       if (dst_size > popup_buffer_size_) { |  | ||||||
|         if (popup_buffer_) |  | ||||||
|           delete [] popup_buffer_; |  | ||||||
|         popup_buffer_ = new unsigned char[dst_size]; |  | ||||||
|         popup_buffer_size_ = dst_size; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   // Set the contents of the RGBA buffer. |  | ||||||
|   void SetRGBA(const void* src, int width, int height, bool view) { |  | ||||||
|     SetBufferSize(width, height, view); |  | ||||||
|     ConvertToRGBA((unsigned char*)src, view?view_buffer_:popup_buffer_, width, |  | ||||||
|         height); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   // Convert from BGRA to RGBA format and from upper-left to lower-left origin. |  | ||||||
|   static void ConvertToRGBA(const unsigned char* src, unsigned char* dst, |  | ||||||
|                            int width, int height) { |  | ||||||
|     int sp = 0, dp = (height-1) * width * 4; |  | ||||||
|     for (int i = 0; i < height; i++) { |  | ||||||
|       for (int j = 0; j < width; j++, dp += 4, sp += 4) { |  | ||||||
|         dst[dp] = src[sp+2];  // R |  | ||||||
|         dst[dp+1] = src[sp+1];  // G |  | ||||||
|         dst[dp+2] = src[sp];  // B |  | ||||||
|         dst[dp+3] = src[sp+3];  // A |  | ||||||
|       } |  | ||||||
|       dp -= width * 8; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   static void ConvertToRGBARect(const CefRect& clipRect, |  | ||||||
|                                 const unsigned char* src, unsigned char* dst, |  | ||||||
|                                 int width, int height) { |  | ||||||
|     int sp = 0, dp = (height-1) * width * 4; |  | ||||||
|     for (int i = 0; i < height; i++) { |  | ||||||
|       for (int j = 0; j < width; j++, dp += 4, sp += 4) { |  | ||||||
|         if ((clipRect.x <= j) && (clipRect.x + clipRect.width > j) && |  | ||||||
|             (clipRect.y <= i) && (clipRect.y + clipRect.height > i)) { |  | ||||||
|           dst[dp] = src[sp+2];  // R |  | ||||||
|           dst[dp+1] = src[sp+1];  // G |  | ||||||
|           dst[dp+2] = src[sp];  // B |  | ||||||
|           dst[dp+3] = src[sp+3];  // A |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|       dp -= width * 8; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   // Set the contents of the RGB buffer. |  | ||||||
|   void SetRGB(const void* src, int width, int height, bool view) { |  | ||||||
|     SetBufferSize(width, height, view); |  | ||||||
|     ConvertToRGB((unsigned char*)src, view?view_buffer_:popup_buffer_, width, |  | ||||||
|         height); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   // Convert from BGRA to RGB format and from upper-left to lower-left origin. |  | ||||||
|   static void ConvertToRGB(const unsigned char* src, unsigned char* dst, |  | ||||||
|                            int width, int height) { |  | ||||||
|     int sp = 0, dp = (height-1) * width * 3; |  | ||||||
|     for (int i = 0; i < height; i++) { |  | ||||||
|       for (int j = 0; j < width; j++, dp += 3, sp += 4) { |  | ||||||
|         dst[dp] = src[sp+2];  // R |  | ||||||
|         dst[dp+1] = src[sp+1];  // G |  | ||||||
|         dst[dp+2] = src[sp];  // B |  | ||||||
|       } |  | ||||||
|       dp -= width * 6; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   static void ConvertToRGBRect(const CefRect& clipRect, |  | ||||||
|                                const unsigned char* src, unsigned char* dst, |  | ||||||
|                                int width, int height) { |  | ||||||
|     int sp = 0, dp = (height-1) * width * 3; |  | ||||||
|     for (int i = 0; i < height; i++) { |  | ||||||
|       for (int j = 0; j < width; j++, dp += 3, sp += 4) { |  | ||||||
|         if ((clipRect.x <= j) && (clipRect.x + clipRect.width > j) && |  | ||||||
|             (clipRect.y <= i) && (clipRect.y + clipRect.height > i)) { |  | ||||||
|           dst[dp] = src[sp+2];  // R |  | ||||||
|           dst[dp+1] = src[sp+1];  // G |  | ||||||
|           dst[dp+2] = src[sp];  // B |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|       dp -= width * 6; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   ClientPlugin* plugin_; |   ClientPlugin* plugin_; | ||||||
|   unsigned char* view_buffer_; |  | ||||||
|   int view_buffer_size_; |  | ||||||
|   unsigned char* popup_buffer_; |  | ||||||
|   int popup_buffer_size_; |  | ||||||
|   CefRect popup_rect_; |  | ||||||
|  |  | ||||||
|   // Include the default reference counting implementation. |   // Include the default reference counting implementation. | ||||||
|   IMPLEMENT_REFCOUNTING(ClientOSRPlugin); |   IMPLEMENT_REFCOUNTING(ClientOSRPlugin); | ||||||
| @@ -473,12 +287,12 @@ LRESULT CALLBACK PluginWndProc(HWND hWnd, UINT message, WPARAM wParam, | |||||||
|                                LPARAM lParam); |                                LPARAM lParam); | ||||||
|  |  | ||||||
| // Enable GL. | // Enable GL. | ||||||
| void EnableGL(HWND hWnd, HDC * hDC, HGLRC * hRC) { | void EnableGL(ClientPlugin* plugin) { | ||||||
|   PIXELFORMATDESCRIPTOR pfd; |   PIXELFORMATDESCRIPTOR pfd; | ||||||
|   int format; |   int format; | ||||||
|  |  | ||||||
|   // Get the device context. |   // Get the device context. | ||||||
|   *hDC = GetDC(hWnd); |   plugin->hDC = GetDC(plugin->hWnd); | ||||||
|  |  | ||||||
|   // Set the pixel format for the DC. |   // Set the pixel format for the DC. | ||||||
|   ZeroMemory(&pfd, sizeof(pfd)); |   ZeroMemory(&pfd, sizeof(pfd)); | ||||||
| @@ -489,83 +303,30 @@ void EnableGL(HWND hWnd, HDC * hDC, HGLRC * hRC) { | |||||||
|   pfd.cColorBits = 24; |   pfd.cColorBits = 24; | ||||||
|   pfd.cDepthBits = 16; |   pfd.cDepthBits = 16; | ||||||
|   pfd.iLayerType = PFD_MAIN_PLANE; |   pfd.iLayerType = PFD_MAIN_PLANE; | ||||||
|   format = ChoosePixelFormat(*hDC, &pfd); |   format = ChoosePixelFormat(plugin->hDC, &pfd); | ||||||
|   SetPixelFormat(*hDC, format, &pfd); |   SetPixelFormat(plugin->hDC, format, &pfd); | ||||||
|  |  | ||||||
|   // Create and enable the render context. |   // Create and enable the render context. | ||||||
|   *hRC = wglCreateContext(*hDC); |   plugin->hRC = wglCreateContext(plugin->hDC); | ||||||
|   wglMakeCurrent(*hDC, *hRC); |   wglMakeCurrent(plugin->hDC, plugin->hRC); | ||||||
|  |  | ||||||
|   glClearColor(0.0f, 0.0f, 0.0f, 1.0f); |   plugin->renderer.Initialize(); | ||||||
|  |  | ||||||
|   // Necessary for non-power-of-2 textures to render correctly. |  | ||||||
|   glPixelStorei(GL_UNPACK_ALIGNMENT, 1); |  | ||||||
|  |  | ||||||
|   if (g_offscreenTransparent) { |  | ||||||
|     // Alpha blending style. |  | ||||||
|     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |  | ||||||
|   } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // Disable GL. | // Disable GL. | ||||||
| void DisableGL(HWND hWnd, HDC hDC, HGLRC hRC) { | void DisableGL(ClientPlugin* plugin) { | ||||||
|   // Delete the texture. |   plugin->renderer.Cleanup(); | ||||||
|   if (g_textureID != -1) |  | ||||||
|     glDeleteTextures(1, &g_textureID); |  | ||||||
|  |  | ||||||
|   wglMakeCurrent(NULL, NULL); |   wglMakeCurrent(NULL, NULL); | ||||||
|   wglDeleteContext(hRC); |   wglDeleteContext(plugin->hRC); | ||||||
|   ReleaseDC(hWnd, hDC); |   ReleaseDC(plugin->hWnd, plugin->hDC); | ||||||
| } | } | ||||||
|  |  | ||||||
| // Size the GL view. | // Size the GL view. | ||||||
| void SizeGL(ClientPlugin* plugin, int width, int height) { | void SizeGL(ClientPlugin* plugin, int width, int height) { | ||||||
|   g_width = width; |  | ||||||
|   g_height = height; |  | ||||||
|  |  | ||||||
|   wglMakeCurrent(plugin->hDC, plugin->hRC); |   wglMakeCurrent(plugin->hDC, plugin->hRC); | ||||||
|  |  | ||||||
|   // Match GL units to screen coordinates. |   plugin->renderer.SetSize(width, height); | ||||||
|   glViewport(0, 0, width, height); |  | ||||||
|   glMatrixMode(GL_PROJECTION); |  | ||||||
|   glLoadIdentity(); |  | ||||||
|   glOrtho(0, 0, width, height, 0.1, 100.0); |  | ||||||
|  |  | ||||||
|   if (g_offscreenTransparent) { |  | ||||||
|     // Enable alpha blending. |  | ||||||
|     glEnable(GL_BLEND); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   // Enable 2D textures. |  | ||||||
|   glEnable(GL_TEXTURE_2D); |  | ||||||
|  |  | ||||||
|   // Delete the existing exture. |  | ||||||
|   if (g_textureID != -1) |  | ||||||
|     glDeleteTextures(1, &g_textureID); |  | ||||||
|  |  | ||||||
|   // Create a new texture. |  | ||||||
|   glGenTextures(1, &g_textureID); |  | ||||||
|   glBindTexture(GL_TEXTURE_2D, g_textureID); |  | ||||||
|   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |  | ||||||
|   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |  | ||||||
|  |  | ||||||
|   // Start with all white contents. |  | ||||||
|   int size = width * height * GL_BYTE_COUNT; |  | ||||||
|   unsigned char* buffer = new unsigned char[size]; |  | ||||||
|   memset(buffer, 255, size); |  | ||||||
|  |  | ||||||
|   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, |  | ||||||
|       GL_IMAGE_FORMAT, GL_UNSIGNED_BYTE, buffer); |  | ||||||
|  |  | ||||||
|   // Disable 2D textures. |  | ||||||
|   glDisable(GL_TEXTURE_2D); |  | ||||||
|  |  | ||||||
|   if (g_offscreenTransparent) { |  | ||||||
|     // Disable alpha blending. |  | ||||||
|     glDisable(GL_BLEND); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   delete [] buffer; |  | ||||||
|  |  | ||||||
|   if (g_offscreenBrowser.get()) |   if (g_offscreenBrowser.get()) | ||||||
|     g_offscreenBrowser->SetSize(PET_VIEW, width, height); |     g_offscreenBrowser->SetSize(PET_VIEW, width, height); | ||||||
| @@ -575,58 +336,7 @@ void SizeGL(ClientPlugin* plugin, int width, int height) { | |||||||
| void RenderGL(ClientPlugin* plugin) { | void RenderGL(ClientPlugin* plugin) { | ||||||
|   wglMakeCurrent(plugin->hDC, plugin->hRC); |   wglMakeCurrent(plugin->hDC, plugin->hRC); | ||||||
|  |  | ||||||
|   struct { |   plugin->renderer.Render(); | ||||||
|     float tu, tv; |  | ||||||
|     float x, y, z; |  | ||||||
|   } static vertices[] = { |  | ||||||
|     {0.0f, 0.0f, -1.0f, -1.0f, 0.0f}, |  | ||||||
|     {1.0f, 0.0f,  1.0f, -1.0f, 0.0f}, |  | ||||||
|     {1.0f, 1.0f,  1.0f,  1.0f, 0.0f}, |  | ||||||
|     {0.0f, 1.0f, -1.0f,  1.0f, 0.0f} |  | ||||||
|   }; |  | ||||||
|  |  | ||||||
|   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |  | ||||||
|  |  | ||||||
|   glMatrixMode(GL_MODELVIEW); |  | ||||||
|   glLoadIdentity(); |  | ||||||
|   // glTranslatef(0.0f, 0.0f, -3.0f); |  | ||||||
|  |  | ||||||
|   // Draw the background gradient. |  | ||||||
|   glPushAttrib(GL_ALL_ATTRIB_BITS); |  | ||||||
|   glBegin(GL_QUADS); |  | ||||||
|   glColor4f(1.0, 0.0, 0.0, 1.0);  // red |  | ||||||
|   glVertex2f(-1.0, -1.0); |  | ||||||
|   glVertex2f(1.0, -1.0); |  | ||||||
|   glColor4f(0.0, 0.0, 1.0, 1.0);  // blue |  | ||||||
|   glVertex2f(1.0, 1.0); |  | ||||||
|   glVertex2f(-1.0, 1.0); |  | ||||||
|   glEnd(); |  | ||||||
|   glPopAttrib(); |  | ||||||
|  |  | ||||||
|   // Rotate the view based on the mouse spin. |  | ||||||
|   glRotatef(-g_spinX, 1.0f, 0.0f, 0.0f); |  | ||||||
|   glRotatef(-g_spinY, 0.0f, 1.0f, 0.0f); |  | ||||||
|  |  | ||||||
|   if (g_offscreenTransparent) { |  | ||||||
|     // Enable alpha blending. |  | ||||||
|     glEnable(GL_BLEND); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   // Enable 2D textures. |  | ||||||
|   glEnable(GL_TEXTURE_2D); |  | ||||||
|  |  | ||||||
|   // Draw the facets with the texture. |  | ||||||
|   glBindTexture(GL_TEXTURE_2D, g_textureID); |  | ||||||
|   glInterleavedArrays(GL_T2F_V3F, 0, vertices); |  | ||||||
|   glDrawArrays(GL_QUADS, 0, 4); |  | ||||||
|  |  | ||||||
|   // Disable 2D textures. |  | ||||||
|   glDisable(GL_TEXTURE_2D); |  | ||||||
|  |  | ||||||
|   if (g_offscreenTransparent) { |  | ||||||
|     // Disable alpha blending. |  | ||||||
|     glDisable(GL_BLEND); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   SwapBuffers(plugin->hDC); |   SwapBuffers(plugin->hDC); | ||||||
| } | } | ||||||
| @@ -637,7 +347,7 @@ NPError NPP_NewImpl(NPMIMEType plugin_type, NPP instance, uint16 mode, | |||||||
|   if (instance == NULL) |   if (instance == NULL) | ||||||
|     return NPERR_INVALID_INSTANCE_ERROR; |     return NPERR_INVALID_INSTANCE_ERROR; | ||||||
|  |  | ||||||
|   ClientPlugin* plugin = new ClientPlugin; |   ClientPlugin* plugin = new ClientPlugin(g_offscreenTransparent); | ||||||
|   instance->pdata = reinterpret_cast<void*>(plugin); |   instance->pdata = reinterpret_cast<void*>(plugin); | ||||||
|  |  | ||||||
|   return NPERR_NO_ERROR; |   return NPERR_NO_ERROR; | ||||||
| @@ -649,7 +359,7 @@ NPError NPP_DestroyImpl(NPP instance, NPSavedData** save) { | |||||||
|   if (plugin) { |   if (plugin) { | ||||||
|     if (plugin->hWnd) { |     if (plugin->hWnd) { | ||||||
|       DestroyWindow(plugin->hWnd); |       DestroyWindow(plugin->hWnd); | ||||||
|       DisableGL(plugin->hWnd, plugin->hDC, plugin->hRC); |       DisableGL(plugin); | ||||||
|     } |     } | ||||||
|     delete plugin; |     delete plugin; | ||||||
|   } |   } | ||||||
| @@ -693,7 +403,7 @@ NPError NPP_SetWindowImpl(NPP instance, NPWindow* window_info) { | |||||||
|         reinterpret_cast<LONG_PTR>(plugin)); |         reinterpret_cast<LONG_PTR>(plugin)); | ||||||
|  |  | ||||||
|     // Enable GL drawing for the window. |     // Enable GL drawing for the window. | ||||||
|     EnableGL(plugin->hWnd, &(plugin->hDC), &(plugin->hRC)); |     EnableGL(plugin); | ||||||
|  |  | ||||||
|     // Create the off-screen rendering window. |     // Create the off-screen rendering window. | ||||||
|     CefWindowInfo windowInfo; |     CefWindowInfo windowInfo; | ||||||
| @@ -771,8 +481,7 @@ LRESULT CALLBACK PluginWndProc(HWND hWnd, UINT message, WPARAM wParam, | |||||||
|     if (mouseRotation) { |     if (mouseRotation) { | ||||||
|       // End rotation effect. |       // End rotation effect. | ||||||
|       mouseRotation = false; |       mouseRotation = false; | ||||||
|       g_spinX = 0; |       plugin->renderer.SetSpin(0, 0); | ||||||
|       g_spinY = 0; |  | ||||||
|     } else { |     } else { | ||||||
|       if (g_offscreenBrowser.get()) { |       if (g_offscreenBrowser.get()) { | ||||||
|         g_offscreenBrowser->SendMouseClickEvent(LOWORD(lParam), HIWORD(lParam), |         g_offscreenBrowser->SendMouseClickEvent(LOWORD(lParam), HIWORD(lParam), | ||||||
| @@ -786,8 +495,8 @@ LRESULT CALLBACK PluginWndProc(HWND hWnd, UINT message, WPARAM wParam, | |||||||
|       // Apply rotation effect. |       // Apply rotation effect. | ||||||
|       curMousePos.x = LOWORD(lParam); |       curMousePos.x = LOWORD(lParam); | ||||||
|       curMousePos.y = HIWORD(lParam); |       curMousePos.y = HIWORD(lParam); | ||||||
|       g_spinX -= (curMousePos.x - lastMousePos.x); |       plugin->renderer.IncrementSpin((curMousePos.x - lastMousePos.x), | ||||||
|       g_spinY -= (curMousePos.y - lastMousePos.y); |                                      (curMousePos.y - lastMousePos.y)); | ||||||
|       lastMousePos.x = curMousePos.x; |       lastMousePos.x = curMousePos.x; | ||||||
|       lastMousePos.y = curMousePos.y; |       lastMousePos.y = curMousePos.y; | ||||||
|     } else { |     } else { | ||||||
| @@ -825,7 +534,7 @@ LRESULT CALLBACK PluginWndProc(HWND hWnd, UINT message, WPARAM wParam, | |||||||
|   case WM_MOUSEWHEEL: |   case WM_MOUSEWHEEL: | ||||||
|     if (g_offscreenBrowser.get()) { |     if (g_offscreenBrowser.get()) { | ||||||
|       g_offscreenBrowser->SendMouseWheelEvent(LOWORD(lParam), HIWORD(lParam), |       g_offscreenBrowser->SendMouseWheelEvent(LOWORD(lParam), HIWORD(lParam), | ||||||
|           GET_WHEEL_DELTA_WPARAM(wParam)); |           0, GET_WHEEL_DELTA_WPARAM(wParam)); | ||||||
|     } |     } | ||||||
|     break; |     break; | ||||||
|  |  | ||||||
| @@ -860,7 +569,8 @@ LRESULT CALLBACK PluginWndProc(HWND hWnd, UINT message, WPARAM wParam, | |||||||
|   case WM_IME_CHAR: |   case WM_IME_CHAR: | ||||||
|     if (g_offscreenBrowser.get()) { |     if (g_offscreenBrowser.get()) { | ||||||
|       CefBrowser::KeyType type = KT_CHAR; |       CefBrowser::KeyType type = KT_CHAR; | ||||||
|       bool sysChar = false, imeChar = false; |       CefKeyInfo keyInfo; | ||||||
|  |       keyInfo.key = wParam; | ||||||
|  |  | ||||||
|       if (message == WM_KEYDOWN || message == WM_SYSKEYDOWN) |       if (message == WM_KEYDOWN || message == WM_SYSKEYDOWN) | ||||||
|         type = KT_KEYDOWN; |         type = KT_KEYDOWN; | ||||||
| @@ -869,12 +579,12 @@ LRESULT CALLBACK PluginWndProc(HWND hWnd, UINT message, WPARAM wParam, | |||||||
|  |  | ||||||
|       if (message == WM_SYSKEYDOWN || message == WM_SYSKEYUP || |       if (message == WM_SYSKEYDOWN || message == WM_SYSKEYUP || | ||||||
|           message == WM_SYSCHAR) |           message == WM_SYSCHAR) | ||||||
|         sysChar = true; |         keyInfo.sysChar = true; | ||||||
|  |  | ||||||
|       if (message == WM_IME_CHAR) |       if (message == WM_IME_CHAR) | ||||||
|         imeChar = true; |         keyInfo.imeChar = true; | ||||||
|  |  | ||||||
|        g_offscreenBrowser->SendKeyEvent(type, wParam, lParam, sysChar, imeChar); |        g_offscreenBrowser->SendKeyEvent(type, keyInfo, lParam); | ||||||
|     } |     } | ||||||
|     break; |     break; | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								cef1/tests/cefclient/osrtest_mac.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								cef1/tests/cefclient/osrtest_mac.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | // Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights | ||||||
|  | // reserved. Use of this source code is governed by a BSD-style license | ||||||
|  | // that can be found in the LICENSE file. | ||||||
|  |  | ||||||
|  | #ifndef CEF_TESTS_CEFCLIENT_OSRTEST_MAC_H_ | ||||||
|  | #define CEF_TESTS_CEFCLIENT_OSRTEST_MAC_H_ | ||||||
|  |  | ||||||
|  | namespace osrtest { | ||||||
|  |  | ||||||
|  | void RunTest(bool transparent); | ||||||
|  |  | ||||||
|  | }  // namespace osrtest | ||||||
|  |  | ||||||
|  | #endif  // CEF_TESTS_CEFCLIENT_OSRTEST_MAC_H_ | ||||||
|  |  | ||||||
							
								
								
									
										752
									
								
								cef1/tests/cefclient/osrtest_mac.mm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										752
									
								
								cef1/tests/cefclient/osrtest_mac.mm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,752 @@ | |||||||
|  |  // Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights | ||||||
|  | // reserved. Use of this source code is governed by a BSD-style license | ||||||
|  | // that can be found in the LICENSE file. | ||||||
|  |  | ||||||
|  | #import <Cocoa/Cocoa.h> | ||||||
|  | #include <OpenGL/gl.h> | ||||||
|  |  | ||||||
|  | #include "cefclient/osrtest_mac.h" | ||||||
|  | #include "include/cef_browser.h" | ||||||
|  | #include "cefclient/osrenderer.h" | ||||||
|  | #include "cefclient/client_popup_handler.h" | ||||||
|  | #include "cefclient/resource_util.h" | ||||||
|  | #include "cefclient/util.h" | ||||||
|  |  | ||||||
|  | // The client OpenGL view. | ||||||
|  | @interface ClientOpenGLView : NSOpenGLView { | ||||||
|  |  @public | ||||||
|  |   NSTrackingArea* tracking_area_; | ||||||
|  |   CefRefPtr<CefBrowser> browser_; | ||||||
|  |   ClientOSRenderer* renderer_; | ||||||
|  |   NSPoint last_mouse_pos_; | ||||||
|  |   NSPoint cur_mouse_pos_; | ||||||
|  |   bool rotating_; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (id)initWithFrame:(NSRect)frame andTransparency:(bool)transparency; | ||||||
|  | - (NSPoint)getClickPointForEvent:(NSEvent*)event; | ||||||
|  | - (void)getKeyInfo:(CefKeyInfo&)info forEvent:(NSEvent*)event; | ||||||
|  | - (int)getModifiersForEvent:(NSEvent*)event; | ||||||
|  | - (BOOL)isKeyUpEvent:(NSEvent*)event; | ||||||
|  | - (BOOL)isKeyPadEvent:(NSEvent*)event; | ||||||
|  | @end | ||||||
|  |  | ||||||
|  |  | ||||||
|  | namespace { | ||||||
|  |  | ||||||
|  | // Handler for off-screen rendering windows. | ||||||
|  | class ClientOSRHandler : public CefClient, | ||||||
|  |                          public CefLifeSpanHandler, | ||||||
|  |                          public CefLoadHandler, | ||||||
|  |                          public CefRequestHandler, | ||||||
|  |                          public CefDisplayHandler, | ||||||
|  |                          public CefRenderHandler { | ||||||
|  |  public: | ||||||
|  |   explicit ClientOSRHandler(ClientOpenGLView* view) | ||||||
|  |     : view_(view) { | ||||||
|  |   } | ||||||
|  |   ~ClientOSRHandler() { | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void Disconnect() { | ||||||
|  |     view_ = nil; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // CefClient methods | ||||||
|  |   virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() OVERRIDE { | ||||||
|  |     return this; | ||||||
|  |   } | ||||||
|  |   virtual CefRefPtr<CefLoadHandler> GetLoadHandler() OVERRIDE { | ||||||
|  |     return this; | ||||||
|  |   } | ||||||
|  |   virtual CefRefPtr<CefRequestHandler> GetRequestHandler() OVERRIDE { | ||||||
|  |     return this; | ||||||
|  |   } | ||||||
|  |   virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler() OVERRIDE { | ||||||
|  |     return this; | ||||||
|  |   } | ||||||
|  |   virtual CefRefPtr<CefRenderHandler> GetRenderHandler() OVERRIDE { | ||||||
|  |     return this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // CefLifeSpanHandler methods | ||||||
|  |  | ||||||
|  |   virtual bool OnBeforePopup(CefRefPtr<CefBrowser> parentBrowser, | ||||||
|  |                              const CefPopupFeatures& popupFeatures, | ||||||
|  |                              CefWindowInfo& windowInfo, | ||||||
|  |                              const CefString& url, | ||||||
|  |                              CefRefPtr<CefClient>& client, | ||||||
|  |                              CefBrowserSettings& settings) OVERRIDE { | ||||||
|  |     REQUIRE_UI_THREAD(); | ||||||
|  |  | ||||||
|  |     windowInfo.m_bWindowRenderingDisabled = TRUE; | ||||||
|  |     client = new ClientPopupHandler(view_->browser_); | ||||||
|  |     return false; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE { | ||||||
|  |     REQUIRE_UI_THREAD(); | ||||||
|  |  | ||||||
|  |     // Set the view size to match the window size. | ||||||
|  |     const NSRect bounds = [view_ bounds]; | ||||||
|  |     browser->SetSize(PET_VIEW, bounds.size.width, bounds.size.height); | ||||||
|  |  | ||||||
|  |     view_->browser_ = browser; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser)  OVERRIDE { | ||||||
|  |     if (view_) | ||||||
|  |       view_->browser_ = NULL; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // CefLoadHandler methods | ||||||
|  |  | ||||||
|  |   virtual void OnLoadStart(CefRefPtr<CefBrowser> browser, | ||||||
|  |                            CefRefPtr<CefFrame> frame) OVERRIDE { | ||||||
|  |     REQUIRE_UI_THREAD(); | ||||||
|  |  | ||||||
|  |     if (!browser->IsPopup() && frame->IsMain()) { | ||||||
|  |       // We've just started loading a page | ||||||
|  |       SetLoading(true); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   virtual void OnLoadEnd(CefRefPtr<CefBrowser> browser, | ||||||
|  |                          CefRefPtr<CefFrame> frame, | ||||||
|  |                          int httpStatusCode) OVERRIDE { | ||||||
|  |     REQUIRE_UI_THREAD(); | ||||||
|  |  | ||||||
|  |     if (!browser->IsPopup() && frame->IsMain()) { | ||||||
|  |       // We've just finished loading a page | ||||||
|  |       SetLoading(false); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // CefRequestHandler methods | ||||||
|  |  | ||||||
|  |   virtual bool OnBeforeResourceLoad(CefRefPtr<CefBrowser> browser, | ||||||
|  |                                     CefRefPtr<CefRequest> request, | ||||||
|  |                                     CefString& redirectUrl, | ||||||
|  |                                     CefRefPtr<CefStreamReader>& resourceStream, | ||||||
|  |                                     CefRefPtr<CefResponse> response, | ||||||
|  |                                     int loadFlags) OVERRIDE { | ||||||
|  |     REQUIRE_IO_THREAD(); | ||||||
|  |  | ||||||
|  |     std::string url = request->GetURL(); | ||||||
|  |     if (url == "http://tests/osrtest") { | ||||||
|  |       // Show the osrtest HTML contents | ||||||
|  |       resourceStream = GetBinaryResourceReader("osrtest.html"); | ||||||
|  |       response->SetMimeType("text/html"); | ||||||
|  |       response->SetStatus(200); | ||||||
|  |     } else if (url == "http://tests/transparency") { | ||||||
|  |       // Show the osrtest HTML contents | ||||||
|  |       resourceStream = GetBinaryResourceReader("transparency.html"); | ||||||
|  |       response->SetMimeType("text/html"); | ||||||
|  |       response->SetStatus(200); | ||||||
|  |     } else if (strstr(url.c_str(), "/logoball.png") != NULL) { | ||||||
|  |       // Load the "logoball.png" image resource. | ||||||
|  |       resourceStream = GetBinaryResourceReader("logoball.png"); | ||||||
|  |       response->SetMimeType("image/png"); | ||||||
|  |       response->SetStatus(200); | ||||||
|  |     }  | ||||||
|  |  | ||||||
|  |     return false; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // CefDisplayHandler methods | ||||||
|  |  | ||||||
|  |   virtual void OnNavStateChange(CefRefPtr<CefBrowser> browser, | ||||||
|  |                                 bool canGoBack, | ||||||
|  |                                 bool canGoForward) OVERRIDE { | ||||||
|  |     REQUIRE_UI_THREAD(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   virtual void OnAddressChange(CefRefPtr<CefBrowser> browser, | ||||||
|  |                                CefRefPtr<CefFrame> frame, | ||||||
|  |                                const CefString& url) OVERRIDE { | ||||||
|  |     REQUIRE_UI_THREAD(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   virtual void OnTitleChange(CefRefPtr<CefBrowser> browser, | ||||||
|  |                              const CefString& title) OVERRIDE { | ||||||
|  |     REQUIRE_UI_THREAD(); | ||||||
|  |  | ||||||
|  |     if (!view_) | ||||||
|  |       return; | ||||||
|  |  | ||||||
|  |     // Set the frame window title bar | ||||||
|  |     NSWindow* window = [view_ window]; | ||||||
|  |     std::string titleStr(title); | ||||||
|  |     NSString* str = [NSString stringWithUTF8String:titleStr.c_str()]; | ||||||
|  |     [window setTitle:str]; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // CefRenderHandler methods | ||||||
|  |  | ||||||
|  |   virtual bool GetViewRect(CefRefPtr<CefBrowser> browser, | ||||||
|  |                            CefRect& rect) OVERRIDE { | ||||||
|  |     REQUIRE_UI_THREAD(); | ||||||
|  |  | ||||||
|  |     if (!view_) | ||||||
|  |       return false; | ||||||
|  |  | ||||||
|  |     // The simulated screen and view rectangle are the same. This is necessary | ||||||
|  |     // for popup menus to be located and sized inside the view. | ||||||
|  |     const NSRect bounds = [view_ bounds]; | ||||||
|  |     rect.x = rect.y = 0; | ||||||
|  |     rect.width = bounds.size.width; | ||||||
|  |     rect.height = bounds.size.height; | ||||||
|  |     return true; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   virtual bool GetScreenRect(CefRefPtr<CefBrowser> browser, | ||||||
|  |                              CefRect& rect) OVERRIDE { | ||||||
|  |     return GetViewRect(browser, rect); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   virtual bool GetScreenPoint(CefRefPtr<CefBrowser> browser, | ||||||
|  |                               int viewX, | ||||||
|  |                               int viewY, | ||||||
|  |                               int& screenX, | ||||||
|  |                               int& screenY) OVERRIDE { | ||||||
|  |     REQUIRE_UI_THREAD(); | ||||||
|  |  | ||||||
|  |     if (!view_) | ||||||
|  |       return false; | ||||||
|  |  | ||||||
|  |     // Convert the point from view coordinates to actual screen coordinates. | ||||||
|  |     NSRect bounds = [view_ bounds]; | ||||||
|  |     NSPoint view_pt = {viewX, bounds.size.height - viewY}; | ||||||
|  |     NSPoint window_pt = [view_ convertPoint:view_pt toView:nil]; | ||||||
|  |     NSPoint screen_pt = [[view_ window] convertBaseToScreen:window_pt]; | ||||||
|  |     screenX = screen_pt.x; | ||||||
|  |     screenY = screen_pt.y; | ||||||
|  |     return true; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   virtual void OnPopupShow(CefRefPtr<CefBrowser> browser, | ||||||
|  |                            bool show) OVERRIDE { | ||||||
|  |     REQUIRE_UI_THREAD(); | ||||||
|  |  | ||||||
|  |     if (!view_) | ||||||
|  |       return; | ||||||
|  |  | ||||||
|  |     view_->renderer_->OnPopupShow(browser, show); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   virtual void OnPopupSize(CefRefPtr<CefBrowser> browser, | ||||||
|  |                            const CefRect& rect) OVERRIDE { | ||||||
|  |     REQUIRE_UI_THREAD(); | ||||||
|  |  | ||||||
|  |     if (!view_) | ||||||
|  |       return; | ||||||
|  |  | ||||||
|  |     view_->renderer_->OnPopupSize(browser, rect); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   virtual void OnPaint(CefRefPtr<CefBrowser> browser, | ||||||
|  |                        PaintElementType type, | ||||||
|  |                        const RectList& dirtyRects, | ||||||
|  |                        const void* buffer) OVERRIDE { | ||||||
|  |     REQUIRE_UI_THREAD(); | ||||||
|  |  | ||||||
|  |     if (!view_) | ||||||
|  |       return; | ||||||
|  |  | ||||||
|  |     [[view_ openGLContext] makeCurrentContext]; | ||||||
|  |  | ||||||
|  |     view_->renderer_->OnPaint(browser, type, dirtyRects, buffer); | ||||||
|  |  | ||||||
|  |     // Notify the view to redraw the invalidated regions. | ||||||
|  |     { | ||||||
|  |       RectList::const_iterator i = dirtyRects.begin(); | ||||||
|  |       for (; i != dirtyRects.end(); ++i) { | ||||||
|  |         NSRect rect = {{i->x, i->y}, {i->width, i->height}}; | ||||||
|  |         [view_ setNeedsDisplayInRect:rect]; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   virtual void OnCursorChange(CefRefPtr<CefBrowser> browser, | ||||||
|  |                               CefCursorHandle cursor) OVERRIDE { | ||||||
|  |     REQUIRE_UI_THREAD(); | ||||||
|  |     [cursor set]; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  private: | ||||||
|  |   void SetLoading(bool isLoading) { | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   ClientOpenGLView* view_; | ||||||
|  |  | ||||||
|  |   // Include the default reference counting implementation. | ||||||
|  |   IMPLEMENT_REFCOUNTING(ClientOSRPlugin); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | }  // namespace | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @implementation ClientOpenGLView | ||||||
|  |  | ||||||
|  | - (id)initWithFrame:(NSRect)frame andTransparency:(bool)transparency { | ||||||
|  |   NSOpenGLPixelFormat * pixelFormat = | ||||||
|  |       [[NSOpenGLPixelFormat alloc] | ||||||
|  |        initWithAttributes:(NSOpenGLPixelFormatAttribute[]) { | ||||||
|  |            NSOpenGLPFAWindow, | ||||||
|  |            NSOpenGLPFADoubleBuffer, | ||||||
|  |            NSOpenGLPFADepthSize, | ||||||
|  |            32, | ||||||
|  |            0}]; | ||||||
|  |   [pixelFormat autorelease]; | ||||||
|  |    | ||||||
|  |   self = [super initWithFrame:frame pixelFormat:pixelFormat]; | ||||||
|  |   if (self) { | ||||||
|  |     renderer_ = new ClientOSRenderer(transparency); | ||||||
|  |     rotating_ = false; | ||||||
|  |  | ||||||
|  |     tracking_area_ = | ||||||
|  |         [[NSTrackingArea alloc] initWithRect:frame | ||||||
|  |                                      options:NSTrackingMouseMoved | | ||||||
|  |                                              NSTrackingActiveInActiveApp | | ||||||
|  |                                              NSTrackingInVisibleRect | ||||||
|  |                                        owner:self | ||||||
|  |                                     userInfo:nil]; | ||||||
|  |     [self addTrackingArea:tracking_area_]; | ||||||
|  |   } | ||||||
|  |   return self; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (void)dealloc { | ||||||
|  |   if (browser_) { | ||||||
|  |     static_cast<ClientOSRHandler*>(browser_->GetClient().get())->Disconnect(); | ||||||
|  |     browser_->CloseBrowser(); | ||||||
|  |     browser_ = NULL; | ||||||
|  |   } | ||||||
|  |   if (renderer_) | ||||||
|  |     delete renderer_; | ||||||
|  |  | ||||||
|  |   [super dealloc]; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (void)drawRect: (NSRect)bounds { | ||||||
|  |   NSOpenGLContext* context = [self openGLContext]; | ||||||
|  |   [context makeCurrentContext]; | ||||||
|  |  | ||||||
|  |   renderer_->Render(); | ||||||
|  |  | ||||||
|  |   [context flushBuffer]; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (void)setFrame:(NSRect)frameRect { | ||||||
|  |   [super setFrame:frameRect]; | ||||||
|  |  | ||||||
|  |   int width = frameRect.size.width; | ||||||
|  |   int height = frameRect.size.height; | ||||||
|  |    | ||||||
|  |   [[self openGLContext] makeCurrentContext]; | ||||||
|  |    | ||||||
|  |   renderer_->SetSize(width, height); | ||||||
|  |  | ||||||
|  |   if (browser_) | ||||||
|  |     browser_->SetSize(PET_VIEW, width, height); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (void)mouseDown:(NSEvent *)event { | ||||||
|  |   if (!browser_) | ||||||
|  |     return; | ||||||
|  |  | ||||||
|  |   NSPoint point = [self getClickPointForEvent:event]; | ||||||
|  |   int clickCount = [event clickCount]; | ||||||
|  |  | ||||||
|  |   browser_->SendMouseClickEvent(point.x, point.y, MBT_LEFT, false, clickCount); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (void)rightMouseDown:(NSEvent *)event { | ||||||
|  |   if (!browser_) | ||||||
|  |     return; | ||||||
|  |  | ||||||
|  |   NSPoint point = [self getClickPointForEvent:event]; | ||||||
|  |  | ||||||
|  |   if ([event modifierFlags] & NSShiftKeyMask) { | ||||||
|  |     // Start rotation effect. | ||||||
|  |     last_mouse_pos_ = cur_mouse_pos_ = point; | ||||||
|  |     rotating_ = true; | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   int clickCount = [event clickCount]; | ||||||
|  |  | ||||||
|  |   browser_->SendMouseClickEvent(point.x, point.y, MBT_RIGHT, false, clickCount); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (void)otherMouseDown:(NSEvent *)event { | ||||||
|  |   if (!browser_) | ||||||
|  |     return; | ||||||
|  |  | ||||||
|  |   NSPoint point = [self getClickPointForEvent:event]; | ||||||
|  |   int clickCount = [event clickCount]; | ||||||
|  |  | ||||||
|  |   browser_->SendMouseClickEvent(point.x, point.y, MBT_MIDDLE, false, | ||||||
|  |                                 clickCount); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (void)mouseUp:(NSEvent *)event { | ||||||
|  |   if (!browser_) | ||||||
|  |     return; | ||||||
|  |  | ||||||
|  |   NSPoint point = [self getClickPointForEvent:event]; | ||||||
|  |   int clickCount = [event clickCount]; | ||||||
|  |  | ||||||
|  |   browser_->SendMouseClickEvent(point.x, point.y, MBT_LEFT, true, clickCount); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (void)rightMouseUp:(NSEvent *)event { | ||||||
|  |   if (!browser_) | ||||||
|  |     return; | ||||||
|  |  | ||||||
|  |   if (rotating_) { | ||||||
|  |     // End rotation effect. | ||||||
|  |     renderer_->SetSpin(0, 0); | ||||||
|  |     rotating_ = false; | ||||||
|  |     [self setNeedsDisplay:YES]; | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   NSPoint point = [self getClickPointForEvent:event]; | ||||||
|  |   int clickCount = [event clickCount]; | ||||||
|  |  | ||||||
|  |   browser_->SendMouseClickEvent(point.x, point.y, MBT_RIGHT, true, clickCount); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (void)otherMouseUp:(NSEvent *)event { | ||||||
|  |   if (!browser_) | ||||||
|  |     return; | ||||||
|  |  | ||||||
|  |   NSPoint point = [self getClickPointForEvent:event]; | ||||||
|  |   int clickCount = [event clickCount]; | ||||||
|  |  | ||||||
|  |   browser_->SendMouseClickEvent(point.x, point.y, MBT_MIDDLE, true, clickCount); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (void)mouseMoved:(NSEvent *)event { | ||||||
|  |   if (!browser_) | ||||||
|  |     return; | ||||||
|  |  | ||||||
|  |   NSPoint point = [self getClickPointForEvent:event]; | ||||||
|  |  | ||||||
|  |   if (rotating_) { | ||||||
|  |     // Apply rotation effect. | ||||||
|  |     cur_mouse_pos_ = point; | ||||||
|  |     renderer_->IncrementSpin((cur_mouse_pos_.x - last_mouse_pos_.x), | ||||||
|  |                              (cur_mouse_pos_.y - last_mouse_pos_.y)); | ||||||
|  |     last_mouse_pos_ = cur_mouse_pos_; | ||||||
|  |     [self setNeedsDisplay:YES]; | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   browser_->SendMouseMoveEvent(point.x, point.y, false); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (void)mouseDragged:(NSEvent *)event { | ||||||
|  |   [self mouseMoved:event]; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (void)rightMouseDragged:(NSEvent *)event { | ||||||
|  |   [self mouseMoved:event]; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (void)otherMouseDragged:(NSEvent *)event { | ||||||
|  |   [self mouseMoved:event]; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (void)mouseEntered:(NSEvent *)event { | ||||||
|  |   [self mouseMoved:event]; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (void)mouseExited:(NSEvent *)event { | ||||||
|  |   if (!browser_) | ||||||
|  |     return; | ||||||
|  |    | ||||||
|  |   NSPoint point = [self getClickPointForEvent:event]; | ||||||
|  |  | ||||||
|  |   browser_->SendMouseMoveEvent(point.x, point.y, true); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (void)keyDown:(NSEvent *)event { | ||||||
|  |   if (!browser_) | ||||||
|  |     return; | ||||||
|  |    | ||||||
|  |   CefKeyInfo keyInfo; | ||||||
|  |   [self getKeyInfo:keyInfo forEvent:event]; | ||||||
|  |   int modifiers = [self getModifiersForEvent:event]; | ||||||
|  |  | ||||||
|  |   browser_->SendKeyEvent(KT_KEYDOWN, keyInfo, modifiers); | ||||||
|  |  | ||||||
|  |   if ([event modifierFlags] & (NSNumericPadKeyMask | NSFunctionKeyMask)) { | ||||||
|  |     // Don't send a Char event for non-char keys like arrows, function keys and | ||||||
|  |     // clear. | ||||||
|  |     switch (keyInfo.keyCode) { | ||||||
|  |       case 81: // = | ||||||
|  |       case 75: // / | ||||||
|  |       case 67: // * | ||||||
|  |       case 78: // - | ||||||
|  |       case 69: // + | ||||||
|  |       case 76: // Enter | ||||||
|  |       case 65: // . | ||||||
|  |       case 82: // 0 | ||||||
|  |       case 83: // 1 | ||||||
|  |       case 84: // 2 | ||||||
|  |       case 85: // 3 | ||||||
|  |       case 86: // 4 | ||||||
|  |       case 87: // 5 | ||||||
|  |       case 88: // 6 | ||||||
|  |       case 89: // 7 | ||||||
|  |       case 91: // 8 | ||||||
|  |       case 92: // 9 | ||||||
|  |         break; | ||||||
|  |       default: | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   browser_->SendKeyEvent(KT_CHAR, keyInfo, modifiers); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (void)keyUp:(NSEvent *)event { | ||||||
|  |   if (!browser_) | ||||||
|  |     return; | ||||||
|  |  | ||||||
|  |   CefKeyInfo keyInfo; | ||||||
|  |   [self getKeyInfo:keyInfo forEvent:event]; | ||||||
|  |   int modifiers = [self getModifiersForEvent:event]; | ||||||
|  |  | ||||||
|  |   browser_->SendKeyEvent(KT_KEYUP, keyInfo, modifiers); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (void)flagsChanged:(NSEvent *)event { | ||||||
|  |   if ([self isKeyUpEvent:event]) | ||||||
|  |     [self keyUp:event]; | ||||||
|  |   else | ||||||
|  |     [self keyDown:event]; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (void)scrollWheel:(NSEvent *)event { | ||||||
|  |   if (!browser_) | ||||||
|  |     return; | ||||||
|  |  | ||||||
|  |   CGEventRef cgEvent = [event CGEvent]; | ||||||
|  |   ASSERT(cgEvent); | ||||||
|  |  | ||||||
|  |   NSPoint point = [self getClickPointForEvent:event]; | ||||||
|  |   int deltaX = | ||||||
|  |       CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventPointDeltaAxis2); | ||||||
|  |   int deltaY = | ||||||
|  |       CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventPointDeltaAxis1); | ||||||
|  |  | ||||||
|  |   browser_->SendMouseWheelEvent(point.x, point.y, deltaX, deltaY); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (BOOL)canBecomeKeyView { | ||||||
|  |   return (browser_ != NULL); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (BOOL)acceptsFirstResponder { | ||||||
|  |   return (browser_ != NULL); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (BOOL)becomeFirstResponder { | ||||||
|  |   if (browser_) { | ||||||
|  |     browser_->SendFocusEvent(true); | ||||||
|  |     return [super becomeFirstResponder]; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return NO; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (BOOL)resignFirstResponder { | ||||||
|  |   if (browser_) { | ||||||
|  |     browser_->SendFocusEvent(false); | ||||||
|  |     return [super resignFirstResponder]; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return NO; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (void)undo:(id)sender { | ||||||
|  |   if (browser_) | ||||||
|  |     browser_->GetFocusedFrame()->Undo(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (void)redo:(id)sender { | ||||||
|  |   if (browser_) | ||||||
|  |     browser_->GetFocusedFrame()->Redo(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (void)cut:(id)sender { | ||||||
|  |   if (browser_) | ||||||
|  |     browser_->GetFocusedFrame()->Cut(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (void)copy:(id)sender { | ||||||
|  |   if (browser_) | ||||||
|  |     browser_->GetFocusedFrame()->Copy(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (void)paste:(id)sender { | ||||||
|  |   if (browser_) | ||||||
|  |     browser_->GetFocusedFrame()->Paste(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (void)delete:(id)sender { | ||||||
|  |   if (browser_) | ||||||
|  |     browser_->GetFocusedFrame()->Delete(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (void)selectAll:(id)sender { | ||||||
|  |   if (browser_) | ||||||
|  |     browser_->GetFocusedFrame()->SelectAll(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (NSPoint)getClickPointForEvent:(NSEvent*)event { | ||||||
|  |   NSPoint windowLocal = [event locationInWindow]; | ||||||
|  |   NSPoint contentLocal = [self convertPoint:windowLocal fromView:nil]; | ||||||
|  |   int x = contentLocal.x; | ||||||
|  |   int y = [self frame].size.height - contentLocal.y;  // Flip y. | ||||||
|  |  | ||||||
|  |   return {x,y}; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (void)getKeyInfo:(CefKeyInfo&)info forEvent:(NSEvent*)event { | ||||||
|  |   if ([event type] == NSKeyDown || [event type] == NSKeyUp) { | ||||||
|  |     NSString* s = [event characters]; | ||||||
|  |     if ([s length] > 0) | ||||||
|  |       info.character = [s characterAtIndex:0]; | ||||||
|  |  | ||||||
|  |     s = [event charactersIgnoringModifiers]; | ||||||
|  |     if ([s length] > 0) | ||||||
|  |       info.characterNoModifiers = [s characterAtIndex:0]; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   info.keyCode = [event keyCode]; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (int)getModifiersForEvent:(NSEvent*)event { | ||||||
|  |   int modifiers = 0; | ||||||
|  |  | ||||||
|  |   if ([event modifierFlags] & NSControlKeyMask) | ||||||
|  |     modifiers |= KEY_CTRL; | ||||||
|  |   if ([event modifierFlags] & NSShiftKeyMask) | ||||||
|  |     modifiers |= KEY_SHIFT;  | ||||||
|  |   if ([event modifierFlags] & NSAlternateKeyMask) | ||||||
|  |     modifiers |= KEY_ALT; | ||||||
|  |   if ([event modifierFlags] & NSCommandKeyMask) | ||||||
|  |     modifiers |= KEY_META; | ||||||
|  |   if ([self isKeyPadEvent:event]) | ||||||
|  |     modifiers |= KEY_KEYPAD; | ||||||
|  |  | ||||||
|  |   return modifiers; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (BOOL)isKeyUpEvent:(NSEvent*)event { | ||||||
|  |   if ([event type] != NSFlagsChanged) | ||||||
|  |     return [event type] == NSKeyUp; | ||||||
|  |  | ||||||
|  |   // FIXME: This logic fails if the user presses both Shift keys at once, for | ||||||
|  |   // example: we treat releasing one of them as keyDown. | ||||||
|  |   switch ([event keyCode]) { | ||||||
|  |     case 54: // Right Command | ||||||
|  |     case 55: // Left Command | ||||||
|  |       return ([event modifierFlags] & NSCommandKeyMask) == 0; | ||||||
|  |  | ||||||
|  |     case 57: // Capslock | ||||||
|  |       return ([event modifierFlags] & NSAlphaShiftKeyMask) == 0; | ||||||
|  |  | ||||||
|  |     case 56: // Left Shift | ||||||
|  |     case 60: // Right Shift | ||||||
|  |       return ([event modifierFlags] & NSShiftKeyMask) == 0; | ||||||
|  |  | ||||||
|  |     case 58: // Left Alt | ||||||
|  |     case 61: // Right Alt | ||||||
|  |      return ([event modifierFlags] & NSAlternateKeyMask) == 0; | ||||||
|  |  | ||||||
|  |     case 59: // Left Ctrl | ||||||
|  |     case 62: // Right Ctrl | ||||||
|  |       return ([event modifierFlags] & NSControlKeyMask) == 0; | ||||||
|  |  | ||||||
|  |     case 63: // Function | ||||||
|  |       return ([event modifierFlags] & NSFunctionKeyMask) == 0; | ||||||
|  |   } | ||||||
|  |   return false; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | - (BOOL)isKeyPadEvent:(NSEvent*)event { | ||||||
|  |   if ([event modifierFlags] & NSNumericPadKeyMask) | ||||||
|  |     return true; | ||||||
|  |  | ||||||
|  |   switch ([event keyCode]) { | ||||||
|  |     case 71: // Clear | ||||||
|  |     case 81: // = | ||||||
|  |     case 75: // / | ||||||
|  |     case 67: // * | ||||||
|  |     case 78: // - | ||||||
|  |     case 69: // + | ||||||
|  |     case 76: // Enter | ||||||
|  |     case 65: // . | ||||||
|  |     case 82: // 0 | ||||||
|  |     case 83: // 1 | ||||||
|  |     case 84: // 2 | ||||||
|  |     case 85: // 3 | ||||||
|  |     case 86: // 4 | ||||||
|  |     case 87: // 5 | ||||||
|  |     case 88: // 6 | ||||||
|  |     case 89: // 7 | ||||||
|  |     case 91: // 8 | ||||||
|  |     case 92: // 9 | ||||||
|  |       return true; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return false; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @end | ||||||
|  |  | ||||||
|  |  | ||||||
|  | namespace osrtest { | ||||||
|  |  | ||||||
|  | void RunTest(bool transparent) { | ||||||
|  |   NSRect screen_rect = [[NSScreen mainScreen] visibleFrame]; | ||||||
|  |   NSRect window_rect = {{0, screen_rect.size.height}, {700, 700}}; | ||||||
|  |   NSWindow* newWnd = [[NSWindow alloc] | ||||||
|  |                       initWithContentRect:window_rect | ||||||
|  |                                 styleMask:(NSTitledWindowMask | | ||||||
|  |                                            NSClosableWindowMask | | ||||||
|  |                                            NSMiniaturizableWindowMask | | ||||||
|  |                                            NSResizableWindowMask | | ||||||
|  |                                            NSUnifiedTitleAndToolbarWindowMask) | ||||||
|  |                                   backing:NSBackingStoreBuffered | ||||||
|  |                                     defer:NO]; | ||||||
|  |   ASSERT(newWnd); | ||||||
|  |  | ||||||
|  |   ClientOpenGLView* view = [[ClientOpenGLView alloc] initWithFrame:window_rect | ||||||
|  |                                                    andTransparency:transparent]; | ||||||
|  |   [view setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; | ||||||
|  |  | ||||||
|  |   [newWnd setContentView:view]; | ||||||
|  |   [view release]; | ||||||
|  |  | ||||||
|  |   CefWindowInfo info; | ||||||
|  |   CefBrowserSettings settings; | ||||||
|  |  | ||||||
|  |   // Initialize the window info as off-screen. | ||||||
|  |   info.SetAsOffScreen(view); | ||||||
|  |   info.SetTransparentPainting(transparent); | ||||||
|  |  | ||||||
|  |   // Creat the browser window. | ||||||
|  |   CefBrowser::CreateBrowser(info, new ClientOSRHandler(view), | ||||||
|  |       "http://tests/osrtest", settings); | ||||||
|  |  | ||||||
|  |   [newWnd makeKeyAndOrderFront: nil]; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | }  // namespace osrtest | ||||||
|  |  | ||||||
							
								
								
									
										40
									
								
								cef1/tests/cefclient/res/osrtest.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								cef1/tests/cefclient/res/osrtest.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | |||||||
|  | <html> | ||||||
|  | <head> | ||||||
|  | <title>Off-Screen Rendering Test</title> | ||||||
|  | </head> | ||||||
|  | <body bottommargin="2" rightmargin="0" leftmargin="0" topmargin="0" marginwidth="0" marginheight="0" style="font-family: Verdana, Arial;" bgcolor="white"> | ||||||
|  | <div align="center"> | ||||||
|  | <table border="0" cellpadding="2" cellspacing="0"> | ||||||
|  |   <tr> | ||||||
|  |     <td colspan="2" style="font-size: 18pt;">Off-Screen Rendering App Example</td> | ||||||
|  |   </tr> | ||||||
|  |   <tr> | ||||||
|  |     <td colspan="2" style="font-size: 8pt;"><i>An OpenGL view that renders content from an off-screen browser window.</i></td> | ||||||
|  |   </tr> | ||||||
|  |   <tr> | ||||||
|  |     <td colspan="2" height="10"></td> | ||||||
|  |   </tr> | ||||||
|  |   <tr> | ||||||
|  |     <td width="100" valign="top"><img src="logoball.png" width="100" height="101"></td> | ||||||
|  |     <td style="font-size: 10pt;"><span style="font-size: 12pt;">You can rotate the view!</span> | ||||||
|  |       <ul> | ||||||
|  |         <li>Click and drag the view with the left mouse button while holding the shift key.</li> | ||||||
|  |         <li>Enter a URL and click the "Go!" button to browse to a new Website.</li> | ||||||
|  |         <li><a href="http://tests/transparency">Click here</a> to test transparency.</li> | ||||||
|  |         <li><a href="http://www.adobe.com/software/flash/about/">Click here</a> to test a windowless plugin.</li> | ||||||
|  |       </ul> | ||||||
|  |     </td> | ||||||
|  |   </tr> | ||||||
|  |   <tr> | ||||||
|  |     <td colspan="2" align="center"> | ||||||
|  |       <form> | ||||||
|  |         <input type="text" id="url" size="100" value="http://www.google.com"/> | ||||||
|  |         <input type="button" value="Go!" onClick="document.location=document.getElementById('url').value;"/> | ||||||
|  |       </form> | ||||||
|  |     </td> | ||||||
|  |   </tr> | ||||||
|  | </table> | ||||||
|  | </div> | ||||||
|  | </body> | ||||||
|  | </html> | ||||||
|  |  | ||||||
| @@ -96,6 +96,7 @@ | |||||||
|           'link_settings': { |           'link_settings': { | ||||||
|             'libraries': [ |             'libraries': [ | ||||||
|               '$(SDKROOT)/System/Library/Frameworks/AppKit.framework', |               '$(SDKROOT)/System/Library/Frameworks/AppKit.framework', | ||||||
|  |               '$(SDKROOT)/System/Library/Frameworks/OpenGL.framework', | ||||||
|               '$(CONFIGURATION)/libcef.dylib' |               '$(CONFIGURATION)/libcef.dylib' | ||||||
|             ], |             ], | ||||||
|           }, |           }, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user