mowc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/mowc
Log | Files | Refs

commit 6f2a50de8c62f625f84bef17a027a0f161425283
parent bc38196909d7b6186fffac43012b7f470104ec6c
Author: Nihal Jere <nihal@nihaljere.xyz>
Date:   Tue, 15 Jun 2021 11:37:01 -0500

dialer: number entry works

Diffstat:
Aclients/dialer.c | 397+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 397 insertions(+), 0 deletions(-)

diff --git a/clients/dialer.c b/clients/dialer.c @@ -0,0 +1,397 @@ +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <wld/wayland.h> +#include <wld/wld.h> +#include <wayland-client.h> +#include <xdg-shell-client-protocol.h> +#include <text-input-unstable-v3-client-protocol.h> +#include <atd.h> +#include <encdec.h> + +#include "drw.h" +#include "util.h" + +#define LENGTH(x) (sizeof x / sizeof x[0]) +#define STRINGTOKEYSYM(X) (XStringToxkb_keysym_t(X)) +#define TEXTW(X) (drw_fontset_getwidth(drw, (X))) + +enum { + SchemeNormal, + SchemeSetting, + SchemeSettingDown, + SchemeHangup, + SchemeHangupDown, + SchemeLast +}; + +enum button { + ButtonNone, + ButtonCall, + ButtonClear, +}; + +static const char *colors[SchemeLast][2] = { + /* fg bg */ + [SchemeNormal] = { "#ffffff", "#2222cc" }, + [SchemeSetting] = { "#ffffff", "#22cc22" }, + [SchemeHangup] = { "#ffffff", "#cc2222" }, + [SchemeSettingDown] = { "#ffffff", "#008800" }, + [SchemeHangupDown] = { "#ffffff", "#880000" }, +}; + +#include "config.h" + +static Clr* scheme[SchemeLast]; + +struct { + struct wl_display *dpy; + struct wl_compositor *cmp; + struct wl_seat *seat; + struct wl_touch *touch; + struct wl_surface *surface; + struct xdg_wm_base *wm; + struct xdg_surface *xdgsurface; + struct xdg_toplevel *toplevel; + struct zwp_text_input_manager_v3 *timanager; + struct zwp_text_input_v3 *textinput; + char number[PHONE_NUMBER_MAX_LEN + 1]; + struct { + char commitbuf[4000]; + uint32_t delbefore; + uint32_t delafter; + } tipending; + uint32_t textserial; + + Drw *drw; + + int32_t w, h; +} wl; + +unsigned int tw, th; +enum button pressed, current; + +static void wmping(void *data, struct xdg_wm_base *wm, uint32_t serial); +static void xdgsurfconfigure(void *data, struct xdg_surface *surf, uint32_t serial); +static void toplevelconfigure(void *data, struct xdg_toplevel *toplevel, int32_t w, int32_t h, struct wl_array *states); +static void toplevelclose(void *data, struct xdg_toplevel *toplevel); +static void regglobal(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version); +static void regglobalremove(void *data, struct wl_registry *registry, uint32_t name); +static void draw(void); +static void touchdown(void *data, struct wl_touch *wl_touch, uint32_t serial, uint32_t time, struct wl_surface *surface, int32_t id, wl_fixed_t x, wl_fixed_t y); +static void touchup(void *data, struct wl_touch *wl_touch, uint32_t serial, uint32_t time, int32_t id); +static void touchmotion(void *data, struct wl_touch *wl_touch, uint32_t time, int32_t id, wl_fixed_t x, wl_fixed_t y); +static void touchframe(void *data, struct wl_touch *wl_touch); +static void touchcancel(void *data, struct wl_touch *wl_touch); +static void tienter(void *data, struct zwp_text_input_v3 *text_input, struct wl_surface *surface); +static void tileave(void *data, struct zwp_text_input_v3 *text_input, struct wl_surface *surface); +static void tipreedit_string(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, const char *text, int32_t cursor_begin, int32_t cursor_end); +static void ticommit_string(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, const char *text); +static void tidelete_surrounding_text(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, uint32_t before_length, uint32_t after_length); +static void tidone(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, uint32_t serial); + + +static struct wl_registry_listener reglistener = { regglobal, regglobalremove }; + +static struct xdg_wm_base_listener wmlistener = { wmping }; +static struct xdg_surface_listener xdgsurflistener = { xdgsurfconfigure }; +static struct xdg_toplevel_listener toplevellistener = + { toplevelconfigure, toplevelclose }; +static struct wl_touch_listener touchlistener = + { touchdown, touchup, touchmotion, touchframe, touchcancel }; +static struct zwp_text_input_v3_listener tilistener = { + .enter = tienter, + .leave = tileave, + .preedit_string = tipreedit_string, + .commit_string = ticommit_string, + .delete_surrounding_text = tidelete_surrounding_text, + .done = tidone +}; + + +void +wmping(void *data, struct xdg_wm_base *wm, uint32_t serial) +{ + xdg_wm_base_pong(wm, serial); +} + +void +xdgsurfconfigure(void *data, struct xdg_surface *surf, uint32_t serial) +{ + xdg_surface_ack_configure(surf, serial); +} + +void +toplevelconfigure(void *data, struct xdg_toplevel *toplevel, int32_t w, int32_t h, + struct wl_array *states) +{ + if (w == wl.w && h == wl.h) + return; + if (w == 0 && h == 0) + return; + + wl.w = w; + wl.h = h; +} + +void +toplevelclose(void *data, struct xdg_toplevel *toplevel) +{ + exit(0); +} + +void +regglobal(void *data, struct wl_registry *registry, uint32_t name, + const char *interface, uint32_t version) +{ + if (strcmp(interface, "wl_compositor") == 0) { + wl.cmp = wl_registry_bind(registry, name, + &wl_compositor_interface, 3); + } else if (strcmp(interface, "xdg_wm_base") == 0) { + wl.wm = wl_registry_bind(registry, name, &xdg_wm_base_interface, 1); + xdg_wm_base_add_listener(wl.wm, &wmlistener, NULL); + } else if (strcmp(interface, "wl_seat") == 0) { + wl.seat = wl_registry_bind(registry, name, + &wl_seat_interface, 4); + } else if (strcmp(interface, "zwp_text_input_manager_v3") == 0) { + wl.timanager = wl_registry_bind(registry, name, &zwp_text_input_manager_v3_interface, 1); + } +} + +void +regglobalremove(void *data, struct wl_registry *registry, uint32_t name) +{ +} + +struct { + bool down; + uint32_t x, y; + int32_t id; +} touchpoint; + +static enum button +getpressed() +{ + if (touchpoint.x < wl.w / 2 && touchpoint.y > 3 * wl.h / 8 && touchpoint.y < wl.h / 2) { + return ButtonCall; + } else if (touchpoint.x > wl.w / 2 && touchpoint.y > 3 * wl.h / 8 && touchpoint.y < wl.h / 2) { + return ButtonClear; + } + + return ButtonNone; +} + +void +touchdown(void *data, struct wl_touch *wl_touch, uint32_t serial, uint32_t time, struct wl_surface *surface, int32_t id, wl_fixed_t x, wl_fixed_t y) +{ + if (touchpoint.down) + return; + + touchpoint.down = true; + touchpoint.x = wl_fixed_to_int(x); + touchpoint.y = wl_fixed_to_int(y); + touchpoint.id = id; + current = pressed = getpressed(); + draw(); +} + +int switchinput() { +} + +void +touchup(void *data, struct wl_touch *wl_touch, uint32_t serial, uint32_t time, int32_t id) +{ + if (touchpoint.id != id) + return; + + touchpoint.down = false; + + if (pressed == current) { + switch (pressed) { + case ButtonCall: + fprintf(stderr, "ButtonCall\n"); + break; + case ButtonClear: + fprintf(stderr, "ButtonClear\n"); + break; + } + } + + current = pressed = ButtonNone; + draw(); +} + +void +touchmotion(void *data, struct wl_touch *wl_touch, uint32_t time, int32_t id, wl_fixed_t x, wl_fixed_t y) +{ + if (touchpoint.id != id) + return; + + touchpoint.x = wl_fixed_to_int(x); + touchpoint.y = wl_fixed_to_int(y); + current = getpressed(); + draw(); +} + +void +touchframe(void *data, struct wl_touch *wl_touch) +{ +} + +void touchcancel(void *data, struct wl_touch *wl_touch) +{ + touchpoint.down = false; +} +void +tienter(void *data, struct zwp_text_input_v3 *text_input, struct wl_surface *surface) +{ + fprintf(stderr, "tienter\n"); + zwp_text_input_v3_enable(text_input); + zwp_text_input_v3_set_content_type(text_input, ZWP_TEXT_INPUT_V3_CONTENT_HINT_NONE, ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_PHONE); + wl.textserial++; + zwp_text_input_v3_commit(text_input); +} + +void +tileave(void *data, struct zwp_text_input_v3 *text_input, struct wl_surface *surface) +{ + zwp_text_input_v3_disable(text_input); +} + +void +tipreedit_string(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, const char *text, int32_t cursor_begin, int32_t cursor_end) +{ +} + +void +ticommit_string(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, const char *text) +{ + fprintf(stderr, "TICOMMIT_STRING\n"); + strcpy(wl.tipending.commitbuf, text); +} + +void +tidelete_surrounding_text(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, uint32_t before_length, uint32_t after_length) +{ + wl.tipending.delbefore = before_length; + wl.tipending.delafter = after_length; +} + +void +tidone(void *data, struct zwp_text_input_v3 *zwp_text_input_v3, uint32_t serial) +{ + fprintf(stderr, "TIDONE\n"); + if (serial != wl.textserial) + return; + + /* 2. Delete requested surrounding text */ + size_t len = strlen(wl.number); + if (len > wl.tipending.delbefore) + wl.number[len - wl.tipending.delbefore] = 0; + else + wl.number[0] = 0; + + /* 3. Insert commit string with the cursor at its end */ + char *next = wl.tipending.commitbuf; + for (int i = 0; i < PHONE_NUMBER_MAX_LEN - len && *next != '\0'; i++, next++) { + /* we only accept characters that are valid in a phone number */ + if (strchr(DIALING_DIGITS, *next) != NULL) { + wl.number[len+i] = *next; + wl.number[len+i+1] = '\0'; + } + } + + fprintf(stderr, "number: %s\n", wl.number); + + zwp_text_input_v3_commit(wl.textinput); + wl.textserial++; + wl.tipending.delbefore = 0; + wl.tipending.delafter = 0; + wl.tipending.commitbuf[0] = 0; + + draw(); +} + +void +draw() +{ + int height = wl.h / 8; + wld_set_target_surface(wl.drw->renderer, wl.drw->surface); + + drw_setscheme(wl.drw, scheme[SchemeNormal]); + drw_rect(wl.drw, 0, 0, wl.w, wl.h - height, 1, 1); + drw_setfontset(wl.drw, &wl.drw->fonts[0]); + drw_font_getexts(&wl.drw->fonts[0], wl.number, strlen(wl.number), &tw, &th); + drw_text(wl.drw, wl.w / 2 - tw / 2, height, tw, th, 0, wl.number, 0); + + drw_map(wl.drw, wl.surface, 0, 0, wl.w, wl.h); +} + +void +wlinit(void) +{ + struct wl_registry *registry; + int j; + + wl.w = wl.h = 500; + + if (!(wl.dpy = wl_display_connect(NULL))) + die("Can't open display\n"); + + registry = wl_display_get_registry(wl.dpy); + wl_registry_add_listener(registry, &reglistener, NULL); + + wl_display_roundtrip(wl.dpy); + + wl.drw = drw_create(wl.dpy); + + if (!wl.seat) + die("Display has no seat\n"); + if (!wl.wm) + die("Display has no window manager\n"); + if (!wl.timanager) + die("Display has no text input manager\n"); + + if (!drw_fontset_create(wl.drw, (const char **) fonts, LENGTH(fonts))) + die("no fonts could be loaded"); + + wl.touch = wl_seat_get_touch(wl.seat); + wl_touch_add_listener(wl.touch, &touchlistener, NULL); + wl.textinput = zwp_text_input_manager_v3_get_text_input(wl.timanager, wl.seat); + zwp_text_input_v3_add_listener(wl.textinput, &tilistener, NULL); + + wl_display_roundtrip(wl.dpy); + + if (!wl.touch) + die("seat has no touch support\n"); + + /* init appearance */ + for (j = 0; j < SchemeLast; j++) + scheme[j] = drw_scm_create(wl.drw, (const char **) colors[j], 2); + + wl.surface = wl_compositor_create_surface(wl.cmp); + wl.xdgsurface = xdg_wm_base_get_xdg_surface(wl.wm, wl.surface); + xdg_surface_add_listener(wl.xdgsurface, &xdgsurflistener, NULL); + wl.toplevel = xdg_surface_get_toplevel(wl.xdgsurface); + xdg_toplevel_add_listener(wl.toplevel, &toplevellistener, NULL); + xdg_toplevel_set_app_id(wl.toplevel, "answer"); + + wl_display_roundtrip(wl.dpy); + + if (wl.w == 0 || wl.h == 0) { + die("window has 0 dimension\n"); + } + + drw_resize(wl.drw, wl.surface, wl.w, wl.h); + draw(); +} + +int +main(int argc, char *argv[]) +{ + wlinit(); + while (wl_display_dispatch(wl.dpy) != -1); + return 0; +}