1 /**************************************************************************
2 *
3 * Copyright 2010, 2011 BMW Car IT GmbH
4 * Copyright (C) 2011 DENSO CORPORATION and Robert Bosch Car Multimedia Gmbh
5 *
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 ****************************************************************************/
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <assert.h>
24 #include "WLContext.h"
25
26 #define WL_UNUSED(A) (A)=(A)
27
28 //////////////////////////////////////////////////////////////////////////////
29
30 static struct wl_registry_listener registryListener = {
31 WLContext::RegistryHandleGlobal,
32 NULL
33 };
34
35 static struct wl_seat_listener seatListener = {
36 WLContext::SeatHandleCapabilities,
37 NULL
38 };
39
40 //////////////////////////////////////////////////////////////////////////////
41
WLContext()42 WLContext::WLContext()
43 : m_wlDisplay(NULL)
44 , m_wlRegistry(NULL)
45 , m_wlCompositor(NULL)
46 , m_iviApp(NULL)
47 , m_wlPointerListener(NULL)
48 , m_wlKeyboardListener(NULL)
49 , m_wlTouchListener(NULL)
50 , m_wlCursorTheme(NULL)
51 , m_wlCursor(NULL)
52 , m_wlShm(NULL)
53 {
54 }
55
~WLContext()56 WLContext::~WLContext()
57 {
58 DestroyWLContext();
59 }
60
61 //////////////////////////////////////////////////////////////////////////////
62
63 /*
64 * The following correspondences between file names and cursors was copied
65 * from: https://bugs.kde.org/attachment.cgi?id=67313
66 */
67
68 static const char *left_ptrs[] = {
69 "left_ptr",
70 "default",
71 "top_left_arrow",
72 "left-arrow"
73 };
74
75 static void
create_cursors(WLContext * wlContext)76 create_cursors(WLContext* wlContext)
77 {
78 int size = 32;
79 unsigned int j;
80 struct wl_cursor *cursor = NULL;
81
82 wlContext->SetWLCursorTheme(wl_cursor_theme_load(NULL, size, wlContext->GetWLShm()));
83 if (!wlContext->GetWLCursorTheme()) {
84 fprintf(stderr, "could not load default theme\n");
85 return;
86 }
87 wlContext->SetWLCursor((wl_cursor*) malloc(sizeof(wl_cursor)));
88
89 for (j = 0; !cursor && j < 4; ++j)
90 cursor = wl_cursor_theme_get_cursor(wlContext->GetWLCursorTheme(),
91 left_ptrs[j]);
92
93 if (!cursor)
94 fprintf(stderr, "could not load cursor '%s'\n", left_ptrs[j]);
95
96 wlContext->SetWLCursor(cursor);
97 }
98
99 void
RegistryHandleGlobal(void * data,struct wl_registry * registry,uint32_t name,const char * interface,uint32_t version)100 WLContext::RegistryHandleGlobal(void* data,
101 struct wl_registry* registry,
102 uint32_t name,
103 const char* interface,
104 uint32_t version)
105 {
106 WL_UNUSED(version);
107
108 WLContext* surface = static_cast<WLContext*>(data);
109 assert(surface);
110
111 do {
112 if (!strcmp(interface, "wl_compositor")){
113 surface->SetWLCompositor(
114 (wl_compositor*)wl_registry_bind(registry,
115 name,
116 &wl_compositor_interface,
117 1));
118 break;
119 }
120
121 if (!strcmp(interface, "ivi_application")){
122 surface->SetIviApp(
123 (struct ivi_application*)wl_registry_bind(registry,
124 name,
125 &ivi_application_interface,
126 1));
127 }
128
129 if (!strcmp(interface, "wl_shm")){
130 surface->SetWLShm(
131 (struct wl_shm*)wl_registry_bind(registry,
132 name,
133 &wl_shm_interface,
134 1));
135 }
136
137 if (!strcmp(interface, "wl_seat")){
138 struct seat_data *seat_data = (struct seat_data *)calloc(1, sizeof *seat_data);
139 seat_data->ctx = surface;
140 seat_data->wlSeat = (wl_seat*)wl_registry_bind(
141 registry, name, &wl_seat_interface, 1);
142 wl_seat_add_listener(seat_data->wlSeat, &seatListener,
143 (void *)seat_data);
144 }
145 } while (0);
146 }
147
148 void
SeatHandleCapabilities(void * data,struct wl_seat * seat,uint32_t caps)149 WLContext::SeatHandleCapabilities(void* data, struct wl_seat* seat, uint32_t caps)
150 {
151 struct seat_data* context =
152 static_cast<struct seat_data*>(data);
153 assert(context);
154
155 if ((caps & WL_SEAT_CAPABILITY_POINTER) && !context->wlPointer){
156 context->wlPointer = wl_seat_get_pointer(seat);
157 wl_pointer_set_user_data(context->wlPointer, data);
158 wl_pointer_add_listener(context->wlPointer,
159 context->ctx->GetWLPointerListener(), data);
160 // create cursors
161 create_cursors(context->ctx);
162 context->ctx->SetPointerSurface(wl_compositor_create_surface(context->ctx->GetWLCompositor()));
163 } else
164 if (!(caps & WL_SEAT_CAPABILITY_POINTER) && context->wlPointer){
165 wl_pointer_destroy(context->wlPointer);
166 context->wlPointer = NULL;
167
168 if (context->ctx->GetPointerSurface()){
169 wl_surface_destroy(context->ctx->GetPointerSurface());
170 context->ctx->SetPointerSurface(NULL);
171 }
172
173 if (context->ctx->GetWLCursorTheme())
174 wl_cursor_theme_destroy(context->ctx->GetWLCursorTheme());
175
176 if (context->ctx->GetWLCursor())
177 free(context->ctx->GetWLCursor());
178 }
179
180 if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !context->wlKeyboard){
181 context->wlKeyboard = wl_seat_get_keyboard(seat);
182 wl_keyboard_set_user_data(context->wlKeyboard, data);
183 wl_keyboard_add_listener(context->wlKeyboard,
184 context->ctx->GetWLKeyboardListener(), data);
185 } else
186 if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && context->wlKeyboard){
187 wl_keyboard_destroy(context->wlKeyboard);
188 context->wlKeyboard = NULL;
189 }
190
191 if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !context->wlTouch){
192 context->wlTouch = wl_seat_get_touch(seat);
193 wl_touch_set_user_data(context->wlTouch, data);
194 wl_touch_add_listener(context->wlTouch, context->ctx->GetWLTouchListener(), data);
195 } else
196 if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && context->wlTouch){
197 wl_touch_destroy(context->wlTouch);
198 context->wlTouch = NULL;
199 }
200 wl_display_dispatch(context->ctx->GetWLDisplay());
201 }
202
203 //////////////////////////////////////////////////////////////////////////////
204
205 bool
InitWLContext(const struct wl_pointer_listener * wlPointerListener,const struct wl_keyboard_listener * wlKeyboardListener,const struct wl_touch_listener * wlTouchListener)206 WLContext::InitWLContext(const struct wl_pointer_listener* wlPointerListener,
207 const struct wl_keyboard_listener* wlKeyboardListener,
208 const struct wl_touch_listener* wlTouchListener)
209 {
210 m_wlPointerListener = const_cast<wl_pointer_listener*>(wlPointerListener);
211 m_wlKeyboardListener = const_cast<wl_keyboard_listener*>(wlKeyboardListener);
212 m_wlTouchListener = const_cast<wl_touch_listener*>(wlTouchListener);
213
214 m_wlDisplay = wl_display_connect(NULL);
215
216 m_wlRegistry = wl_display_get_registry(m_wlDisplay);
217 wl_registry_add_listener(m_wlRegistry, ®istryListener, this);
218 wl_display_dispatch(m_wlDisplay);
219 wl_display_roundtrip(m_wlDisplay);
220
221 return true;
222 }
223
224 void
DestroyWLContext()225 WLContext::DestroyWLContext()
226 {
227 if (m_iviApp)
228 ivi_application_destroy(m_iviApp);
229
230 if (m_wlCompositor)
231 wl_compositor_destroy(m_wlCompositor);
232
233 if (m_pointerSurface){
234 wl_surface_destroy(m_pointerSurface);
235 m_pointerSurface = NULL;
236 }
237
238 if (m_wlCursorTheme)
239 wl_cursor_theme_destroy(m_wlCursorTheme);
240
241 if (m_wlCursor)
242 free(m_wlCursor);
243
244 wl_registry_destroy(m_wlRegistry);
245 wl_display_flush(m_wlDisplay);
246 wl_display_disconnect(m_wlDisplay);
247 }
248