1 // Copyright 2020 The Chromium Embedded Framework Authors. Portions copyright 2 // 2012 The Chromium Authors. All rights reserved. Use of this source code is 3 // governed by a BSD-style license that can be found in the LICENSE file. 4 5 #include "libcef/browser/native/cursor_util.h" 6 7 #include <windows.h> 8 9 #include "libcef/common/app_manager.h" 10 11 #include "ui/base/cursor/mojom/cursor_type.mojom.h" 12 #include "ui/base/win/win_cursor.h" 13 #include "ui/resources/grit/ui_unscaled_resources.h" 14 15 namespace cursor_util { 16 17 namespace { 18 19 // From content/common/cursors/webcursor_win.cc. ToCursorID(ui::mojom::CursorType type)20LPCWSTR ToCursorID(ui::mojom::CursorType type) { 21 switch (type) { 22 case ui::mojom::CursorType::kPointer: 23 return IDC_ARROW; 24 case ui::mojom::CursorType::kCross: 25 return IDC_CROSS; 26 case ui::mojom::CursorType::kHand: 27 return IDC_HAND; 28 case ui::mojom::CursorType::kIBeam: 29 return IDC_IBEAM; 30 case ui::mojom::CursorType::kWait: 31 return IDC_WAIT; 32 case ui::mojom::CursorType::kHelp: 33 return IDC_HELP; 34 case ui::mojom::CursorType::kEastResize: 35 return IDC_SIZEWE; 36 case ui::mojom::CursorType::kNorthResize: 37 return IDC_SIZENS; 38 case ui::mojom::CursorType::kNorthEastResize: 39 return IDC_SIZENESW; 40 case ui::mojom::CursorType::kNorthWestResize: 41 return IDC_SIZENWSE; 42 case ui::mojom::CursorType::kSouthResize: 43 return IDC_SIZENS; 44 case ui::mojom::CursorType::kSouthEastResize: 45 return IDC_SIZENWSE; 46 case ui::mojom::CursorType::kSouthWestResize: 47 return IDC_SIZENESW; 48 case ui::mojom::CursorType::kWestResize: 49 return IDC_SIZEWE; 50 case ui::mojom::CursorType::kNorthSouthNoResize: 51 case ui::mojom::CursorType::kNorthSouthResize: 52 return IDC_SIZENS; 53 case ui::mojom::CursorType::kEastWestNoResize: 54 case ui::mojom::CursorType::kEastWestResize: 55 return IDC_SIZEWE; 56 case ui::mojom::CursorType::kNorthEastSouthWestNoResize: 57 case ui::mojom::CursorType::kNorthEastSouthWestResize: 58 return IDC_SIZENESW; 59 case ui::mojom::CursorType::kNorthWestSouthEastNoResize: 60 case ui::mojom::CursorType::kNorthWestSouthEastResize: 61 return IDC_SIZENWSE; 62 case ui::mojom::CursorType::kColumnResize: 63 return MAKEINTRESOURCE(IDC_COLRESIZE); 64 case ui::mojom::CursorType::kRowResize: 65 return MAKEINTRESOURCE(IDC_ROWRESIZE); 66 case ui::mojom::CursorType::kMiddlePanning: 67 return MAKEINTRESOURCE(IDC_PAN_MIDDLE); 68 case ui::mojom::CursorType::kEastPanning: 69 return MAKEINTRESOURCE(IDC_PAN_EAST); 70 case ui::mojom::CursorType::kNorthPanning: 71 return MAKEINTRESOURCE(IDC_PAN_NORTH); 72 case ui::mojom::CursorType::kNorthEastPanning: 73 return MAKEINTRESOURCE(IDC_PAN_NORTH_EAST); 74 case ui::mojom::CursorType::kNorthWestPanning: 75 return MAKEINTRESOURCE(IDC_PAN_NORTH_WEST); 76 case ui::mojom::CursorType::kSouthPanning: 77 return MAKEINTRESOURCE(IDC_PAN_SOUTH); 78 case ui::mojom::CursorType::kSouthEastPanning: 79 return MAKEINTRESOURCE(IDC_PAN_SOUTH_EAST); 80 case ui::mojom::CursorType::kSouthWestPanning: 81 return MAKEINTRESOURCE(IDC_PAN_SOUTH_WEST); 82 case ui::mojom::CursorType::kWestPanning: 83 return MAKEINTRESOURCE(IDC_PAN_WEST); 84 case ui::mojom::CursorType::kMove: 85 return IDC_SIZEALL; 86 case ui::mojom::CursorType::kVerticalText: 87 return MAKEINTRESOURCE(IDC_VERTICALTEXT); 88 case ui::mojom::CursorType::kCell: 89 return MAKEINTRESOURCE(IDC_CELL); 90 case ui::mojom::CursorType::kAlias: 91 return MAKEINTRESOURCE(IDC_ALIAS); 92 case ui::mojom::CursorType::kProgress: 93 return IDC_APPSTARTING; 94 case ui::mojom::CursorType::kNoDrop: 95 return IDC_NO; 96 case ui::mojom::CursorType::kCopy: 97 return MAKEINTRESOURCE(IDC_COPYCUR); 98 case ui::mojom::CursorType::kNotAllowed: 99 return IDC_NO; 100 case ui::mojom::CursorType::kZoomIn: 101 return MAKEINTRESOURCE(IDC_ZOOMIN); 102 case ui::mojom::CursorType::kZoomOut: 103 return MAKEINTRESOURCE(IDC_ZOOMOUT); 104 case ui::mojom::CursorType::kGrab: 105 return MAKEINTRESOURCE(IDC_HAND_GRAB); 106 case ui::mojom::CursorType::kGrabbing: 107 return MAKEINTRESOURCE(IDC_HAND_GRABBING); 108 case ui::mojom::CursorType::kNull: 109 return IDC_NO; 110 case ui::mojom::CursorType::kMiddlePanningVertical: 111 return MAKEINTRESOURCE(IDC_PAN_MIDDLE_VERTICAL); 112 case ui::mojom::CursorType::kMiddlePanningHorizontal: 113 return MAKEINTRESOURCE(IDC_PAN_MIDDLE_HORIZONTAL); 114 // TODO(cef): Find better cursors for these things 115 case ui::mojom::CursorType::kDndNone: 116 return IDC_ARROW; 117 case ui::mojom::CursorType::kDndMove: 118 return IDC_ARROW; 119 case ui::mojom::CursorType::kDndCopy: 120 return IDC_ARROW; 121 case ui::mojom::CursorType::kDndLink: 122 return IDC_ARROW; 123 case ui::mojom::CursorType::kContextMenu: 124 case ui::mojom::CursorType::kCustom: 125 case ui::mojom::CursorType::kNone: 126 NOTIMPLEMENTED(); 127 return IDC_ARROW; 128 } 129 NOTREACHED(); 130 return NULL; 131 } 132 IsSystemCursorID(LPCWSTR cursor_id)133bool IsSystemCursorID(LPCWSTR cursor_id) { 134 return cursor_id >= IDC_ARROW; // See WinUser.h 135 } 136 137 } // namespace 138 GetPlatformCursor(ui::mojom::CursorType type)139cef_cursor_handle_t GetPlatformCursor(ui::mojom::CursorType type) { 140 // Using a dark 1x1 bit bmp kNone cursor may still cause DWM to do composition 141 // work unnecessarily. Better to totally remove it from the screen. 142 // crbug.com/1069698 143 if (type == ui::mojom::CursorType::kNone) { 144 return nullptr; 145 } 146 147 HMODULE module_handle = NULL; 148 const wchar_t* cursor_id = ToCursorID(type); 149 if (!IsSystemCursorID(cursor_id)) { 150 module_handle = 151 ::GetModuleHandle(CefAppManager::Get()->GetResourceDllName()); 152 if (!module_handle) 153 module_handle = ::GetModuleHandle(NULL); 154 } 155 156 return LoadCursor(module_handle, cursor_id); 157 } 158 ToCursorHandle(scoped_refptr<ui::PlatformCursor> cursor)159cef_cursor_handle_t ToCursorHandle(scoped_refptr<ui::PlatformCursor> cursor) { 160 return ui::WinCursor::FromPlatformCursor(cursor)->hcursor(); 161 } 162 163 } // namespace cursor_util 164