├── .gitignore ├── Makefile.am ├── README ├── autogen.sh ├── clients ├── .gitignore ├── Makefile.am ├── cairo-util.c ├── cairo-util.h ├── clickdot.c ├── desktop-shell.c ├── dnd.c ├── eventdemo.c ├── flower.c ├── gears.c ├── glmatrix.c ├── image.c ├── matrix3.xpm ├── resizor.c ├── screenshot ├── screenshot.c ├── simple-egl.c ├── simple-shm.c ├── simple-touch.c ├── smoke.c ├── tablet-shell.c ├── terminal.c ├── view.c ├── window.c ├── window.h ├── wscreensaver-glue.c ├── wscreensaver-glue.h ├── wscreensaver.c └── wscreensaver.h ├── configure.ac ├── data ├── .gitignore ├── COPYING ├── Makefile.am ├── border.png ├── bottom_left_corner.png ├── bottom_right_corner.png ├── bottom_side.png ├── dnd-copy.png ├── dnd-link.png ├── dnd-move.png ├── grabbing.png ├── hand1.png ├── hand2.png ├── left_ptr.png ├── left_side.png ├── pattern.png ├── right_side.png ├── sb_h_double_arrow.png ├── sb_v_double_arrow.png ├── terminal.png ├── top_left_corner.png ├── top_right_corner.png ├── top_side.png ├── wayland.svg └── xterm.png ├── depcomp ├── install-sh ├── ltmain.sh ├── missing ├── protocol ├── Makefile.am ├── desktop-shell.xml ├── screenshooter.xml ├── tablet-shell.xml └── xserver.xml ├── shared ├── Makefile.am ├── config-parser.c ├── config-parser.h ├── image-loader.c └── option-parser.c ├── src ├── .gitignore ├── Makefile.am ├── adwc.c ├── adwc.h ├── adwc_config.h ├── be-drm.c ├── be-drm.h ├── compositor-drm.c ├── compositor-openwfd.c ├── compositor-wayland.c ├── compositor-x11.c ├── compositor.c ├── compositor.h ├── evdev.c ├── evdev.h ├── hash.c ├── hash.h ├── launcher-util.c ├── launcher-util.h ├── libbacklight.c ├── libbacklight.h ├── matrix.c ├── matrix.h ├── screenshooter.c ├── shell.c ├── tablet-shell.c ├── tty.c ├── util.c ├── weston-launch.c ├── weston-launch.h └── xserver-launcher.c ├── tests ├── .gitignore ├── Makefile.am ├── matrix-test.c └── setbacklight.c └── weston.ini /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | 3 | Makefile 4 | Makefile.in 5 | .deps 6 | .libs 7 | 8 | *~ 9 | *.o 10 | *.lo 11 | *.la 12 | 13 | *.avi 14 | 15 | /libtool 16 | /config* 17 | /autom4te.cache/ 18 | /aclocal.m4 19 | /stamp-h1 20 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = shared src clients data protocol tests 2 | 3 | DISTCHECK_CONFIGURE_FLAGS = --disable-setuid-install 4 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Wayland Demos 2 | 3 | This repository contains a few demos application for the Wayland 4 | project. There's a sample compositor that can run on KMS, under X11 5 | or under another Wayland compositor and there's a handful of simple 6 | clients that demonstrate various aspects of Wayland: 7 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | test -n "$srcdir" || srcdir=`dirname "$0"` 4 | test -n "$srcdir" || srcdir=. 5 | ( 6 | cd "$srcdir" && 7 | autoreconf --force -v --install 8 | ) || exit 9 | test -n "$NOCONFIGURE" || "$srcdir/configure" "$@" 10 | -------------------------------------------------------------------------------- /clients/.gitignore: -------------------------------------------------------------------------------- 1 | clickdot 2 | desktop-shell-client-protocol.h 3 | desktop-shell-protocol.c 4 | dnd 5 | eventdemo 6 | flower 7 | gears 8 | image 9 | libtoytoolkit.a 10 | resizor 11 | screenshooter-client-protocol.h 12 | screenshooter-protocol.c 13 | simple-egl 14 | simple-shm 15 | simple-touch 16 | smoke 17 | tablet-shell-client-protocol.h 18 | tablet-shell-protocol.c 19 | view 20 | weston-desktop-shell 21 | weston-tablet-shell 22 | weston-screenshooter 23 | weston-terminal 24 | wscreensaver 25 | -------------------------------------------------------------------------------- /clients/Makefile.am: -------------------------------------------------------------------------------- 1 | bin_PROGRAMS = \ 2 | $(terminal) 3 | 4 | noinst_PROGRAMS = \ 5 | $(clients_programs) \ 6 | $(poppler_programs) \ 7 | $(simple_clients_programs) 8 | 9 | libexec_PROGRAMS = \ 10 | $(desktop_shell) \ 11 | $(tablet_shell) \ 12 | $(screenshooter) 13 | 14 | if BUILD_SIMPLE_CLIENTS 15 | simple_clients_programs = \ 16 | simple-egl \ 17 | simple-shm \ 18 | simple-touch 19 | 20 | simple_egl_SOURCES = simple-egl.c 21 | simple_egl_LDADD = $(SIMPLE_CLIENT_LIBS) -lm 22 | 23 | simple_shm_SOURCES = simple-shm.c 24 | simple_shm_LDADD = $(SIMPLE_CLIENT_LIBS) 25 | 26 | simple_touch_SOURCES = simple-touch.c 27 | simple_touch_LDADD = $(SIMPLE_CLIENT_LIBS) 28 | endif 29 | 30 | if BUILD_CLIENTS 31 | terminal = weston-terminal 32 | 33 | clients_programs = \ 34 | flower \ 35 | image \ 36 | dnd \ 37 | smoke \ 38 | resizor \ 39 | eventdemo \ 40 | clickdot \ 41 | $(full_gl_client_programs) 42 | 43 | desktop_shell = weston-desktop-shell 44 | tablet_shell = weston-tablet-shell 45 | screenshooter = weston-screenshooter 46 | 47 | noinst_LIBRARIES = libtoytoolkit.a 48 | 49 | AM_CFLAGS = $(GCC_CFLAGS) 50 | AM_CPPFLAGS = \ 51 | -DDATADIR='"$(datadir)"' \ 52 | -DBINDIR='"$(bindir)"' \ 53 | $(CLIENT_CFLAGS) $(CAIRO_EGL_CFLAGS) 54 | 55 | libtoytoolkit_a_SOURCES = \ 56 | window.c \ 57 | window.h \ 58 | cairo-util.c \ 59 | cairo-util.h 60 | 61 | toolkit_libs = \ 62 | libtoytoolkit.a \ 63 | ../shared/libconfig-parser.la \ 64 | $(CLIENT_LIBS) $(CAIRO_EGL_LIBS) -lrt -lm 65 | 66 | flower_SOURCES = flower.c 67 | flower_LDADD = $(toolkit_libs) 68 | 69 | weston_screenshooter_SOURCES = screenshot.c screenshooter-protocol.c 70 | weston_screenshooter_LDADD = $(toolkit_libs) 71 | 72 | weston_terminal_SOURCES = terminal.c 73 | weston_terminal_LDADD = $(toolkit_libs) -lutil 74 | 75 | image_SOURCES = image.c 76 | image_LDADD = $(toolkit_libs) 77 | 78 | dnd_SOURCES = dnd.c 79 | dnd_LDADD = $(toolkit_libs) 80 | 81 | smoke_SOURCES = smoke.c 82 | smoke_LDADD = $(toolkit_libs) 83 | 84 | resizor_SOURCES = resizor.c 85 | resizor_LDADD = $(toolkit_libs) 86 | 87 | eventdemo_SOURCES = eventdemo.c 88 | eventdemo_LDADD = $(toolkit_libs) 89 | 90 | clickdot_SOURCES = clickdot.c 91 | clickdot_LDADD = $(toolkit_libs) 92 | 93 | weston_desktop_shell_SOURCES = \ 94 | desktop-shell.c \ 95 | desktop-shell-client-protocol.h \ 96 | desktop-shell-protocol.c 97 | weston_desktop_shell_LDADD = $(toolkit_libs) \ 98 | ../shared/libconfig-parser.la 99 | 100 | weston_tablet_shell_SOURCES = \ 101 | tablet-shell.c \ 102 | tablet-shell-client-protocol.h \ 103 | tablet-shell-protocol.c 104 | weston_tablet_shell_LDADD = $(toolkit_libs) \ 105 | ../shared/libconfig-parser.la 106 | 107 | BUILT_SOURCES = \ 108 | screenshooter-client-protocol.h \ 109 | screenshooter-protocol.c \ 110 | desktop-shell-client-protocol.h \ 111 | desktop-shell-protocol.c \ 112 | tablet-shell-client-protocol.h \ 113 | tablet-shell-protocol.c 114 | 115 | CLEANFILES = $(BUILT_SOURCES) 116 | endif 117 | 118 | if BUILD_FULL_GL_CLIENTS 119 | full_gl_client_programs = \ 120 | gears \ 121 | wscreensaver 122 | 123 | gears_SOURCES = gears.c 124 | gears_LDADD = $(toolkit_libs) 125 | 126 | wscreensaver_SOURCES = \ 127 | wscreensaver.c \ 128 | wscreensaver.h \ 129 | desktop-shell-client-protocol.h \ 130 | desktop-shell-protocol.c \ 131 | wscreensaver-glue.c \ 132 | wscreensaver-glue.h \ 133 | glmatrix.c \ 134 | matrix3.xpm 135 | wscreensaver_LDADD = $(toolkit_libs) -lGLU 136 | endif 137 | 138 | @wayland_scanner_rules@ 139 | 140 | if HAVE_POPPLER 141 | poppler_programs = view 142 | view_SOURCES = view.c 143 | view_LDADD = $(toolkit_libs) $(POPPLER_LIBS) 144 | view_CPPFLAGS = $(AM_CPPFLAGS) $(POPPLER_CFLAGS) 145 | endif 146 | -------------------------------------------------------------------------------- /clients/cairo-util.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2008 Kristian Høgsberg 3 | * Copyright © 2012 Intel Corporation 4 | * 5 | * Permission to use, copy, modify, distribute, and sell this software and its 6 | * documentation for any purpose is hereby granted without fee, provided that 7 | * the above copyright notice appear in all copies and that both that copyright 8 | * notice and this permission notice appear in supporting documentation, and 9 | * that the name of the copyright holders not be used in advertising or 10 | * publicity pertaining to distribution of the software without specific, 11 | * written prior permission. The copyright holders make no representations 12 | * about the suitability of this software for any purpose. It is provided "as 13 | * is" without express or implied warranty. 14 | * 15 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 17 | * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 18 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 19 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 20 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 21 | * OF THIS SOFTWARE. 22 | */ 23 | 24 | #include "../config.h" 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include "cairo-util.h" 33 | 34 | #include "../shared/config-parser.h" 35 | 36 | #define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0]) 37 | 38 | void 39 | surface_flush_device(cairo_surface_t *surface) 40 | { 41 | cairo_device_t *device; 42 | 43 | device = cairo_surface_get_device(surface); 44 | if (device) 45 | cairo_device_flush(device); 46 | } 47 | 48 | void 49 | blur_surface(cairo_surface_t *surface, int margin) 50 | { 51 | int32_t width, height, stride, x, y, z, w; 52 | uint8_t *src, *dst; 53 | uint32_t *s, *d, a, p; 54 | int i, j, k, size, half; 55 | uint32_t kernel[71]; 56 | double f; 57 | 58 | size = ARRAY_LENGTH(kernel); 59 | width = cairo_image_surface_get_width(surface); 60 | height = cairo_image_surface_get_height(surface); 61 | stride = cairo_image_surface_get_stride(surface); 62 | src = cairo_image_surface_get_data(surface); 63 | 64 | dst = malloc(height * stride); 65 | 66 | half = size / 2; 67 | a = 0; 68 | for (i = 0; i < size; i++) { 69 | f = (i - half); 70 | kernel[i] = exp(- f * f / ARRAY_LENGTH(kernel)) * 10000; 71 | a += kernel[i]; 72 | } 73 | 74 | for (i = 0; i < height; i++) { 75 | s = (uint32_t *) (src + i * stride); 76 | d = (uint32_t *) (dst + i * stride); 77 | for (j = 0; j < width; j++) { 78 | if (margin < j && j < width - margin) { 79 | d[j] = s[j]; 80 | continue; 81 | } 82 | 83 | x = 0; 84 | y = 0; 85 | z = 0; 86 | w = 0; 87 | for (k = 0; k < size; k++) { 88 | if (j - half + k < 0 || j - half + k >= width) 89 | continue; 90 | p = s[j - half + k]; 91 | 92 | x += (p >> 24) * kernel[k]; 93 | y += ((p >> 16) & 0xff) * kernel[k]; 94 | z += ((p >> 8) & 0xff) * kernel[k]; 95 | w += (p & 0xff) * kernel[k]; 96 | } 97 | d[j] = (x / a << 24) | (y / a << 16) | (z / a << 8) | w / a; 98 | } 99 | } 100 | 101 | for (i = 0; i < height; i++) { 102 | s = (uint32_t *) (dst + i * stride); 103 | d = (uint32_t *) (src + i * stride); 104 | for (j = 0; j < width; j++) { 105 | if (margin <= i && i < height - margin) { 106 | d[j] = s[j]; 107 | continue; 108 | } 109 | 110 | x = 0; 111 | y = 0; 112 | z = 0; 113 | w = 0; 114 | for (k = 0; k < size; k++) { 115 | if (i - half + k < 0 || i - half + k >= height) 116 | continue; 117 | s = (uint32_t *) (dst + (i - half + k) * stride); 118 | p = s[j]; 119 | 120 | x += (p >> 24) * kernel[k]; 121 | y += ((p >> 16) & 0xff) * kernel[k]; 122 | z += ((p >> 8) & 0xff) * kernel[k]; 123 | w += (p & 0xff) * kernel[k]; 124 | } 125 | d[j] = (x / a << 24) | (y / a << 16) | (z / a << 8) | w / a; 126 | } 127 | } 128 | 129 | free(dst); 130 | cairo_surface_mark_dirty(surface); 131 | } 132 | 133 | void 134 | tile_mask(cairo_t *cr, cairo_surface_t *surface, 135 | int x, int y, int width, int height, int margin, int top_margin) 136 | { 137 | cairo_pattern_t *pattern; 138 | cairo_matrix_t matrix; 139 | int i, fx, fy, vmargin; 140 | 141 | cairo_set_operator(cr, CAIRO_OPERATOR_OVER); 142 | pattern = cairo_pattern_create_for_surface (surface); 143 | cairo_pattern_set_filter(pattern, CAIRO_FILTER_NEAREST); 144 | 145 | for (i = 0; i < 4; i++) { 146 | fx = i & 1; 147 | fy = i >> 1; 148 | 149 | cairo_matrix_init_translate(&matrix, 150 | -x + fx * (128 - width), 151 | -y + fy * (128 - height)); 152 | cairo_pattern_set_matrix(pattern, &matrix); 153 | 154 | if (fy) 155 | vmargin = margin; 156 | else 157 | vmargin = top_margin; 158 | 159 | cairo_reset_clip(cr); 160 | cairo_rectangle(cr, 161 | x + fx * (width - margin), 162 | y + fy * (height - vmargin), 163 | margin, vmargin); 164 | cairo_clip (cr); 165 | cairo_mask(cr, pattern); 166 | } 167 | 168 | /* Top stretch */ 169 | cairo_matrix_init_translate(&matrix, 60, 0); 170 | cairo_matrix_scale(&matrix, 8.0 / width, 1); 171 | cairo_matrix_translate(&matrix, -x - width / 2, -y); 172 | cairo_pattern_set_matrix(pattern, &matrix); 173 | cairo_rectangle(cr, x + margin, y, width - 2 * margin, margin); 174 | 175 | cairo_reset_clip(cr); 176 | cairo_rectangle(cr, 177 | x + margin, 178 | y, 179 | width - 2 * margin, margin); 180 | cairo_clip (cr); 181 | cairo_mask(cr, pattern); 182 | 183 | /* Bottom stretch */ 184 | cairo_matrix_translate(&matrix, 0, -height + 128); 185 | cairo_pattern_set_matrix(pattern, &matrix); 186 | 187 | cairo_reset_clip(cr); 188 | cairo_rectangle(cr, x + margin, y + height - margin, 189 | width - 2 * margin, margin); 190 | cairo_clip (cr); 191 | cairo_mask(cr, pattern); 192 | 193 | /* Left stretch */ 194 | cairo_matrix_init_translate(&matrix, 0, 60); 195 | cairo_matrix_scale(&matrix, 1, 8.0 / height); 196 | cairo_matrix_translate(&matrix, -x, -y - height / 2); 197 | cairo_pattern_set_matrix(pattern, &matrix); 198 | cairo_reset_clip(cr); 199 | cairo_rectangle(cr, x, y + margin, margin, height - 2 * margin); 200 | cairo_clip (cr); 201 | cairo_mask(cr, pattern); 202 | 203 | /* Right stretch */ 204 | cairo_matrix_translate(&matrix, -width + 128, 0); 205 | cairo_pattern_set_matrix(pattern, &matrix); 206 | cairo_rectangle(cr, x + width - margin, y + margin, 207 | margin, height - 2 * margin); 208 | cairo_reset_clip(cr); 209 | cairo_clip (cr); 210 | cairo_mask(cr, pattern); 211 | 212 | cairo_pattern_destroy(pattern); 213 | cairo_reset_clip(cr); 214 | } 215 | 216 | void 217 | tile_source(cairo_t *cr, cairo_surface_t *surface, 218 | int x, int y, int width, int height, int margin, int top_margin) 219 | { 220 | cairo_pattern_t *pattern; 221 | cairo_matrix_t matrix; 222 | int i, fx, fy, vmargin; 223 | 224 | cairo_set_operator(cr, CAIRO_OPERATOR_OVER); 225 | pattern = cairo_pattern_create_for_surface (surface); 226 | cairo_pattern_set_filter(pattern, CAIRO_FILTER_NEAREST); 227 | cairo_set_source(cr, pattern); 228 | cairo_pattern_destroy(pattern); 229 | 230 | for (i = 0; i < 4; i++) { 231 | fx = i & 1; 232 | fy = i >> 1; 233 | 234 | cairo_matrix_init_translate(&matrix, 235 | -x + fx * (128 - width), 236 | -y + fy * (128 - height)); 237 | cairo_pattern_set_matrix(pattern, &matrix); 238 | 239 | if (fy) 240 | vmargin = margin; 241 | else 242 | vmargin = top_margin; 243 | 244 | cairo_rectangle(cr, 245 | x + fx * (width - margin), 246 | y + fy * (height - vmargin), 247 | margin, vmargin); 248 | cairo_fill(cr); 249 | } 250 | 251 | /* Top stretch */ 252 | cairo_matrix_init_translate(&matrix, 60, 0); 253 | cairo_matrix_scale(&matrix, 8.0 / (width - 2 * margin), 1); 254 | cairo_matrix_translate(&matrix, -x - width / 2, -y); 255 | cairo_pattern_set_matrix(pattern, &matrix); 256 | cairo_rectangle(cr, x + margin, y, width - 2 * margin, top_margin); 257 | cairo_fill(cr); 258 | 259 | /* Bottom stretch */ 260 | cairo_matrix_translate(&matrix, 0, -height + 128); 261 | cairo_pattern_set_matrix(pattern, &matrix); 262 | cairo_rectangle(cr, x + margin, y + height - margin, 263 | width - 2 * margin, margin); 264 | cairo_fill(cr); 265 | 266 | /* Left stretch */ 267 | cairo_matrix_init_translate(&matrix, 0, 60); 268 | cairo_matrix_scale(&matrix, 1, 8.0 / (height - margin - top_margin)); 269 | cairo_matrix_translate(&matrix, -x, -y - height / 2); 270 | cairo_pattern_set_matrix(pattern, &matrix); 271 | cairo_rectangle(cr, x, y + top_margin, 272 | margin, height - margin - top_margin); 273 | cairo_fill(cr); 274 | 275 | /* Right stretch */ 276 | cairo_matrix_translate(&matrix, -width + 128, 0); 277 | cairo_pattern_set_matrix(pattern, &matrix); 278 | cairo_rectangle(cr, x + width - margin, y + top_margin, 279 | margin, height - margin - top_margin); 280 | cairo_fill(cr); 281 | } 282 | 283 | void 284 | rounded_rect(cairo_t *cr, int x0, int y0, int x1, int y1, int radius) 285 | { 286 | cairo_move_to(cr, x0, y0 + radius); 287 | cairo_arc(cr, x0 + radius, y0 + radius, radius, M_PI, 3 * M_PI / 2); 288 | cairo_line_to(cr, x1 - radius, y0); 289 | cairo_arc(cr, x1 - radius, y0 + radius, radius, 3 * M_PI / 2, 2 * M_PI); 290 | cairo_line_to(cr, x1, y1 - radius); 291 | cairo_arc(cr, x1 - radius, y1 - radius, radius, 0, M_PI / 2); 292 | cairo_line_to(cr, x0 + radius, y1); 293 | cairo_arc(cr, x0 + radius, y1 - radius, radius, M_PI / 2, M_PI); 294 | cairo_close_path(cr); 295 | } 296 | 297 | cairo_surface_t * 298 | load_cairo_surface(const char *filename) 299 | { 300 | pixman_image_t *image; 301 | int width, height, stride; 302 | void *data; 303 | 304 | image = load_image(filename); 305 | if (image == NULL) { 306 | return NULL; 307 | } 308 | 309 | data = pixman_image_get_data(image); 310 | width = pixman_image_get_width(image); 311 | height = pixman_image_get_height(image); 312 | stride = pixman_image_get_stride(image); 313 | 314 | return cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32, 315 | width, height, stride); 316 | } 317 | -------------------------------------------------------------------------------- /clients/cairo-util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2008 Kristian Høgsberg 3 | * 4 | * Permission to use, copy, modify, distribute, and sell this software and its 5 | * documentation for any purpose is hereby granted without fee, provided that 6 | * the above copyright notice appear in all copies and that both that copyright 7 | * notice and this permission notice appear in supporting documentation, and 8 | * that the name of the copyright holders not be used in advertising or 9 | * publicity pertaining to distribution of the software without specific, 10 | * written prior permission. The copyright holders make no representations 11 | * about the suitability of this software for any purpose. It is provided "as 12 | * is" without express or implied warranty. 13 | * 14 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 | * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 20 | * OF THIS SOFTWARE. 21 | */ 22 | 23 | #ifndef _CAIRO_UTIL_H 24 | #define _CAIRO_UTIL_H 25 | 26 | void 27 | surface_flush_device(cairo_surface_t *surface); 28 | 29 | void 30 | blur_surface(cairo_surface_t *surface, int margin); 31 | 32 | void 33 | tile_mask(cairo_t *cr, cairo_surface_t *surface, 34 | int x, int y, int width, int height, int margin, int top_margin); 35 | 36 | void 37 | tile_source(cairo_t *cr, cairo_surface_t *surface, 38 | int x, int y, int width, int height, int margin, int top_margin); 39 | 40 | void 41 | rounded_rect(cairo_t *cr, int x0, int y0, int x1, int y1, int radius); 42 | 43 | cairo_surface_t * 44 | load_cairo_surface(const char *filename); 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /clients/clickdot.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2010 Intel Corporation 3 | * Copyright © 2012 Collabora, Ltd. 4 | * 5 | * Permission to use, copy, modify, distribute, and sell this software and its 6 | * documentation for any purpose is hereby granted without fee, provided that 7 | * the above copyright notice appear in all copies and that both that copyright 8 | * notice and this permission notice appear in supporting documentation, and 9 | * that the name of the copyright holders not be used in advertising or 10 | * publicity pertaining to distribution of the software without specific, 11 | * written prior permission. The copyright holders make no representations 12 | * about the suitability of this software for any purpose. It is provided "as 13 | * is" without express or implied warranty. 14 | * 15 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 17 | * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 18 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 19 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 20 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 21 | * OF THIS SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | #include 34 | 35 | #include "window.h" 36 | 37 | #include 38 | 39 | struct clickdot { 40 | struct display *display; 41 | struct window *window; 42 | struct widget *widget; 43 | 44 | int32_t x, y; 45 | }; 46 | 47 | static void 48 | redraw_handler(struct widget *widget, void *data) 49 | { 50 | static const double r = 10.0; 51 | struct clickdot *clickdot = data; 52 | cairo_surface_t *surface; 53 | cairo_t *cr; 54 | struct rectangle allocation; 55 | 56 | widget_get_allocation(clickdot->widget, &allocation); 57 | 58 | surface = window_get_surface(clickdot->window); 59 | 60 | cr = cairo_create(surface); 61 | cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); 62 | cairo_rectangle(cr, 63 | allocation.x, 64 | allocation.y, 65 | allocation.width, 66 | allocation.height); 67 | cairo_set_source_rgba(cr, 0, 0, 0, 0.8); 68 | cairo_fill(cr); 69 | 70 | cairo_translate(cr, clickdot->x + 0.5, clickdot->y + 0.5); 71 | cairo_set_line_width(cr, 1.0); 72 | cairo_set_source_rgb(cr, 0.1, 0.9, 0.9); 73 | cairo_move_to(cr, 0.0, -r); 74 | cairo_line_to(cr, 0.0, r); 75 | cairo_move_to(cr, -r, 0.0); 76 | cairo_line_to(cr, r, 0.0); 77 | cairo_arc(cr, 0.0, 0.0, r, 0.0, 2.0 * M_PI); 78 | cairo_stroke(cr); 79 | 80 | cairo_destroy(cr); 81 | 82 | cairo_surface_destroy(surface); 83 | } 84 | 85 | static void 86 | keyboard_focus_handler(struct window *window, 87 | struct input *device, void *data) 88 | { 89 | struct clickdot *clickdot = data; 90 | 91 | window_schedule_redraw(clickdot->window); 92 | } 93 | 94 | static void 95 | key_handler(struct window *window, struct input *input, uint32_t time, 96 | uint32_t key, uint32_t sym, uint32_t state, void *data) 97 | { 98 | struct clickdot *clickdot = data; 99 | 100 | if (state == 0) 101 | return; 102 | 103 | switch (sym) { 104 | case XK_Escape: 105 | display_exit(clickdot->display); 106 | break; 107 | } 108 | } 109 | 110 | static void 111 | button_handler(struct widget *widget, 112 | struct input *input, uint32_t time, 113 | int button, int state, void *data) 114 | { 115 | struct clickdot *clickdot = data; 116 | 117 | if (state && button == BTN_LEFT) 118 | input_get_position(input, &clickdot->x, &clickdot->y); 119 | 120 | widget_schedule_redraw(widget); 121 | } 122 | 123 | static struct clickdot * 124 | clickdot_create(struct display *display) 125 | { 126 | struct clickdot *clickdot; 127 | 128 | clickdot = malloc(sizeof *clickdot); 129 | if (clickdot == NULL) 130 | return clickdot; 131 | memset(clickdot, 0, sizeof *clickdot); 132 | 133 | clickdot->window = window_create(display); 134 | clickdot->widget = frame_create(clickdot->window, clickdot); 135 | window_set_title(clickdot->window, "Wayland ClickDot"); 136 | clickdot->display = display; 137 | 138 | window_set_key_handler(clickdot->window, key_handler); 139 | window_set_user_data(clickdot->window, clickdot); 140 | window_set_keyboard_focus_handler(clickdot->window, 141 | keyboard_focus_handler); 142 | 143 | widget_set_redraw_handler(clickdot->widget, redraw_handler); 144 | widget_set_button_handler(clickdot->widget, button_handler); 145 | 146 | widget_schedule_resize(clickdot->widget, 500, 400); 147 | clickdot->x = 250; 148 | clickdot->y = 200; 149 | 150 | return clickdot; 151 | } 152 | 153 | static void 154 | clickdot_destroy(struct clickdot *clickdot) 155 | { 156 | widget_destroy(clickdot->widget); 157 | window_destroy(clickdot->window); 158 | free(clickdot); 159 | } 160 | 161 | int 162 | main(int argc, char *argv[]) 163 | { 164 | struct display *display; 165 | struct clickdot *clickdot; 166 | 167 | display = display_create(argc, argv); 168 | if (display == NULL) { 169 | fprintf(stderr, "failed to create display: %m\n"); 170 | return -1; 171 | } 172 | 173 | clickdot = clickdot_create(display); 174 | 175 | display_run(display); 176 | 177 | clickdot_destroy(clickdot); 178 | display_destroy(display); 179 | 180 | return 0; 181 | } 182 | -------------------------------------------------------------------------------- /clients/flower.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2008 Kristian Høgsberg 3 | * 4 | * Permission to use, copy, modify, distribute, and sell this software and its 5 | * documentation for any purpose is hereby granted without fee, provided that 6 | * the above copyright notice appear in all copies and that both that copyright 7 | * notice and this permission notice appear in supporting documentation, and 8 | * that the name of the copyright holders not be used in advertising or 9 | * publicity pertaining to distribution of the software without specific, 10 | * written prior permission. The copyright holders make no representations 11 | * about the suitability of this software for any purpose. It is provided "as 12 | * is" without express or implied warranty. 13 | * 14 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 | * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 20 | * OF THIS SOFTWARE. 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #include 37 | #include 38 | #include "window.h" 39 | 40 | struct flower { 41 | struct display *display; 42 | struct window *window; 43 | struct widget *widget; 44 | int width, height; 45 | }; 46 | 47 | static void 48 | set_random_color(cairo_t *cr) 49 | { 50 | cairo_set_source_rgba(cr, 51 | 0.5 + (random() % 50) / 49.0, 52 | 0.5 + (random() % 50) / 49.0, 53 | 0.5 + (random() % 50) / 49.0, 54 | 0.5 + (random() % 100) / 99.0); 55 | } 56 | 57 | 58 | static void 59 | draw_stuff(cairo_surface_t *surface, int width, int height) 60 | { 61 | const int petal_count = 3 + random() % 5; 62 | const double r1 = 60 + random() % 35; 63 | const double r2 = 20 + random() % 40; 64 | const double u = (10 + random() % 90) / 100.0; 65 | const double v = (random() % 90) / 100.0; 66 | 67 | cairo_t *cr; 68 | int i; 69 | double t, dt = 2 * M_PI / (petal_count * 2); 70 | double x1, y1, x2, y2, x3, y3; 71 | 72 | cr = cairo_create(surface); 73 | cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); 74 | cairo_set_source_rgba(cr, 0, 0, 0, 0); 75 | cairo_paint(cr); 76 | 77 | cairo_set_operator(cr, CAIRO_OPERATOR_OVER); 78 | cairo_translate(cr, width / 2, height / 2); 79 | cairo_move_to(cr, cos(0) * r1, sin(0) * r1); 80 | for (t = 0, i = 0; i < petal_count; i++, t += dt * 2) { 81 | x1 = cos(t) * r1; 82 | y1 = sin(t) * r1; 83 | x2 = cos(t + dt) * r2; 84 | y2 = sin(t + dt) * r2; 85 | x3 = cos(t + 2 * dt) * r1; 86 | y3 = sin(t + 2 * dt) * r1; 87 | 88 | cairo_curve_to(cr, 89 | x1 - y1 * u, y1 + x1 * u, 90 | x2 + y2 * v, y2 - x2 * v, 91 | x2, y2); 92 | 93 | cairo_curve_to(cr, 94 | x2 - y2 * v, y2 + x2 * v, 95 | x3 + y3 * u, y3 - x3 * u, 96 | x3, y3); 97 | } 98 | 99 | cairo_close_path(cr); 100 | set_random_color(cr); 101 | cairo_fill_preserve(cr); 102 | set_random_color(cr); 103 | cairo_stroke(cr); 104 | 105 | cairo_destroy(cr); 106 | } 107 | 108 | static void 109 | resize_handler(struct widget *widget, 110 | int32_t width, int32_t height, void *data) 111 | { 112 | struct flower *flower = data; 113 | 114 | /* Dont resize me */ 115 | widget_set_size(flower->widget, flower->width, flower->height); 116 | } 117 | 118 | static void 119 | redraw_handler(struct widget *widget, void *data) 120 | { 121 | struct flower *flower = data; 122 | cairo_surface_t *surface; 123 | 124 | surface = window_get_surface(flower->window); 125 | if (surface == NULL || 126 | cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) { 127 | fprintf(stderr, "failed to create cairo egl surface\n"); 128 | return; 129 | } 130 | 131 | draw_stuff(surface, flower->width, flower->height); 132 | cairo_surface_destroy(surface); 133 | } 134 | 135 | static int 136 | motion_handler(struct widget *widget, struct input *input, 137 | uint32_t time, int32_t x, int32_t y, void *data) 138 | { 139 | return POINTER_HAND1; 140 | } 141 | 142 | static void 143 | button_handler(struct widget *widget, 144 | struct input *input, uint32_t time, 145 | int button, int state, void *data) 146 | { 147 | struct flower *flower = data; 148 | 149 | switch (button) { 150 | case BTN_LEFT: 151 | if (state) 152 | window_move(flower->window, input, 153 | display_get_serial(flower->display)); 154 | break; 155 | case BTN_MIDDLE: 156 | if (state) 157 | widget_schedule_redraw(widget); 158 | break; 159 | case BTN_RIGHT: 160 | if (state) 161 | window_show_frame_menu(flower->window, input, time); 162 | break; 163 | } 164 | } 165 | 166 | int main(int argc, char *argv[]) 167 | { 168 | struct flower flower; 169 | struct display *d; 170 | struct timeval tv; 171 | 172 | d = display_create(argc, argv); 173 | if (d == NULL) { 174 | fprintf(stderr, "failed to create display: %m\n"); 175 | return -1; 176 | } 177 | 178 | gettimeofday(&tv, NULL); 179 | srandom(tv.tv_usec); 180 | 181 | flower.width = 200; 182 | flower.height = 200; 183 | flower.display = d; 184 | flower.window = window_create(d); 185 | flower.widget = window_add_widget(flower.window, &flower); 186 | 187 | widget_set_resize_handler(flower.widget, resize_handler); 188 | widget_set_redraw_handler(flower.widget, redraw_handler); 189 | widget_set_motion_handler(flower.widget, motion_handler); 190 | widget_set_button_handler(flower.widget, button_handler); 191 | 192 | window_schedule_resize(flower.window, flower.width, flower.height); 193 | 194 | display_run(d); 195 | 196 | return 0; 197 | } 198 | -------------------------------------------------------------------------------- /clients/image.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2008 Kristian Høgsberg 3 | * Copyright © 2009 Chris Wilson 4 | * 5 | * Permission to use, copy, modify, distribute, and sell this software and its 6 | * documentation for any purpose is hereby granted without fee, provided that 7 | * the above copyright notice appear in all copies and that both that copyright 8 | * notice and this permission notice appear in supporting documentation, and 9 | * that the name of the copyright holders not be used in advertising or 10 | * publicity pertaining to distribution of the software without specific, 11 | * written prior permission. The copyright holders make no representations 12 | * about the suitability of this software for any purpose. It is provided "as 13 | * is" without express or implied warranty. 14 | * 15 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 17 | * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 18 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 19 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 20 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 21 | * OF THIS SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #include 36 | 37 | #include "window.h" 38 | #include "cairo-util.h" 39 | 40 | struct image { 41 | struct window *window; 42 | struct widget *widget; 43 | struct display *display; 44 | char *filename; 45 | cairo_surface_t *image; 46 | }; 47 | 48 | static void 49 | redraw_handler(struct widget *widget, void *data) 50 | { 51 | struct image *image = data; 52 | struct rectangle allocation; 53 | cairo_t *cr; 54 | cairo_surface_t *surface; 55 | double width, height, doc_aspect, window_aspect, scale; 56 | 57 | widget_get_allocation(image->widget, &allocation); 58 | 59 | surface = window_get_surface(image->window); 60 | cr = cairo_create(surface); 61 | widget_get_allocation(image->widget, &allocation); 62 | cairo_rectangle(cr, allocation.x, allocation.y, 63 | allocation.width, allocation.height); 64 | cairo_clip(cr); 65 | cairo_push_group(cr); 66 | cairo_translate(cr, allocation.x, allocation.y); 67 | 68 | cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); 69 | cairo_set_source_rgba(cr, 0, 0, 0, 1); 70 | cairo_paint(cr); 71 | 72 | width = cairo_image_surface_get_width(image->image); 73 | height = cairo_image_surface_get_height(image->image); 74 | doc_aspect = width / height; 75 | window_aspect = (double) allocation.width / allocation.height; 76 | if (doc_aspect < window_aspect) 77 | scale = allocation.height / height; 78 | else 79 | scale = allocation.width / width; 80 | cairo_scale(cr, scale, scale); 81 | cairo_translate(cr, 82 | (allocation.width - width * scale) / 2 / scale, 83 | (allocation.height - height * scale) / 2 / scale); 84 | 85 | cairo_set_source_surface(cr, image->image, 0, 0); 86 | cairo_set_operator(cr, CAIRO_OPERATOR_OVER); 87 | cairo_paint(cr); 88 | 89 | cairo_pop_group_to_source(cr); 90 | cairo_paint(cr); 91 | cairo_destroy(cr); 92 | 93 | cairo_surface_destroy(surface); 94 | } 95 | 96 | static void 97 | keyboard_focus_handler(struct window *window, 98 | struct input *device, void *data) 99 | { 100 | struct image *image = data; 101 | 102 | window_schedule_redraw(image->window); 103 | } 104 | 105 | static struct image * 106 | image_create(struct display *display, const char *filename) 107 | { 108 | struct image *image; 109 | char *b, *copy, title[512];; 110 | 111 | image = malloc(sizeof *image); 112 | if (image == NULL) 113 | return image; 114 | memset(image, 0, sizeof *image); 115 | 116 | copy = strdup(filename); 117 | b = basename(copy); 118 | snprintf(title, sizeof title, "Wayland Image - %s", b); 119 | free(copy); 120 | 121 | image->filename = strdup(filename); 122 | image->image = load_cairo_surface(filename); 123 | image->window = window_create(display); 124 | image->widget = frame_create(image->window, image); 125 | window_set_title(image->window, title); 126 | image->display = display; 127 | 128 | window_set_user_data(image->window, image); 129 | widget_set_redraw_handler(image->widget, redraw_handler); 130 | window_set_keyboard_focus_handler(image->window, 131 | keyboard_focus_handler); 132 | 133 | widget_schedule_resize(image->widget, 500, 400); 134 | 135 | return image; 136 | } 137 | 138 | int 139 | main(int argc, char *argv[]) 140 | { 141 | struct display *d; 142 | int i; 143 | 144 | d = display_create(argc, argv); 145 | if (d == NULL) { 146 | fprintf(stderr, "failed to create display: %m\n"); 147 | return -1; 148 | } 149 | 150 | for (i = 1; i < argc; i++) 151 | image_create (d, argv[i]); 152 | 153 | display_run(d); 154 | 155 | return 0; 156 | } 157 | -------------------------------------------------------------------------------- /clients/resizor.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2010 Intel Corporation 3 | * 4 | * Permission to use, copy, modify, distribute, and sell this software and its 5 | * documentation for any purpose is hereby granted without fee, provided that 6 | * the above copyright notice appear in all copies and that both that copyright 7 | * notice and this permission notice appear in supporting documentation, and 8 | * that the name of the copyright holders not be used in advertising or 9 | * publicity pertaining to distribution of the software without specific, 10 | * written prior permission. The copyright holders make no representations 11 | * about the suitability of this software for any purpose. It is provided "as 12 | * is" without express or implied warranty. 13 | * 14 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 | * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 20 | * OF THIS SOFTWARE. 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include 32 | #include 33 | 34 | #include "window.h" 35 | 36 | #include 37 | 38 | struct resizor { 39 | struct display *display; 40 | struct window *window; 41 | struct widget *widget; 42 | struct window *menu; 43 | int32_t width; 44 | 45 | struct { 46 | double current; 47 | double target; 48 | double previous; 49 | } height; 50 | struct wl_callback *frame_callback; 51 | }; 52 | 53 | static void 54 | frame_callback(void *data, struct wl_callback *callback, uint32_t time) 55 | { 56 | struct resizor *resizor = data; 57 | double force, height; 58 | 59 | assert(!callback || callback == resizor->frame_callback); 60 | 61 | height = resizor->height.current; 62 | force = (resizor->height.target - height) / 10.0 + 63 | (resizor->height.previous - height); 64 | 65 | resizor->height.current = 66 | height + (height - resizor->height.previous) + force; 67 | resizor->height.previous = height; 68 | 69 | if (resizor->height.current >= 400) { 70 | resizor->height.current = 400; 71 | resizor->height.previous = 400; 72 | } 73 | 74 | if (resizor->height.current <= 200) { 75 | resizor->height.current = 200; 76 | resizor->height.previous = 200; 77 | } 78 | 79 | widget_schedule_resize(resizor->widget, resizor->width, height + 0.5); 80 | 81 | if (resizor->frame_callback) { 82 | wl_callback_destroy(resizor->frame_callback); 83 | resizor->frame_callback = NULL; 84 | } 85 | } 86 | 87 | static const struct wl_callback_listener listener = { 88 | frame_callback 89 | }; 90 | 91 | static void 92 | redraw_handler(struct widget *widget, void *data) 93 | { 94 | struct resizor *resizor = data; 95 | cairo_surface_t *surface; 96 | cairo_t *cr; 97 | struct rectangle allocation; 98 | 99 | widget_get_allocation(resizor->widget, &allocation); 100 | 101 | surface = window_get_surface(resizor->window); 102 | 103 | cr = cairo_create(surface); 104 | cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); 105 | cairo_rectangle(cr, 106 | allocation.x, 107 | allocation.y, 108 | allocation.width, 109 | allocation.height); 110 | cairo_set_source_rgba(cr, 0, 0, 0, 0.8); 111 | cairo_fill(cr); 112 | cairo_destroy(cr); 113 | 114 | cairo_surface_destroy(surface); 115 | 116 | if (fabs(resizor->height.previous - resizor->height.target) > 0.1) { 117 | resizor->frame_callback = 118 | wl_surface_frame( 119 | window_get_wl_surface(resizor->window)); 120 | wl_callback_add_listener(resizor->frame_callback, &listener, 121 | resizor); 122 | } 123 | 124 | } 125 | 126 | static void 127 | keyboard_focus_handler(struct window *window, 128 | struct input *device, void *data) 129 | { 130 | struct resizor *resizor = data; 131 | 132 | window_schedule_redraw(resizor->window); 133 | } 134 | 135 | static void 136 | key_handler(struct window *window, struct input *input, uint32_t time, 137 | uint32_t key, uint32_t sym, uint32_t state, void *data) 138 | { 139 | struct resizor *resizor = data; 140 | 141 | if (state == 0) 142 | return; 143 | 144 | switch (sym) { 145 | case XK_Down: 146 | resizor->height.target = 400; 147 | frame_callback(resizor, NULL, 0); 148 | break; 149 | case XK_Up: 150 | resizor->height.target = 200; 151 | frame_callback(resizor, NULL, 0); 152 | break; 153 | case XK_Escape: 154 | display_exit(resizor->display); 155 | break; 156 | } 157 | } 158 | 159 | static void 160 | menu_func(struct window *window, int index, void *user_data) 161 | { 162 | fprintf(stderr, "picked entry %d\n", index); 163 | } 164 | 165 | static void 166 | show_menu(struct resizor *resizor, struct input *input, uint32_t time) 167 | { 168 | int32_t x, y; 169 | static const char *entries[] = { 170 | "Roy", "Pris", "Leon", "Zhora" 171 | }; 172 | 173 | input_get_position(input, &x, &y); 174 | window_show_menu(resizor->display, input, time, resizor->window, 175 | x - 10, y - 10, menu_func, entries, 4); 176 | } 177 | 178 | static void 179 | button_handler(struct widget *widget, 180 | struct input *input, uint32_t time, 181 | int button, int state, void *data) 182 | { 183 | struct resizor *resizor = data; 184 | 185 | switch (button) { 186 | case BTN_RIGHT: 187 | if (state) 188 | show_menu(resizor, input, time); 189 | break; 190 | } 191 | } 192 | 193 | static struct resizor * 194 | resizor_create(struct display *display) 195 | { 196 | struct resizor *resizor; 197 | int32_t height; 198 | 199 | resizor = malloc(sizeof *resizor); 200 | if (resizor == NULL) 201 | return resizor; 202 | memset(resizor, 0, sizeof *resizor); 203 | 204 | resizor->window = window_create(display); 205 | resizor->widget = frame_create(resizor->window, resizor); 206 | window_set_title(resizor->window, "Wayland Resizor"); 207 | resizor->display = display; 208 | 209 | window_set_key_handler(resizor->window, key_handler); 210 | window_set_user_data(resizor->window, resizor); 211 | widget_set_redraw_handler(resizor->widget, redraw_handler); 212 | window_set_keyboard_focus_handler(resizor->window, 213 | keyboard_focus_handler); 214 | 215 | resizor->width = 300; 216 | resizor->height.current = 400; 217 | resizor->height.previous = resizor->height.current; 218 | resizor->height.target = resizor->height.current; 219 | height = resizor->height.current + 0.5; 220 | 221 | widget_set_button_handler(resizor->widget, button_handler); 222 | 223 | widget_schedule_resize(resizor->widget, resizor->width, height); 224 | 225 | return resizor; 226 | } 227 | 228 | static void 229 | resizor_destroy(struct resizor *resizor) 230 | { 231 | if (resizor->frame_callback) 232 | wl_callback_destroy(resizor->frame_callback); 233 | 234 | widget_destroy(resizor->widget); 235 | window_destroy(resizor->window); 236 | free(resizor); 237 | } 238 | 239 | int 240 | main(int argc, char *argv[]) 241 | { 242 | struct display *display; 243 | struct resizor *resizor; 244 | 245 | display = display_create(argc, argv); 246 | if (display == NULL) { 247 | fprintf(stderr, "failed to create display: %m\n"); 248 | return -1; 249 | } 250 | 251 | resizor = resizor_create(display); 252 | 253 | display_run(display); 254 | 255 | resizor_destroy(resizor); 256 | display_destroy(display); 257 | 258 | return 0; 259 | } 260 | -------------------------------------------------------------------------------- /clients/screenshot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/detomastah/adwc/737c0c6569978a20e4a397f8d7d2223e31e20bbf/clients/screenshot -------------------------------------------------------------------------------- /clients/screenshot.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2008 Kristian Høgsberg 3 | * 4 | * Permission to use, copy, modify, distribute, and sell this software and its 5 | * documentation for any purpose is hereby granted without fee, provided that 6 | * the above copyright notice appear in all copies and that both that copyright 7 | * notice and this permission notice appear in supporting documentation, and 8 | * that the name of the copyright holders not be used in advertising or 9 | * publicity pertaining to distribution of the software without specific, 10 | * written prior permission. The copyright holders make no representations 11 | * about the suitability of this software for any purpose. It is provided "as 12 | * is" without express or implied warranty. 13 | * 14 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 | * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 20 | * OF THIS SOFTWARE. 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | #include "screenshooter-client-protocol.h" 34 | 35 | #define MAX(X,Y) ((X) > (Y) ? (X) : (Y)) 36 | 37 | /* The screenshooter is a good example of a custom object exposed by 38 | * the compositor and serves as a test bed for implementing client 39 | * side marshalling outside libwayland.so */ 40 | 41 | static struct wl_shm *shm; 42 | static struct screenshooter *screenshooter; 43 | static struct wl_list output_list; 44 | 45 | struct screenshooter_output { 46 | struct wl_output *output; 47 | struct wl_buffer *buffer; 48 | int width, height, offset_x, offset_y; 49 | struct wl_list link; 50 | }; 51 | 52 | static void 53 | display_handle_geometry(void *data, 54 | struct wl_output *wl_output, 55 | int x, 56 | int y, 57 | int physical_width, 58 | int physical_height, 59 | int subpixel, 60 | const char *make, 61 | const char *model) 62 | { 63 | struct screenshooter_output *output; 64 | 65 | output = wl_output_get_user_data(wl_output); 66 | 67 | if (wl_output == output->output) { 68 | output->offset_x = x; 69 | output->offset_y = y; 70 | } 71 | } 72 | 73 | static void 74 | display_handle_mode(void *data, 75 | struct wl_output *wl_output, 76 | uint32_t flags, 77 | int width, 78 | int height, 79 | int refresh) 80 | { 81 | struct screenshooter_output *output; 82 | 83 | output = wl_output_get_user_data(wl_output); 84 | 85 | if (wl_output == output->output && (flags & WL_OUTPUT_MODE_CURRENT)) { 86 | output->width = width; 87 | output->height = height; 88 | } 89 | } 90 | 91 | static const struct wl_output_listener output_listener = { 92 | display_handle_geometry, 93 | display_handle_mode 94 | }; 95 | 96 | static void 97 | handle_global(struct wl_display *display, uint32_t id, 98 | const char *interface, uint32_t version, void *data) 99 | { 100 | static struct screenshooter_output *output; 101 | 102 | if (strcmp(interface, "wl_output") == 0) { 103 | output = malloc(sizeof *output); 104 | output->output = wl_display_bind(display, id, &wl_output_interface); 105 | wl_list_insert(&output_list, &output->link); 106 | wl_output_add_listener(output->output, &output_listener, output); 107 | } else if (strcmp(interface, "wl_shm") == 0) { 108 | shm = wl_display_bind(display, id, &wl_shm_interface); 109 | } else if (strcmp(interface, "screenshooter") == 0) { 110 | screenshooter = wl_display_bind(display, id, &screenshooter_interface); 111 | } 112 | } 113 | 114 | static struct wl_buffer * 115 | create_shm_buffer(int width, int height, void **data_out) 116 | { 117 | char filename[] = "/tmp/wayland-shm-XXXXXX"; 118 | struct wl_shm_pool *pool; 119 | struct wl_buffer *buffer; 120 | int fd, size, stride; 121 | void *data; 122 | 123 | fd = mkstemp(filename); 124 | if (fd < 0) { 125 | fprintf(stderr, "open %s failed: %m\n", filename); 126 | return NULL; 127 | } 128 | stride = width * 4; 129 | size = stride * height; 130 | if (ftruncate(fd, size) < 0) { 131 | fprintf(stderr, "ftruncate failed: %m\n"); 132 | close(fd); 133 | return NULL; 134 | } 135 | 136 | data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 137 | unlink(filename); 138 | 139 | if (data == MAP_FAILED) { 140 | fprintf(stderr, "mmap failed: %m\n"); 141 | close(fd); 142 | return NULL; 143 | } 144 | 145 | pool = wl_shm_create_pool(shm, fd, size); 146 | close(fd); 147 | buffer = wl_shm_pool_create_buffer(pool, 0, width, height, stride, 148 | WL_SHM_FORMAT_XRGB8888); 149 | wl_shm_pool_destroy(pool); 150 | 151 | *data_out = data; 152 | 153 | return buffer; 154 | } 155 | 156 | static void 157 | write_png(int width, int height, void *data) 158 | { 159 | cairo_surface_t *surface; 160 | 161 | surface = cairo_image_surface_create_for_data(data, 162 | CAIRO_FORMAT_ARGB32, 163 | width, height, width * 4); 164 | cairo_surface_write_to_png(surface, "wayland-screenshot.png"); 165 | cairo_surface_destroy(surface); 166 | } 167 | 168 | int main(int argc, char *argv[]) 169 | { 170 | struct wl_display *display; 171 | struct wl_buffer *buffer; 172 | void *data = NULL; 173 | struct screenshooter_output *output, *next; 174 | int width = 0, height = 0; 175 | 176 | display = wl_display_connect(NULL); 177 | if (display == NULL) { 178 | fprintf(stderr, "failed to create display: %m\n"); 179 | return -1; 180 | } 181 | 182 | wl_list_init(&output_list); 183 | wl_display_add_global_listener(display, handle_global, &screenshooter); 184 | wl_display_iterate(display, WL_DISPLAY_READABLE); 185 | wl_display_roundtrip(display); 186 | if (screenshooter == NULL) { 187 | fprintf(stderr, "display doesn't support screenshooter\n"); 188 | return -1; 189 | } 190 | 191 | wl_list_for_each(output, &output_list, link) { 192 | width = MAX(width, output->offset_x + output->width); 193 | height = MAX(height, output->offset_y + output->height); 194 | } 195 | 196 | buffer = create_shm_buffer(width, height, &data); 197 | 198 | wl_list_for_each_safe(output, next, &output_list, link) { 199 | screenshooter_shoot(screenshooter, output->output, buffer); 200 | free(output); 201 | } 202 | 203 | wl_display_roundtrip(display); 204 | 205 | write_png(width, height, data); 206 | 207 | return 0; 208 | } 209 | -------------------------------------------------------------------------------- /clients/simple-shm.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2011 Benjamin Franzke 3 | * Copyright © 2010 Intel Corporation 4 | * 5 | * Permission to use, copy, modify, distribute, and sell this software and its 6 | * documentation for any purpose is hereby granted without fee, provided that 7 | * the above copyright notice appear in all copies and that both that copyright 8 | * notice and this permission notice appear in supporting documentation, and 9 | * that the name of the copyright holders not be used in advertising or 10 | * publicity pertaining to distribution of the software without specific, 11 | * written prior permission. The copyright holders make no representations 12 | * about the suitability of this software for any purpose. It is provided "as 13 | * is" without express or implied warranty. 14 | * 15 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 17 | * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 18 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 19 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 20 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 21 | * OF THIS SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | #include 35 | 36 | struct display { 37 | struct wl_display *display; 38 | struct wl_compositor *compositor; 39 | struct wl_shell *shell; 40 | struct wl_shm *shm; 41 | uint32_t formats; 42 | uint32_t mask; 43 | }; 44 | 45 | struct window { 46 | struct display *display; 47 | int width, height; 48 | struct wl_surface *surface; 49 | struct wl_shell_surface *shell_surface; 50 | struct wl_buffer *buffer; 51 | void *shm_data; 52 | struct wl_callback *callback; 53 | }; 54 | 55 | static struct wl_buffer * 56 | create_shm_buffer(struct display *display, 57 | int width, int height, uint32_t format, void **data_out) 58 | { 59 | char filename[] = "/tmp/wayland-shm-XXXXXX"; 60 | struct wl_shm_pool *pool; 61 | struct wl_buffer *buffer; 62 | int fd, size, stride; 63 | void *data; 64 | 65 | fd = mkstemp(filename); 66 | if (fd < 0) { 67 | fprintf(stderr, "open %s failed: %m\n", filename); 68 | return NULL; 69 | } 70 | stride = width * 4; 71 | size = stride * height; 72 | if (ftruncate(fd, size) < 0) { 73 | fprintf(stderr, "ftruncate failed: %m\n"); 74 | close(fd); 75 | return NULL; 76 | } 77 | 78 | data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 79 | unlink(filename); 80 | 81 | if (data == MAP_FAILED) { 82 | fprintf(stderr, "mmap failed: %m\n"); 83 | close(fd); 84 | return NULL; 85 | } 86 | 87 | pool = wl_shm_create_pool(display->shm, fd, size); 88 | buffer = wl_shm_pool_create_buffer(pool, 0, 89 | width, height, stride, format); 90 | wl_shm_pool_destroy(pool); 91 | close(fd); 92 | 93 | *data_out = data; 94 | 95 | return buffer; 96 | } 97 | 98 | static struct window * 99 | create_window(struct display *display, int width, int height) 100 | { 101 | struct window *window; 102 | 103 | window = malloc(sizeof *window); 104 | window->callback = NULL; 105 | window->display = display; 106 | window->width = width; 107 | window->height = height; 108 | window->surface = wl_compositor_create_surface(display->compositor); 109 | window->shell_surface = wl_shell_get_shell_surface(display->shell, 110 | window->surface); 111 | window->buffer = create_shm_buffer(display, 112 | width, height, 113 | WL_SHM_FORMAT_XRGB8888, 114 | &window->shm_data); 115 | 116 | wl_shell_surface_set_toplevel(window->shell_surface); 117 | 118 | return window; 119 | } 120 | 121 | static void 122 | destroy_window(struct window *window) 123 | { 124 | if (window->callback) 125 | wl_callback_destroy(window->callback); 126 | 127 | wl_buffer_destroy(window->buffer); 128 | wl_shell_surface_destroy(window->shell_surface); 129 | wl_surface_destroy(window->surface); 130 | free(window); 131 | } 132 | 133 | static const struct wl_callback_listener frame_listener; 134 | 135 | static void 136 | redraw(void *data, struct wl_callback *callback, uint32_t time) 137 | { 138 | struct window *window = data; 139 | uint32_t *p; 140 | int i, end, offset; 141 | 142 | p = window->shm_data; 143 | end = window->width * window->height; 144 | offset = time >> 4; 145 | for (i = 0; i < end; i++) 146 | p[i] = (i + offset) * 0x0080401; 147 | 148 | wl_surface_attach(window->surface, window->buffer, 0, 0); 149 | wl_surface_damage(window->surface, 150 | 0, 0, window->width, window->height); 151 | 152 | if (callback) 153 | wl_callback_destroy(callback); 154 | 155 | window->callback = wl_surface_frame(window->surface); 156 | wl_callback_add_listener(window->callback, &frame_listener, window); 157 | } 158 | 159 | static const struct wl_callback_listener frame_listener = { 160 | redraw 161 | }; 162 | 163 | static void 164 | shm_format(void *data, struct wl_shm *wl_shm, uint32_t format) 165 | { 166 | struct display *d = data; 167 | 168 | d->formats |= (1 << format); 169 | } 170 | 171 | struct wl_shm_listener shm_listenter = { 172 | shm_format 173 | }; 174 | 175 | static void 176 | display_handle_global(struct wl_display *display, uint32_t id, 177 | const char *interface, uint32_t version, void *data) 178 | { 179 | struct display *d = data; 180 | 181 | if (strcmp(interface, "wl_compositor") == 0) { 182 | d->compositor = 183 | wl_display_bind(display, id, &wl_compositor_interface); 184 | } else if (strcmp(interface, "wl_shell") == 0) { 185 | d->shell = wl_display_bind(display, id, &wl_shell_interface); 186 | } else if (strcmp(interface, "wl_shm") == 0) { 187 | d->shm = wl_display_bind(display, id, &wl_shm_interface); 188 | wl_shm_add_listener(d->shm, &shm_listenter, d); 189 | } 190 | } 191 | 192 | static int 193 | event_mask_update(uint32_t mask, void *data) 194 | { 195 | struct display *d = data; 196 | 197 | d->mask = mask; 198 | 199 | return 0; 200 | } 201 | 202 | static struct display * 203 | create_display(void) 204 | { 205 | struct display *display; 206 | 207 | display = malloc(sizeof *display); 208 | display->display = wl_display_connect(NULL); 209 | assert(display->display); 210 | 211 | display->formats = 0; 212 | wl_display_add_global_listener(display->display, 213 | display_handle_global, display); 214 | wl_display_iterate(display->display, WL_DISPLAY_READABLE); 215 | wl_display_roundtrip(display->display); 216 | 217 | if (!(display->formats & (1 << WL_SHM_FORMAT_XRGB8888))) { 218 | fprintf(stderr, "WL_SHM_FORMAT_XRGB32 not available\n"); 219 | exit(1); 220 | } 221 | 222 | wl_display_get_fd(display->display, event_mask_update, display); 223 | 224 | return display; 225 | } 226 | 227 | static void 228 | destroy_display(struct display *display) 229 | { 230 | if (display->shm) 231 | wl_shm_destroy(display->shm); 232 | 233 | if (display->shell) 234 | wl_shell_destroy(display->shell); 235 | 236 | if (display->compositor) 237 | wl_compositor_destroy(display->compositor); 238 | 239 | wl_display_flush(display->display); 240 | wl_display_disconnect(display->display); 241 | free(display); 242 | } 243 | 244 | static int running = 1; 245 | 246 | static void 247 | signal_int(int signum) 248 | { 249 | running = 0; 250 | } 251 | 252 | int 253 | main(int argc, char **argv) 254 | { 255 | struct sigaction sigint; 256 | struct display *display; 257 | struct window *window; 258 | 259 | display = create_display(); 260 | window = create_window(display, 250, 250); 261 | 262 | sigint.sa_handler = signal_int; 263 | sigemptyset(&sigint.sa_mask); 264 | sigint.sa_flags = SA_RESETHAND; 265 | sigaction(SIGINT, &sigint, NULL); 266 | 267 | redraw(window, NULL, 0); 268 | 269 | while (running) 270 | wl_display_iterate(display->display, display->mask); 271 | 272 | fprintf(stderr, "simple-shm exiting\n"); 273 | destroy_window(window); 274 | destroy_display(display); 275 | 276 | return 0; 277 | } 278 | -------------------------------------------------------------------------------- /clients/simple-touch.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2011 Benjamin Franzke 3 | * Copyright © 2011 Intel Corporation 4 | * 5 | * Permission to use, copy, modify, distribute, and sell this software and its 6 | * documentation for any purpose is hereby granted without fee, provided that 7 | * the above copyright notice appear in all copies and that both that copyright 8 | * notice and this permission notice appear in supporting documentation, and 9 | * that the name of the copyright holders not be used in advertising or 10 | * publicity pertaining to distribution of the software without specific, 11 | * written prior permission. The copyright holders make no representations 12 | * about the suitability of this software for any purpose. It is provided "as 13 | * is" without express or implied warranty. 14 | * 15 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 17 | * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 18 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 19 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 20 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 21 | * OF THIS SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | #include 34 | 35 | struct touch { 36 | struct wl_display *display; 37 | struct wl_compositor *compositor; 38 | struct wl_shell *shell; 39 | struct wl_shm *shm; 40 | struct wl_input_device *input_device; 41 | struct wl_surface *surface; 42 | struct wl_shell_surface *shell_surface; 43 | struct wl_buffer *buffer; 44 | int has_argb; 45 | uint32_t mask; 46 | int width, height; 47 | void *data; 48 | }; 49 | 50 | static void 51 | create_shm_buffer(struct touch *touch) 52 | { 53 | struct wl_shm_pool *pool; 54 | char filename[] = "/tmp/wayland-shm-XXXXXX"; 55 | int fd, size, stride; 56 | 57 | fd = mkstemp(filename); 58 | if (fd < 0) { 59 | fprintf(stderr, "open %s failed: %m\n", filename); 60 | exit(1); 61 | } 62 | stride = touch->width * 4; 63 | size = stride * touch->height; 64 | if (ftruncate(fd, size) < 0) { 65 | fprintf(stderr, "ftruncate failed: %m\n"); 66 | close(fd); 67 | exit(1); 68 | } 69 | 70 | touch->data = 71 | mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 72 | unlink(filename); 73 | 74 | if (touch->data == MAP_FAILED) { 75 | fprintf(stderr, "mmap failed: %m\n"); 76 | close(fd); 77 | exit(1); 78 | } 79 | 80 | pool = wl_shm_create_pool(touch->shm, fd, size); 81 | touch->buffer = 82 | wl_shm_pool_create_buffer(pool, 0, 83 | touch->width, touch->height, stride, 84 | WL_SHM_FORMAT_ARGB8888); 85 | wl_shm_pool_destroy(pool); 86 | 87 | close(fd); 88 | } 89 | 90 | static void 91 | shm_format(void *data, struct wl_shm *wl_shm, uint32_t format) 92 | { 93 | struct touch *touch = data; 94 | 95 | if (format == WL_SHM_FORMAT_ARGB8888) 96 | touch->has_argb = 1; 97 | } 98 | 99 | struct wl_shm_listener shm_listenter = { 100 | shm_format 101 | }; 102 | 103 | 104 | static void 105 | input_device_handle_motion(void *data, struct wl_input_device *input_device, 106 | uint32_t time, int32_t sx, int32_t sy) 107 | { 108 | } 109 | 110 | static void 111 | input_device_handle_button(void *data, 112 | struct wl_input_device *input_device, 113 | uint32_t serial, uint32_t time, 114 | uint32_t button, uint32_t state) 115 | { 116 | } 117 | 118 | static void 119 | input_device_handle_axis(void *data, struct wl_input_device *input_device, 120 | uint32_t time, uint32_t axis, int32_t value) 121 | { 122 | } 123 | 124 | static void 125 | input_device_handle_key(void *data, struct wl_input_device *input_device, 126 | uint32_t serial, uint32_t time, 127 | uint32_t key, uint32_t state) 128 | { 129 | } 130 | 131 | static void 132 | input_device_handle_pointer_enter(void *data, 133 | struct wl_input_device *input_device, 134 | uint32_t serial, struct wl_surface *surface, 135 | int32_t sx, int32_t sy) 136 | { 137 | } 138 | 139 | static void 140 | input_device_handle_pointer_leave(void *data, 141 | struct wl_input_device *input_device, 142 | uint32_t serial, struct wl_surface *surface) 143 | { 144 | } 145 | 146 | static void 147 | input_device_handle_keyboard_enter(void *data, 148 | struct wl_input_device *input_device, 149 | uint32_t serial, 150 | struct wl_surface *surface, 151 | struct wl_array *keys) 152 | { 153 | } 154 | 155 | static void 156 | input_device_handle_keyboard_leave(void *data, 157 | struct wl_input_device *input_device, 158 | uint32_t serial, 159 | struct wl_surface *surface) 160 | { 161 | } 162 | 163 | static void 164 | touch_paint(struct touch *touch, int32_t x, int32_t y, int32_t id) 165 | { 166 | uint32_t *p, c; 167 | static const uint32_t colors[] = { 168 | 0xffff0000, 169 | 0xffffff00, 170 | 0xff0000ff, 171 | 0xffff00ff, 172 | }; 173 | 174 | if (id < (int32_t) ARRAY_LENGTH(colors)) 175 | c = colors[id]; 176 | else 177 | c = 0xffffffff; 178 | 179 | if (x < 1 || touch->width - 1 < x || 180 | y < 1 || touch->height - 1 < y) 181 | return; 182 | 183 | p = (uint32_t *) touch->data + (x - 1) + (y -1 ) * touch->width; 184 | p[1] = c; 185 | p += touch->width; 186 | p[0] = c; 187 | p[1] = c; 188 | p[2] = c; 189 | p += touch->width; 190 | p[1] = c; 191 | 192 | wl_surface_damage(touch->surface, 0, 0, touch->width, touch->height); 193 | } 194 | 195 | static void 196 | input_device_handle_touch_down(void *data, 197 | struct wl_input_device *wl_input_device, 198 | uint32_t serial, uint32_t time, 199 | struct wl_surface *surface, 200 | int32_t id, int32_t x, int32_t y) 201 | { 202 | struct touch *touch = data; 203 | 204 | touch_paint(touch, x, y, id); 205 | } 206 | 207 | static void 208 | input_device_handle_touch_up(void *data, 209 | struct wl_input_device *wl_input_device, 210 | uint32_t serial, uint32_t time, int32_t id) 211 | { 212 | } 213 | 214 | static void 215 | input_device_handle_touch_motion(void *data, 216 | struct wl_input_device *wl_input_device, 217 | uint32_t time, 218 | int32_t id, int32_t x, int32_t y) 219 | { 220 | struct touch *touch = data; 221 | 222 | touch_paint(touch, x, y, id); 223 | } 224 | 225 | static void 226 | input_device_handle_touch_frame(void *data, 227 | struct wl_input_device *wl_input_device) 228 | { 229 | } 230 | 231 | static void 232 | input_device_handle_touch_cancel(void *data, 233 | struct wl_input_device *wl_input_device) 234 | { 235 | } 236 | 237 | static const struct wl_input_device_listener input_device_listener = { 238 | input_device_handle_motion, 239 | input_device_handle_button, 240 | input_device_handle_axis, 241 | input_device_handle_key, 242 | input_device_handle_pointer_enter, 243 | input_device_handle_pointer_leave, 244 | input_device_handle_keyboard_enter, 245 | input_device_handle_keyboard_leave, 246 | input_device_handle_touch_down, 247 | input_device_handle_touch_up, 248 | input_device_handle_touch_motion, 249 | input_device_handle_touch_frame, 250 | input_device_handle_touch_cancel, 251 | }; 252 | 253 | static void 254 | handle_global(struct wl_display *display, uint32_t id, 255 | const char *interface, uint32_t version, void *data) 256 | { 257 | struct touch *touch = data; 258 | 259 | if (strcmp(interface, "wl_compositor") == 0) { 260 | touch->compositor = 261 | wl_display_bind(display, id, &wl_compositor_interface); 262 | } else if (strcmp(interface, "wl_shell") == 0) { 263 | touch->shell = 264 | wl_display_bind(display, id, &wl_shell_interface); 265 | } else if (strcmp(interface, "wl_shm") == 0) { 266 | touch->shm = wl_display_bind(display, id, &wl_shm_interface); 267 | wl_shm_add_listener(touch->shm, &shm_listenter, touch); 268 | } else if (strcmp(interface, "wl_input_device") == 0) { 269 | touch->input_device = 270 | wl_display_bind(display, id, 271 | &wl_input_device_interface); 272 | wl_input_device_add_listener(touch->input_device, 273 | &input_device_listener, touch); 274 | } 275 | } 276 | 277 | static int 278 | event_mask_update(uint32_t mask, void *data) 279 | { 280 | struct touch *touch = data; 281 | 282 | touch->mask = mask; 283 | 284 | return 0; 285 | } 286 | 287 | static struct touch * 288 | touch_create(int width, int height) 289 | { 290 | struct touch *touch; 291 | 292 | touch = malloc(sizeof *touch); 293 | touch->display = wl_display_connect(NULL); 294 | assert(touch->display); 295 | 296 | touch->has_argb = 0; 297 | wl_display_add_global_listener(touch->display, handle_global, touch); 298 | wl_display_iterate(touch->display, WL_DISPLAY_READABLE); 299 | wl_display_roundtrip(touch->display); 300 | 301 | if (!touch->has_argb) { 302 | fprintf(stderr, "WL_SHM_FORMAT_ARGB32 not available\n"); 303 | exit(1); 304 | } 305 | 306 | wl_display_get_fd(touch->display, event_mask_update, touch); 307 | 308 | touch->width = width; 309 | touch->height = height; 310 | touch->surface = wl_compositor_create_surface(touch->compositor); 311 | touch->shell_surface = wl_shell_get_shell_surface(touch->shell, 312 | touch->surface); 313 | create_shm_buffer(touch); 314 | 315 | wl_shell_surface_set_toplevel(touch->shell_surface); 316 | wl_surface_set_user_data(touch->surface, touch); 317 | 318 | memset(touch->data, 64, width * height * 4); 319 | wl_surface_attach(touch->surface, touch->buffer, 0, 0); 320 | wl_surface_damage(touch->surface, 0, 0, width, height); 321 | 322 | return touch; 323 | } 324 | 325 | int 326 | main(int argc, char **argv) 327 | { 328 | struct touch *touch; 329 | 330 | touch = touch_create(600, 500); 331 | 332 | while (true) 333 | wl_display_iterate(touch->display, touch->mask); 334 | 335 | return 0; 336 | } 337 | -------------------------------------------------------------------------------- /clients/smoke.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2010 Kristian Høgsberg 3 | * 4 | * Permission to use, copy, modify, distribute, and sell this software and its 5 | * documentation for any purpose is hereby granted without fee, provided that 6 | * the above copyright notice appear in all copies and that both that copyright 7 | * notice and this permission notice appear in supporting documentation, and 8 | * that the name of the copyright holders not be used in advertising or 9 | * publicity pertaining to distribution of the software without specific, 10 | * written prior permission. The copyright holders make no representations 11 | * about the suitability of this software for any purpose. It is provided "as 12 | * is" without express or implied warranty. 13 | * 14 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 | * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 20 | * OF THIS SOFTWARE. 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #include 36 | #include "window.h" 37 | 38 | struct smoke { 39 | struct display *display; 40 | struct window *window; 41 | struct widget *widget; 42 | int width, height; 43 | int offset, current; 44 | uint32_t time; 45 | struct { float *d, *u, *v; } b[2]; 46 | }; 47 | 48 | static void diffuse(struct smoke *smoke, uint32_t time, 49 | float *source, float *dest) 50 | { 51 | float *s, *d; 52 | int x, y, k, stride; 53 | float t, a = 0.0002; 54 | 55 | stride = smoke->width; 56 | 57 | for (k = 0; k < 5; k++) { 58 | for (y = 1; y < smoke->height - 1; y++) { 59 | s = source + y * stride; 60 | d = dest + y * stride; 61 | for (x = 1; x < smoke->width - 1; x++) { 62 | t = d[x - 1] + d[x + 1] + 63 | d[x - stride] + d[x + stride]; 64 | d[x] = (s[x] + a * t) / (1 + 4 * a) * 0.995; 65 | } 66 | } 67 | } 68 | } 69 | 70 | static void advect(struct smoke *smoke, uint32_t time, 71 | float *uu, float *vv, float *source, float *dest) 72 | { 73 | float *s, *d; 74 | float *u, *v; 75 | int x, y, stride; 76 | int i, j; 77 | float px, py, fx, fy; 78 | 79 | stride = smoke->width; 80 | 81 | for (y = 1; y < smoke->height - 1; y++) { 82 | d = dest + y * stride; 83 | u = uu + y * stride; 84 | v = vv + y * stride; 85 | 86 | for (x = 1; x < smoke->width - 1; x++) { 87 | px = x - u[x]; 88 | py = y - v[x]; 89 | if (px < 0.5) 90 | px = 0.5; 91 | if (py < 0.5) 92 | py = 0.5; 93 | if (px > smoke->width - 0.5) 94 | px = smoke->width - 0.5; 95 | if (py > smoke->height - 0.5) 96 | py = smoke->height - 0.5; 97 | i = (int) px; 98 | j = (int) py; 99 | fx = px - i; 100 | fy = py - j; 101 | s = source + j * stride + i; 102 | d[x] = (s[0] * (1 - fx) + s[1] * fx) * (1 - fy) + 103 | (s[stride] * (1 - fx) + s[stride + 1] * fx) * fy; 104 | } 105 | } 106 | } 107 | 108 | static void project(struct smoke *smoke, uint32_t time, 109 | float *u, float *v, float *p, float *div) 110 | { 111 | int x, y, k, l, s; 112 | float h; 113 | 114 | h = 1.0 / smoke->width; 115 | s = smoke->width; 116 | memset(p, 0, smoke->height * smoke->width); 117 | for (y = 1; y < smoke->height - 1; y++) { 118 | l = y * s; 119 | for (x = 1; x < smoke->width - 1; x++) { 120 | div[l + x] = -0.5 * h * (u[l + x + 1] - u[l + x - 1] + 121 | v[l + x + s] - v[l + x - s]); 122 | p[l + x] = 0; 123 | } 124 | } 125 | 126 | for (k = 0; k < 5; k++) { 127 | for (y = 1; y < smoke->height - 1; y++) { 128 | l = y * s; 129 | for (x = 1; x < smoke->width - 1; x++) { 130 | p[l + x] = (div[l + x] + 131 | p[l + x - 1] + 132 | p[l + x + 1] + 133 | p[l + x - s] + 134 | p[l + x + s]) / 4; 135 | } 136 | } 137 | } 138 | 139 | for (y = 1; y < smoke->height - 1; y++) { 140 | l = y * s; 141 | for (x = 1; x < smoke->width - 1; x++) { 142 | u[l + x] -= 0.5 * (p[l + x + 1] - p[l + x - 1]) / h; 143 | v[l + x] -= 0.5 * (p[l + x + s] - p[l + x - s]) / h; 144 | } 145 | } 146 | } 147 | 148 | static void render(struct smoke *smoke, cairo_surface_t *surface) 149 | { 150 | unsigned char *dest; 151 | int x, y, width, height, stride; 152 | float *s; 153 | uint32_t *d, c, a; 154 | 155 | dest = cairo_image_surface_get_data(surface); 156 | width = cairo_image_surface_get_width(surface); 157 | height = cairo_image_surface_get_height(surface); 158 | stride = cairo_image_surface_get_stride(surface); 159 | 160 | for (y = 1; y < height - 1; y++) { 161 | s = smoke->b[smoke->current].d + y * smoke->height; 162 | d = (uint32_t *) (dest + y * stride); 163 | for (x = 1; x < width - 1; x++) { 164 | c = (int) (s[x] * 800); 165 | if (c > 255) 166 | c = 255; 167 | a = c; 168 | if (a < 0x33) 169 | a = 0x33; 170 | d[x] = (a << 24) | (c << 16) | (c << 8) | c; 171 | } 172 | } 173 | } 174 | 175 | static void 176 | frame_callback(void *data, struct wl_callback *callback, uint32_t time) 177 | { 178 | struct smoke *smoke = data; 179 | 180 | window_schedule_redraw(smoke->window); 181 | smoke->time = time; 182 | 183 | if (callback) 184 | wl_callback_destroy(callback); 185 | } 186 | 187 | static const struct wl_callback_listener listener = { 188 | frame_callback, 189 | }; 190 | 191 | static void 192 | redraw_handler(struct widget *widget, void *data) 193 | { 194 | struct smoke *smoke = data; 195 | uint32_t time = smoke->time; 196 | struct wl_callback *callback; 197 | cairo_surface_t *surface; 198 | 199 | diffuse(smoke, time / 30, smoke->b[0].u, smoke->b[1].u); 200 | diffuse(smoke, time / 30, smoke->b[0].v, smoke->b[1].v); 201 | project(smoke, time / 30, 202 | smoke->b[1].u, smoke->b[1].v, 203 | smoke->b[0].u, smoke->b[0].v); 204 | advect(smoke, time / 30, 205 | smoke->b[1].u, smoke->b[1].v, 206 | smoke->b[1].u, smoke->b[0].u); 207 | advect(smoke, time / 30, 208 | smoke->b[1].u, smoke->b[1].v, 209 | smoke->b[1].v, smoke->b[0].v); 210 | project(smoke, time / 30, 211 | smoke->b[0].u, smoke->b[0].v, 212 | smoke->b[1].u, smoke->b[1].v); 213 | 214 | diffuse(smoke, time / 30, smoke->b[0].d, smoke->b[1].d); 215 | advect(smoke, time / 30, 216 | smoke->b[0].u, smoke->b[0].v, 217 | smoke->b[1].d, smoke->b[0].d); 218 | 219 | surface = window_get_surface(smoke->window); 220 | 221 | render(smoke, surface); 222 | 223 | window_damage(smoke->window, 0, 0, smoke->width, smoke->height); 224 | 225 | cairo_surface_destroy(surface); 226 | 227 | callback = wl_surface_frame(window_get_wl_surface(smoke->window)); 228 | wl_callback_add_listener(callback, &listener, smoke); 229 | } 230 | 231 | static int 232 | smoke_motion_handler(struct widget *widget, struct input *input, 233 | uint32_t time, int32_t x, int32_t y, void *data) 234 | { 235 | struct smoke *smoke = data; 236 | int i, i0, i1, j, j0, j1, k, d = 5; 237 | 238 | if (x - d < 1) 239 | i0 = 1; 240 | else 241 | i0 = x - d; 242 | if (i0 + 2 * d > smoke->width - 1) 243 | i1 = smoke->width - 1; 244 | else 245 | i1 = i0 + 2 * d; 246 | 247 | if (y - d < 1) 248 | j0 = 1; 249 | else 250 | j0 = y - d; 251 | if (j0 + 2 * d > smoke->height - 1) 252 | j1 = smoke->height - 1; 253 | else 254 | j1 = j0 + 2 * d; 255 | 256 | for (i = i0; i < i1; i++) 257 | for (j = j0; j < j1; j++) { 258 | k = j * smoke->width + i; 259 | smoke->b[0].u[k] += 256 - (random() & 512); 260 | smoke->b[0].v[k] += 256 - (random() & 512); 261 | smoke->b[0].d[k] += 1; 262 | } 263 | 264 | return POINTER_HAND1; 265 | } 266 | 267 | static void 268 | resize_handler(struct widget *widget, 269 | int32_t width, int32_t height, void *data) 270 | { 271 | struct smoke *smoke = data; 272 | 273 | /* Dont resize me */ 274 | widget_set_size(smoke->widget, smoke->width, smoke->height); 275 | } 276 | 277 | int main(int argc, char *argv[]) 278 | { 279 | struct timespec ts; 280 | struct smoke smoke; 281 | struct display *d; 282 | int size; 283 | 284 | d = display_create(argc, argv); 285 | if (d == NULL) { 286 | fprintf(stderr, "failed to create display: %m\n"); 287 | return -1; 288 | } 289 | 290 | smoke.width = 200; 291 | smoke.height = 200; 292 | smoke.display = d; 293 | smoke.window = window_create(d); 294 | smoke.widget = window_add_widget(smoke.window, &smoke); 295 | window_set_title(smoke.window, "smoke"); 296 | 297 | window_set_buffer_type(smoke.window, WINDOW_BUFFER_TYPE_SHM); 298 | clock_gettime(CLOCK_MONOTONIC, &ts); 299 | srandom(ts.tv_nsec); 300 | smoke.offset = random(); 301 | 302 | smoke.current = 0; 303 | size = smoke.height * smoke.width; 304 | smoke.b[0].d = calloc(size, sizeof(float)); 305 | smoke.b[0].u = calloc(size, sizeof(float)); 306 | smoke.b[0].v = calloc(size, sizeof(float)); 307 | smoke.b[1].d = calloc(size, sizeof(float)); 308 | smoke.b[1].u = calloc(size, sizeof(float)); 309 | smoke.b[1].v = calloc(size, sizeof(float)); 310 | 311 | widget_set_motion_handler(smoke.widget, smoke_motion_handler); 312 | widget_set_resize_handler(smoke.widget, resize_handler); 313 | widget_set_redraw_handler(smoke.widget, redraw_handler); 314 | 315 | window_set_user_data(smoke.window, &smoke); 316 | 317 | widget_schedule_resize(smoke.widget, smoke.width, smoke.height); 318 | 319 | display_run(d); 320 | 321 | return 0; 322 | } 323 | -------------------------------------------------------------------------------- /clients/view.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2008 Kristian Høgsberg 3 | * Copyright © 2009 Chris Wilson 4 | * 5 | * Permission to use, copy, modify, distribute, and sell this software and its 6 | * documentation for any purpose is hereby granted without fee, provided that 7 | * the above copyright notice appear in all copies and that both that copyright 8 | * notice and this permission notice appear in supporting documentation, and 9 | * that the name of the copyright holders not be used in advertising or 10 | * publicity pertaining to distribution of the software without specific, 11 | * written prior permission. The copyright holders make no representations 12 | * about the suitability of this software for any purpose. It is provided "as 13 | * is" without express or implied warranty. 14 | * 15 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 17 | * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 18 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 19 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 20 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 21 | * OF THIS SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | #include 38 | #include 39 | 40 | #include 41 | 42 | #include "window.h" 43 | 44 | struct view { 45 | struct window *window; 46 | struct widget *widget; 47 | struct display *display; 48 | 49 | PopplerDocument *document; 50 | int page; 51 | int fullscreen; 52 | }; 53 | 54 | static void 55 | redraw_handler(struct widget *widget, void *data) 56 | { 57 | struct view *view = data; 58 | 59 | struct rectangle allocation; 60 | cairo_surface_t *surface; 61 | cairo_t *cr; 62 | PopplerPage *page; 63 | double width, height, doc_aspect, window_aspect, scale; 64 | 65 | widget_get_allocation(view->widget, &allocation); 66 | 67 | surface = window_get_surface(view->window); 68 | 69 | cr = cairo_create(surface); 70 | cairo_rectangle(cr, allocation.x, allocation.y, 71 | allocation.width, allocation.height); 72 | cairo_clip(cr); 73 | 74 | cairo_set_source_rgba(cr, 0, 0, 0, 0.8); 75 | cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); 76 | cairo_paint(cr); 77 | 78 | if(!view->document) { 79 | cairo_destroy(cr); 80 | cairo_surface_destroy(surface); 81 | window_flush(view->window); 82 | return; 83 | } 84 | 85 | page = poppler_document_get_page(view->document, view->page); 86 | poppler_page_get_size(page, &width, &height); 87 | doc_aspect = width / height; 88 | window_aspect = (double) allocation.width / allocation.height; 89 | if (doc_aspect < window_aspect) 90 | scale = allocation.height / height; 91 | else 92 | scale = allocation.width / width; 93 | cairo_translate(cr, allocation.x, allocation.y); 94 | cairo_scale(cr, scale, scale); 95 | cairo_translate(cr, 96 | (allocation.width - width * scale) / 2 / scale, 97 | (allocation.height - height * scale) / 2 / scale); 98 | cairo_rectangle(cr, 0, 0, width, height); 99 | cairo_set_operator(cr, CAIRO_OPERATOR_OVER); 100 | cairo_set_source_rgb(cr, 1, 1, 1); 101 | cairo_fill(cr); 102 | poppler_page_render(page, cr); 103 | cairo_destroy(cr); 104 | cairo_surface_destroy(surface); 105 | g_object_unref(G_OBJECT(page)); 106 | } 107 | 108 | static void 109 | resize_handler(struct widget *widget, 110 | int32_t width, int32_t height, void *data) 111 | { 112 | struct view *view = data; 113 | 114 | widget_set_size(view->widget, width, height); 115 | } 116 | 117 | static void 118 | view_page_up(struct view *view) 119 | { 120 | if(view->page <= 0) 121 | return; 122 | 123 | view->page--; 124 | window_schedule_redraw(view->window); 125 | } 126 | 127 | static void 128 | view_page_down(struct view *view) 129 | { 130 | if(!view->document || 131 | view->page >= poppler_document_get_n_pages(view->document) - 1) { 132 | return; 133 | } 134 | 135 | view->page++; 136 | window_schedule_redraw(view->window); 137 | } 138 | 139 | static void 140 | button_handler(struct widget *widget, struct input *input, uint32_t time, 141 | int button, int state, void *data) 142 | { 143 | struct view *view = data; 144 | 145 | if(!state) 146 | return; 147 | 148 | switch(button) { 149 | case 275: 150 | view_page_up(view); 151 | break; 152 | case 276: 153 | view_page_down(view); 154 | break; 155 | default: 156 | break; 157 | } 158 | } 159 | 160 | static void 161 | key_handler(struct window *window, struct input *input, uint32_t time, 162 | uint32_t key, uint32_t unicode, uint32_t state, void *data) 163 | { 164 | struct view *view = data; 165 | 166 | if(!state) 167 | return; 168 | 169 | switch (key) { 170 | case KEY_F11: 171 | view->fullscreen ^= 1; 172 | window_set_fullscreen(window, view->fullscreen); 173 | break; 174 | case KEY_SPACE: 175 | case KEY_PAGEDOWN: 176 | case KEY_RIGHT: 177 | case KEY_DOWN: 178 | view_page_down(view); 179 | break; 180 | case KEY_BACKSPACE: 181 | case KEY_PAGEUP: 182 | case KEY_LEFT: 183 | case KEY_UP: 184 | view_page_up(view); 185 | break; 186 | default: 187 | break; 188 | } 189 | } 190 | 191 | static void 192 | keyboard_focus_handler(struct window *window, 193 | struct input *device, void *data) 194 | { 195 | struct view *view = data; 196 | window_schedule_redraw(view->window); 197 | } 198 | 199 | static struct view * 200 | view_create(struct display *display, 201 | uint32_t key, const char *filename, int fullscreen) 202 | { 203 | struct view *view; 204 | gchar *basename; 205 | gchar *title; 206 | GFile *file = NULL; 207 | GError *error = NULL; 208 | 209 | view = malloc(sizeof *view); 210 | if (view == NULL) 211 | return view; 212 | memset(view, 0, sizeof *view); 213 | 214 | file = g_file_new_for_commandline_arg(filename); 215 | basename = g_file_get_basename(file); 216 | if(!basename) { 217 | title = "Wayland View"; 218 | } else { 219 | title = g_strdup_printf("Wayland View - %s", basename); 220 | g_free(basename); 221 | } 222 | 223 | view->document = poppler_document_new_from_file(g_file_get_uri(file), 224 | NULL, &error); 225 | 226 | if(error) { 227 | title = "File not found"; 228 | } 229 | 230 | view->window = window_create(display); 231 | view->widget = frame_create(view->window, view); 232 | window_set_title(view->window, title); 233 | view->display = display; 234 | 235 | window_set_user_data(view->window, view); 236 | window_set_key_handler(view->window, key_handler); 237 | window_set_keyboard_focus_handler(view->window, 238 | keyboard_focus_handler); 239 | widget_set_button_handler(view->widget, button_handler); 240 | widget_set_resize_handler(view->widget, resize_handler); 241 | widget_set_redraw_handler(view->widget, redraw_handler); 242 | 243 | view->page = 0; 244 | 245 | view->fullscreen = fullscreen; 246 | window_set_fullscreen(view->window, view->fullscreen); 247 | 248 | window_schedule_resize(view->window, 500, 400); 249 | 250 | return view; 251 | } 252 | 253 | static int option_fullscreen; 254 | 255 | static const struct weston_option view_options[] = { 256 | { WESTON_OPTION_BOOLEAN, "fullscreen", 0, &option_fullscreen }, 257 | }; 258 | 259 | int 260 | main(int argc, char *argv[]) 261 | { 262 | struct display *d; 263 | int i; 264 | 265 | g_type_init(); 266 | 267 | argc = parse_options(view_options, 268 | ARRAY_LENGTH(view_options), argc, argv); 269 | 270 | d = display_create(argc, argv); 271 | if (d == NULL) { 272 | fprintf(stderr, "failed to create display: %m\n"); 273 | return -1; 274 | } 275 | 276 | for (i = 1; i < argc; i++) 277 | view_create (d, i, argv[i], option_fullscreen); 278 | 279 | display_run(d); 280 | 281 | return 0; 282 | } 283 | -------------------------------------------------------------------------------- /clients/wscreensaver-glue.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2011 Collabora, Ltd. 3 | * 4 | * Permission to use, copy, modify, distribute, and sell this software and its 5 | * documentation for any purpose is hereby granted without fee, provided that 6 | * the above copyright notice appear in all copies and that both that copyright 7 | * notice and this permission notice appear in supporting documentation, and 8 | * that the name of the copyright holders not be used in advertising or 9 | * publicity pertaining to distribution of the software without specific, 10 | * written prior permission. The copyright holders make no representations 11 | * about the suitability of this software for any purpose. It is provided "as 12 | * is" without express or implied warranty. 13 | * 14 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 | * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 20 | * OF THIS SOFTWARE. 21 | */ 22 | 23 | #include "wscreensaver-glue.h" 24 | 25 | double frand(double f) 26 | { 27 | double r = random(); 28 | return r * f / (double)RAND_MAX; 29 | } 30 | 31 | void clear_gl_error(void) 32 | { 33 | while (glGetError() != GL_NO_ERROR) 34 | ; 35 | } 36 | 37 | void check_gl_error(const char *msg) 38 | { 39 | const char *emsg; 40 | int err = glGetError(); 41 | 42 | switch (err) 43 | { 44 | case GL_NO_ERROR: 45 | return; 46 | 47 | #define ERR(tok) case tok: emsg = #tok; break; 48 | ERR(GL_INVALID_ENUM) 49 | ERR(GL_INVALID_VALUE) 50 | ERR(GL_INVALID_OPERATION) 51 | ERR(GL_STACK_OVERFLOW) 52 | ERR(GL_STACK_UNDERFLOW) 53 | ERR(GL_OUT_OF_MEMORY) 54 | #undef ERR 55 | 56 | default: 57 | fprintf(stderr, "%s: %s: unknown GL error 0x%04x\n", 58 | progname, msg, err); 59 | exit(1); 60 | } 61 | 62 | fprintf(stderr, "%s: %s: GL error %s\n", progname, msg, emsg); 63 | exit(1); 64 | } 65 | 66 | static void 67 | read_xpm_color(uint32_t *ctable, const char *line) 68 | { 69 | unsigned char key; 70 | char cstr[10]; 71 | char *end; 72 | uint32_t value; 73 | 74 | if (sscanf(line, "%1c c %9s", &key, cstr) < 2) { 75 | fprintf(stderr, "%s: error in XPM color definition '%s'\n", 76 | progname, line); 77 | return; 78 | } 79 | 80 | value = strtol(&cstr[1], &end, 16); 81 | 82 | if (strcmp(cstr, "None") == 0) 83 | ctable[key] = 0x00ffffff; 84 | else if (cstr[0] != '#' || !(cstr[1] != '\0' && *end == '\0')) { 85 | fprintf(stderr, "%s: error interpreting XPM color '%s'\n", 86 | progname, cstr); 87 | return; 88 | } 89 | 90 | ctable[key] = value | 0xff000000; 91 | } 92 | 93 | static void 94 | read_xpm_row(char *data, const char *line, uint32_t *ctable, int width) 95 | { 96 | uint32_t *pixel = (uint32_t *)data; 97 | uint8_t *p = (uint8_t *)line; 98 | int i; 99 | 100 | for (i = 0; i < width; ++i) 101 | pixel[i] = ctable[p[i]]; 102 | } 103 | 104 | XImage *xpm_to_ximage(char **xpm_data) 105 | { 106 | XImage *xi; 107 | int colors; 108 | int cpp; 109 | int i; 110 | uint32_t ctable[256] = { 0 }; 111 | 112 | xi = malloc(sizeof *xi); 113 | if (!xi) 114 | return NULL; 115 | xi->data = NULL; 116 | 117 | if (sscanf(xpm_data[0], "%d %d %d %d", &xi->width, 118 | &xi->height, &colors, &cpp) < 4) 119 | goto errout; 120 | 121 | if (xi->width < 1 || xi->height < 1 || cpp != 1) 122 | goto errout; 123 | 124 | xi->bytes_per_line = xi->width * sizeof(uint32_t); 125 | xi->data = malloc(xi->height * xi->bytes_per_line); 126 | if (!xi->data) 127 | goto errout; 128 | 129 | for (i = 0; i < colors; ++i) 130 | read_xpm_color(ctable, xpm_data[i + 1]); 131 | 132 | for (i = 0; i < xi->height; ++i) 133 | read_xpm_row(xi->data + i * xi->bytes_per_line, 134 | xpm_data[i + colors + 1], ctable, xi->width); 135 | 136 | return xi; 137 | 138 | errout: 139 | fprintf(stderr, "%s: error processing XPM data.\n", progname); 140 | XDestroyImage(xi); 141 | return NULL; 142 | } 143 | 144 | void XDestroyImage(XImage *xi) 145 | { 146 | free(xi->data); 147 | free(xi); 148 | } 149 | -------------------------------------------------------------------------------- /clients/wscreensaver-glue.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2011 Collabora, Ltd. 3 | * 4 | * Permission to use, copy, modify, distribute, and sell this software and its 5 | * documentation for any purpose is hereby granted without fee, provided that 6 | * the above copyright notice appear in all copies and that both that copyright 7 | * notice and this permission notice appear in supporting documentation, and 8 | * that the name of the copyright holders not be used in advertising or 9 | * publicity pertaining to distribution of the software without specific, 10 | * written prior permission. The copyright holders make no representations 11 | * about the suitability of this software for any purpose. It is provided "as 12 | * is" without express or implied warranty. 13 | * 14 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 | * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 20 | * OF THIS SOFTWARE. 21 | */ 22 | 23 | #ifndef WSCREENSAVER_GLUE_H 24 | #define WSCREENSAVER_GLUE_H 25 | 26 | /* 27 | * This file is glue, that tries to avoid changing glmatrix.c from the 28 | * original too much, hopefully easing the porting of other (GL) 29 | * xscreensaver "hacks". 30 | */ 31 | 32 | #include "wscreensaver.h" 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #include 44 | #include 45 | 46 | #include "window.h" 47 | 48 | #define ENTRYPOINT static 49 | 50 | typedef bool Bool; 51 | #define True true 52 | #define False false 53 | 54 | typedef struct ModeInfo ModeInfo; 55 | 56 | #define MI_DISPLAY(mi) NULL 57 | #define MI_WINDOW(mi) (mi) 58 | #define MI_SCREEN(mi) ((mi)->instance_number) 59 | #define MI_WIDTH(mi) ((mi)->width) 60 | #define MI_HEIGHT(mi) ((mi)->height) 61 | #define MI_IS_WIREFRAME(mi) 0 62 | #define MI_NUM_SCREENS(mi) 16 63 | 64 | typedef EGLContext GLXContext; 65 | 66 | double frand(double f); 67 | void clear_gl_error(void); 68 | void check_gl_error(const char *msg); 69 | 70 | static inline void 71 | glXMakeCurrent(void *dummy, ModeInfo *mi, EGLContext ctx) 72 | { 73 | assert(mi->eglctx == ctx); 74 | } 75 | 76 | static inline void 77 | glXSwapBuffers(void *dummy, ModeInfo *mi) 78 | { 79 | mi->swap_buffers = 1; 80 | } 81 | 82 | static inline void 83 | do_fps(ModeInfo *mi) 84 | { 85 | } 86 | 87 | /* just enough XImage to satisfy glmatrix.c */ 88 | 89 | typedef struct _XImage { 90 | int width; 91 | int height; 92 | char *data; 93 | int bytes_per_line; 94 | } XImage; 95 | 96 | XImage *xpm_to_ximage(char **xpm_data); 97 | void XDestroyImage(XImage *xi); 98 | 99 | static inline unsigned long 100 | XGetPixel(XImage *xi, int x, int y) 101 | { 102 | return *(uint32_t *)(xi->data + xi->bytes_per_line * y + 4 * x); 103 | } 104 | 105 | static inline void 106 | XPutPixel(XImage *xi, int x, int y, unsigned long pixel) 107 | { 108 | *(uint32_t *)(xi->data + xi->bytes_per_line * y + 4 * x) = pixel; 109 | } 110 | 111 | /* 112 | * override glViewport from the plugin, so we can set it up properly 113 | * rendering to a regular decorated Wayland window. 114 | */ 115 | #ifdef glViewport 116 | #undef glViewport 117 | #endif 118 | #define glViewport(x,y,w,h) do {} while (0) 119 | 120 | #endif /* WSCREENSAVER_GLUE_H */ 121 | -------------------------------------------------------------------------------- /clients/wscreensaver.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2011 Collabora, Ltd. 3 | * 4 | * Permission to use, copy, modify, distribute, and sell this software and its 5 | * documentation for any purpose is hereby granted without fee, provided that 6 | * the above copyright notice appear in all copies and that both that copyright 7 | * notice and this permission notice appear in supporting documentation, and 8 | * that the name of the copyright holders not be used in advertising or 9 | * publicity pertaining to distribution of the software without specific, 10 | * written prior permission. The copyright holders make no representations 11 | * about the suitability of this software for any purpose. It is provided "as 12 | * is" without express or implied warranty. 13 | * 14 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 | * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 20 | * OF THIS SOFTWARE. 21 | */ 22 | 23 | #include "../config.h" 24 | 25 | #include "wscreensaver.h" 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | #include 34 | 35 | #include 36 | 37 | #include "desktop-shell-client-protocol.h" 38 | #include "window.h" 39 | 40 | extern struct wscreensaver_plugin glmatrix_screensaver; 41 | 42 | static const struct wscreensaver_plugin * const plugins[] = { 43 | &glmatrix_screensaver, 44 | NULL 45 | }; 46 | 47 | const char *progname = NULL; 48 | 49 | static int demo_mode; 50 | 51 | struct wscreensaver { 52 | struct screensaver *interface; 53 | 54 | struct display *display; 55 | 56 | struct ModeInfo *demomode; 57 | 58 | struct { 59 | EGLDisplay display; 60 | EGLConfig config; 61 | } egl; 62 | 63 | const struct wscreensaver_plugin *plugin; 64 | }; 65 | 66 | static void 67 | frame_callback(void *data, struct wl_callback *callback, uint32_t time) 68 | { 69 | struct ModeInfo *mi = data; 70 | 71 | window_schedule_redraw(mi->window); 72 | wl_callback_destroy(callback); 73 | } 74 | 75 | static const struct wl_callback_listener listener = { 76 | frame_callback 77 | }; 78 | 79 | static void 80 | redraw_handler(struct widget *widget, void *data) 81 | { 82 | struct ModeInfo *mi = data; 83 | struct wscreensaver *wscr = mi->priv; 84 | struct rectangle drawarea; 85 | struct rectangle winarea; 86 | struct wl_callback *callback; 87 | int bottom; 88 | 89 | mi->swap_buffers = 0; 90 | 91 | widget_get_allocation(mi->widget, &drawarea); 92 | window_get_allocation(mi->window, &winarea); 93 | 94 | if (display_acquire_window_surface(wscr->display, 95 | mi->window, 96 | mi->eglctx) < 0) { 97 | fprintf(stderr, "%s: unable to acquire window surface", 98 | progname); 99 | return; 100 | } 101 | 102 | bottom = winarea.height - (drawarea.height + drawarea.y); 103 | glViewport(drawarea.x, bottom, drawarea.width, drawarea.height); 104 | glScissor(drawarea.x, bottom, drawarea.width, drawarea.height); 105 | glEnable(GL_SCISSOR_TEST); 106 | 107 | if (mi->width != drawarea.width || mi->height != drawarea.height) { 108 | mi->width = drawarea.width; 109 | mi->height = drawarea.height; 110 | wscr->plugin->reshape(mi, mi->width, mi->height); 111 | } 112 | 113 | wscr->plugin->draw(mi); 114 | 115 | if (mi->swap_buffers == 0) 116 | fprintf(stderr, "%s: swapBuffers not called\n", progname); 117 | 118 | display_release_window_surface(wscr->display, mi->window); 119 | 120 | callback = wl_surface_frame(window_get_wl_surface(mi->window)); 121 | wl_callback_add_listener(callback, &listener, mi); 122 | } 123 | 124 | static void 125 | init_frand(void) 126 | { 127 | struct timeval tv; 128 | gettimeofday(&tv, NULL); 129 | srandom(tv.tv_sec * 100 + tv.tv_usec / 10000); 130 | } 131 | 132 | WL_EXPORT EGLContext * 133 | init_GL(struct ModeInfo *mi) 134 | { 135 | struct wscreensaver *wscr = mi->priv; 136 | EGLContext *pctx; 137 | 138 | pctx = malloc(sizeof *pctx); 139 | if (!pctx) 140 | return NULL; 141 | 142 | if (mi->eglctx != EGL_NO_CONTEXT) { 143 | fprintf(stderr, "%s: multiple GL contexts are not supported", 144 | progname); 145 | goto errout; 146 | } 147 | 148 | mi->eglctx = eglCreateContext(wscr->egl.display, wscr->egl.config, 149 | EGL_NO_CONTEXT, NULL); 150 | if (mi->eglctx == EGL_NO_CONTEXT) { 151 | fprintf(stderr, "%s: init_GL failed to create EGL context\n", 152 | progname); 153 | goto errout; 154 | } 155 | 156 | if (!eglMakeCurrent(wscr->egl.display, NULL, NULL, mi->eglctx)) { 157 | fprintf(stderr, "%s: init_GL failed on eglMakeCurrent\n", 158 | progname); 159 | goto errout; 160 | } 161 | 162 | glClearColor(0.0, 0.0, 0.0, 1.0); 163 | 164 | *pctx = mi->eglctx; 165 | return pctx; 166 | 167 | errout: 168 | free(pctx); 169 | return NULL; 170 | } 171 | 172 | static struct ModeInfo * 173 | create_wscreensaver_instance(struct wscreensaver *screensaver, 174 | struct wl_output *output, int width, int height) 175 | { 176 | static int instance; 177 | struct ModeInfo *mi; 178 | struct rectangle drawarea; 179 | 180 | mi = calloc(1, sizeof *mi); 181 | if (!mi) 182 | return NULL; 183 | 184 | mi->window = window_create(screensaver->display); 185 | if (!mi->window) { 186 | fprintf(stderr, "%s: creating a window failed.\n", progname); 187 | free(mi); 188 | return NULL; 189 | } 190 | 191 | window_set_title(mi->window, progname); 192 | 193 | if (screensaver->interface) { 194 | window_set_custom(mi->window); 195 | mi->widget = window_add_widget(mi->window, mi); 196 | screensaver_set_surface(screensaver->interface, 197 | window_get_wl_shell_surface(mi->window), 198 | output); 199 | } else { 200 | mi->widget = frame_create(mi->window, mi); 201 | } 202 | widget_set_redraw_handler(mi->widget, redraw_handler); 203 | 204 | mi->priv = screensaver; 205 | mi->eglctx = EGL_NO_CONTEXT; 206 | mi->instance_number = instance++; /* XXX */ 207 | 208 | widget_get_allocation(mi->widget, &drawarea); 209 | mi->width = drawarea.width; 210 | mi->height = drawarea.height; 211 | 212 | screensaver->plugin->init(mi); 213 | 214 | window_schedule_resize(mi->window, width, height); 215 | return mi; 216 | } 217 | 218 | static void 219 | handle_output_destroy(struct output *output, void *data) 220 | { 221 | /* struct ModeInfo *mi = data; 222 | * TODO */ 223 | } 224 | 225 | static void 226 | handle_output_configure(struct output *output, void *data) 227 | { 228 | struct wscreensaver *screensaver = data; 229 | struct ModeInfo *mi; 230 | struct rectangle area; 231 | 232 | /* skip existing outputs */ 233 | if (output_get_user_data(output)) 234 | return; 235 | 236 | output_get_allocation(output, &area); 237 | mi = create_wscreensaver_instance(screensaver, 238 | output_get_wl_output(output), 239 | area.width, area.height); 240 | output_set_user_data(output, mi); 241 | output_set_destroy_handler(output, handle_output_destroy); 242 | } 243 | 244 | static int 245 | init_wscreensaver(struct wscreensaver *wscr, struct display *display) 246 | { 247 | int size; 248 | const char prefix[] = "wscreensaver::"; 249 | char *str; 250 | 251 | display_set_user_data(display, wscr); 252 | wscr->display = display; 253 | wscr->plugin = plugins[0]; 254 | 255 | size = sizeof(prefix) + strlen(wscr->plugin->name); 256 | str = malloc(size); 257 | if (!str) { 258 | fprintf(stderr, "init: out of memory\n"); 259 | return -1; 260 | } 261 | snprintf(str, size, "%s%s", prefix, wscr->plugin->name); 262 | progname = str; 263 | 264 | wscr->egl.display = display_get_egl_display(wscr->display); 265 | if (!wscr->egl.display) { 266 | fprintf(stderr, "init: no EGL display\n"); 267 | return -1; 268 | } 269 | 270 | eglBindAPI(EGL_OPENGL_API); 271 | wscr->egl.config = display_get_argb_egl_config(wscr->display); 272 | 273 | if (demo_mode) { 274 | struct wl_output *o = 275 | output_get_wl_output(display_get_output(display)); 276 | /* only one instance */ 277 | wscr->demomode = 278 | create_wscreensaver_instance(wscr, o, 400, 300); 279 | return 0; 280 | } 281 | 282 | display_set_output_configure_handler(display, handle_output_configure); 283 | 284 | return 0; 285 | } 286 | 287 | static void 288 | global_handler(struct wl_display *display, uint32_t id, 289 | const char *interface, uint32_t version, void *data) 290 | { 291 | struct wscreensaver *screensaver = data; 292 | 293 | if (!strcmp(interface, "screensaver")) { 294 | screensaver->interface = 295 | wl_display_bind(display, id, &screensaver_interface); 296 | } 297 | } 298 | 299 | static const struct weston_option wscreensaver_options[] = { 300 | { WESTON_OPTION_BOOLEAN, "demo", 0, &demo_mode }, 301 | }; 302 | 303 | int main(int argc, char *argv[]) 304 | { 305 | struct display *d; 306 | struct wscreensaver screensaver = { 0 }; 307 | 308 | init_frand(); 309 | 310 | argc = parse_options(wscreensaver_options, 311 | ARRAY_LENGTH(wscreensaver_options), argc, argv); 312 | 313 | d = display_create(argc, argv); 314 | if (d == NULL) { 315 | fprintf(stderr, "failed to create display: %m\n"); 316 | return EXIT_FAILURE; 317 | } 318 | 319 | if (!demo_mode) { 320 | /* iterates already known globals immediately */ 321 | wl_display_add_global_listener(display_get_display(d), 322 | global_handler, &screensaver); 323 | if (!screensaver.interface) { 324 | fprintf(stderr, 325 | "Server did not offer screensaver interface," 326 | " exiting.\n"); 327 | return EXIT_FAILURE; 328 | } 329 | } 330 | 331 | if (init_wscreensaver(&screensaver, d) < 0) { 332 | fprintf(stderr, "wscreensaver init failed.\n"); 333 | return EXIT_FAILURE; 334 | } 335 | 336 | display_run(d); 337 | 338 | free((void *)progname); 339 | 340 | return EXIT_SUCCESS; 341 | } 342 | -------------------------------------------------------------------------------- /clients/wscreensaver.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2011 Collabora, Ltd. 3 | * 4 | * Permission to use, copy, modify, distribute, and sell this software and its 5 | * documentation for any purpose is hereby granted without fee, provided that 6 | * the above copyright notice appear in all copies and that both that copyright 7 | * notice and this permission notice appear in supporting documentation, and 8 | * that the name of the copyright holders not be used in advertising or 9 | * publicity pertaining to distribution of the software without specific, 10 | * written prior permission. The copyright holders make no representations 11 | * about the suitability of this software for any purpose. It is provided "as 12 | * is" without express or implied warranty. 13 | * 14 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 | * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 20 | * OF THIS SOFTWARE. 21 | */ 22 | 23 | #ifndef WSCREENSAVER_H 24 | #define WSCREENSAVER_H 25 | 26 | #define MESA_EGL_NO_X11_HEADERS 27 | #include 28 | 29 | extern const char *progname; 30 | 31 | struct wscreensaver; 32 | 33 | struct ModeInfo { 34 | struct wscreensaver *priv; 35 | EGLContext eglctx; 36 | int swap_buffers; 37 | 38 | struct window *window; 39 | struct widget *widget; 40 | 41 | int instance_number; 42 | int width; 43 | int height; 44 | 45 | unsigned long polygon_count; 46 | int fps_p; 47 | }; 48 | 49 | struct wscreensaver_plugin { 50 | const char *name; 51 | void (*init)(struct ModeInfo *mi); 52 | void (*draw)(struct ModeInfo *mi); 53 | void (*reshape)(struct ModeInfo *mi, int w, int h); 54 | /* void (*refresh)(struct ModeInfo *mi); 55 | void (*finish)(struct ModeInfo *mi);*/ 56 | }; 57 | 58 | EGLContext * 59 | init_GL(struct ModeInfo *mi); 60 | 61 | #endif /* WSCREENSAVER_H */ 62 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | AC_PREREQ([2.64]) 2 | AC_INIT([weston], 3 | [0.89], 4 | [https://bugs.freedesktop.org/enter_bug.cgi?product=weston], 5 | [weston], 6 | [http://wayland.freedesktop.org/]) 7 | 8 | AC_CONFIG_HEADERS([config.h]) 9 | 10 | AM_INIT_AUTOMAKE([1.11 foreign no-dist-gzip dist-xz]) 11 | 12 | AM_SILENT_RULES([yes]) 13 | 14 | # Check for programs 15 | AC_PROG_CC 16 | 17 | # Initialize libtool 18 | LT_PREREQ([2.2]) 19 | LT_INIT([disable-static]) 20 | 21 | PKG_PROG_PKG_CONFIG() 22 | 23 | AC_CHECK_FUNC([dlopen], [], 24 | AC_CHECK_LIB([dl], [dlopen], DLOPEN_LIBS="-ldl")) 25 | AC_SUBST(DLOPEN_LIBS) 26 | 27 | PKG_CHECK_MODULES(COMPOSITOR, 28 | [wayland-server egl >= 7.10 glesv2]) 29 | 30 | AC_CHECK_PROG(RSVG_CONVERT, rsvg-convert, rsvg-convert) 31 | AM_CONDITIONAL(HAVE_RSVG_CONVERT, test -n "$RSVG_CONVERT") 32 | 33 | 34 | AC_ARG_ENABLE(setuid-install, [ --enable-setuid-install],, 35 | enable_setuid_install=yes) 36 | AM_CONDITIONAL(ENABLE_SETUID_INSTALL, test x$enable_setuid_install = xyes) 37 | 38 | 39 | AC_ARG_ENABLE(xserver-launcher, [ --enable-xserver-launcher],, 40 | enable_xserver_launcher=yes) 41 | AM_CONDITIONAL(ENABLE_XSERVER_LAUNCHER, test x$enable_xserver_launcher = xyes) 42 | if test x$enable_xserver_launcher = xyes; then 43 | PKG_CHECK_MODULES([XSERVER_LAUNCHER], xcb xcb-xfixes) 44 | AC_DEFINE([BUILD_XSERVER_LAUNCHER], [1], [Build the X server launcher]) 45 | 46 | AC_ARG_WITH(xserver-path, AS_HELP_STRING([--with-xserver-path=PATH], 47 | [Path to X server]), [XSERVER_PATH="$withval"], 48 | [XSERVER_PATH="$bindir/Xorg"]) 49 | AC_SUBST([XSERVER_PATH]) 50 | fi 51 | 52 | 53 | AC_ARG_ENABLE(x11-compositor, [ --enable-x11-compositor],, 54 | enable_x11_compositor=yes) 55 | AM_CONDITIONAL(ENABLE_X11_COMPOSITOR, test x$enable_x11_compositor = xyes) 56 | if test x$enable_x11_compositor = xyes; then 57 | PKG_CHECK_MODULES([XCB], xcb) 58 | xcb_save_LIBS=$LIBS 59 | xcb_save_CFLAGS=$CFLAGS 60 | CFLAGS=$XCB_CFLAGS 61 | LIBS=$XCB_LIBS 62 | AC_CHECK_FUNCS([xcb_poll_for_queued_event]) 63 | LIBS=$xcb_save_LIBS 64 | CFLAGS=$xcb_save_CFLAGS 65 | 66 | AC_DEFINE([BUILD_X11_COMPOSITOR], [1], [Build the X11 compositor]) 67 | PKG_CHECK_MODULES(X11_COMPOSITOR, [x11 x11-xcb]) 68 | fi 69 | 70 | 71 | AC_ARG_ENABLE(drm-compositor, [ --enable-drm-compositor],, 72 | enable_drm_compositor=yes) 73 | AM_CONDITIONAL(ENABLE_DRM_COMPOSITOR, test x$enable_drm_compositor = xyes) 74 | if test x$enable_drm_compositor = xyes; then 75 | AC_DEFINE([BUILD_DRM_COMPOSITOR], [1], [Build the DRM compositor]) 76 | PKG_CHECK_MODULES(DRM_COMPOSITOR, [libudev >= 136 libdrm >= 2.4.30 gbm mtdev]) 77 | fi 78 | 79 | 80 | AC_ARG_ENABLE(openwfd-compositor, [ --enable-openwfd-compositor],, 81 | enable_openwfd_compositor=no) 82 | AM_CONDITIONAL(ENABLE_OPENWFD_COMPOSITOR, test x$enable_openwfd_compositor = xyes) 83 | if test x$enable_openwfd_compositor = xyes; then 84 | AC_DEFINE([BUILD_OPENWFD_COMPOSITOR], [1], [Build the OpenWF compositor]) 85 | PKG_CHECK_MODULES(OPENWFD_COMPOSITOR, [openwfd gbm]) 86 | fi 87 | 88 | 89 | AC_ARG_ENABLE(wayland-compositor, [ --enable-wayland-compositor],, 90 | enable_wayland_compositor=yes) 91 | AM_CONDITIONAL(ENABLE_WAYLAND_COMPOSITOR, 92 | test x$enable_wayland_compositor = xyes) 93 | if test x$enable_wayland_compositor = xyes; then 94 | AC_DEFINE([BUILD_WAYLAND_COMPOSITOR], [1], 95 | [Build the Wayland (nested) compositor]) 96 | PKG_CHECK_MODULES(WAYLAND_COMPOSITOR, [wayland-client wayland-egl]) 97 | fi 98 | 99 | AC_ARG_WITH(cairo-glesv2, AS_HELP_STRING([--with-cairo-glesv2], 100 | [Use GLESv2 cairo instead of full GL]), 101 | [cairo_modules="cairo-glesv2"], 102 | [cairo_modules="cairo-gl"]) 103 | if test x$cairo_modules = xcairo-glesv2; then 104 | AC_DEFINE([USE_CAIRO_GLESV2], [1], [Use the GLESv2 GL cairo backend]) 105 | fi 106 | 107 | PKG_CHECK_MODULES(PIXMAN, [pixman-1]) 108 | PKG_CHECK_MODULES(PNG, [libpng]) 109 | PKG_CHECK_MODULES(WEBP, [libwebp], [have_webp=yes], [have_webp=no]) 110 | AS_IF([test "x$have_webp" = "xyes"], 111 | [AC_DEFINE([HAVE_WEBP], [1], [Have webp])]) 112 | IMAGE_LIBS="$PIXMAN_LIBS $PNG_LIBS $WEBP_LIBS" 113 | IMAGE_CFLAGS="$PIXMAN_CFLAGS $PNG_CFLAGS $WEBP_CFLAGS" 114 | AC_SUBST(IMAGE_LIBS) 115 | AC_SUBST(IMAGE_CFLAGS) 116 | 117 | AC_CHECK_LIB([jpeg], [jpeg_CreateDecompress], have_jpeglib=yes) 118 | if test x$have_jpeglib = xyes; then 119 | IMAGE_LIBS="$IMAGE_LIBS -ljpeg" 120 | else 121 | AC_ERROR([libjpeg not found]) 122 | fi 123 | 124 | COMPOSITOR_LIBS="$COMPOSITOR_LIBS $IMAGE_LIBS" 125 | COMPOSITOR_CFLAGS="$COMPOSITOR_CFLAGS $IMAGE_CFLAGS" 126 | 127 | AC_ARG_ENABLE(simple-clients, [ --enable-simple-clients],, enable_simple_clients=yes) 128 | AM_CONDITIONAL(BUILD_SIMPLE_CLIENTS, test x$enable_simple_clients = xyes) 129 | if test x$enable_simple_clients = xyes; then 130 | AC_DEFINE([BUILD_SIMPLE_CLIENTS], [1], [Build the Wayland simple clients]) 131 | PKG_CHECK_MODULES(SIMPLE_CLIENT, 132 | [egl >= 7.10 glesv2 wayland-client wayland-egl]) 133 | fi 134 | 135 | AC_ARG_ENABLE(clients, [ --enable-clients],, enable_clients=yes) 136 | AM_CONDITIONAL(BUILD_CLIENTS, test x$enable_clients = xyes) 137 | if test x$enable_clients = xyes; then 138 | AC_DEFINE([BUILD_CLIENTS], [1], [Build the Wayland clients]) 139 | 140 | PKG_CHECK_MODULES(CLIENT, [wayland-client wayland-egl egl >= 7.10 cairo >= 1.10.0 xkbcommon]) 141 | 142 | CLIENT_CFLAGS="$CLIENT_CFLAGS $IMAGE_CFLAGS" 143 | CLIENT_LIBS="$CLIENT_LIBS $IMAGE_LIBS" 144 | 145 | PKG_CHECK_MODULES(POPPLER, [poppler-glib glib-2.0 gobject-2.0 gio-2.0 ], 146 | [have_poppler=yes], [have_poppler=no]) 147 | PKG_CHECK_MODULES(CAIRO_EGL, [cairo-egl >= 1.11.3 $cairo_modules], 148 | [have_cairo_egl=yes], [have_cairo_egl=no]) 149 | AS_IF([test "x$have_cairo_egl" = "xyes"], 150 | [AC_DEFINE([HAVE_CAIRO_EGL], [1], [Have cairo-egl])], 151 | [AC_MSG_WARN([Cairo-EGL not found - clients will use cairo image])]) 152 | fi 153 | 154 | AC_ARG_ENABLE(weston-launch, [ --enable-weston-launch],, enable_weston_launch=yes) 155 | AM_CONDITIONAL(BUILD_WESTON_LAUNCH, test x$enable_weston_launch == xyes) 156 | if test x$enable_weston_launch == xyes; then 157 | PKG_CHECK_MODULES(WESTON_LAUNCH, [libdrm]) 158 | PKG_CHECK_MODULES(SYSTEMD_LOGIN, [libsystemd-login], 159 | [have_systemd_login=yes], [have_systemd_login=no]) 160 | AS_IF([test "x$have_systemd_login" = "xyes"], 161 | [AC_DEFINE([HAVE_SYSTEMD_LOGIN], [1], [Have systemd-login])]) 162 | 163 | AC_CHECK_LIB([pam], [pam_open_session], [have_pam=yes], [have_pam=no]) 164 | if test x$have_pam == xno; then 165 | AC_ERROR([weston-launch requires pam]) 166 | fi 167 | WESTON_LAUNCH_LIBS="$WESTON_LAUNCH_LIBS -lpam" 168 | fi 169 | 170 | AM_CONDITIONAL(HAVE_POPPLER, test "x$have_poppler" = "xyes") 171 | 172 | AM_CONDITIONAL(BUILD_FULL_GL_CLIENTS, 173 | test x$cairo_modules = "xcairo-gl" -a "x$have_cairo_egl" = "xyes") 174 | 175 | AM_CONDITIONAL(ENABLE_DESKTOP_SHELL, true) 176 | 177 | AC_ARG_ENABLE(tablet-shell, [ --enable-tablet-shell],, 178 | enable_tablet_shell=yes) 179 | AM_CONDITIONAL(ENABLE_TABLET_SHELL, 180 | test x$enable_tablet_shell = xyes) 181 | 182 | if test "x$GCC" = "xyes"; then 183 | GCC_CFLAGS="-Wall -Wextra -Wstrict-prototypes -Wmissing-prototypes \ 184 | -Wno-unused-parameter -Wno-missing-field-initializers \ 185 | -g -fvisibility=hidden" 186 | 187 | fi 188 | AC_SUBST(GCC_CFLAGS) 189 | 190 | WAYLAND_SCANNER_RULES(['$(top_srcdir)/protocol']) 191 | 192 | AC_CONFIG_FILES([Makefile 193 | shared/Makefile 194 | src/Makefile 195 | clients/Makefile 196 | data/Makefile 197 | protocol/Makefile 198 | tests/Makefile]) 199 | AC_OUTPUT 200 | 201 | if test "x$enable_setuid_install" = xyes; then 202 | AC_MSG_WARN([ 203 | 204 | *** You've enabled the setuid install hook. Weston is still a 205 | *** pre-alpha project and may have bugs and issues that make a 206 | *** setuid install unsafe. Proceed at your own risk. 207 | ]) 208 | fi 209 | 210 | -------------------------------------------------------------------------------- /data/.gitignore: -------------------------------------------------------------------------------- 1 | wayland.png 2 | -------------------------------------------------------------------------------- /data/COPYING: -------------------------------------------------------------------------------- 1 | For the DMZ cursors: 2 | 3 | (c) 2007-2010 Novell, Inc. 4 | 5 | This work is licenced under the Creative Commons Attribution-Share Alike 3.0 6 | United States License. To view a copy of this licence, visit 7 | http://creativecommons.org/licenses/by-sa/3.0/ or send a letter to Creative 8 | Commons, 171 Second Street, Suite 300, San Francisco, California 94105, USA. 9 | 10 | The terminal icon is taken from the gnome-icon-theme collection which 11 | is also distributed under the Creative Commons BY-SA 3.0 license. -------------------------------------------------------------------------------- /data/Makefile.am: -------------------------------------------------------------------------------- 1 | westondatadir = $(datadir)/weston 2 | 3 | dist_westondata_DATA = \ 4 | bottom_left_corner.png \ 5 | bottom_right_corner.png \ 6 | bottom_side.png \ 7 | dnd-copy.png \ 8 | dnd-link.png \ 9 | dnd-move.png \ 10 | grabbing.png \ 11 | hand1.png \ 12 | hand2.png \ 13 | left_ptr.png \ 14 | left_side.png \ 15 | right_side.png \ 16 | sb_h_double_arrow.png \ 17 | sb_v_double_arrow.png \ 18 | top_left_corner.png \ 19 | top_right_corner.png \ 20 | top_side.png \ 21 | xterm.png \ 22 | wayland.svg \ 23 | $(wayland_icon_png) \ 24 | pattern.png \ 25 | terminal.png \ 26 | border.png 27 | 28 | if HAVE_RSVG_CONVERT 29 | wayland_icon_png = wayland.png 30 | 31 | wayland.png : $(top_srcdir)/data/wayland.svg 32 | $(RSVG_CONVERT) -w 128 -h 128 $< -o $@ 33 | endif 34 | -------------------------------------------------------------------------------- /data/border.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/detomastah/adwc/737c0c6569978a20e4a397f8d7d2223e31e20bbf/data/border.png -------------------------------------------------------------------------------- /data/bottom_left_corner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/detomastah/adwc/737c0c6569978a20e4a397f8d7d2223e31e20bbf/data/bottom_left_corner.png -------------------------------------------------------------------------------- /data/bottom_right_corner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/detomastah/adwc/737c0c6569978a20e4a397f8d7d2223e31e20bbf/data/bottom_right_corner.png -------------------------------------------------------------------------------- /data/bottom_side.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/detomastah/adwc/737c0c6569978a20e4a397f8d7d2223e31e20bbf/data/bottom_side.png -------------------------------------------------------------------------------- /data/dnd-copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/detomastah/adwc/737c0c6569978a20e4a397f8d7d2223e31e20bbf/data/dnd-copy.png -------------------------------------------------------------------------------- /data/dnd-link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/detomastah/adwc/737c0c6569978a20e4a397f8d7d2223e31e20bbf/data/dnd-link.png -------------------------------------------------------------------------------- /data/dnd-move.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/detomastah/adwc/737c0c6569978a20e4a397f8d7d2223e31e20bbf/data/dnd-move.png -------------------------------------------------------------------------------- /data/grabbing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/detomastah/adwc/737c0c6569978a20e4a397f8d7d2223e31e20bbf/data/grabbing.png -------------------------------------------------------------------------------- /data/hand1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/detomastah/adwc/737c0c6569978a20e4a397f8d7d2223e31e20bbf/data/hand1.png -------------------------------------------------------------------------------- /data/hand2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/detomastah/adwc/737c0c6569978a20e4a397f8d7d2223e31e20bbf/data/hand2.png -------------------------------------------------------------------------------- /data/left_ptr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/detomastah/adwc/737c0c6569978a20e4a397f8d7d2223e31e20bbf/data/left_ptr.png -------------------------------------------------------------------------------- /data/left_side.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/detomastah/adwc/737c0c6569978a20e4a397f8d7d2223e31e20bbf/data/left_side.png -------------------------------------------------------------------------------- /data/pattern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/detomastah/adwc/737c0c6569978a20e4a397f8d7d2223e31e20bbf/data/pattern.png -------------------------------------------------------------------------------- /data/right_side.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/detomastah/adwc/737c0c6569978a20e4a397f8d7d2223e31e20bbf/data/right_side.png -------------------------------------------------------------------------------- /data/sb_h_double_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/detomastah/adwc/737c0c6569978a20e4a397f8d7d2223e31e20bbf/data/sb_h_double_arrow.png -------------------------------------------------------------------------------- /data/sb_v_double_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/detomastah/adwc/737c0c6569978a20e4a397f8d7d2223e31e20bbf/data/sb_v_double_arrow.png -------------------------------------------------------------------------------- /data/terminal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/detomastah/adwc/737c0c6569978a20e4a397f8d7d2223e31e20bbf/data/terminal.png -------------------------------------------------------------------------------- /data/top_left_corner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/detomastah/adwc/737c0c6569978a20e4a397f8d7d2223e31e20bbf/data/top_left_corner.png -------------------------------------------------------------------------------- /data/top_right_corner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/detomastah/adwc/737c0c6569978a20e4a397f8d7d2223e31e20bbf/data/top_right_corner.png -------------------------------------------------------------------------------- /data/top_side.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/detomastah/adwc/737c0c6569978a20e4a397f8d7d2223e31e20bbf/data/top_side.png -------------------------------------------------------------------------------- /data/wayland.svg: -------------------------------------------------------------------------------- 1 | 2 | 24 | 25 | 26 | 27 | 44 | 46 | 64 | 66 | 67 | 69 | image/svg+xml 70 | 72 | 73 | 74 | 75 | 76 | 82 | 92 | 96 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /data/xterm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/detomastah/adwc/737c0c6569978a20e4a397f8d7d2223e31e20bbf/data/xterm.png -------------------------------------------------------------------------------- /protocol/Makefile.am: -------------------------------------------------------------------------------- 1 | EXTRA_DIST = \ 2 | desktop-shell.xml \ 3 | screenshooter.xml \ 4 | tablet-shell.xml \ 5 | xserver.xml 6 | -------------------------------------------------------------------------------- /protocol/desktop-shell.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /protocol/screenshooter.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /protocol/tablet-shell.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /protocol/xserver.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /shared/Makefile.am: -------------------------------------------------------------------------------- 1 | libconfig_parser_la_LIBADD = $(IMAGE_LIBS) 2 | AM_CPPFLAGS = $(IMAGE_CFLAGS) 3 | AM_CFLAGS = $(GCC_CFLAGS) 4 | 5 | noinst_LTLIBRARIES = libconfig-parser.la 6 | libconfig_parser_la_SOURCES = \ 7 | config-parser.c \ 8 | option-parser.c \ 9 | image-loader.c \ 10 | config-parser.h 11 | -------------------------------------------------------------------------------- /shared/config-parser.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2011 Intel Corporation 3 | * 4 | * Permission to use, copy, modify, distribute, and sell this software and its 5 | * documentation for any purpose is hereby granted without fee, provided that 6 | * the above copyright notice appear in all copies and that both that copyright 7 | * notice and this permission notice appear in supporting documentation, and 8 | * that the name of the copyright holders not be used in advertising or 9 | * publicity pertaining to distribution of the software without specific, 10 | * written prior permission. The copyright holders make no representations 11 | * about the suitability of this software for any purpose. It is provided "as 12 | * is" without express or implied warranty. 13 | * 14 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 | * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 20 | * OF THIS SOFTWARE. 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include "config-parser.h" 29 | 30 | static int 31 | handle_key(const struct config_key *key, const char *value) 32 | { 33 | char *end, *s; 34 | int i, len; 35 | unsigned int ui; 36 | 37 | switch (key->type) { 38 | case CONFIG_KEY_INTEGER: 39 | i = strtol(value, &end, 0); 40 | if (*end != '\n') { 41 | fprintf(stderr, "invalid integer: %s\n", value); 42 | return -1; 43 | } 44 | *(int *)key->data = i; 45 | return 0; 46 | 47 | case CONFIG_KEY_UNSIGNED_INTEGER: 48 | ui = strtoul(value, &end, 0); 49 | if (*end != '\n') { 50 | fprintf(stderr, "invalid integer: %s\n", value); 51 | return -1; 52 | } 53 | *(unsigned int *)key->data = ui; 54 | return 0; 55 | 56 | case CONFIG_KEY_STRING: 57 | len = strlen(value); 58 | s = malloc(len); 59 | if (s == NULL) 60 | return -1; 61 | memcpy(s, value, len - 1); 62 | s[len - 1] = '\0'; 63 | *(char **)key->data = s; 64 | return 0; 65 | 66 | case CONFIG_KEY_BOOLEAN: 67 | if (strcmp(value, "false\n") == 0) 68 | *(int *)key->data = 0; 69 | else if (strcmp(value, "true\n") == 0) 70 | *(int *)key->data = 1; 71 | else { 72 | fprintf(stderr, "invalid bool: %s\n", value); 73 | return -1; 74 | } 75 | return 0; 76 | 77 | default: 78 | assert(0); 79 | break; 80 | } 81 | } 82 | 83 | int 84 | parse_config_file(const char *path, 85 | const struct config_section *sections, int num_sections, 86 | void *data) 87 | { 88 | FILE *fp; 89 | char line[512], *p; 90 | const struct config_section *current = NULL; 91 | int i; 92 | 93 | fp = fopen(path, "r"); 94 | if (fp == NULL) { 95 | fprintf(stderr, "couldn't open %s\n", path); 96 | return -1; 97 | } 98 | 99 | while (fgets(line, sizeof line, fp)) { 100 | if (line[0] == '#' || line[0] == '\n') { 101 | continue; 102 | } if (line[0] == '[') { 103 | p = strchr(&line[1], ']'); 104 | if (!p || p[1] != '\n') { 105 | fprintf(stderr, "malformed " 106 | "section header: %s\n", line); 107 | fclose(fp); 108 | return -1; 109 | } 110 | if (current && current->done) 111 | current->done(data); 112 | p[0] = '\0'; 113 | for (i = 0; i < num_sections; i++) { 114 | if (strcmp(sections[i].name, &line[1]) == 0) { 115 | current = §ions[i]; 116 | break; 117 | } 118 | } 119 | if (i == num_sections) 120 | current = NULL; 121 | } else if (p = strchr(line, '='), p != NULL) { 122 | if (current == NULL) 123 | continue; 124 | p[0] = '\0'; 125 | for (i = 0; i < current->num_keys; i++) { 126 | if (strcmp(current->keys[i].name, line) == 0) { 127 | if (handle_key(¤t->keys[i], &p[1]) < 0) { 128 | fclose(fp); 129 | return -1; 130 | } 131 | break; 132 | } 133 | } 134 | } else { 135 | fprintf(stderr, "malformed config line: %s\n", line); 136 | fclose(fp); 137 | return -1; 138 | } 139 | } 140 | 141 | if (current && current->done) 142 | current->done(data); 143 | 144 | fclose(fp); 145 | 146 | return 0; 147 | } 148 | 149 | char * 150 | config_file_path(const char *name) 151 | { 152 | const char dotconf[] = "/.config/"; 153 | const char *config_dir; 154 | const char *home_dir; 155 | char *path; 156 | size_t size; 157 | 158 | config_dir = getenv("XDG_CONFIG_HOME"); 159 | if (!config_dir) { 160 | home_dir = getenv("HOME"); 161 | if (!home_dir) { 162 | fprintf(stderr, "HOME is not set, using cwd.\n"); 163 | return strdup(name); 164 | } 165 | 166 | size = strlen(home_dir) + sizeof dotconf + strlen(name); 167 | path = malloc(size); 168 | if (!path) 169 | return NULL; 170 | 171 | snprintf(path, size, "%s%s%s", home_dir, dotconf, name); 172 | return path; 173 | } 174 | 175 | size = strlen(config_dir) + 1 + strlen(name) + 1; 176 | path = malloc(size); 177 | if (!path) 178 | return NULL; 179 | 180 | snprintf(path, size, "%s/%s", config_dir, name); 181 | return path; 182 | } 183 | -------------------------------------------------------------------------------- /shared/config-parser.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2008 Kristian Høgsberg 3 | * 4 | * Permission to use, copy, modify, distribute, and sell this software and its 5 | * documentation for any purpose is hereby granted without fee, provided that 6 | * the above copyright notice appear in all copies and that both that copyright 7 | * notice and this permission notice appear in supporting documentation, and 8 | * that the name of the copyright holders not be used in advertising or 9 | * publicity pertaining to distribution of the software without specific, 10 | * written prior permission. The copyright holders make no representations 11 | * about the suitability of this software for any purpose. It is provided "as 12 | * is" without express or implied warranty. 13 | * 14 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 | * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 20 | * OF THIS SOFTWARE. 21 | */ 22 | 23 | #ifndef CONFIGPARSER_H 24 | #define CONFIGPARSER_H 25 | 26 | #include 27 | 28 | enum config_key_type { 29 | CONFIG_KEY_INTEGER, /* typeof data = int */ 30 | CONFIG_KEY_UNSIGNED_INTEGER, /* typeof data = unsigned int */ 31 | CONFIG_KEY_STRING, /* typeof data = char* */ 32 | CONFIG_KEY_BOOLEAN /* typeof data = int */ 33 | }; 34 | 35 | struct config_key { 36 | const char *name; 37 | enum config_key_type type; 38 | void *data; 39 | }; 40 | 41 | struct config_section { 42 | const char *name; 43 | const struct config_key *keys; 44 | int num_keys; 45 | void (*done)(void *data); 46 | }; 47 | 48 | int 49 | parse_config_file(const char *path, 50 | const struct config_section *sections, int num_sections, 51 | void *data); 52 | 53 | char * 54 | config_file_path(const char *name); 55 | 56 | enum weston_option_type { 57 | WESTON_OPTION_INTEGER, 58 | WESTON_OPTION_UNSIGNED_INTEGER, 59 | WESTON_OPTION_STRING, 60 | WESTON_OPTION_BOOLEAN, 61 | }; 62 | 63 | struct weston_option { 64 | enum weston_option_type type; 65 | const char *name; 66 | int short_name; 67 | void *data; 68 | }; 69 | 70 | int 71 | parse_options(const struct weston_option *options, 72 | int count, int argc, char *argv[]); 73 | 74 | pixman_image_t * 75 | load_image(const char *filename); 76 | 77 | #endif /* CONFIGPARSER_H */ 78 | 79 | -------------------------------------------------------------------------------- /shared/option-parser.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2012 Kristian Høgsberg 3 | * 4 | * Permission to use, copy, modify, distribute, and sell this software and its 5 | * documentation for any purpose is hereby granted without fee, provided that 6 | * the above copyright notice appear in all copies and that both that copyright 7 | * notice and this permission notice appear in supporting documentation, and 8 | * that the name of the copyright holders not be used in advertising or 9 | * publicity pertaining to distribution of the software without specific, 10 | * written prior permission. The copyright holders make no representations 11 | * about the suitability of this software for any purpose. It is provided "as 12 | * is" without express or implied warranty. 13 | * 14 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 | * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 20 | * OF THIS SOFTWARE. 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include "config-parser.h" 30 | 31 | static void 32 | handle_option(const struct weston_option *option, char *value) 33 | { 34 | switch (option->type) { 35 | case WESTON_OPTION_INTEGER: 36 | * (int32_t *) option->data = strtol(value, NULL, 0); 37 | return; 38 | case WESTON_OPTION_UNSIGNED_INTEGER: 39 | * (uint32_t *) option->data = strtoul(value, NULL, 0); 40 | return; 41 | case WESTON_OPTION_STRING: 42 | * (char **) option->data = strdup(value); 43 | return; 44 | case WESTON_OPTION_BOOLEAN: 45 | * (int32_t *) option->data = 1; 46 | return; 47 | default: 48 | assert(0); 49 | } 50 | } 51 | 52 | int 53 | parse_options(const struct weston_option *options, 54 | int count, int argc, char *argv[]) 55 | { 56 | int i, j, k, len = 0; 57 | 58 | for (i = 1, j = 1; i < argc; i++) { 59 | for (k = 0; k < count; k++) { 60 | if (options[k].name) 61 | len = strlen(options[k].name); 62 | if (options[k].name && 63 | argv[i][0] == '-' && 64 | argv[i][1] == '-' && 65 | strncmp(options[k].name, &argv[i][2], len) == 0 && 66 | (argv[i][len + 2] == '=' || argv[i][len + 2] == '\0')) { 67 | handle_option(&options[k], &argv[i][len + 3]); 68 | break; 69 | } else if (options[k].short_name && 70 | argv[i][0] == '-' && 71 | options[k].short_name == argv[i][1]) { 72 | handle_option(&options[k], &argv[i][2]); 73 | break; 74 | } 75 | } 76 | if (k == count) 77 | argv[j++] = argv[i]; 78 | } 79 | argv[j] = NULL; 80 | 81 | return j; 82 | } 83 | -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | weston 2 | weston-launch 3 | screenshooter-protocol.c 4 | screenshooter-server-protocol.h 5 | tablet-shell-protocol.c 6 | tablet-shell-server-protocol.h 7 | xserver-protocol.c 8 | xserver-server-protocol.h 9 | desktop-shell-protocol.c 10 | desktop-shell-server-protocol.h 11 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | bin_PROGRAMS = weston \ 2 | $(weston_launch) 3 | 4 | AM_CPPFLAGS = \ 5 | -DDATADIR='"$(datadir)"' \ 6 | -DMODULEDIR='"$(moduledir)"' \ 7 | -DLIBEXECDIR='"$(libexecdir)"' \ 8 | -DXSERVER_PATH='"@XSERVER_PATH@"' \ 9 | $(COMPOSITOR_CFLAGS) 10 | 11 | weston_LDFLAGS = -export-dynamic 12 | weston_CFLAGS = $(GCC_CFLAGS) $(DRM_COMPOSITOR_CFLAGS) $(GCC_CFLAGS) 13 | weston_LDADD = \ 14 | $(COMPOSITOR_LIBS) $(DLOPEN_LIBS) $(DRM_COMPOSITOR_LIBS) -lm ../shared/libconfig-parser.la 15 | 16 | weston_SOURCES = \ 17 | adwc.c \ 18 | adwc.h \ 19 | xserver-launcher.c \ 20 | xserver-protocol.c \ 21 | xserver-server-protocol.h \ 22 | screenshooter.c \ 23 | screenshooter-protocol.c \ 24 | screenshooter-server-protocol.h \ 25 | desktop-shell-protocol.c \ 26 | util.c \ 27 | matrix.c \ 28 | matrix.h \ 29 | weston-launch.h \ 30 | hash.c \ 31 | hash.h \ 32 | be-drm.c \ 33 | tty.c \ 34 | evdev.c \ 35 | evdev.h \ 36 | launcher-util.c \ 37 | launcher-util.h \ 38 | libbacklight.c \ 39 | libbacklight.h 40 | 41 | 42 | if BUILD_WESTON_LAUNCH 43 | weston_launch = weston-launch 44 | weston_launch_SOURCES = weston-launch.c weston-launch.h 45 | weston_launch_CFLAGS= $(GCC_CFLAGS) 46 | weston_launch_CPPFLAGS = $(WESTON_LAUNCH_CFLAGS) $(SYSTEMD_LOGIN_CFLAGS) \ 47 | -DBINDIR='"$(bindir)"' 48 | weston_launch_LDADD = $(WESTON_LAUNCH_LIBS) $(SYSTEMD_LOGIN_LIBS) 49 | 50 | if ENABLE_SETUID_INSTALL 51 | install-exec-hook: 52 | chown root $(DESTDIR)$(bindir)/weston-launch 53 | chmod u+s $(DESTDIR)$(bindir)/weston-launch 54 | endif 55 | 56 | else # BUILD_WESTON_LAUNCH 57 | 58 | if ENABLE_SETUID_INSTALL 59 | install-exec-hook: 60 | chown root $(DESTDIR)$(bindir)/weston 61 | chmod u+s $(DESTDIR)$(bindir)/weston 62 | endif 63 | 64 | endif # BUILD_WESTON_LAUNCH 65 | 66 | moduledir = @libdir@/weston 67 | module_LTLIBRARIES = \ 68 | $(desktop_shell) \ 69 | $(tablet_shell) \ 70 | $(xserver_launcher) \ 71 | $(x11_backend) \ 72 | $(drm_backend) \ 73 | $(wayland_backend) \ 74 | $(openwfd_backend) 75 | 76 | if ENABLE_X11_COMPOSITOR 77 | x11_backend = x11-backend.la 78 | x11_backend_la_LDFLAGS = -module -avoid-version 79 | x11_backend_la_LIBADD = $(COMPOSITOR_LIBS) $(X11_COMPOSITOR_LIBS) \ 80 | ../shared/libconfig-parser.la 81 | x11_backend_la_CFLAGS = $(X11_COMPOSITOR_CFLAGS) $(GCC_CFLAGS) 82 | x11_backend_la_SOURCES = compositor-x11.c 83 | endif 84 | 85 | if ENABLE_DRM_COMPOSITOR 86 | drm_backend = drm-backend.la 87 | drm_backend_la_LDFLAGS = -module -avoid-version 88 | drm_backend_la_LIBADD = $(COMPOSITOR_LIBS) $(DRM_COMPOSITOR_LIBS) \ 89 | ../shared/libconfig-parser.la 90 | drm_backend_la_CFLAGS = $(DRM_COMPOSITOR_CFLAGS) $(GCC_CFLAGS) 91 | drm_backend_la_SOURCES = \ 92 | compositor-drm.c \ 93 | tty.c \ 94 | evdev.c \ 95 | evdev.h \ 96 | launcher-util.c \ 97 | launcher-util.h \ 98 | libbacklight.c \ 99 | libbacklight.h 100 | endif 101 | 102 | if ENABLE_WAYLAND_COMPOSITOR 103 | wayland_backend = wayland-backend.la 104 | wayland_backend_la_LDFLAGS = -module -avoid-version 105 | wayland_backend_la_LIBADD = $(COMPOSITOR_LIBS) $(WAYLAND_COMPOSITOR_LIBS) \ 106 | ../shared/libconfig-parser.la 107 | wayland_backend_la_CFLAGS = $(WAYLAND_COMPOSITOR_CFLAGS) $(GCC_CFLAGS) 108 | wayland_backend_la_SOURCES = compositor-wayland.c 109 | endif 110 | 111 | if ENABLE_OPENWFD_COMPOSITOR 112 | openwfd_backend = openwfd-backend.la 113 | openwfd_backend_la_LDFLAGS = -module -avoid-version 114 | openwfd_backend_la_LIBADD = $(COMPOSITOR_LIBS) $(OPENWFD_COMPOSITOR_LIBS) 115 | openwfd_backend_la_CFLAGS = $(OPENWFD_COMPOSITOR_CFLAGS) $(GCC_CFLAGS) 116 | openwfd_backend_la_SOURCES = compositor-openwfd.c tty.c evdev.c evdev.h 117 | endif 118 | 119 | if ENABLE_XSERVER_LAUNCHER 120 | #xserver_launcher = xserver-launcher.la 121 | #xserver_launcher_la_LDFLAGS = -module -avoid-version 122 | #xserver_launcher_la_LIBADD = $(XSERVER_LAUNCHER_LIBS) 123 | #xserver_launcher_la_CFLAGS = $(GCC_CFLAGS) 124 | #xserver_launcher_la_SOURCES = \ 125 | # xserver-server-protocol.h \ 126 | # hash.c \ 127 | # hash.h 128 | endif 129 | 130 | if ENABLE_DESKTOP_SHELL 131 | desktop_shell = desktop-shell.la 132 | desktop_shell_la_LDFLAGS = -module -avoid-version 133 | desktop_shell_la_LIBADD = $(COMPOSITOR_LIBS) \ 134 | ../shared/libconfig-parser.la 135 | desktop_shell_la_CFLAGS = $(GCC_CFLAGS) 136 | desktop_shell_la_SOURCES = \ 137 | shell.c \ 138 | desktop-shell-protocol.c \ 139 | desktop-shell-server-protocol.h 140 | endif 141 | 142 | if ENABLE_TABLET_SHELL 143 | tablet_shell = tablet-shell.la 144 | tablet_shell_la_LDFLAGS = -module -avoid-version 145 | tablet_shell_la_LIBADD = $(COMPOSITOR_LIBS) 146 | tablet_shell_la_CFLAGS = $(GCC_CFLAGS) 147 | tablet_shell_la_SOURCES = \ 148 | tablet-shell.c \ 149 | tablet-shell-protocol.c \ 150 | tablet-shell-server-protocol.h 151 | endif 152 | 153 | BUILT_SOURCES = \ 154 | screenshooter-server-protocol.h \ 155 | screenshooter-protocol.c \ 156 | tablet-shell-protocol.c \ 157 | tablet-shell-server-protocol.h \ 158 | xserver-protocol.c \ 159 | xserver-server-protocol.h \ 160 | desktop-shell-protocol.c \ 161 | desktop-shell-server-protocol.h 162 | 163 | CLEANFILES = $(BUILT_SOURCES) 164 | 165 | @wayland_scanner_rules@ 166 | -------------------------------------------------------------------------------- /src/adwc_config.h: -------------------------------------------------------------------------------- 1 | 2 | #define dWayland_WithPosition 1 3 | #define dWayland_WithGlobalTransient 1 4 | 5 | #define dXWayland_Mode 0 6 | 7 | #define dModKey MODIFIER_ALT 8 | /* 9 | #define TAGKEYS(KEY,TAG) \ 10 | ((tADWC_Binding){ .Key = dModKey, KEY, view, {.ui = 1 << (TAG)} }), \ 11 | { dModKey|ControlMask, KEY, toggleview, {.ui = 1 << (TAG)} }, \ 12 | { dModKey|ShiftMask, KEY, tag, {.ui = 1 << (TAG)} }, \ 13 | { dModKey|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << (TAG)} }, 14 | */ 15 | #define TAGKEYS(KEY,TAG) \ 16 | ((tADWC_Binding){ .Mods = dModKey, .Key = KEY, .Handler = 0, .Priv = 1 << (TAG) }), 17 | 18 | 19 | static tADWC_Binding keys[] = { 20 | /* modifier key function argument */ 21 | /* 22 | // { MODKEY, XK_p, spawn, {.v = dmenucmd } }, 23 | { MODKEY, XK_Return, spawn, {.v = termcmd } }, 24 | // { MODKEY, XK_b, togglebar, {0} }, 25 | { MODKEY, XK_Tab, focusstack, {.i = +1 } }, 26 | { MODKEY|ShiftMask, XK_Tab, focusstack, {.i = -1 } }, 27 | // { MODKEY, XK_h, setmfact, {.f = -0.05} }, 28 | // { MODKEY, XK_l, setmfact, {.f = +0.05} }, 29 | { MODKEY|ShiftMask, XK_Return, zoom, {0} }, 30 | // { MODKEY, XK_Tab, view, {0} }, 31 | 32 | // { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, 33 | // { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, 34 | // { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, 35 | // { MODKEY, XK_space, setlayout, {0} }, 36 | 37 | { MODKEY, XK_Insert, togglefloating, {0} }, 38 | 39 | // { MODKEY, XK_0, view, {.ui = ~0 } }, 40 | // { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, 41 | 42 | { MODKEY, XK_Left, focusmon, {.i = -1 } }, 43 | { MODKEY, XK_Right, focusmon, {.i = +1 } }, 44 | // { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, 45 | // { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, 46 | { MODKEY, XK_Escape, Act_Exec, {0} }, 47 | 48 | { MODKEY, XK_F1, Act_Ring_Switch, {0} }, 49 | { MODKEY, XK_F5, Act_Ring_LinkAdd, {0} }, 50 | { MODKEY, XK_F8, Act_Ring_LinkDel, {0} }, 51 | 52 | { MODKEY, XK_BackSpace, killclient, {0} }, 53 | 54 | // { MODKEY|ShiftMask, XK_q, quit, {0} }, 55 | 56 | { MODKEY, XK_space, Act_Planes_Rot, {.i = -1} }, 57 | // { MODKEY|ShiftMask, XK_space, Act_Planes_Rot, {.i = +1} }, 58 | /**/ 59 | TAGKEYS (KEY_A, 0*3 + 0) TAGKEYS (XK_z, 0*3 + 1) TAGKEYS (XK_q, 0*3 + 2) 60 | TAGKEYS (XK_s, 1*3 + 0) TAGKEYS (XK_x, 1*3 + 1) TAGKEYS (XK_w, 1*3 + 2) 61 | TAGKEYS (XK_d, 2*3 + 0) TAGKEYS (XK_c, 2*3 + 1) TAGKEYS (XK_e, 2*3 + 2) 62 | TAGKEYS (XK_f, 3*3 + 0) TAGKEYS (XK_v, 3*3 + 1) TAGKEYS (XK_r, 3*3 + 2) 63 | TAGKEYS (XK_j, 4*3 + 0) TAGKEYS (XK_m, 4*3 + 1) TAGKEYS (XK_u, 4*3 + 2) 64 | TAGKEYS (XK_k, 5*3 + 0) TAGKEYS (XK_comma, 5*3 + 1) TAGKEYS (XK_i, 5*3 + 2) 65 | TAGKEYS (XK_l, 6*3 + 0) TAGKEYS (XK_period, 6*3 + 1) TAGKEYS (XK_o, 6*3 + 2) 66 | TAGKEYS (XK_semicolon, 7*3 + 0) TAGKEYS (XK_slash, 7*3 + 1) TAGKEYS (XK_p, 7*3 + 2) 67 | 68 | }; 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /src/be-drm.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ifndef _WAYLAND_SYSTEM_BE_DRM_H_ 4 | #define _WAYLAND_SYSTEM_BE_DRM_H_ 5 | 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | struct be_compositor { 14 | struct weston_compositor base; 15 | 16 | struct udev *udev; 17 | struct wl_event_source *be_source; 18 | 19 | struct udev_monitor *udev_monitor; 20 | struct wl_event_source *udev_be_source; 21 | 22 | struct { 23 | int id; 24 | int fd; 25 | } drm; 26 | 27 | struct gbm_device *gbm; 28 | uint32_t *crtcs; 29 | int num_crtcs; 30 | uint32_t crtc_allocator; 31 | uint32_t connector_allocator; 32 | struct tty *tty; 33 | 34 | struct gbm_surface *dummy_surface; 35 | EGLSurface dummy_egl_surface; 36 | 37 | struct wl_list sprite_list; 38 | int sprites_are_broken; 39 | 40 | uint32_t prev_state; 41 | }; 42 | 43 | struct be_mode { 44 | struct weston_mode base; 45 | drmModeModeInfo mode_info; 46 | }; 47 | 48 | struct be_output { 49 | struct weston_output base; 50 | 51 | uint32_t crtc_id; 52 | uint32_t connector_id; 53 | drmModeCrtcPtr original_crtc; 54 | 55 | struct gbm_surface *surface; 56 | EGLSurface egl_surface; 57 | 58 | uint32_t current_fb_id; 59 | uint32_t next_fb_id; 60 | struct gbm_bo *current_bo; 61 | struct gbm_bo *next_bo; 62 | 63 | struct wl_buffer *scanout_buffer; 64 | struct wl_listener scanout_buffer_destroy_listener; 65 | 66 | struct wl_buffer *pending_scanout_buffer; 67 | struct wl_listener pending_scanout_buffer_destroy_listener; 68 | 69 | struct backlight *backlight; 70 | }; 71 | 72 | /* 73 | * An output has a primary display plane plus zero or more sprites for 74 | * blending display contents. 75 | */ 76 | struct be_sprite { 77 | struct wl_list link; 78 | 79 | uint32_t fb_id; 80 | uint32_t pending_fb_id; 81 | 82 | struct weston_surface *surface; 83 | struct weston_surface *pending_surface; 84 | 85 | struct be_compositor *compositor; 86 | 87 | struct wl_listener destroy_listener; 88 | struct wl_listener pending_destroy_listener; 89 | 90 | uint32_t possible_crtcs; 91 | uint32_t plane_id; 92 | uint32_t count_formats; 93 | 94 | int32_t src_x, src_y; 95 | uint32_t src_w, src_h; 96 | uint32_t dest_x, dest_y; 97 | uint32_t dest_w, dest_h; 98 | 99 | uint32_t formats[]; 100 | }; 101 | 102 | extern struct be_compositor gBE; 103 | int be_output_set_cursor (struct weston_output *output_base, struct weston_input_device *eid); 104 | 105 | 106 | #endif 107 | 108 | -------------------------------------------------------------------------------- /src/evdev.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2011 Intel Corporation 3 | * 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. 13 | * 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. 21 | */ 22 | 23 | void 24 | evdev_add_devices(struct udev *udev, struct weston_input_device 25 | *input_base); 26 | 27 | void 28 | evdev_remove_devices(struct weston_input_device *input_base); 29 | 30 | void 31 | evdev_input_create(struct weston_compositor *c, struct udev *udev, 32 | const char *seat); 33 | 34 | void 35 | evdev_input_destroy(struct weston_input_device *input_base); 36 | 37 | int 38 | evdev_enable_udev_monitor(struct udev *udev, struct weston_input_device *input_base); 39 | 40 | void 41 | evdev_disable_udev_monitor(struct weston_input_device *input_base); 42 | -------------------------------------------------------------------------------- /src/hash.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2009 Intel Corporation 3 | * Copyright © 1988-2004 Keith Packard and Bart Massey. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a 6 | * copy of this software and associated documentation files (the "Software"), 7 | * to deal in the Software without restriction, including without limitation 8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | * and/or sell copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice (including the next 13 | * paragraph) shall be included in all copies or substantial portions of the 14 | * Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 | * IN THE SOFTWARE. 23 | * 24 | * Except as contained in this notice, the names of the authors 25 | * or their institutions shall not be used in advertising or 26 | * otherwise to promote the sale, use or other dealings in this 27 | * Software without prior written authorization from the 28 | * authors. 29 | * 30 | * Authors: 31 | * Eric Anholt 32 | * Keith Packard 33 | */ 34 | 35 | #include 36 | #include 37 | 38 | #include "hash.h" 39 | 40 | struct hash_entry { 41 | uint32_t hash; 42 | void *data; 43 | }; 44 | 45 | struct hash_table { 46 | struct hash_entry *table; 47 | uint32_t size; 48 | uint32_t rehash; 49 | uint32_t max_entries; 50 | uint32_t size_index; 51 | uint32_t entries; 52 | uint32_t deleted_entries; 53 | }; 54 | 55 | #define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0])) 56 | 57 | /* 58 | * From Knuth -- a good choice for hash/rehash values is p, p-2 where 59 | * p and p-2 are both prime. These tables are sized to have an extra 10% 60 | * free to avoid exponential performance degradation as the hash table fills 61 | */ 62 | 63 | static const uint32_t deleted_data; 64 | 65 | static const struct { 66 | uint32_t max_entries, size, rehash; 67 | } hash_sizes[] = { 68 | { 2, 5, 3 }, 69 | { 4, 7, 5 }, 70 | { 8, 13, 11 }, 71 | { 16, 19, 17 }, 72 | { 32, 43, 41 }, 73 | { 64, 73, 71 }, 74 | { 128, 151, 149 }, 75 | { 256, 283, 281 }, 76 | { 512, 571, 569 }, 77 | { 1024, 1153, 1151 }, 78 | { 2048, 2269, 2267 }, 79 | { 4096, 4519, 4517 }, 80 | { 8192, 9013, 9011 }, 81 | { 16384, 18043, 18041 }, 82 | { 32768, 36109, 36107 }, 83 | { 65536, 72091, 72089 }, 84 | { 131072, 144409, 144407 }, 85 | { 262144, 288361, 288359 }, 86 | { 524288, 576883, 576881 }, 87 | { 1048576, 1153459, 1153457 }, 88 | { 2097152, 2307163, 2307161 }, 89 | { 4194304, 4613893, 4613891 }, 90 | { 8388608, 9227641, 9227639 }, 91 | { 16777216, 18455029, 18455027 }, 92 | { 33554432, 36911011, 36911009 }, 93 | { 67108864, 73819861, 73819859 }, 94 | { 134217728, 147639589, 147639587 }, 95 | { 268435456, 295279081, 295279079 }, 96 | { 536870912, 590559793, 590559791 }, 97 | { 1073741824, 1181116273, 1181116271}, 98 | { 2147483648ul, 2362232233ul, 2362232231ul} 99 | }; 100 | 101 | static int 102 | entry_is_free(struct hash_entry *entry) 103 | { 104 | return entry->data == NULL; 105 | } 106 | 107 | static int 108 | entry_is_deleted(struct hash_entry *entry) 109 | { 110 | return entry->data == &deleted_data; 111 | } 112 | 113 | static int 114 | entry_is_present(struct hash_entry *entry) 115 | { 116 | return entry->data != NULL && entry->data != &deleted_data; 117 | } 118 | 119 | struct hash_table * 120 | hash_table_create(void) 121 | { 122 | struct hash_table *ht; 123 | 124 | ht = malloc(sizeof(*ht)); 125 | if (ht == NULL) 126 | return NULL; 127 | 128 | ht->size_index = 0; 129 | ht->size = hash_sizes[ht->size_index].size; 130 | ht->rehash = hash_sizes[ht->size_index].rehash; 131 | ht->max_entries = hash_sizes[ht->size_index].max_entries; 132 | ht->table = calloc(ht->size, sizeof(*ht->table)); 133 | ht->entries = 0; 134 | ht->deleted_entries = 0; 135 | 136 | if (ht->table == NULL) { 137 | free(ht); 138 | return NULL; 139 | } 140 | 141 | return ht; 142 | } 143 | 144 | /** 145 | * Frees the given hash table. 146 | */ 147 | void 148 | hash_table_destroy(struct hash_table *ht) 149 | { 150 | if (!ht) 151 | return; 152 | 153 | free(ht->table); 154 | free(ht); 155 | } 156 | 157 | /** 158 | * Finds a hash table entry with the given key and hash of that key. 159 | * 160 | * Returns NULL if no entry is found. Note that the data pointer may be 161 | * modified by the user. 162 | */ 163 | static void * 164 | hash_table_search(struct hash_table *ht, uint32_t hash) 165 | { 166 | uint32_t hash_address; 167 | 168 | hash_address = hash % ht->size; 169 | do { 170 | uint32_t double_hash; 171 | 172 | struct hash_entry *entry = ht->table + hash_address; 173 | 174 | if (entry_is_free(entry)) { 175 | return NULL; 176 | } else if (entry_is_present(entry) && entry->hash == hash) { 177 | return entry; 178 | } 179 | 180 | double_hash = 1 + hash % ht->rehash; 181 | 182 | hash_address = (hash_address + double_hash) % ht->size; 183 | } while (hash_address != hash % ht->size); 184 | 185 | return NULL; 186 | } 187 | 188 | void 189 | hash_table_for_each(struct hash_table *ht, 190 | hash_table_iterator_func_t func, void *data) 191 | { 192 | struct hash_entry *entry; 193 | uint32_t i; 194 | 195 | for (i = 0; i < ht->size; i++) { 196 | entry = ht->table + i; 197 | if (entry_is_present(entry)) 198 | func(entry->data, data); 199 | } 200 | } 201 | 202 | void * 203 | hash_table_lookup(struct hash_table *ht, uint32_t hash) 204 | { 205 | struct hash_entry *entry; 206 | 207 | entry = hash_table_search(ht, hash); 208 | if (entry != NULL) 209 | return entry->data; 210 | 211 | return NULL; 212 | } 213 | 214 | static void 215 | hash_table_rehash(struct hash_table *ht, unsigned int new_size_index) 216 | { 217 | struct hash_table old_ht; 218 | struct hash_entry *table, *entry; 219 | 220 | if (new_size_index >= ARRAY_SIZE(hash_sizes)) 221 | return; 222 | 223 | table = calloc(hash_sizes[new_size_index].size, sizeof(*ht->table)); 224 | if (table == NULL) 225 | return; 226 | 227 | old_ht = *ht; 228 | 229 | ht->table = table; 230 | ht->size_index = new_size_index; 231 | ht->size = hash_sizes[ht->size_index].size; 232 | ht->rehash = hash_sizes[ht->size_index].rehash; 233 | ht->max_entries = hash_sizes[ht->size_index].max_entries; 234 | ht->entries = 0; 235 | ht->deleted_entries = 0; 236 | 237 | for (entry = old_ht.table; 238 | entry != old_ht.table + old_ht.size; 239 | entry++) { 240 | if (entry_is_present(entry)) { 241 | hash_table_insert(ht, entry->hash, entry->data); 242 | } 243 | } 244 | 245 | free(old_ht.table); 246 | } 247 | 248 | /** 249 | * Inserts the data with the given hash into the table. 250 | * 251 | * Note that insertion may rearrange the table on a resize or rehash, 252 | * so previously found hash_entries are no longer valid after this function. 253 | */ 254 | int 255 | hash_table_insert(struct hash_table *ht, uint32_t hash, void *data) 256 | { 257 | uint32_t hash_address; 258 | 259 | if (ht->entries >= ht->max_entries) { 260 | hash_table_rehash(ht, ht->size_index + 1); 261 | } else if (ht->deleted_entries + ht->entries >= ht->max_entries) { 262 | hash_table_rehash(ht, ht->size_index); 263 | } 264 | 265 | hash_address = hash % ht->size; 266 | do { 267 | struct hash_entry *entry = ht->table + hash_address; 268 | uint32_t double_hash; 269 | 270 | if (!entry_is_present(entry)) { 271 | if (entry_is_deleted(entry)) 272 | ht->deleted_entries--; 273 | entry->hash = hash; 274 | entry->data = data; 275 | ht->entries++; 276 | return 0; 277 | } 278 | 279 | double_hash = 1 + hash % ht->rehash; 280 | 281 | hash_address = (hash_address + double_hash) % ht->size; 282 | } while (hash_address != hash % ht->size); 283 | 284 | /* We could hit here if a required resize failed. An unchecked-malloc 285 | * application could ignore this result. 286 | */ 287 | return -1; 288 | } 289 | 290 | /** 291 | * This function deletes the given hash table entry. 292 | * 293 | * Note that deletion doesn't otherwise modify the table, so an iteration over 294 | * the table deleting entries is safe. 295 | */ 296 | void 297 | hash_table_remove(struct hash_table *ht, uint32_t hash) 298 | { 299 | struct hash_entry *entry; 300 | 301 | entry = hash_table_search(ht, hash); 302 | if (entry != NULL) { 303 | entry->data = (void *) &deleted_data; 304 | ht->entries--; 305 | ht->deleted_entries++; 306 | } 307 | } 308 | -------------------------------------------------------------------------------- /src/hash.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2009 Intel Corporation 3 | * Copyright © 1988-2004 Keith Packard and Bart Massey. 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a 6 | * copy of this software and associated documentation files (the "Software"), 7 | * to deal in the Software without restriction, including without limitation 8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 | * and/or sell copies of the Software, and to permit persons to whom the 10 | * Software is furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice (including the next 13 | * paragraph) shall be included in all copies or substantial portions of the 14 | * Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 | * IN THE SOFTWARE. 23 | * 24 | * Except as contained in this notice, the names of the authors 25 | * or their institutions shall not be used in advertising or 26 | * otherwise to promote the sale, use or other dealings in this 27 | * Software without prior written authorization from the 28 | * authors. 29 | * 30 | * Authors: 31 | * Eric Anholt 32 | * Keith Packard 33 | */ 34 | 35 | #ifndef HASH_H 36 | #define HASH_H 37 | 38 | struct hash_table; 39 | struct hash_table *hash_table_create(void); 40 | typedef void (*hash_table_iterator_func_t)(void *element, void *data); 41 | 42 | void hash_table_destroy(struct hash_table *ht); 43 | void *hash_table_lookup(struct hash_table *ht, uint32_t hash); 44 | int hash_table_insert(struct hash_table *ht, uint32_t hash, void *data); 45 | void hash_table_remove(struct hash_table *ht, uint32_t hash); 46 | void hash_table_for_each(struct hash_table *ht, 47 | hash_table_iterator_func_t func, void *data); 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src/launcher-util.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2012 Benjamin Franzke 3 | * 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. 13 | * 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. 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include 35 | 36 | #include "adwc.h" 37 | #include "launcher-util.h" 38 | #include "weston-launch.h" 39 | 40 | union cmsg_data { unsigned char b[4]; int fd; }; 41 | 42 | int 43 | weston_launcher_open(struct weston_compositor *compositor, 44 | const char *path, int flags) 45 | { 46 | int sock = compositor->launcher_sock; 47 | int n, ret = -1; 48 | struct msghdr msg; 49 | struct cmsghdr *cmsg; 50 | struct iovec iov; 51 | union cmsg_data *data; 52 | char control[CMSG_SPACE(sizeof data->fd)]; 53 | ssize_t len; 54 | struct weston_launcher_open *message; 55 | 56 | if (sock == -1) 57 | return open(path, flags); 58 | 59 | n = sizeof(*message) + strlen(path) + 1; 60 | message = malloc(n); 61 | if (!message) 62 | return -1; 63 | 64 | message->header.opcode = WESTON_LAUNCHER_OPEN; 65 | message->flags = flags; 66 | strcpy(message->path, path); 67 | 68 | do { 69 | len = send(sock, message, n, 0); 70 | } while (len < 0 && errno == EINTR); 71 | free(message); 72 | 73 | memset(&msg, 0, sizeof msg); 74 | iov.iov_base = &ret; 75 | iov.iov_len = sizeof ret; 76 | msg.msg_iov = &iov; 77 | msg.msg_iovlen = 1; 78 | msg.msg_control = control; 79 | msg.msg_controllen = sizeof control; 80 | 81 | do { 82 | len = recvmsg(sock, &msg, MSG_CMSG_CLOEXEC); 83 | } while (len < 0 && errno == EINTR); 84 | 85 | if (len != sizeof ret || 86 | ret < 0) 87 | return -1; 88 | 89 | cmsg = CMSG_FIRSTHDR(&msg); 90 | if (!cmsg || 91 | cmsg->cmsg_level != SOL_SOCKET || 92 | cmsg->cmsg_type != SCM_RIGHTS) { 93 | fprintf(stderr, "invalid control message\n"); 94 | return -1; 95 | } 96 | 97 | data = (union cmsg_data *) CMSG_DATA(cmsg); 98 | if (data->fd == -1) { 99 | fprintf(stderr, "missing drm fd in socket request"); 100 | return -1; 101 | } 102 | 103 | return data->fd; 104 | } 105 | 106 | int 107 | weston_launcher_drm_set_master(struct weston_compositor *compositor, 108 | int drm_fd, char master) 109 | { 110 | struct msghdr msg; 111 | struct cmsghdr *cmsg; 112 | struct iovec iov; 113 | char control[CMSG_SPACE(sizeof(drm_fd))]; 114 | int ret; 115 | ssize_t len; 116 | struct weston_launcher_set_master message; 117 | union cmsg_data *data; 118 | 119 | if (compositor->launcher_sock == -1) { 120 | if (master) 121 | return drmSetMaster(drm_fd); 122 | else 123 | return drmDropMaster(drm_fd); 124 | } 125 | 126 | memset(&msg, 0, sizeof msg); 127 | msg.msg_iov = &iov; 128 | msg.msg_iovlen = 1; 129 | msg.msg_control = control; 130 | msg.msg_controllen = sizeof control; 131 | cmsg = CMSG_FIRSTHDR(&msg); 132 | cmsg->cmsg_level = SOL_SOCKET; 133 | cmsg->cmsg_type = SCM_RIGHTS; 134 | cmsg->cmsg_len = CMSG_LEN(sizeof(drm_fd)); 135 | 136 | data = (union cmsg_data *) CMSG_DATA(cmsg); 137 | data->fd = drm_fd; 138 | msg.msg_controllen = cmsg->cmsg_len; 139 | 140 | iov.iov_base = &message; 141 | iov.iov_len = sizeof message; 142 | 143 | message.header.opcode = WESTON_LAUNCHER_DRM_SET_MASTER; 144 | message.set_master = master; 145 | 146 | do { 147 | len = sendmsg(compositor->launcher_sock, &msg, 0); 148 | } while (len < 0 && errno == EINTR); 149 | if (len < 0) 150 | return -1; 151 | 152 | do { 153 | len = recv(compositor->launcher_sock, &ret, sizeof ret, 0); 154 | } while (len < 0 && errno == EINTR); 155 | if (len < 0) 156 | return -1; 157 | 158 | return ret; 159 | } 160 | 161 | -------------------------------------------------------------------------------- /src/launcher-util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2012 Benjamin Franzke 3 | * 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. 13 | * 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. 21 | */ 22 | 23 | #ifndef _WESTON_LAUNCHER_UTIL_H_ 24 | #define _WESTON_LAUNCHER_UTIL_H_ 25 | 26 | #include "adwc.h" 27 | 28 | int 29 | weston_launcher_open(struct weston_compositor *compositor, 30 | const char *path, int flags); 31 | int 32 | weston_launcher_drm_set_master(struct weston_compositor *compositor, 33 | int drm_fd, char master); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/libbacklight.c: -------------------------------------------------------------------------------- 1 | /* 2 | * libbacklight - userspace interface to Linux backlight control 3 | * 4 | * Copyright © 2012 Intel Corporation 5 | * Copyright 2010 Red Hat 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a 8 | * copy of this software and associated documentation files (the "Software"), 9 | * to deal in the Software without restriction, including without limitation 10 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 | * and/or sell copies of the Software, and to permit persons to whom the 12 | * Software is furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice (including the next 15 | * paragraph) shall be included in all copies or substantial portions of the 16 | * Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | * DEALINGS IN THE SOFTWARE. 26 | * 27 | * Authors: 28 | * Matthew Garrett 29 | * Tiago Vignatti 30 | */ 31 | 32 | #define _GNU_SOURCE 33 | 34 | #include "libbacklight.h" 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | static long backlight_get(struct backlight *backlight, char *node) 47 | { 48 | char buffer[100]; 49 | char *path; 50 | int fd; 51 | long value, ret; 52 | 53 | if (asprintf(&path, "%s/%s", backlight->path, node) < 0) 54 | return -ENOMEM 55 | ; 56 | fd = open(path, O_RDONLY); 57 | if (fd < 0) { 58 | ret = -1; 59 | goto out; 60 | } 61 | 62 | ret = read(fd, &buffer, sizeof(buffer)); 63 | if (ret < 1) { 64 | ret = -1; 65 | goto out; 66 | } 67 | 68 | value = strtol(buffer, NULL, 10); 69 | ret = value; 70 | out: 71 | close(fd); 72 | if (path) 73 | free(path); 74 | return ret; 75 | } 76 | 77 | long backlight_get_brightness(struct backlight *backlight) 78 | { 79 | return backlight_get(backlight, "brightness"); 80 | } 81 | 82 | long backlight_get_max_brightness(struct backlight *backlight) 83 | { 84 | return backlight_get(backlight, "max_brightness"); 85 | } 86 | 87 | long backlight_get_actual_brightness(struct backlight *backlight) 88 | { 89 | return backlight_get(backlight, "actual_brightness"); 90 | } 91 | 92 | long backlight_set_brightness(struct backlight *backlight, long brightness) 93 | { 94 | char *path; 95 | char *buffer = NULL; 96 | int fd; 97 | long ret; 98 | 99 | if (asprintf(&path, "%s/%s", backlight->path, "brightness") < 0) 100 | return -ENOMEM; 101 | 102 | fd = open(path, O_RDWR); 103 | if (fd < 0) { 104 | ret = -1; 105 | goto out; 106 | } 107 | 108 | ret = read(fd, &buffer, sizeof(buffer)); 109 | if (ret < 1) { 110 | ret = -1; 111 | goto out; 112 | } 113 | 114 | if (asprintf(&buffer, "%ld", brightness) < 0) 115 | return -ENOMEM; 116 | 117 | ret = write(fd, buffer, strlen(buffer)); 118 | if (ret < 0) { 119 | ret = -1; 120 | goto out; 121 | } 122 | 123 | ret = backlight_get_brightness(backlight); 124 | backlight->brightness = ret; 125 | out: 126 | if (buffer) 127 | free(buffer); 128 | if (path) 129 | free(path); 130 | close(fd); 131 | return ret; 132 | } 133 | 134 | void backlight_destroy(struct backlight *backlight) 135 | { 136 | if (!backlight) 137 | return; 138 | 139 | if (backlight->path) 140 | free(backlight->path); 141 | 142 | free(backlight); 143 | } 144 | 145 | struct backlight *backlight_init(struct udev_device *drm_device, 146 | uint32_t connector_type) 147 | { 148 | const char *syspath = NULL; 149 | char *pci_name = NULL; 150 | char *chosen_path = NULL; 151 | char *path = NULL; 152 | DIR *backlights; 153 | struct dirent *entry; 154 | enum backlight_type type = 0; 155 | char buffer[100]; 156 | struct backlight *backlight; 157 | int ret; 158 | 159 | if (!drm_device) 160 | return NULL; 161 | 162 | syspath = udev_device_get_syspath(drm_device); 163 | if (!syspath) 164 | return NULL; 165 | 166 | if (asprintf(&path, "%s/%s", syspath, "device") < 0) 167 | return NULL; 168 | 169 | ret = readlink(path, buffer, sizeof(buffer)); 170 | free(path); 171 | if (ret < 0) 172 | return NULL; 173 | 174 | buffer[ret] = '\0'; 175 | pci_name = basename(buffer); 176 | 177 | if (connector_type <= 0) 178 | return NULL; 179 | 180 | backlights = opendir("/sys/class/backlight"); 181 | if (!backlights) 182 | return NULL; 183 | 184 | /* Find the "best" backlight for the device. Firmware 185 | interfaces are preferred over platform interfaces are 186 | preferred over raw interfaces. For raw interfaces we'll 187 | check if the device ID in the form of pci match, while 188 | for firmware interfaces we require the pci ID to 189 | match. It's assumed that platform interfaces always match, 190 | since we can't actually associate them with IDs. 191 | 192 | A further awkwardness is that, while it's theoretically 193 | possible for an ACPI interface to include support for 194 | changing the backlight of external devices, it's unlikely 195 | to ever be done. It's effectively impossible for a platform 196 | interface to do so. So if we get asked about anything that 197 | isn't LVDS or eDP, we pretty much have to require that the 198 | control be supplied via a raw interface */ 199 | 200 | while ((entry = readdir(backlights))) { 201 | char *backlight_path; 202 | char *parent; 203 | enum backlight_type entry_type; 204 | int fd; 205 | 206 | if (entry->d_name[0] == '.') 207 | continue; 208 | 209 | if (asprintf(&backlight_path, "%s/%s", "/sys/class/backlight", 210 | entry->d_name) < 0) 211 | return NULL; 212 | 213 | if (asprintf(&path, "%s/%s", backlight_path, "type") < 0) 214 | return NULL; 215 | 216 | fd = open(path, O_RDONLY); 217 | 218 | if (fd < 0) 219 | goto out; 220 | 221 | ret = read (fd, &buffer, sizeof(buffer)); 222 | close (fd); 223 | 224 | if (ret < 1) 225 | goto out; 226 | 227 | buffer[ret] = '\0'; 228 | 229 | if (!strncmp(buffer, "raw\n", sizeof(buffer))) 230 | entry_type = BACKLIGHT_RAW; 231 | else if (!strncmp(buffer, "platform\n", sizeof(buffer))) 232 | entry_type = BACKLIGHT_PLATFORM; 233 | else if (!strncmp(buffer, "firmware\n", sizeof(buffer))) 234 | entry_type = BACKLIGHT_FIRMWARE; 235 | else 236 | goto out; 237 | 238 | if (connector_type != DRM_MODE_CONNECTOR_LVDS && 239 | connector_type != DRM_MODE_CONNECTOR_eDP) { 240 | /* External displays are assumed to require 241 | gpu control at the moment */ 242 | if (entry_type != BACKLIGHT_RAW) 243 | goto out; 244 | } 245 | 246 | free (path); 247 | 248 | if (asprintf(&path, "%s/%s", backlight_path, "device") < 0) 249 | return NULL; 250 | 251 | ret = readlink(path, buffer, sizeof(buffer)); 252 | 253 | if (ret < 0) 254 | goto out; 255 | 256 | buffer[ret] = '\0'; 257 | 258 | parent = basename(buffer); 259 | 260 | /* Perform matching for raw and firmware backlights - 261 | platform backlights have to be assumed to match */ 262 | if (entry_type == BACKLIGHT_RAW || 263 | entry_type == BACKLIGHT_FIRMWARE) { 264 | if (!(pci_name && !strcmp(pci_name, parent))) 265 | goto out; 266 | } 267 | 268 | if (entry_type < type) 269 | goto out; 270 | 271 | type = entry_type; 272 | 273 | if (chosen_path) 274 | free(chosen_path); 275 | chosen_path = strdup(backlight_path); 276 | 277 | out: 278 | free(backlight_path); 279 | free(path); 280 | } 281 | 282 | if (!chosen_path) 283 | return NULL; 284 | 285 | backlight = malloc(sizeof(struct backlight)); 286 | 287 | if (!backlight) 288 | goto err; 289 | 290 | backlight->path = chosen_path; 291 | backlight->type = type; 292 | 293 | backlight->max_brightness = backlight_get_max_brightness(backlight); 294 | if (backlight->max_brightness < 0) 295 | goto err; 296 | 297 | backlight->brightness = backlight_get_actual_brightness(backlight); 298 | if (backlight->brightness < 0) 299 | goto err; 300 | 301 | return backlight; 302 | err: 303 | if (chosen_path) 304 | free(chosen_path); 305 | free (backlight); 306 | return NULL; 307 | } 308 | -------------------------------------------------------------------------------- /src/libbacklight.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBBACKLIGHT_H 2 | #define LIBBACKLIGHT_H 3 | #include 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | enum backlight_type { 11 | BACKLIGHT_RAW, 12 | BACKLIGHT_PLATFORM, 13 | BACKLIGHT_FIRMWARE, 14 | }; 15 | 16 | struct backlight { 17 | char *path; 18 | int max_brightness; 19 | int brightness; 20 | enum backlight_type type; 21 | }; 22 | 23 | /* 24 | * Find and set up a backlight for a valid udev connector device, i.e. one 25 | * matching drm subsytem and with status of connected. 26 | */ 27 | struct backlight *backlight_init(struct udev_device *drm_device, 28 | uint32_t connector_type); 29 | 30 | /* Free backlight resources */ 31 | void backlight_destroy(struct backlight *backlight); 32 | 33 | /* Provide the maximum backlight value */ 34 | long backlight_get_max_brightness(struct backlight *backlight); 35 | 36 | /* Provide the cached backlight value */ 37 | long backlight_get_brightness(struct backlight *backlight); 38 | 39 | /* Provide the hardware backlight value */ 40 | long backlight_get_actual_brightness(struct backlight *backlight); 41 | 42 | /* Set the backlight to a value between 0 and max */ 43 | long backlight_set_brightness(struct backlight *backlight, long brightness); 44 | 45 | #ifdef __cplusplus 46 | } 47 | #endif 48 | 49 | #endif /* LIBBACKLIGHT_H */ 50 | -------------------------------------------------------------------------------- /src/matrix.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2011 Intel Corporation 3 | * Copyright © 2012 Collabora, Ltd. 4 | * 5 | * Permission to use, copy, modify, distribute, and sell this software and 6 | * its documentation for any purpose is hereby granted without fee, provided 7 | * that the above copyright notice appear in all copies and that both that 8 | * copyright notice and this permission notice appear in supporting 9 | * documentation, and that the name of the copyright holders not be used in 10 | * advertising or publicity pertaining to distribution of the software 11 | * without specific, written prior permission. The copyright holders make 12 | * no representations about the suitability of this software for any 13 | * purpose. It is provided "as is" without express or implied warranty. 14 | * 15 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS 16 | * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 17 | * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER 19 | * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF 20 | * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 21 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include "matrix.h" 31 | 32 | 33 | /* 34 | * Matrices are stored in column-major order, that is the array indices are: 35 | * 0 4 8 12 36 | * 1 5 9 13 37 | * 2 6 10 14 38 | * 3 7 11 15 39 | */ 40 | 41 | WL_EXPORT void 42 | weston_matrix_init(struct weston_matrix *matrix) 43 | { 44 | static const struct weston_matrix identity = { 45 | { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 } 46 | }; 47 | 48 | memcpy(matrix, &identity, sizeof identity); 49 | } 50 | 51 | /* m <- n * m, that is, m is multiplied on the LEFT. */ 52 | WL_EXPORT void 53 | weston_matrix_multiply(struct weston_matrix *m, const struct weston_matrix *n) 54 | { 55 | struct weston_matrix tmp; 56 | const GLfloat *row, *column; 57 | div_t d; 58 | int i, j; 59 | 60 | for (i = 0; i < 16; i++) { 61 | tmp.d[i] = 0; 62 | d = div(i, 4); 63 | row = m->d + d.quot * 4; 64 | column = n->d + d.rem; 65 | for (j = 0; j < 4; j++) 66 | tmp.d[i] += row[j] * column[j * 4]; 67 | } 68 | memcpy(m, &tmp, sizeof tmp); 69 | } 70 | 71 | WL_EXPORT void 72 | weston_matrix_translate(struct weston_matrix *matrix, GLfloat x, GLfloat y, GLfloat z) 73 | { 74 | struct weston_matrix translate = { 75 | { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1 } 76 | }; 77 | 78 | weston_matrix_multiply(matrix, &translate); 79 | } 80 | 81 | WL_EXPORT void 82 | weston_matrix_scale(struct weston_matrix *matrix, GLfloat x, GLfloat y, GLfloat z) 83 | { 84 | struct weston_matrix scale = { 85 | { x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1 } 86 | }; 87 | 88 | weston_matrix_multiply(matrix, &scale); 89 | } 90 | 91 | /* v <- m * v */ 92 | WL_EXPORT void 93 | weston_matrix_transform(struct weston_matrix *matrix, struct weston_vector *v) 94 | { 95 | int i, j; 96 | struct weston_vector t; 97 | 98 | for (i = 0; i < 4; i++) { 99 | t.f[i] = 0; 100 | for (j = 0; j < 4; j++) 101 | t.f[i] += v->f[j] * matrix->d[i + j * 4]; 102 | } 103 | 104 | *v = t; 105 | } 106 | 107 | static inline void 108 | swap_rows(double *a, double *b) 109 | { 110 | unsigned k; 111 | double tmp; 112 | 113 | for (k = 0; k < 13; k += 4) { 114 | tmp = a[k]; 115 | a[k] = b[k]; 116 | b[k] = tmp; 117 | } 118 | } 119 | 120 | static inline void 121 | swap_unsigned(unsigned *a, unsigned *b) 122 | { 123 | unsigned tmp; 124 | 125 | tmp = *a; 126 | *a = *b; 127 | *b = tmp; 128 | } 129 | 130 | static inline unsigned 131 | find_pivot(double *column, unsigned k) 132 | { 133 | unsigned p = k; 134 | for (++k; k < 4; ++k) 135 | if (fabs(column[p]) < fabs(column[k])) 136 | p = k; 137 | 138 | return p; 139 | } 140 | 141 | /* 142 | * reference: Gene H. Golub and Charles F. van Loan. Matrix computations. 143 | * 3rd ed. The Johns Hopkins University Press. 1996. 144 | * LU decomposition, forward and back substitution: Chapter 3. 145 | */ 146 | 147 | MATRIX_TEST_EXPORT inline int 148 | matrix_invert(double *A, unsigned *p, const struct weston_matrix *matrix) 149 | { 150 | unsigned i, j, k; 151 | unsigned pivot; 152 | double pv; 153 | 154 | for (i = 0; i < 4; ++i) 155 | p[i] = i; 156 | for (i = 16; i--; ) 157 | A[i] = matrix->d[i]; 158 | 159 | /* LU decomposition with partial pivoting */ 160 | for (k = 0; k < 4; ++k) { 161 | pivot = find_pivot(&A[k * 4], k); 162 | if (pivot != k) { 163 | swap_unsigned(&p[k], &p[pivot]); 164 | swap_rows(&A[k], &A[pivot]); 165 | } 166 | 167 | pv = A[k * 4 + k]; 168 | if (fabs(pv) < 1e-9) 169 | return -1; /* zero pivot, not invertible */ 170 | 171 | for (i = k + 1; i < 4; ++i) { 172 | A[i + k * 4] /= pv; 173 | 174 | for (j = k + 1; j < 4; ++j) 175 | A[i + j * 4] -= A[i + k * 4] * A[k + j * 4]; 176 | } 177 | } 178 | 179 | return 0; 180 | } 181 | 182 | MATRIX_TEST_EXPORT inline void 183 | inverse_transform(const double *LU, const unsigned *p, GLfloat *v) 184 | { 185 | /* Solve A * x = v, when we have P * A = L * U. 186 | * P * A * x = P * v => L * U * x = P * v 187 | * Let U * x = b, then L * b = P * v. 188 | */ 189 | double b[4]; 190 | unsigned j; 191 | 192 | /* Forward substitution, column version, solves L * b = P * v */ 193 | /* The diagonal of L is all ones, and not explicitly stored. */ 194 | b[0] = v[p[0]]; 195 | b[1] = (double)v[p[1]] - b[0] * LU[1 + 0 * 4]; 196 | b[2] = (double)v[p[2]] - b[0] * LU[2 + 0 * 4]; 197 | b[3] = (double)v[p[3]] - b[0] * LU[3 + 0 * 4]; 198 | b[2] -= b[1] * LU[2 + 1 * 4]; 199 | b[3] -= b[1] * LU[3 + 1 * 4]; 200 | b[3] -= b[2] * LU[3 + 2 * 4]; 201 | 202 | /* backward substitution, column version, solves U * y = b */ 203 | #if 1 204 | /* hand-unrolled, 25% faster for whole function */ 205 | b[3] /= LU[3 + 3 * 4]; 206 | b[0] -= b[3] * LU[0 + 3 * 4]; 207 | b[1] -= b[3] * LU[1 + 3 * 4]; 208 | b[2] -= b[3] * LU[2 + 3 * 4]; 209 | 210 | b[2] /= LU[2 + 2 * 4]; 211 | b[0] -= b[2] * LU[0 + 2 * 4]; 212 | b[1] -= b[2] * LU[1 + 2 * 4]; 213 | 214 | b[1] /= LU[1 + 1 * 4]; 215 | b[0] -= b[1] * LU[0 + 1 * 4]; 216 | 217 | b[0] /= LU[0 + 0 * 4]; 218 | #else 219 | for (j = 3; j > 0; --j) { 220 | unsigned k; 221 | b[j] /= LU[j + j * 4]; 222 | for (k = 0; k < j; ++k) 223 | b[k] -= b[j] * LU[k + j * 4]; 224 | } 225 | 226 | b[0] /= LU[0 + 0 * 4]; 227 | #endif 228 | 229 | /* the result */ 230 | for (j = 0; j < 4; ++j) 231 | v[j] = b[j]; 232 | } 233 | 234 | WL_EXPORT int 235 | weston_matrix_invert(struct weston_matrix *inverse, 236 | const struct weston_matrix *matrix) 237 | { 238 | double LU[16]; /* column-major */ 239 | unsigned perm[4]; /* permutation */ 240 | unsigned c; 241 | 242 | if (matrix_invert(LU, perm, matrix) < 0) 243 | return -1; 244 | 245 | weston_matrix_init(inverse); 246 | for (c = 0; c < 4; ++c) 247 | inverse_transform(LU, perm, &inverse->d[c * 4]); 248 | 249 | return 0; 250 | } 251 | -------------------------------------------------------------------------------- /src/matrix.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2008-2011 Kristian Høgsberg 3 | * Copyright © 2012 Collabora, Ltd. 4 | * 5 | * Permission to use, copy, modify, distribute, and sell this software and 6 | * its documentation for any purpose is hereby granted without fee, provided 7 | * that the above copyright notice appear in all copies and that both that 8 | * copyright notice and this permission notice appear in supporting 9 | * documentation, and that the name of the copyright holders not be used in 10 | * advertising or publicity pertaining to distribution of the software 11 | * without specific, written prior permission. The copyright holders make 12 | * no representations about the suitability of this software for any 13 | * purpose. It is provided "as is" without express or implied warranty. 14 | * 15 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS 16 | * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 17 | * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER 19 | * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF 20 | * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 21 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 22 | */ 23 | 24 | #ifndef WESTON_MATRIX_H 25 | #define WESTON_MATRIX_H 26 | 27 | struct weston_matrix { 28 | GLfloat d[16]; 29 | }; 30 | 31 | struct weston_vector { 32 | GLfloat f[4]; 33 | }; 34 | 35 | void 36 | weston_matrix_init(struct weston_matrix *matrix); 37 | void 38 | weston_matrix_multiply(struct weston_matrix *m, const struct weston_matrix *n); 39 | void 40 | weston_matrix_scale(struct weston_matrix *matrix, GLfloat x, GLfloat y, GLfloat z); 41 | void 42 | weston_matrix_translate(struct weston_matrix *matrix, 43 | GLfloat x, GLfloat y, GLfloat z); 44 | void 45 | weston_matrix_transform(struct weston_matrix *matrix, struct weston_vector *v); 46 | 47 | int 48 | weston_matrix_invert(struct weston_matrix *inverse, 49 | const struct weston_matrix *matrix); 50 | 51 | #ifdef UNIT_TEST 52 | # define MATRIX_TEST_EXPORT WL_EXPORT 53 | 54 | int 55 | matrix_invert(double *A, unsigned *p, const struct weston_matrix *matrix); 56 | 57 | void 58 | inverse_transform(const double *LU, const unsigned *p, GLfloat *v); 59 | 60 | #else 61 | # define MATRIX_TEST_EXPORT static 62 | #endif 63 | 64 | #endif /* WESTON_MATRIX_H */ 65 | -------------------------------------------------------------------------------- /src/screenshooter.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2008-2011 Kristian Høgsberg 3 | * 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. 13 | * 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. 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #include "compositor.h" 28 | #include "screenshooter-server-protocol.h" 29 | 30 | struct screenshooter { 31 | struct wl_object base; 32 | struct weston_compositor *ec; 33 | struct wl_global *global; 34 | struct wl_client *client; 35 | struct weston_process process; 36 | struct wl_listener destroy_listener; 37 | }; 38 | 39 | static void 40 | screenshooter_shoot(struct wl_client *client, 41 | struct wl_resource *resource, 42 | struct wl_resource *output_resource, 43 | struct wl_resource *buffer_resource) 44 | { 45 | struct weston_output *output = output_resource->data; 46 | struct wl_buffer *buffer = buffer_resource->data; 47 | uint8_t *tmp, *d, *s; 48 | int32_t buffer_stride, output_stride, i; 49 | 50 | if (!wl_buffer_is_shm(buffer)) 51 | return; 52 | 53 | if (buffer->width < output->current->width || 54 | buffer->height < output->current->height) 55 | return; 56 | 57 | buffer_stride = wl_shm_buffer_get_stride(buffer); 58 | output_stride = output->current->width * 4; 59 | tmp = malloc(output_stride * output->current->height); 60 | if (tmp == NULL) { 61 | wl_resource_post_no_memory(resource); 62 | return; 63 | } 64 | 65 | glPixelStorei(GL_PACK_ALIGNMENT, 1); 66 | output->read_pixels(output, tmp); 67 | 68 | d = wl_shm_buffer_get_data(buffer) + output->y * buffer_stride + 69 | output->x * 4; 70 | s = tmp + output_stride * (output->current->height - 1); 71 | 72 | for (i = 0; i < output->current->height; i++) { 73 | memcpy(d, s, output_stride); 74 | d += buffer_stride; 75 | s -= output_stride; 76 | } 77 | 78 | free(tmp); 79 | } 80 | 81 | struct screenshooter_interface screenshooter_implementation = { 82 | screenshooter_shoot 83 | }; 84 | 85 | static void 86 | bind_shooter(struct wl_client *client, 87 | void *data, uint32_t version, uint32_t id) 88 | { 89 | struct screenshooter *shooter = data; 90 | struct wl_resource *resource; 91 | 92 | resource = wl_client_add_object(client, &screenshooter_interface, 93 | &screenshooter_implementation, id, data); 94 | 95 | if (client != shooter->client) { 96 | wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT, 97 | "screenshooter failed: permission denied"); 98 | wl_resource_destroy(resource); 99 | } 100 | } 101 | 102 | static void 103 | screenshooter_sigchld(struct weston_process *process, int status) 104 | { 105 | struct screenshooter *shooter = 106 | container_of(process, struct screenshooter, process); 107 | 108 | shooter->client = NULL; 109 | } 110 | 111 | static void 112 | screenshooter_binding(struct wl_input_device *device, uint32_t time, 113 | uint32_t key, uint32_t button, uint32_t axis, 114 | int32_t state, void *data) 115 | { 116 | struct screenshooter *shooter = data; 117 | const char *screenshooter_exe = LIBEXECDIR "/weston-screenshooter"; 118 | 119 | if (!shooter->client) 120 | shooter->client = weston_client_launch(shooter->ec, 121 | &shooter->process, 122 | screenshooter_exe, screenshooter_sigchld); 123 | } 124 | 125 | static void 126 | screenshooter_destroy(struct wl_listener *listener, void *data) 127 | { 128 | struct screenshooter *shooter = 129 | container_of(listener, struct screenshooter, destroy_listener); 130 | 131 | wl_display_remove_global(shooter->ec->wl_display, shooter->global); 132 | free(shooter); 133 | } 134 | 135 | void 136 | screenshooter_create(struct weston_compositor *ec) 137 | { 138 | struct screenshooter *shooter; 139 | 140 | shooter = malloc(sizeof *shooter); 141 | if (shooter == NULL) 142 | return; 143 | 144 | shooter->base.interface = &screenshooter_interface; 145 | shooter->base.implementation = 146 | (void(**)(void)) &screenshooter_implementation; 147 | shooter->ec = ec; 148 | shooter->client = NULL; 149 | 150 | shooter->global = wl_display_add_global(ec->wl_display, 151 | &screenshooter_interface, 152 | shooter, bind_shooter); 153 | weston_compositor_add_binding(ec, KEY_S, 0, 0, MODIFIER_SUPER, 154 | screenshooter_binding, shooter); 155 | 156 | shooter->destroy_listener.notify = screenshooter_destroy; 157 | wl_signal_add(&ec->destroy_signal, &shooter->destroy_listener); 158 | } 159 | -------------------------------------------------------------------------------- /src/tty.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2010 Intel Corporation 3 | * 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. 13 | * 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. 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #include "adwc.h" 36 | 37 | struct tty { 38 | struct weston_compositor *compositor; 39 | int fd; 40 | struct termios terminal_attributes; 41 | 42 | struct wl_event_source *vt_source; 43 | tty_vt_func_t vt_func; 44 | int vt, starting_vt, has_vt; 45 | int kb_mode; 46 | }; 47 | 48 | static int vt_handler(int signal_number, void *data) 49 | { 50 | struct tty *tty = data; 51 | 52 | if (tty->has_vt) { 53 | tty->vt_func(tty->compositor, TTY_LEAVE_VT); 54 | tty->has_vt = 0; 55 | 56 | ioctl(tty->fd, VT_RELDISP, 1); 57 | } else { 58 | ioctl(tty->fd, VT_RELDISP, VT_ACKACQ); 59 | 60 | tty->vt_func(tty->compositor, TTY_ENTER_VT); 61 | tty->has_vt = 1; 62 | } 63 | 64 | return 1; 65 | } 66 | 67 | static int 68 | try_open_vt(struct tty *tty) 69 | { 70 | int tty0, fd; 71 | char filename[16]; 72 | 73 | tty0 = open("/dev/tty0", O_WRONLY | O_CLOEXEC); 74 | if (tty0 < 0) { 75 | fprintf(stderr, "could not open tty0: %m\n"); 76 | return -1; 77 | } 78 | 79 | if (ioctl(tty0, VT_OPENQRY, &tty->vt) < 0 || tty->vt == -1) { 80 | fprintf(stderr, "could not open tty0: %m\n"); 81 | close(tty0); 82 | return -1; 83 | } 84 | 85 | close(tty0); 86 | snprintf(filename, sizeof filename, "/dev/tty%d", tty->vt); 87 | fprintf(stderr, "compositor: using new vt %s\n", filename); 88 | fd = open(filename, O_RDWR | O_NOCTTY | O_CLOEXEC); 89 | if (fd < 0) 90 | return fd; 91 | 92 | return fd; 93 | } 94 | 95 | int 96 | tty_activate_vt(struct tty *tty, int vt) 97 | { 98 | return ioctl(tty->fd, VT_ACTIVATE, vt); 99 | } 100 | 101 | struct tty * 102 | tty_create(struct weston_compositor *compositor, tty_vt_func_t vt_func, 103 | int tty_nr) 104 | { 105 | struct termios raw_attributes; 106 | struct vt_mode mode = { 0 }; 107 | int ret; 108 | struct tty *tty; 109 | struct wl_event_loop *loop; 110 | struct stat buf; 111 | char filename[16]; 112 | struct vt_stat vts; 113 | 114 | tty = malloc(sizeof *tty); 115 | if (tty == NULL) 116 | return NULL; 117 | 118 | memset(tty, 0, sizeof *tty); 119 | tty->compositor = compositor; 120 | tty->vt_func = vt_func; 121 | 122 | tty->fd = weston_environment_get_fd("WESTON_TTY_FD"); 123 | if (tty->fd < 0) 124 | tty->fd = STDIN_FILENO; 125 | 126 | if (tty_nr > 0) { 127 | snprintf(filename, sizeof filename, "/dev/tty%d", tty_nr); 128 | fprintf(stderr, "compositor: using %s\n", filename); 129 | tty->fd = open(filename, O_RDWR | O_NOCTTY | O_CLOEXEC); 130 | tty->vt = tty_nr; 131 | } else if (fstat(tty->fd, &buf) == 0 && 132 | major(buf.st_rdev) == TTY_MAJOR && 133 | minor(buf.st_rdev) > 0) { 134 | if (tty->fd == STDIN_FILENO) 135 | tty->fd = fcntl(STDIN_FILENO, F_DUPFD_CLOEXEC, 0); 136 | tty->vt = minor(buf.st_rdev); 137 | } else { 138 | /* Fall back to try opening a new VT. This typically 139 | * requires root. */ 140 | tty->fd = try_open_vt(tty); 141 | } 142 | 143 | if (tty->fd <= 0) { 144 | fprintf(stderr, "failed to open tty: %m\n"); 145 | free(tty); 146 | return NULL; 147 | } 148 | 149 | if (ioctl(tty->fd, VT_GETSTATE, &vts) == 0) 150 | tty->starting_vt = vts.v_active; 151 | else 152 | tty->starting_vt = tty->vt; 153 | 154 | if (tty->starting_vt != tty->vt) { 155 | if (ioctl(tty->fd, VT_ACTIVATE, tty->vt) < 0 || 156 | ioctl(tty->fd, VT_WAITACTIVE, tty->vt) < 0) { 157 | fprintf(stderr, "failed to swtich to new vt\n"); 158 | return NULL; 159 | } 160 | } 161 | 162 | if (tcgetattr(tty->fd, &tty->terminal_attributes) < 0) { 163 | fprintf(stderr, "could not get terminal attributes: %m\n"); 164 | goto err; 165 | } 166 | 167 | /* Ignore control characters and disable echo */ 168 | raw_attributes = tty->terminal_attributes; 169 | cfmakeraw(&raw_attributes); 170 | 171 | /* Fix up line endings to be normal (cfmakeraw hoses them) */ 172 | raw_attributes.c_oflag |= OPOST | OCRNL; 173 | 174 | if (tcsetattr(tty->fd, TCSANOW, &raw_attributes) < 0) 175 | fprintf(stderr, "could not put terminal into raw mode: %m\n"); 176 | 177 | ioctl(tty->fd, KDGKBMODE, &tty->kb_mode); 178 | ret = ioctl(tty->fd, KDSKBMODE, K_OFF); 179 | if (ret) { 180 | fprintf(stderr, "failed to set K_OFF keyboard mode on tty: %m\n"); 181 | goto err_attr; 182 | } 183 | 184 | ret = ioctl(tty->fd, KDSETMODE, KD_GRAPHICS); 185 | if (ret) { 186 | fprintf(stderr, "failed to set KD_GRAPHICS mode on tty: %m\n"); 187 | goto err_kdkbmode; 188 | } 189 | 190 | tty->has_vt = 1; 191 | mode.mode = VT_PROCESS; 192 | mode.relsig = SIGUSR1; 193 | mode.acqsig = SIGUSR1; 194 | if (ioctl(tty->fd, VT_SETMODE, &mode) < 0) { 195 | fprintf(stderr, "failed to take control of vt handling\n"); 196 | goto err_kdmode; 197 | } 198 | 199 | loop = wl_display_get_event_loop(compositor->wl_display); 200 | tty->vt_source = 201 | wl_event_loop_add_signal(loop, SIGUSR1, vt_handler, tty); 202 | if (!tty->vt_source) 203 | goto err_vtmode; 204 | 205 | return tty; 206 | 207 | err_vtmode: 208 | ioctl(tty->fd, VT_SETMODE, &mode); 209 | 210 | err_kdmode: 211 | ioctl(tty->fd, KDSETMODE, KD_TEXT); 212 | 213 | err_kdkbmode: 214 | ioctl(tty->fd, KDSKBMODE, tty->kb_mode); 215 | 216 | err_attr: 217 | tcsetattr(tty->fd, TCSANOW, &tty->terminal_attributes); 218 | 219 | err: 220 | close(tty->fd); 221 | free(tty); 222 | return NULL; 223 | } 224 | 225 | void 226 | tty_destroy(struct tty *tty) 227 | { 228 | struct vt_mode mode = { 0 }; 229 | 230 | if(!tty) 231 | return; 232 | 233 | if (ioctl(tty->fd, KDSKBMODE, tty->kb_mode)) 234 | fprintf(stderr, "failed to restore keyboard mode: %m\n"); 235 | 236 | if (ioctl(tty->fd, KDSETMODE, KD_TEXT)) 237 | fprintf(stderr, 238 | "failed to set KD_TEXT mode on tty: %m\n"); 239 | 240 | if (tcsetattr(tty->fd, TCSANOW, &tty->terminal_attributes) < 0) 241 | fprintf(stderr, 242 | "could not restore terminal to canonical mode\n"); 243 | 244 | mode.mode = VT_AUTO; 245 | if (ioctl(tty->fd, VT_SETMODE, &mode) < 0) 246 | fprintf(stderr, "could not reset vt handling\n"); 247 | 248 | if (tty->has_vt && tty->vt != tty->starting_vt) { 249 | ioctl(tty->fd, VT_ACTIVATE, tty->starting_vt); 250 | ioctl(tty->fd, VT_WAITACTIVE, tty->starting_vt); 251 | } 252 | 253 | wl_event_source_remove(tty->vt_source); 254 | 255 | close(tty->fd); 256 | 257 | free(tty); 258 | } 259 | -------------------------------------------------------------------------------- /src/util.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2011 Intel Corporation 3 | * 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. 13 | * 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. 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | 31 | #include "adwc.h" 32 | /* 33 | WL_EXPORT void 34 | weston_spring_init(struct weston_spring *spring, 35 | double k, double current, double target) 36 | { 37 | spring->k = k; 38 | spring->friction = 400.0; 39 | spring->current = current; 40 | spring->previous = current; 41 | spring->target = target; 42 | } 43 | 44 | WL_EXPORT void 45 | weston_spring_update(struct weston_spring *spring, uint32_t msec) 46 | { 47 | double force, v, current, step; 48 | 49 | step = 0.01; 50 | while (4 < msec - spring->timestamp) { 51 | current = spring->current; 52 | v = current - spring->previous; 53 | force = spring->k * (spring->target - current) / 10.0 + 54 | (spring->previous - current) - v * spring->friction; 55 | 56 | spring->current = 57 | current + (current - spring->previous) + 58 | force * step * step; 59 | spring->previous = current; 60 | 61 | #if 0 62 | if (spring->current >= 1.0) { 63 | #ifdef TWEENER_BOUNCE 64 | spring->current = 2.0 - spring->current; 65 | spring->previous = 2.0 - spring->previous; 66 | #else 67 | spring->current = 1.0; 68 | spring->previous = 1.0; 69 | #endif 70 | } 71 | 72 | if (spring->current <= 0.0) { 73 | spring->current = 0.0; 74 | spring->previous = 0.0; 75 | } 76 | #endif 77 | spring->timestamp += 4; 78 | } 79 | } 80 | 81 | WL_EXPORT int 82 | weston_spring_done(struct weston_spring *spring) 83 | { 84 | return fabs(spring->previous - spring->target) < 0.0002 && 85 | fabs(spring->current - spring->target) < 0.0002; 86 | } 87 | 88 | struct weston_zoom { 89 | struct weston_surface *surface; 90 | struct weston_animation animation; 91 | struct weston_spring spring; 92 | struct weston_transform transform; 93 | struct wl_listener listener; 94 | GLfloat start, stop; 95 | void (*done)(struct weston_zoom *zoom, void *data); 96 | void *data; 97 | }; 98 | */ 99 | /* 100 | static void 101 | weston_zoom_destroy(struct weston_zoom *zoom) 102 | { 103 | wl_list_remove(&zoom->animation.link); 104 | wl_list_remove(&zoom->listener.link); 105 | wl_list_remove(&zoom->transform.link); 106 | zoom->surface->geometry.dirty = 1; 107 | if (zoom->done) 108 | zoom->done(zoom, zoom->data); 109 | free(zoom); 110 | } 111 | 112 | static void 113 | handle_zoom_surface_destroy(struct wl_listener *listener, void *data) 114 | { 115 | struct weston_zoom *zoom = 116 | container_of(listener, struct weston_zoom, listener); 117 | 118 | weston_zoom_destroy(zoom); 119 | } 120 | 121 | static void 122 | weston_zoom_frame(struct weston_animation *animation, 123 | struct weston_output *output, uint32_t msecs) 124 | { 125 | struct weston_zoom *zoom = 126 | container_of(animation, struct weston_zoom, animation); 127 | struct weston_surface *es = zoom->surface; 128 | GLfloat scale; 129 | 130 | weston_spring_update(&zoom->spring, msecs); 131 | 132 | if (weston_spring_done(&zoom->spring)) { 133 | weston_zoom_destroy(zoom); 134 | return; 135 | } 136 | 137 | scale = zoom->start + 138 | (zoom->stop - zoom->start) * zoom->spring.current; 139 | weston_matrix_init(&zoom->transform.matrix); 140 | weston_matrix_translate(&zoom->transform.matrix, 141 | -0.5f * es->geometry.width, 142 | -0.5f * es->geometry.height, 0); 143 | weston_matrix_scale(&zoom->transform.matrix, scale, scale, scale); 144 | weston_matrix_translate(&zoom->transform.matrix, 145 | 0.5f * es->geometry.width, 146 | 0.5f * es->geometry.height, 0); 147 | 148 | es->alpha = zoom->spring.current * 255; 149 | if (es->alpha > 255) 150 | es->alpha = 255; 151 | 152 | zoom->surface->geometry.dirty = 1; 153 | weston_compositor_schedule_repaint(es->compositor); 154 | } 155 | 156 | WL_EXPORT struct weston_zoom * 157 | weston_zoom_run(struct weston_surface *surface, GLfloat start, GLfloat stop, 158 | weston_zoom_done_func_t done, void *data) 159 | { 160 | struct weston_zoom *zoom; 161 | 162 | zoom = malloc(sizeof *zoom); 163 | if (!zoom) 164 | return NULL; 165 | 166 | zoom->surface = surface; 167 | zoom->done = done; 168 | zoom->data = data; 169 | zoom->start = start; 170 | zoom->stop = stop; 171 | wl_list_insert(&surface->geometry.transformation_list, 172 | &zoom->transform.link); 173 | weston_spring_init(&zoom->spring, 200.0, 0.0, 1.0); 174 | zoom->spring.friction = 700; 175 | zoom->spring.timestamp = weston_compositor_get_time(); 176 | zoom->animation.frame = weston_zoom_frame; 177 | weston_zoom_frame(&zoom->animation, NULL, zoom->spring.timestamp); 178 | 179 | zoom->listener.notify = handle_zoom_surface_destroy; 180 | wl_signal_add(&surface->surface.resource.destroy_signal, 181 | &zoom->listener); 182 | 183 | wl_list_insert(&surface->compositor->animation_list, 184 | &zoom->animation.link); 185 | 186 | return zoom; 187 | } 188 | */ 189 | struct weston_binding { 190 | uint32_t key; 191 | uint32_t button; 192 | uint32_t axis; 193 | uint32_t modifier; 194 | weston_binding_handler_t handler; 195 | void *data; 196 | struct wl_list link; 197 | }; 198 | 199 | WL_EXPORT struct weston_binding * 200 | weston_compositor_add_binding(struct weston_compositor *compositor, 201 | uint32_t key, uint32_t button, uint32_t axis, uint32_t modifier, 202 | weston_binding_handler_t handler, void *data) 203 | { 204 | struct weston_binding *binding; 205 | 206 | binding = malloc(sizeof *binding); 207 | if (binding == NULL) 208 | return NULL; 209 | 210 | binding->key = key; 211 | binding->button = button; 212 | binding->axis = axis; 213 | binding->modifier = modifier; 214 | binding->handler = handler; 215 | binding->data = data; 216 | wl_list_insert(compositor->binding_list.prev, &binding->link); 217 | 218 | return binding; 219 | } 220 | 221 | WL_EXPORT void 222 | weston_binding_destroy(struct weston_binding *binding) 223 | { 224 | wl_list_remove(&binding->link); 225 | free(binding); 226 | } 227 | 228 | WL_EXPORT void 229 | weston_binding_list_destroy_all(struct wl_list *list) 230 | { 231 | struct weston_binding *binding, *tmp; 232 | 233 | wl_list_for_each_safe(binding, tmp, list, link) 234 | weston_binding_destroy(binding); 235 | } 236 | 237 | struct binding_keyboard_grab { 238 | uint32_t key; 239 | struct wl_keyboard_grab grab; 240 | }; 241 | 242 | static void 243 | binding_key(struct wl_keyboard_grab *grab, 244 | uint32_t time, uint32_t key, int32_t state) 245 | { 246 | struct binding_keyboard_grab *b = 247 | container_of(grab, struct binding_keyboard_grab, grab); 248 | struct wl_resource *resource; 249 | struct wl_display *display; 250 | uint32_t serial; 251 | 252 | resource = grab->input_device->keyboard_focus_resource; 253 | if (key == b->key) { 254 | if (!state) { 255 | wl_input_device_end_keyboard_grab(grab->input_device); 256 | free(b); 257 | } 258 | } else if (resource) { 259 | display = wl_client_get_display(resource->client); 260 | serial = wl_display_next_serial(display); 261 | wl_input_device_send_key(resource, serial, time, key, state); 262 | } 263 | } 264 | 265 | static const struct wl_keyboard_grab_interface binding_grab = { 266 | binding_key 267 | }; 268 | 269 | static void 270 | install_binding_grab(struct wl_input_device *device, 271 | uint32_t time, uint32_t key) 272 | { 273 | struct binding_keyboard_grab *grab; 274 | 275 | grab = malloc(sizeof *grab); 276 | grab->key = key; 277 | grab->grab.interface = &binding_grab; 278 | wl_input_device_start_keyboard_grab(device, &grab->grab); 279 | } 280 | 281 | WL_EXPORT void 282 | weston_compositor_run_binding(struct weston_compositor *compositor, 283 | struct weston_input_device *device, 284 | uint32_t time, uint32_t key, 285 | uint32_t button, uint32_t axis, int32_t state) 286 | { 287 | struct weston_binding *b; 288 | 289 | wl_list_for_each(b, &compositor->binding_list, link) { 290 | if (b->key == key && b->button == button && b->axis == axis && 291 | b->modifier == device->modifier_state && state) { 292 | b->handler(&device->input_device, 293 | time, key, button, axis, state, b->data); 294 | 295 | /* If this was a key binding and it didn't 296 | * install a keyboard grab, install one now to 297 | * swallow the key release. */ 298 | if (b->key && 299 | device->input_device.keyboard_grab == 300 | &device->input_device.default_keyboard_grab) 301 | install_binding_grab(&device->input_device, 302 | time, key); 303 | } 304 | } 305 | } 306 | 307 | WL_EXPORT int 308 | weston_environment_get_fd(const char *env) 309 | { 310 | char *e, *end; 311 | int fd, flags; 312 | 313 | e = getenv(env); 314 | if (!e) 315 | return -1; 316 | fd = strtol(e, &end, 0); 317 | if (*end != '\0') 318 | return -1; 319 | 320 | flags = fcntl(fd, F_GETFD); 321 | if (flags == -1) 322 | return -1; 323 | 324 | fcntl(fd, F_SETFD, flags | FD_CLOEXEC); 325 | unsetenv(env); 326 | 327 | return fd; 328 | } 329 | -------------------------------------------------------------------------------- /src/weston-launch.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2012 Benjamin Franzke 3 | * 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. 13 | * 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. 21 | */ 22 | 23 | #ifndef _WESTON_LAUNCH_H_ 24 | #define _WESTON_LAUNCH_H_ 25 | 26 | enum weston_launcher_opcode { 27 | WESTON_LAUNCHER_OPEN, 28 | WESTON_LAUNCHER_DRM_SET_MASTER 29 | }; 30 | 31 | struct weston_launcher_message { 32 | int opcode; 33 | }; 34 | 35 | struct weston_launcher_open { 36 | struct weston_launcher_message header; 37 | int flags; 38 | char path[0]; 39 | }; 40 | 41 | struct weston_launcher_set_master { 42 | struct weston_launcher_message header; 43 | int set_master; 44 | }; 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /tests/.gitignore: -------------------------------------------------------------------------------- 1 | matrix-test 2 | setbacklight 3 | 4 | -------------------------------------------------------------------------------- /tests/Makefile.am: -------------------------------------------------------------------------------- 1 | TESTS = $(check_PROGRAMS) 2 | 3 | check_PROGRAMS = matrix-test 4 | 5 | noinst_PROGRAMS = setbacklight 6 | 7 | AM_CFLAGS = $(GCC_CFLAGS) 8 | AM_CPPFLAGS = -I$(top_srcdir)/src -DUNIT_TEST $(COMPOSITOR_CFLAGS) 9 | 10 | matrix_test_SOURCES = \ 11 | matrix-test.c \ 12 | $(top_srcdir)/src/matrix.c \ 13 | $(top_srcdir)/src/matrix.h 14 | matrix_test_LDADD = -lm -lrt 15 | 16 | setbacklight_SOURCES = \ 17 | setbacklight.c \ 18 | $(top_srcdir)/src/libbacklight.c \ 19 | $(top_srcdir)/src/libbacklight.h 20 | 21 | setbacklight_LDADD = -ludev -ldrm 22 | -------------------------------------------------------------------------------- /tests/setbacklight.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2012 Intel Corporation 3 | * 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. 13 | * 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. 21 | * 22 | * Author: Tiago Vignatti 23 | */ 24 | /* 25 | * \file setbacklight.c 26 | * Test program to get a backlight connector and set its brightness value. 27 | * Queries for the connectors id can be performed using drm/tests/modeprint 28 | * program. 29 | */ 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #include "libbacklight.h" 39 | 40 | static uint32_t 41 | get_drm_connector_type(struct udev_device *drm_device, uint32_t connector_id) 42 | { 43 | const char *filename; 44 | int fd, i, connector_type; 45 | drmModeResPtr res; 46 | drmModeConnectorPtr connector; 47 | 48 | filename = udev_device_get_devnode(drm_device); 49 | fd = open(filename, O_RDWR | O_CLOEXEC); 50 | if (fd < 0) { 51 | printf("couldn't open drm_device\n"); 52 | return -1; 53 | } 54 | 55 | res = drmModeGetResources(fd); 56 | if (res == 0) { 57 | printf("Failed to get resources from card\n"); 58 | close(fd); 59 | return -1; 60 | } 61 | 62 | for (i = 0; i < res->count_connectors; i++) { 63 | connector = drmModeGetConnector(fd, res->connectors[i]); 64 | if (!connector) 65 | continue; 66 | 67 | if ((connector->connection == DRM_MODE_DISCONNECTED) || 68 | (connector->connector_id != connector_id)) { 69 | drmModeFreeConnector(connector); 70 | continue; 71 | } 72 | 73 | connector_type = connector->connector_type; 74 | drmModeFreeConnector(connector); 75 | drmModeFreeResources(res); 76 | 77 | return connector_type; 78 | } 79 | 80 | drmModeFreeResources(res); 81 | return -1; 82 | } 83 | 84 | /* returns a value between 0-255 range, where higher is brighter */ 85 | static uint32_t 86 | get_normalized_backlight(struct backlight *backlight) 87 | { 88 | long brightness, max_brightness; 89 | long norm; 90 | 91 | brightness = backlight_get_brightness(backlight); 92 | max_brightness = backlight_get_max_brightness(backlight); 93 | 94 | /* convert it to a scale of 0 to 255 */ 95 | norm = (brightness * 255)/(max_brightness); 96 | 97 | return (int) norm; 98 | } 99 | 100 | static void 101 | set_backlight(struct udev_device *drm_device, int connector_id, int blight) 102 | { 103 | int connector_type; 104 | long max_brightness, brightness, actual_brightness; 105 | struct backlight *backlight; 106 | long new_blight; 107 | 108 | connector_type = get_drm_connector_type(drm_device, connector_id); 109 | if (connector_type < 0) 110 | return; 111 | 112 | backlight = backlight_init(drm_device, connector_type); 113 | if (!backlight) { 114 | printf("backlight adjust failed\n"); 115 | return; 116 | } 117 | 118 | max_brightness = backlight_get_max_brightness(backlight); 119 | printf("Max backlight: %ld\n", max_brightness); 120 | 121 | brightness = backlight_get_brightness(backlight); 122 | printf("Cached backlight: %ld\n", brightness); 123 | 124 | actual_brightness = backlight_get_actual_brightness(backlight); 125 | printf("Hardware backlight: %ld\n", actual_brightness); 126 | 127 | printf("normalized current brightness: %d\n", 128 | get_normalized_backlight(backlight)); 129 | 130 | /* denormalized value */ 131 | new_blight = (blight * max_brightness) / 255; 132 | 133 | backlight_set_brightness(backlight, new_blight); 134 | printf("Setting brightness to: %ld (norm: %d)\n", new_blight, blight); 135 | 136 | backlight_destroy(backlight); 137 | } 138 | 139 | int 140 | main(int argc, char **argv) 141 | { 142 | int blight, connector_id; 143 | const char *default_seat = "seat0"; 144 | const char *path, *device_seat; 145 | struct udev *udev; 146 | struct udev_enumerate *e; 147 | struct udev_list_entry *entry; 148 | struct udev_device *device, *drm_device; 149 | 150 | if (argc < 3) { 151 | printf("Please add connector_id and brightness values from 0-255\n"); 152 | return 1; 153 | } 154 | 155 | connector_id = atoi(argv[1]); 156 | blight = atoi(argv[2]); 157 | 158 | udev = udev_new(); 159 | if (udev == NULL) { 160 | printf("failed to initialize udev context\n"); 161 | return 1; 162 | } 163 | 164 | e = udev_enumerate_new(udev); 165 | udev_enumerate_add_match_subsystem(e, "drm"); 166 | udev_enumerate_add_match_sysname(e, "card[0-9]*"); 167 | 168 | udev_enumerate_scan_devices(e); 169 | drm_device = NULL; 170 | udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) { 171 | path = udev_list_entry_get_name(entry); 172 | device = udev_device_new_from_syspath(udev, path); 173 | device_seat = 174 | udev_device_get_property_value(device, "ID_SEAT"); 175 | if (!device_seat) 176 | device_seat = default_seat; 177 | 178 | drm_device = device; 179 | break; 180 | } 181 | 182 | if (drm_device == NULL) { 183 | printf("no drm device found\n"); 184 | return 1; 185 | } 186 | 187 | set_backlight(drm_device, connector_id, blight); 188 | 189 | udev_device_unref(drm_device); 190 | return 0; 191 | } 192 | -------------------------------------------------------------------------------- /weston.ini: -------------------------------------------------------------------------------- 1 | [shell] 2 | type=desktop-shell.so 3 | background-image=/usr/share/backgrounds/gnome/Aqua.jpg 4 | background-color=0xff002244 5 | panel-color=0x90ff0000 6 | locking=true 7 | 8 | #type=tablet-shell.so 9 | #lockscreen-icon=/usr/share/icons/gnome/256x256/actions/lock.png 10 | #lockscreen=/usr/share/backgrounds/gnome/Garden.jpg 11 | #homescreen=/usr/share/backgrounds/gnome/Blinds.jpg 12 | [launcher] 13 | icon=/usr/share/icons/gnome/24x24/apps/utilities-terminal.png 14 | path=/usr/bin/gnome-terminal 15 | 16 | [launcher] 17 | icon=/usr/share/icons/gnome/24x24/apps/utilities-terminal.png 18 | path=/usr/bin/weston-terminal 19 | 20 | [launcher] 21 | icon=/usr/share/icons/hicolor/24x24/apps/google-chrome.png 22 | path=/usr/bin/google-chrome 23 | 24 | [launcher] 25 | icon=/usr/share/icons/gnome/24x24/apps/arts.png 26 | path=./clients/flower 27 | 28 | [screensaver] 29 | #path=./clients/wscreensaver 30 | duration=600 31 | 32 | --------------------------------------------------------------------------------