Skip to content

Commit cf2f9f1

Browse files
authored
Enable mouse cursors for TV devices (#290)
Fixes flutter-tizen/flutter-tizen#364. * Add the EnableCursor method to TizenWindowEcoreWl2 which is implemented for TV devices only. The method uses dlopen to invoke the Cursor_Set_Config function in libvd-win-util.so. * Style the code in SetTizenPolicyNotificationLevel in a consistent way. dlopen and dlsym should not affect the performance (launching time) noticeably.
1 parent 1730d83 commit cf2f9f1

File tree

2 files changed

+87
-14
lines changed

2 files changed

+87
-14
lines changed

shell/platform/tizen/tizen_window_ecore_wl2.cc

Lines changed: 85 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55

66
#include "tizen_window_ecore_wl2.h"
77

8+
#ifdef TV_PROFILE
9+
#include <dlfcn.h>
10+
#endif
11+
812
#include "flutter/shell/platform/tizen/flutter_tizen_view.h"
913
#include "flutter/shell/platform/tizen/logger.h"
1014

@@ -114,6 +118,72 @@ void TizenWindowEcoreWl2::SetWindowOptions() {
114118
int rotations[4] = {0, 90, 180, 270};
115119
ecore_wl2_window_available_rotations_set(ecore_wl2_window_, rotations,
116120
sizeof(rotations) / sizeof(int));
121+
122+
EnableCursor();
123+
}
124+
125+
void TizenWindowEcoreWl2::EnableCursor() {
126+
#ifdef TV_PROFILE
127+
// dlopen is used here because the TV-specific library libvd-win-util.so
128+
// and the relevant headers are not present in the rootstrap.
129+
void* handle = dlopen("libvd-win-util.so", RTLD_LAZY);
130+
if (!handle) {
131+
FT_LOG(Error) << "Could not open a shared library libvd-win-util.so.";
132+
return;
133+
}
134+
135+
// These functions are defined in vd-win-util's cursor_module.h.
136+
int (*CursorModule_Initialize)(wl_display * display, wl_registry * registry,
137+
wl_seat * seat, unsigned int id);
138+
int (*Cursor_Set_Config)(wl_surface * surface, uint32_t config_type,
139+
void* data);
140+
void (*CursorModule_Finalize)(void);
141+
*(void**)(&CursorModule_Initialize) =
142+
dlsym(handle, "CursorModule_Initialize");
143+
*(void**)(&Cursor_Set_Config) = dlsym(handle, "Cursor_Set_Config");
144+
*(void**)(&CursorModule_Finalize) = dlsym(handle, "CursorModule_Finalize");
145+
146+
if (!CursorModule_Initialize || !Cursor_Set_Config ||
147+
!CursorModule_Finalize) {
148+
FT_LOG(Error) << "Could not load symbols from the library.";
149+
dlclose(handle);
150+
return;
151+
}
152+
153+
wl_registry* registry = ecore_wl2_display_registry_get(ecore_wl2_display_);
154+
wl_seat* seat = ecore_wl2_input_seat_get(
155+
ecore_wl2_input_default_input_get(ecore_wl2_display_));
156+
if (!registry || !seat) {
157+
FT_LOG(Error)
158+
<< "Could not retreive wl_registry or wl_seat from the display.";
159+
dlclose(handle);
160+
return;
161+
}
162+
163+
Eina_Iterator* iter = ecore_wl2_display_globals_get(ecore_wl2_display_);
164+
Ecore_Wl2_Global* global = nullptr;
165+
166+
EINA_ITERATOR_FOREACH(iter, global) {
167+
if (strcmp(global->interface, "tizen_cursor") == 0) {
168+
if (!CursorModule_Initialize(wl2_display_, registry, seat, global->id)) {
169+
FT_LOG(Error) << "Failed to initialize the cursor module.";
170+
}
171+
}
172+
}
173+
eina_iterator_free(iter);
174+
175+
ecore_wl2_sync();
176+
177+
wl_surface* surface = ecore_wl2_window_surface_get(ecore_wl2_window_);
178+
// The config_type 1 refers to TIZEN_CURSOR_CONFIG_CURSOR_AVAILABLE
179+
// defined in the TV extension protocol tizen-extension-tv.xml.
180+
if (!Cursor_Set_Config(surface, 1, nullptr)) {
181+
FT_LOG(Error) << "Failed to set a cursor config value.";
182+
}
183+
184+
CursorModule_Finalize();
185+
dlclose(handle);
186+
#endif
117187
}
118188

119189
void TizenWindowEcoreWl2::RegisterEventHandlers() {
@@ -364,25 +434,26 @@ void TizenWindowEcoreWl2::OnGeometryChanged(Geometry geometry) {
364434
}
365435

366436
void TizenWindowEcoreWl2::SetTizenPolicyNotificationLevel(int level) {
437+
wl_registry* registry = ecore_wl2_display_registry_get(ecore_wl2_display_);
438+
if (!registry) {
439+
FT_LOG(Error) << "Could not retreive wl_registry from the display.";
440+
return;
441+
}
442+
367443
Eina_Iterator* iter = ecore_wl2_display_globals_get(ecore_wl2_display_);
368-
struct wl_registry* registry =
369-
ecore_wl2_display_registry_get(ecore_wl2_display_);
370-
371-
if (iter && registry) {
372-
Ecore_Wl2_Global* global = nullptr;
373-
374-
// Retrieve global objects to bind tizen policy
375-
EINA_ITERATOR_FOREACH(iter, global) {
376-
if (strcmp(global->interface, tizen_policy_interface.name) == 0) {
377-
tizen_policy_ = static_cast<tizen_policy*>(
378-
wl_registry_bind(registry, global->id, &tizen_policy_interface, 1));
379-
break;
380-
}
444+
Ecore_Wl2_Global* global = nullptr;
445+
446+
// Retrieve global objects to bind a tizen policy.
447+
EINA_ITERATOR_FOREACH(iter, global) {
448+
if (strcmp(global->interface, tizen_policy_interface.name) == 0) {
449+
tizen_policy_ = static_cast<tizen_policy*>(
450+
wl_registry_bind(registry, global->id, &tizen_policy_interface, 1));
451+
break;
381452
}
382453
}
383454
eina_iterator_free(iter);
384455

385-
if (tizen_policy_ == nullptr) {
456+
if (!tizen_policy_) {
386457
FT_LOG(Error)
387458
<< "Failed to initialize the tizen policy handle, the top_level "
388459
"attribute is ignored.";

shell/platform/tizen/tizen_window_ecore_wl2.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ class TizenWindowEcoreWl2 : public TizenWindow {
5959

6060
void SetWindowOptions();
6161

62+
void EnableCursor();
63+
6264
void RegisterEventHandlers();
6365

6466
void UnregisterEventHandlers();

0 commit comments

Comments
 (0)