• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &registryListener, 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