From 1493d2ae1cc8187684bb8f8939d0ec0335ed60f8 Mon Sep 17 00:00:00 2001 From: Ander Conselvan de Oliveira Date: Thu, 3 May 2012 12:29:46 +0300 Subject: [PATCH] window: use libXcursor for loading pointer images --- clients/window.c | 214 +++++++++++++++++++---------------- configure.ac | 2 +- data/Makefile.am | 18 --- data/bottom_left_corner.png | Bin 1100 -> 0 bytes data/bottom_right_corner.png | Bin 1033 -> 0 bytes data/bottom_side.png | Bin 994 -> 0 bytes data/dnd-copy.png | Bin 1244 -> 0 bytes data/dnd-link.png | Bin 1321 -> 0 bytes data/dnd-move.png | Bin 1213 -> 0 bytes data/grabbing.png | Bin 1004 -> 0 bytes data/hand1.png | Bin 1117 -> 0 bytes data/hand2.png | Bin 1108 -> 0 bytes data/left_ptr.png | Bin 1046 -> 0 bytes data/left_side.png | Bin 1141 -> 0 bytes data/right_side.png | Bin 1051 -> 0 bytes data/sb_h_double_arrow.png | Bin 1287 -> 0 bytes data/sb_v_double_arrow.png | Bin 1140 -> 0 bytes data/top_left_corner.png | Bin 1251 -> 0 bytes data/top_right_corner.png | Bin 1163 -> 0 bytes data/top_side.png | Bin 1116 -> 0 bytes data/xterm.png | Bin 615 -> 0 bytes 21 files changed, 120 insertions(+), 114 deletions(-) delete mode 100644 data/bottom_left_corner.png delete mode 100644 data/bottom_right_corner.png delete mode 100644 data/bottom_side.png delete mode 100644 data/dnd-copy.png delete mode 100644 data/dnd-link.png delete mode 100644 data/dnd-move.png delete mode 100644 data/grabbing.png delete mode 100644 data/hand1.png delete mode 100644 data/hand2.png delete mode 100644 data/left_ptr.png delete mode 100644 data/left_side.png delete mode 100644 data/right_side.png delete mode 100644 data/sb_h_double_arrow.png delete mode 100644 data/sb_v_double_arrow.png delete mode 100644 data/top_left_corner.png delete mode 100644 data/top_right_corner.png delete mode 100644 data/top_side.png delete mode 100644 data/xterm.png diff --git a/clients/window.c b/clients/window.c index 54f57a33..2dcf421f 100644 --- a/clients/window.c +++ b/clients/window.c @@ -57,6 +57,7 @@ #include #include +#include #include #include @@ -64,6 +65,8 @@ #include "window.h" +struct cursor; + struct display { struct wl_display *display; struct wl_compositor *compositor; @@ -91,7 +94,7 @@ struct display { cairo_surface_t *active_frame, *inactive_frame, *shadow; int frame_radius; struct xkb_desc *xkb; - cairo_surface_t **pointer_surfaces; + struct cursor *cursors; PFNGLEGLIMAGETARGETTEXTURE2DOESPROC image_target_texture_2d; PFNEGLCREATEIMAGEKHRPROC create_image; @@ -172,7 +175,7 @@ struct input { struct wl_input_device *input_device; struct window *pointer_focus; struct window *keyboard_focus; - int current_pointer_image; + int current_cursor; uint32_t modifiers; uint32_t pointer_enter_serial; int32_t sx, sy; @@ -216,6 +219,18 @@ struct menu { menu_func_t func; }; +struct cursor_image { + cairo_surface_t *surface; + int width, height; + int hotspot_x, hotspot_y; + int delay; +}; + +struct cursor { + int n_images; + struct cursor_image *images; +}; + enum { POINTER_DEFAULT = 100, POINTER_UNSET @@ -345,6 +360,14 @@ shm_surface_data_destroy(void *p) munmap(data->map, data->length); } +static void +shm_surface_write(cairo_surface_t *surface, unsigned char *data, int count) +{ + void *dest = cairo_image_surface_get_data(surface); + + memcpy(dest, data, count); +} + static struct wl_shm_pool * make_shm_pool(struct display *display, int size, void **data) { @@ -432,35 +455,6 @@ display_create_shm_surface(struct display *display, return surface; } -static cairo_surface_t * -display_create_shm_surface_from_file(struct display *display, - const char *filename, - struct rectangle *rect) -{ - cairo_surface_t *surface; - pixman_image_t *image; - void *dest; - int size; - - image = load_image(filename); - if (image == NULL) - return NULL; - - surface = display_create_shm_surface(display, rect, 0, NULL); - if (surface == NULL) { - pixman_image_unref(image); - return NULL; - } - - size = pixman_image_get_stride(image) * pixman_image_get_height(image); - dest = cairo_image_surface_get_data(surface); - memcpy(dest, pixman_image_get_data(image), size); - - pixman_image_unref(image); - - return surface; -} - static int check_size(struct rectangle *rect) { @@ -490,70 +484,102 @@ display_create_surface(struct display *display, return display_create_shm_surface(display, rectangle, flags, NULL); } -static cairo_surface_t * -display_create_surface_from_file(struct display *display, - const char *filename, - struct rectangle *rectangle) +static const char *cursors[] = { + "bottom_left_corner", + "bottom_right_corner", + "bottom_side", + "grabbing", + "left_ptr", + "left_side", + "right_side", + "top_left_corner", + "top_right_corner", + "top_side", + "xterm", + "hand1", +}; + +static void +create_cursor_from_images(struct display *display, struct cursor *cursor, + XcursorImages *images) { - if (check_size(rectangle) < 0) - return NULL; + int i; + struct rectangle rect; + XcursorImage *image; + + cursor->images = malloc(images->nimage * sizeof *cursor->images); + cursor->n_images = images->nimage; + + for (i = 0; i < images->nimage; i++) { + image = images->images[i]; + + rect.width = image->width; + rect.height = image->height; + + cursor->images[i].surface = + display_create_shm_surface(display, &rect, 0, NULL); + + shm_surface_write(cursor->images[i].surface, + (unsigned char *) image->pixels, + image->width * image->height * sizeof image->pixels[0]); + + cursor->images[i].width = image->width; + cursor->images[i].height = image->height; + cursor->images[i].hotspot_x = image->xhot; + cursor->images[i].hotspot_y = image->yhot; + cursor->images[i].delay = image->delay; + } - return display_create_shm_surface_from_file(display, filename, rectangle); } - static const struct { - const char *filename; - int hotspot_x, hotspot_y; -} pointer_images[] = { - { DATADIR "/weston/bottom_left_corner.png", 6, 30 }, - { DATADIR "/weston/bottom_right_corner.png", 28, 28 }, - { DATADIR "/weston/bottom_side.png", 16, 20 }, - { DATADIR "/weston/grabbing.png", 20, 17 }, - { DATADIR "/weston/left_ptr.png", 10, 5 }, - { DATADIR "/weston/left_side.png", 10, 20 }, - { DATADIR "/weston/right_side.png", 30, 19 }, - { DATADIR "/weston/top_left_corner.png", 8, 8 }, - { DATADIR "/weston/top_right_corner.png", 26, 8 }, - { DATADIR "/weston/top_side.png", 18, 8 }, - { DATADIR "/weston/xterm.png", 15, 15 }, - { DATADIR "/weston/hand1.png", 18, 11 } -}; static void -create_pointer_surfaces(struct display *display) +create_cursors(struct display *display) { int i, count; - const int width = 32, height = 32; - struct rectangle rect; + struct cursor *cursor; + XcursorImages *images; - count = ARRAY_LENGTH(pointer_images); - display->pointer_surfaces = - malloc(count * sizeof *display->pointer_surfaces); - rect.width = width; - rect.height = height; + count = ARRAY_LENGTH(cursors); + display->cursors = malloc(count * sizeof *display->cursors); for (i = 0; i < count; i++) { - display->pointer_surfaces[i] = - display_create_surface_from_file(display, - pointer_images[i].filename, - &rect); - if (!display->pointer_surfaces[i]) { - fprintf(stderr, "Error loading pointer image: %s\n", - pointer_images[i].filename); + images = XcursorLibraryLoadImages(cursors[i], NULL, 32); + + if (!images) { + fprintf(stderr, "Error loading cursor: %s\n", + cursors[i]); + continue; } + + cursor = &display->cursors[i]; + create_cursor_from_images(display, cursor, images); + + XcursorImagesDestroy(images); } } static void -destroy_pointer_surfaces(struct display *display) +destroy_cursor_images(struct cursor *cursor) +{ + int i; + + for (i = 0; i < cursor->n_images; i++) + if (cursor->images[i].surface) + cairo_surface_destroy(cursor->images[i].surface); + + free(cursor->images); +} + +static void +destroy_cursors(struct display *display) { int i, count; - count = ARRAY_LENGTH(pointer_images); + count = ARRAY_LENGTH(cursors); for (i = 0; i < count; ++i) { - if (display->pointer_surfaces[i]) - cairo_surface_destroy(display->pointer_surfaces[i]); + destroy_cursor_images(&display->cursors[i]); } - free(display->pointer_surfaces); + free(display->cursors); } cairo_surface_t * @@ -561,18 +587,17 @@ display_get_pointer_surface(struct display *display, int pointer, int *width, int *height, int *hotspot_x, int *hotspot_y) { - cairo_surface_t *surface; + struct cursor *cursor = &display->cursors[pointer]; + cairo_surface_t *surface = cursor->images[0].surface; + + /* FIXME returning information for the first image. Something better + * is needed for animated cursors */ - surface = display->pointer_surfaces[pointer]; -#if HAVE_CAIRO_EGL - *width = cairo_gl_surface_get_width(surface); - *height = cairo_gl_surface_get_height(surface); -#else *width = cairo_image_surface_get_width(surface); *height = cairo_image_surface_get_height(surface); -#endif - *hotspot_x = pointer_images[pointer].hotspot_x; - *hotspot_y = pointer_images[pointer].hotspot_y; + + *hotspot_x = cursor->images[0].hotspot_x; + *hotspot_y = cursor->images[0].hotspot_y; return cairo_surface_reference(surface); } @@ -1442,7 +1467,7 @@ input_remove_pointer_focus(struct input *input) input_set_focus_widget(input, NULL, 0, 0); input->pointer_focus = NULL; - input->current_pointer_image = POINTER_UNSET; + input->current_cursor = POINTER_UNSET; } static void @@ -1773,21 +1798,20 @@ input_set_pointer_image(struct input *input, uint32_t time, int pointer) { struct display *display = input->display; struct wl_buffer *buffer; - cairo_surface_t *surface; + struct cursor_image *image; - if (pointer == input->current_pointer_image) + if (pointer == input->current_cursor) return; - input->current_pointer_image = pointer; - surface = display->pointer_surfaces[pointer]; + image = &display->cursors[pointer].images[0]; - if (!surface) + if (!image->surface) return; - buffer = display_get_buffer_for_surface(display, surface); + input->current_cursor = pointer; + buffer = display_get_buffer_for_surface(display, image->surface); wl_input_device_attach(input->input_device, time, buffer, - pointer_images[pointer].hotspot_x, - pointer_images[pointer].hotspot_y); + image->hotspot_x, image->hotspot_y); } struct wl_data_device * @@ -2854,7 +2878,7 @@ display_create(int argc, char *argv[]) d->create_image = (void *) eglGetProcAddress("eglCreateImageKHR"); d->destroy_image = (void *) eglGetProcAddress("eglDestroyImageKHR"); - create_pointer_surfaces(d); + create_cursors(d); display_render_frame(d); @@ -2902,7 +2926,7 @@ display_destroy(struct display *display) cairo_surface_destroy(display->active_frame); cairo_surface_destroy(display->inactive_frame); cairo_surface_destroy(display->shadow); - destroy_pointer_surfaces(display); + destroy_cursors(display); #ifdef HAVE_CAIRO_EGL fini_egl(display); diff --git a/configure.ac b/configure.ac index 6da79224..26c4283d 100644 --- a/configure.ac +++ b/configure.ac @@ -137,7 +137,7 @@ AM_CONDITIONAL(BUILD_CLIENTS, test x$enable_clients = xyes) if test x$enable_clients = xyes; then AC_DEFINE([BUILD_CLIENTS], [1], [Build the Wayland clients]) - PKG_CHECK_MODULES(CLIENT, [wayland-client wayland-egl egl >= 7.10 cairo >= 1.10.0 xkbcommon]) + PKG_CHECK_MODULES(CLIENT, [wayland-client wayland-egl egl >= 7.10 cairo >= 1.10.0 xkbcommon xcursor]) CLIENT_CFLAGS="$CLIENT_CFLAGS $IMAGE_CFLAGS" CLIENT_LIBS="$CLIENT_LIBS $IMAGE_LIBS" diff --git a/data/Makefile.am b/data/Makefile.am index 39b62ffd..ec2723aa 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -1,24 +1,6 @@ westondatadir = $(datadir)/weston dist_westondata_DATA = \ - 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 \ - right_side.png \ - sb_h_double_arrow.png \ - sb_v_double_arrow.png \ - top_left_corner.png \ - top_right_corner.png \ - top_side.png \ - xterm.png \ wayland.svg \ $(wayland_icon_png) \ pattern.png \ diff --git a/data/bottom_left_corner.png b/data/bottom_left_corner.png deleted file mode 100644 index 2d4370fed1bd3280d9c32b03293c8f355a28b54f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1100 zcmV-S1he~zP)~~v(eK;vz}yvCd5g&Obkakcr)S417lF*S7cy^T}EDaKM&nK z8HOh84Cr30q>@T^zxV&Ys(Mw`Vy)$Iih8W*{}TY5e;YtVB(`lr!d>VAi6pWe5z+OV zUa!UqxrBbOq*L4Hebq|2s zKnI{teRs~{w*lLr?*K0VR%^Wk+yGKZB!C;KRBEfcyW5mXB|APo?mLcC1?~Wy^(2zO z74TIild-X6G8qee1H2Ry5|J-~ry5BBov!PCmrke6?(VL&*4mSk6FV_65h$fRU^XJ5 zthI?bAb{%V=%_u2>}$Z201FEXD5a*AQl9`%MDZ07X>%Os>-P5c7uVL-oSvQ@0CskE zSYKZcwAMcWzXI0*9iKKylAfz556EV-EH5vMh|DOZJ_fpgHm&s+uIs*BEEaWdZ!Z8F z8ygG_4f#h$N4v(D4}ibx!rF8lsAd1u)D%lgO9H$Be591hiO6e(LO~A<3;?jXxfz3( zj4_MAFTfwb10aA))`6Ls8GPTDxw*MJ0Qr1gMn*d@%yvBRu^>YpoxzZ;3#h@o_zxpP#S2+uq)e!GDav z_s#={7JGr`d3c@|U%Q%At5wFv#%#G}}vv-}m1F4n)K>cEpwlIF3U)oyPaidR0VFN-;b<%c02}^GWb(Qe~@qi=XIpBK{ z@mncGH-W*3#1U}P#9DwV@E2hdsu6F7!1KU+O@f{h*L7bv#=Hs~i%4LtwU2ZS^Z9(@ z;L?odayg7K1B5d~JCPUuv#GeNt1C8d))P1{1b(ShviW@eQIqUKDHe;d*+zXHB#dMl zm~|ZI0cYpJmQ_Ro;2tmxJPkP3+HjVumuPhE1a3uoJz{%VZv=!l;Wxqtb>CVWB!$2N z$H4EvLqeBbMJOy`0lFXU8_xepf5%bdP=q<6u8=?g_<$dm<3s`tM6OgCo6$c;j7Z31 SY}*|G00007p2feH@Xtt>cT~v2D_^k-PC_zXjg^Wx~ilwrG*hqVv~E%EZ%!D zZC}#NOvc%G;F3q)z4!aM=iYPfd7`R3OfwHv{eJ+!zpR6ZNb;-?;J|eBfQaNpvfUvpvl!>19JnwK|V4zVhmsM4@R;%gQ*q9B1;7{PS7{Z(re^*3YEcQ9@KA^|P z$EvEjwziglyaYT3_^O(E22QNCrEw1gpRZkQEUVyZs#z z`EG7*E^+mvz!iX8E=TJx&cLeBepodt;1SUS8J3j*gCWXlSSrhT#ElEuQFx zh}h}rX^r<)fiHjppw((sRaG}OHj;O50M7y0c3WWLiJu3SjWKRzWu*ymaB!gg{r!zF z41WV=jWM=RC^X;4B42g@coP_G3lKwi@jkx*tQcclu~=-1?C$PrUteDX(5a~@r!CeK zfE0*TV~kr}U2O_&ZEfl7?5sL>M!$CeDG()Nj4PE&nr6;9wbtG>K*vm|QNpPLN5E&! zxtkLc6S}jrbD^(uj(WY`X}VOq^e#|UDM-c9Fr0RI5xc#=BsH&BV+T~-w-Q5t{oo&e&#zab*us_Fx;8Pfy=cztwqR61qJ zZrf#{nFe40FQ3o3mPESu?J2*JN^E^DyV`F2(7-K#HUI2}B}BfUyh6b;6|H z`(?7px&F`AWSJZCfDpUcb>Nokx~-+9 zrJ*9CDAFJZwB2rNwOUQde*kU+3&4v&5ikPw_Mk4mCNPu^z>9)t(FEspkWwluh&!G z_tp1(-Q3(v$?qlPfcflw14$P@6sh{#ztrn>XMKI0$;rvbB4BrSS6$cr^X%*_Ak$wS%7LVV zO#z=23WbV@6!^EpT^ZKeW*COw0^b9_0!>x5{RE_Se;t@1_HLI)M?_p1C&Vu>9aW9; zs=yGx@syI!VKcxmqzQNibb+p_TF5EGL_}&rj}-boh{y~jxdQ$xjD05j8)Q3AC*qJx QGXMYp07*qoM6N<$f=O}6+yDRo diff --git a/data/dnd-copy.png b/data/dnd-copy.png deleted file mode 100644 index fd044ae1570eef02084125b9c39e6836bb0eea81..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1244 zcmV<21S9*2P)^HZ7)(EL2M1e%AYgcSxZ64RT@*#fMI^7P;VVS|_}CcZo;-P?s;c>XUXLC7 zU9hC7uYjMewLbwnfL0Olo9blMu3LQH|1FV7{AsOyno6ZYt;6KxWPMZb-o0D<4uU{0 zUc9LJd|t=K#&q-M&0#DS`vd3#-T-XFNY^gjH;?$xpHOQ1gbcF`m_S8?TbbP>NT)42!giW z-rkq#_NADZn4q_}m)Y4_#>dAwaNvLg-fc9t{us6cbar+=H^@0hp-@0oX>Dz#QmGIG z0YMPZ*49R`SOlP0EV6a$Rsek8XVa!lq|<49-)~CxxqHBvrJxK93@|V-0Ko0rx7odW zHvo6;+@Vk?(ACuiKrWYKYHEr{j~)?*A&ZNPOifL(ZQC}CF=R5C>Y5!uzlbPM27XZ0 zsGfk<6R1Zvo8{cObEqmOPo5;7&vX9#d7N_$4GnSX)G4lCzmBz*>S^of=)m(lwr}4~ zGMNSyk3MK0s8FOGp$rA>$2|dZas10#EQNsid0oK48s-u<#Ji~ z@82H*-veHK1o8k6A3mhLy}fD98X<}z%H=ZC)6+}JHil#}Nh+0MW@d&cifWOGqKHzd z1j`R$J%LFPaW`(MR9j#<4b~X*buyU@&z?Q24<0FMb;*@X)iG?7SXJRaA0Jg&wVJ$(4Emdj7896EF;VoCMQpJP>ZA~NHg`waLI_yCBnj(CIb)s>9`9|G^NB<@CYYglm)sA?!8 z^T02_??5X{PiiwXE34kl<#IbNUApAW&CPND{{5!qmuQ31OhgPzDY2_|u~xhvi^aY* z#>4?}&Xs~7_(WBIT@!(S6V?9!ZQ|%ZC-5?CcwMmJ1pWqPCV|II-1yu80000r78>|Qi4shsK|5? zB^aeEQ;034Ny$PN1qB1*N~zsAB#5{YOhjv;R*{0@pSDrbRzyp!wPv)tj=^LkP7=(& z$>h!HBF;2P$C)M-?7{;d@4i3xo%4O)dGB6J5-$_>OJ#p0;FW;?g8;LXNtR{VKrvuT z8u>2*7F_|$vOYG(3<0A++~@P1vMkH@Ow{5bDQ5r$z+T63zH=Psd&hAmTUuIl<;oQu zIdVjRj4>0&m~mswAW#c9fR*pvl4c*u1!K%t#+a>5O-+t5hP!v~a`x<5R<2wLKqwTV zzP_G{iVC{ByS>}DZx1Jv$@RdWz_juacfmAA0P*G8lxv*iw28{XJyP;5s%F0RrmM>pUAP}&C z4}h-=3JQJ!8h{m+W%;xEyI?r*ODc}>}4ZvlAH?onxV_8P_nQc z3&|azD;NwWCF$|w$BPz_#^J+3h?{=(OtWCNs@+!hL$8C z7K_Po9PQY#L$O#)l63w0byZha3;060Oz3%DX-!QH0Jc5<_QQt{NhA^s4GjU%-`~&F z)D-b}9Du>WK_(_9IC0_xe!riC2M==L!UY-{8YnL>r@g%$V5?(ib+do(#YnXbV5&#i#tI1>W{ z1A#;$k*_%a!1(w$Cr_TFr>BSh{(j=|IOootqpz=z=H_NDUAhF20)9--$!5aeFJHc# zN+c32CQhF|O;uGD`}XZ47z|QgUe5ING>+p?TU(1H4jecD&?{-+c`dMk_W-rFwki^d z=+UD`dE@BOqcX;5`}XY`9v+q?&CJYbaBxtSm6ckvW{oV%67U-k%Jm-981vK^ zlL`a^USVOOS6Eo+xvo1e{C>aZ^Z7hLJ9qAsBpo_*NY}1iQzDVjojZ5ZJ^vPH0sM3M zlx;blv)ic#nxBo+tq_?>w!dPXQ!gksBGI7pjE3@DHe+<91aT@2VMu9tX$bH z&S{5Xb_EOMh+kV6FY?**ga_k54Zkh50@M%#|k#60( zmHB&~KYu<={te*EIsXL+C<1;0w07-U)zs98*>C;JeB@b8xD;5HWdZL3A3pO>hos2A fn)@OI{1^NM#V|4y!8;*w00000NkvXXu0mjf{vu!l diff --git a/data/dnd-move.png b/data/dnd-move.png deleted file mode 100644 index c3ccd6e64bfc80d77fa93728923cc76b7903cf0c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1213 zcmV;u1Va0XP)NIrExW9K|kb7{rbmLcul>W>H6s znP3)fx(T#&5eQ7SSriHt+`A}Um{nbL6Nrlt2tfxlfuxNAtDS~GR@ zy?49NnapTL$CNe{^21@~+fdyi-;U3m@%d#1L7hwq_rMVO8wT*(BNLbe%&OKNmEl( z<7%xlmSsKHTCV{Y0Sl1*;#wu%@yEc`lP6F5wY9ZsVPS#Or%%(>)dj%0bLaH@{Jf6E zV)o3;41IllUjZw?fQbBMjPZ-b-j{%gh}Qbk_V#vfcz9R?^!N8uQBjdQ)7aQZRaF%i zE?fX$dV1Qwd-v|=zVCa$k0SCjunG8P$Ludf1EQ3wuCK4x*@e2gI+~iAatB&kTBxtD z&-qnVRm%7MCg5A8)DOTHz&n5=BAR^cQS*;%+nxyo0<&7{=ZQqZWbx?HBa=?2bH3+! zW^QgS=MM}Fn8%MFn^Y=gy1Tm#V1Rz$7*GMIT%IDy%Wd2KwWX!S>*?t+;c(c`C$Jx$ zJb6;!cXoFAz;{49P?Jw!mjO}` zotv9udU~4C(NO>#$3ZETOAgT5+DcnnTQ$(OGiOPIXuF00c%H|lOP8=Li$o&9+S(fT z@874cu8u2Lt`v=tOeVQ~`}VH&q6CaFxURcvJr;`*i^TwNU6)g*PBAz*$k^CeDfdz` zfu~DLOMWJk(M9$P;CbFl*L!<=nVg&iU~zHrKm>kz@Zf=7SXiLCy84v~oIih_cs!mZ zu>#Bh1@DEIiO>L7ecxX`d-kk9F)=|VliAZe&&v)lVC!A+?AbFyp%6E3-sJf4<5-qe z&ek-{kT3Eglh6X{A84-`w2n1U^Zp(_sqBWp;c=_|USf zr_pG1v#YDi-Tt-oK|%ce2>eq6j#-xVRBN39T6gYCzIy*Hh{*fEyT+L0uD$<)z+QOm be@y-csua@(y!>_W00000NkvXXu0mjfJt;y~ diff --git a/data/grabbing.png b/data/grabbing.png deleted file mode 100644 index 04694594b218dc411f2b38073571053246dccc99..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1004 zcmVljO4%af_Vo1ZipU2d z^5%G2>#iCw1AGH~Cn7(E!(ls>O6kqbO&tn_9Md#^@9XRPwYRtT7vL430C^18*JZ?? zipciF#DqICG9s2`v9PdUtgfyCP$(4C@$vDCcs%|hm&=jKWWLo}zXrBNFH@kM@Kz96bczy>jbc^l*$921MiB6zxkZBB_JXRpU<~r zn&!^U&CS&PwMZnw`1rV|$K!Egv6!bXEiIAFX36LCtgNi`0$&4P0v`hJ$Xz7R`Va!9 zX_`MrqfsZBOzLnr>?V^*eJ8H#>P}KFmmBoi*;yCZ0X_x>0i*39th4*bw(a=V))t9G zf`fyDW}9}217L7)utD$d?*|aTq$%sIwm^VShKGmkL?Ur(Wc+vasvUA97K?ddDy6)! zWm!}z6^g|o02db*RI63a&dvZRm&;VERZ68&C%+zEr_em3OeVv|#s&bnT#jHch*AoG z!^1-YfdE%mR{)%zo)QQIS`lcuZ(S9lfq?;UT&Yw@r_)%L#oF2$rBaD>I?d(fC1Yb_ z6bc3Q_xG`Fo2jX(4yf%3Xt@149LIUEI5#)P_4PG=zaPhOn4h0-&=(gM8}vJ@JKXy| zI%S|@S(aO?)l{oR!!W4TYF+D&h64baX_mR(oyp&_?Uj!u26 zIm@yX@SEc}UjVr}k;{6ZZ3zhA2i^ygz{`8t()ar2);teT1%3oh>dw!#)^^7X+#}Ho z1cCQ}er_)rounB|bDQ!%feYXdt@Ymxeja<8iHPFg8ZPzrChs{7+yIW&`sM-t^V{%$ aPv9T>QxjZeYd&lM00008exT{OVNK86lP*_fP@gjUj$W^Rjq&!LIs`yD)5o2s-Mr!&iW#e2=nvvALsM=Ebt@nj}YQl z;BTr?MM`;R1K#)h{jUI7Xj4;DvS5>wlXmg5Kp^lNkOG2$xGi?ITkvTznT#DB9g)do zn3Xnv$KLL<}R0vJgr$AbkB>~aY)I>{5i&Z=}7z~z16{6%+)YsR0guQ8ANoY9$05mo>y5z^l z$K-N3&d$zUKby^Rad82_>FFtN-n=25PCp31wk*qa8X6jua5xNrs;a1}%KrX7wrvv* zhtV{R-Q8W%>9qTf*xuf*3cza%Y|}Jd1(uhWT?JNFR*+KC*Vl)lC@d{4;q&Xw)&ub7-yamerYZ%8SJdV71NuIp~nIC+dzU2EtJ3Ks;mzS49O8GVL z3-AYUE~UJx2;e~Yfh6z+@B!DCNZ}|JN-xTK>G3QL`~C>C%#BOw9x#>zkttsMRsaX0Pz~Ly*7pJ` jF2$+>_%H0q{~P`bh2jP=IyL|`00000NkvXXu0mjfGgkKN diff --git a/data/hand2.png b/data/hand2.png deleted file mode 100644 index 016b9a6e0780d1e4e5046e54e1b9b6e52afc06b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1108 zcmV-a1grarP)g9K#rih|qxb0w!<^)Rj`!V*&1sfbBf! za5#R@H0^g?*Z*)h9Nz)YMZ{^}f4G!V0~?JfeeLyn&7GYcmCa_A%jK#AUjfem{k}N{ z&VP?{0Y;oo=j)A)4b{}#+*}R#1_%Sr#{dko33WgW!)OgymIaOFbJ&m%*05R7;lu_| z_P8b@56-5cvY=ZwKn(btMpk?&BIiKO215;5;T{B_>$>ju`)8)7r{h;wS8{W6^Py>) z%Rt12I2MsIjZ_^7@*n_@$0Ntb$9gmxrBEmkiA0`@$S+DM0Wb{XO|@G61Sp8eUqH1V z%zbO8^|Fb_<3yuT0H&s<2!%qD$zm`{?vc0|i&i?-Xo~CKLmSue^ zB7ZBT>U{xh=T5^gz6}HdiTU|?IXpb<$b#9~**g)LnVD(zW3d>ktEG7_9kxJ^&2E zXgydg7P+{%;P&`FwsTfPQsg#O-#sItK>_t?O(yOQljFl}a%> zI?C487PVT9wY4>Z!62KPn<%ANUtb>zpw|g#0Naa;i#5|U)!S&VUcFLIr}GS$1x5jB z`s)_~x7+QOa=AR*zqm)u{n1PP(ojmJ5~Whzomr-7{y8jw0)9FB(XV4)nbvB+K}3BhWML?mVx&ICi)#Xuky5hO^gQYMXsl|_)1G%1uoykyta+5Nuv zikZPA>?X69J?@3C+Hdyx&HFviJ2RrH+|TmP+8`ow-vDCqYa(Lq6-Y~fSkMQ42A%>Q z5Ro%G)-iy%eBf2z_t$`D?g@mdHeG-K4+09P@B6<3F9MeUX?0z@E7jd(vsr>5c*z*^ z9q@GAiH>+86+nM~KkMu3o-yVXV@wIS4qWU6L@EI190LObtgWqiBJzfad<#6;35e7H z0E2^rtgfz#=Xq}fw}8ii3+I7I1)!=}YXKM<8e(~QSw!R=;A`Nq^FXBTK+*+(k&zKf zr4l0YAutU*3IulrktT+vQb}vInl>5@Jz8^fb4nD`MIvKfpv{P;0w@-XTB%et3`0Fx zGcz*@#4RFYwgr(2U~zF#4-O8Rc0pA&m&+v(UjZ2)NDGk)U}0fF_xJa;TCFzif~xAo z#Dt2719HF%b0D&FcD88d9n(H0;8j& zc%GL7J_a5JPJNX7X#f&YV+__>JkP@zgL96Jjg92U02m$~md(vg+1}p%(mD4pumao` z5vxZxwhNFzB;wXuf*>H5%dxe!)$B3@%mBB6AAu^7QIAzyN05N5tgKM0)o{)+K0cmo zTL5kno&P9s1Na2^gV>NQ|NN{JCc}x3{O|aybE5iua`&#b*Ir0>*&XfMIEV;?4$<2(Kb2vyY``TYv;I#KQ`z$Wk;@H=pj>^-eo z0vr)ZhLt-xN=3xP5Le@F{RjLV!!#YeZ2_dI_)EzU9g7lqM$?FQ1mL`N2bo{|5UpHQ Q_W%F@07*qoM6N<$f@){UGXMYp diff --git a/data/left_side.png b/data/left_side.png deleted file mode 100644 index 2e2fab54708ccd91b3bb83ed1b9d0ad8413b89a6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1141 zcmV-*1d98KP)$pr90_2uc~HbQg|vY3Q6ZmM9Xi!MYGQb053=QtX~{*t_S2 zC~}i0jqY~e?EC-c&71$sh^q1;&3U2d{}TY*PEHY#_GkSM3P#dmiiiWe2fRa^rF*~+ zz@I>rMnpuqf!euAs_HWh_z;N3#>N`AZr!T8t{Vb(fL8!FrTkr``X&mQ{p)Utiyo`S0oJK}3Au zHNXcXN&B$1_UA^Uan%^p1zc+P=dm;bk`X`v3z!&Nu2^fgZ``=?=H%ogfR|*){kH_3 z*I$4kYwdQiSR5*s%Wk1iX!*_seh~rygVx%uVzGFo4IHvF*U>uaK#CQtwclO8etoc9 zF1wd6Ury^I#8Z?tIBj35xe0_}*ki5z^4hg)g*5PHv-v9UF|k(EfHXa*0N;zqE)b}y z<|fc=HZR@0c{AMJ-ZuUH{bzhbLqm*?j`phR`x(Fh?C(*Xl~ zJ25d4v~-|UD(T3`NVvDRr|lL+k%nQIt2LWV-QC^Qgy0-d0Nh*|C=?2m%VlR^VBpES zD2k}p>ztmR5=BwR?^Ts3itv5E_391cC3~EUz~SK`8yg#}uCAU5TCG+&I5;2-LmVf2 zL8&U9=h55S+j`|C&B;YTRk?lpHpUoMR#pIT90y|zzVCB#azdq2=@`Rt9PZw|+j@M^ z`jfi|MWj(Gl{{mNEG;b|B6yyMwU+hub=KC_^2AWrb$z7Z*Qr z97m?7r|ItQMnn*i5ZDDCCc)DxGfGDOSJJ}s5;z9F0qP423v(jE)YMd~02Md^_KC$P z$cPgrzVKW^lvo3J1l&`bv( zJOhw`bQXuiF0vc8NIU{QSJkiX-@o4ij_4r8X_l3N{hgg1-Q3*77{k`qmWE+?)CLd{ zr}_~13~*|-+Ph@Wd$whq3CFCp_YyGmJg)+L0*n*OsA=o_5-?1x?{5RIxBPk9Gsp7e zF3=7114BR`@g9Ey`~mC%k6Uw`?E5~kwj1J=a+he#aMoI9ji;2MbZ%>&7o(_DG;CbwCH9BW>v5Qh%00000NkvXX Hu0mjf1s@!P diff --git a/data/right_side.png b/data/right_side.png deleted file mode 100644 index d49b1142f64f4bf9d18e2c6b41a3b068d6820d4b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1051 zcmV+$1mydPP)?%@4Mgm&djN(Do--Z6Gi`@0Fe2&0YpTSkAP~*bTX(3MdS|fC+=6T*fR~h z3*><#;A`L^(0-JosskyG@G_87)k`HXKrWxpb98jX@bEDG zs30Qb^Z5&EEH5t;1VPW-ZYC5}rP*w9dU~2Db7fd-$z(DV3WW;wtlW%1 zyWRd_b93{>@$qq!u5UV2m8q#IRP_>gu~>`_4i0*^V#)&^Fq6$@e>BFld#ni1-Q8WS z*X!DDw^dcOR;%gQ*jQUc&KbZ13VhdUwcZ0>0PYa`qTBP}4dA{phLMpGj4|x(?NKZi zqaX+ZRs9y2?|)r~+4pwVbB zGc(f({xfg@+#85M7c!SZL=r z^S<&t?;KEf{RVi8xP!8)I@nn5%$Wm59B9+6NLAI{&k)alFS%<5ICm=T1AnM$besPL zhR3sA1lUf~y8A=KBie}D+afN}84#+f4otv-2wdAO$>fxj#yYZ5l5;BpHznGQ?BA-7 VZQEf>Wbpt1002ovPDHLkV1kU7-Esf` diff --git a/data/sb_h_double_arrow.png b/data/sb_h_double_arrow.png deleted file mode 100644 index 8e55c0aa65f79caa0aa848e4d56e7945ce2f1527..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1287 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 N002ovPDHLkV1nCIGzkCz diff --git a/data/top_right_corner.png b/data/top_right_corner.png deleted file mode 100644 index fb7727ca54daa59505a27140b936f0156dc53409..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1163 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 B58wa*