2 * Copyright © 2012 Philipp Brüschweiler
4 * Permission to use, copy, modify, distribute, and sell this software and
5 * its documentation for any purpose is hereby granted without fee, provided
6 * that the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of the copyright holders not be used in
9 * advertising or publicity pertaining to distribution of the software
10 * without specific, written prior permission. The copyright holders make
11 * no representations about the suitability of this software for any
12 * purpose. It is provided "as is" without express or implied warranty.
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
15 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
17 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
18 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
19 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
28 #include <wayland-client.h>
30 #include "../shared/os-compatibility.h"
32 typedef void (*print_info_t)(void *info);
48 int32_t width, height;
53 struct global_info global;
55 struct wl_output *output;
59 int32_t physical_width, physical_height;
60 enum wl_output_subpixel subpixel;
61 enum wl_output_transform output_transform;
76 struct global_info global;
79 struct wl_list formats;
83 struct global_info global;
86 uint32_t capabilities;
91 struct wl_display *display;
92 struct wl_registry *registry;
95 bool roundtrip_needed;
104 fprintf(stderr, "out of memory\n");
112 print_global_info(void *data)
114 struct global_info *global = data;
116 printf("interface: '%s', version: %u, name: %u\n",
117 global->interface, global->version, global->id);
121 init_global_info(struct weston_info *info,
122 struct global_info *global, uint32_t id,
123 const char *interface, uint32_t version)
126 global->version = version;
127 global->interface = strdup(interface);
129 wl_list_insert(info->infos.prev, &global->link);
133 print_output_info(void *data)
135 struct output_info *output = data;
136 struct output_mode *mode;
137 const char *subpixel_orientation;
138 const char *transform;
140 print_global_info(data);
142 switch (output->geometry.subpixel) {
143 case WL_OUTPUT_SUBPIXEL_UNKNOWN:
144 subpixel_orientation = "unknown";
146 case WL_OUTPUT_SUBPIXEL_NONE:
147 subpixel_orientation = "none";
149 case WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB:
150 subpixel_orientation = "horizontal rgb";
152 case WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR:
153 subpixel_orientation = "horizontal bgr";
155 case WL_OUTPUT_SUBPIXEL_VERTICAL_RGB:
156 subpixel_orientation = "vertical rgb";
158 case WL_OUTPUT_SUBPIXEL_VERTICAL_BGR:
159 subpixel_orientation = "vertical bgr";
162 fprintf(stderr, "unknown subpixel orientation %u\n",
163 output->geometry.subpixel);
164 subpixel_orientation = "unexpected value";
168 switch (output->geometry.output_transform) {
169 case WL_OUTPUT_TRANSFORM_NORMAL:
170 transform = "normal";
172 case WL_OUTPUT_TRANSFORM_90:
175 case WL_OUTPUT_TRANSFORM_180:
178 case WL_OUTPUT_TRANSFORM_270:
181 case WL_OUTPUT_TRANSFORM_FLIPPED:
182 transform = "flipped";
184 case WL_OUTPUT_TRANSFORM_FLIPPED_90:
185 transform = "flipped 90°";
187 case WL_OUTPUT_TRANSFORM_FLIPPED_180:
188 transform = "flipped 180°";
190 case WL_OUTPUT_TRANSFORM_FLIPPED_270:
191 transform = "flipped 270°";
194 fprintf(stderr, "unknown output transform %u\n",
195 output->geometry.output_transform);
196 transform = "unexpected value";
200 printf("\tx: %d, y: %d,\n",
201 output->geometry.x, output->geometry.y);
202 printf("\tphysical_width: %d mm, physical_height: %d mm,\n",
203 output->geometry.physical_width,
204 output->geometry.physical_height);
205 printf("\tmake: '%s', model: '%s',\n",
206 output->geometry.make, output->geometry.model);
207 printf("\tsubpixel_orientation: %s, output_tranform: %s,\n",
208 subpixel_orientation, transform);
210 wl_list_for_each(mode, &output->modes, link) {
213 printf("\t\twidth: %d px, height: %d px, refresh: %.f Hz,\n",
214 mode->width, mode->height,
215 (float) mode->refresh / 1000);
217 printf("\t\tflags:");
218 if (mode->flags & WL_OUTPUT_MODE_CURRENT)
220 if (mode->flags & WL_OUTPUT_MODE_PREFERRED)
221 printf(" preferred");
227 print_shm_info(void *data)
229 struct shm_info *shm = data;
230 struct shm_format *format;
232 print_global_info(data);
234 printf("\tformats:");
236 wl_list_for_each(format, &shm->formats, link)
237 switch (format->format) {
238 case WL_SHM_FORMAT_ARGB8888:
241 case WL_SHM_FORMAT_XRGB8888:
244 case WL_SHM_FORMAT_RGB565:
248 printf(" unknown(%08x)", format->format);
256 print_seat_info(void *data)
258 struct seat_info *seat = data;
260 print_global_info(data);
262 printf("\tname: %s\n", seat->name);
263 printf("\tcapabilities:");
265 if (seat->capabilities & WL_SEAT_CAPABILITY_POINTER)
267 if (seat->capabilities & WL_SEAT_CAPABILITY_KEYBOARD)
269 if (seat->capabilities & WL_SEAT_CAPABILITY_TOUCH)
276 seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
277 enum wl_seat_capability caps)
279 struct seat_info *seat = data;
280 seat->capabilities = caps;
284 seat_handle_name(void *data, struct wl_seat *wl_seat,
287 struct seat_info *seat = data;
288 seat->name = strdup(name);
291 static const struct wl_seat_listener seat_listener = {
292 seat_handle_capabilities,
297 add_seat_info(struct weston_info *info, uint32_t id, uint32_t version)
299 struct seat_info *seat = xmalloc(sizeof *seat);
301 init_global_info(info, &seat->global, id, "wl_seat", version);
302 seat->global.print = print_seat_info;
304 seat->seat = wl_registry_bind(info->registry,
305 id, &wl_seat_interface, 2);
306 wl_seat_add_listener(seat->seat, &seat_listener, seat);
308 info->roundtrip_needed = true;
312 shm_handle_format(void *data, struct wl_shm *wl_shm, uint32_t format)
314 struct shm_info *shm = data;
315 struct shm_format *shm_format = xmalloc(sizeof *shm_format);
317 wl_list_insert(&shm->formats, &shm_format->link);
318 shm_format->format = format;
321 static const struct wl_shm_listener shm_listener = {
326 add_shm_info(struct weston_info *info, uint32_t id, uint32_t version)
328 struct shm_info *shm = xmalloc(sizeof *shm);
330 init_global_info(info, &shm->global, id, "wl_shm", version);
331 shm->global.print = print_shm_info;
332 wl_list_init(&shm->formats);
334 shm->shm = wl_registry_bind(info->registry,
335 id, &wl_shm_interface, 1);
336 wl_shm_add_listener(shm->shm, &shm_listener, shm);
338 info->roundtrip_needed = true;
342 output_handle_geometry(void *data, struct wl_output *wl_output,
343 int32_t x, int32_t y,
344 int32_t physical_width, int32_t physical_height,
346 const char *make, const char *model,
347 int32_t output_transform)
349 struct output_info *output = data;
351 output->geometry.x = x;
352 output->geometry.y = y;
353 output->geometry.physical_width = physical_width;
354 output->geometry.physical_height = physical_height;
355 output->geometry.subpixel = subpixel;
356 output->geometry.make = strdup(make);
357 output->geometry.model = strdup(model);
358 output->geometry.output_transform = output_transform;
362 output_handle_mode(void *data, struct wl_output *wl_output,
363 uint32_t flags, int32_t width, int32_t height,
366 struct output_info *output = data;
367 struct output_mode *mode = xmalloc(sizeof *mode);
371 mode->height = height;
372 mode->refresh = refresh;
374 wl_list_insert(output->modes.prev, &mode->link);
377 static const struct wl_output_listener output_listener = {
378 output_handle_geometry,
383 add_output_info(struct weston_info *info, uint32_t id, uint32_t version)
385 struct output_info *output = xmalloc(sizeof *output);
387 init_global_info(info, &output->global, id, "wl_output", version);
388 output->global.print = print_output_info;
390 wl_list_init(&output->modes);
392 output->output = wl_registry_bind(info->registry, id,
393 &wl_output_interface, 1);
394 wl_output_add_listener(output->output, &output_listener,
397 info->roundtrip_needed = true;
401 add_global_info(struct weston_info *info, uint32_t id,
402 const char *interface, uint32_t version)
404 struct global_info *global = xmalloc(sizeof *global);
406 init_global_info(info, global, id, interface, version);
407 global->print = print_global_info;
411 global_handler(void *data, struct wl_registry *registry, uint32_t id,
412 const char *interface, uint32_t version)
414 struct weston_info *info = data;
416 if (!strcmp(interface, "wl_seat"))
417 add_seat_info(info, id, version);
418 else if (!strcmp(interface, "wl_shm"))
419 add_shm_info(info, id, version);
420 else if (!strcmp(interface, "wl_output"))
421 add_output_info(info, id, version);
423 add_global_info(info, id, interface, version);
427 global_remove_handler(void *data, struct wl_registry *registry, uint32_t name)
431 static const struct wl_registry_listener registry_listener = {
433 global_remove_handler
437 print_infos(struct wl_list *infos)
439 struct global_info *info;
441 wl_list_for_each(info, infos, link)
446 main(int argc, char **argv)
448 struct weston_info info;
450 info.display = wl_display_connect(NULL);
452 fprintf(stderr, "failed to create display: %m\n");
456 wl_list_init(&info.infos);
458 info.registry = wl_display_get_registry(info.display);
459 wl_registry_add_listener(info.registry, ®istry_listener, &info);
462 info.roundtrip_needed = false;
463 wl_display_roundtrip(info.display);
464 } while (info.roundtrip_needed);
466 print_infos(&info.infos);