Hello community, here is the log from the commit of package wob for openSUSE:Factory checked in at 2020-09-09 18:01:28 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/wob (Old) and /work/SRC/openSUSE:Factory/.wob.new.3399 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "wob" Wed Sep 9 18:01:28 2020 rev:2 rq:833090 version:0.10 Changes: -------- --- /work/SRC/openSUSE:Factory/wob/wob.changes 2020-07-30 10:03:27.791353555 +0200 +++ /work/SRC/openSUSE:Factory/.wob.new.3399/wob.changes 2020-09-09 18:07:47.343517467 +0200 @@ -1,0 +2,12 @@ +Mon Aug 31 14:21:21 UTC 2020 - Dirk Mueller <dmuel...@suse.com> + +- update to 0.10: + * NULL terminate color buffer string to prevent usage of uninitialised memory + * Correctly display colors with aplha value < 100% + * Short option -v no longer shows current version but increases debug level + instead. + * Enable seccomp rules by default if libseccomp is found. + * Long options (--border-color, --background-color, --bar-color). + * Log output. Use -v increase verbosity. + +------------------------------------------------------------------- Old: ---- wob-0.8.tar.gz wob-0.8.tar.gz.sig New: ---- wob-0.10.tar.gz wob-0.10.tar.gz.sig ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ wob.spec ++++++ --- /var/tmp/diff_new_pack.7xpfxT/_old 2020-09-09 18:07:50.087519968 +0200 +++ /var/tmp/diff_new_pack.7xpfxT/_new 2020-09-09 18:07:50.091519971 +0200 @@ -17,7 +17,7 @@ Name: wob -Version: 0.8 +Version: 0.10 Release: 0 Summary: A lightweight overlay volume/backlight/progress/anything bar for Wayland License: ISC @@ -26,9 +26,11 @@ Source0: https://github.com/francma/wob/releases/download/%{version}/wob-%{version}.tar.gz Source1: https://github.com/francma/wob/releases/download/%{version}/wob-%{version}.tar.gz.sig Source2: https://keys.openpgp.org/vks/v1/by-fingerprint/5C6DA024DDE27178073EA103F4B432D5D67990E3#/%{name}.keyring +BuildRequires: cmake BuildRequires: meson BuildRequires: pkgconfig BuildRequires: wayland-devel +BuildRequires: pkgconfig(libseccomp) BuildRequires: pkgconfig(scdoc) BuildRequires: pkgconfig(wayland-client) BuildRequires: pkgconfig(wayland-protocols) ++++++ wob-0.8.tar.gz -> wob-0.10.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wob-0.8/LICENSE new/wob-0.8/LICENSE --- old/wob-0.8/LICENSE 2020-03-01 12:25:07.000000000 +0100 +++ new/wob-0.8/LICENSE 1970-01-01 01:00:00.000000000 +0100 @@ -1,15 +0,0 @@ -ISC License - -Copyright (c) 2019, Martin Franc - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wob-0.8/meson.build new/wob-0.8/meson.build --- old/wob-0.8/meson.build 2020-03-01 12:25:07.000000000 +0100 +++ new/wob-0.8/meson.build 1970-01-01 01:00:00.000000000 +0100 @@ -1,97 +0,0 @@ -project( - 'wob', - 'c', - version: '0.8', - license: 'ISC', - default_options: ['c_std=c99'] - ) - -cc = meson.get_compiler('c') - -wayland_protos = dependency('wayland-protocols', version: '>=1.13') -wl_protocol_dir = wayland_protos.get_pkgconfig_variable('pkgdatadir') -wayland_scanner = find_program('wayland-scanner') -wayland_client = dependency('wayland-client') -rt = cc.find_library('rt') - -seccomp = dependency('libseccomp', required: get_option('seccomp')) -if seccomp.found() - add_project_arguments('-DWOB_USE_SECCOMP', language: 'c') -endif - -wob_version = '"@0@"'.format(meson.project_version()) -add_project_arguments('-DWOB_VERSION=@0@'.format(wob_version), language: 'c') - -wayland_scanner_code = generator( - wayland_scanner, - output: '@BASENAME@-protocol.c', - arguments: ['private-code', '@INPUT@', '@OUTPUT@'], -) - -wayland_scanner_client = generator( - wayland_scanner, - output: '@BASENAME@-client-protocol.h', - arguments: ['client-header', '@INPUT@', '@OUTPUT@'], -) - -client_protocols = [ - [wl_protocol_dir + '/stable/xdg-shell', 'xdg-shell.xml'], - [wl_protocol_dir + '/unstable/xdg-output', 'xdg-output-unstable-v1.xml'], - [meson.source_root(), 'wlr-layer-shell-unstable-v1.xml'], -] - -foreach p : client_protocols - xml = join_paths(p) - src = wayland_scanner_code.process(xml) - header = wayland_scanner_client.process(xml) - - name = p[1].split('.')[0].underscorify() - - lib = static_library( - name, - [src, header], - dependencies: [wayland_client], - ) - - dep = declare_dependency( - link_with: lib, - sources: header, - ) - - set_variable(name, dep) -endforeach - -executable( - 'wob', - 'wob.c', - dependencies: [seccomp, xdg_output_unstable_v1, wayland_client, wlr_layer_shell_unstable_v1, xdg_shell, rt], - install: true -) - -e = executable( - 'wob-test', - 'test.c', - dependencies: [seccomp, xdg_output_unstable_v1, wayland_client, wlr_layer_shell_unstable_v1, xdg_shell, rt], - c_args: ['-Wno-unused-function'] -) -test('wob-test', e) - -scdoc = dependency('scdoc', version: '>=1.9.2', native: true, required: get_option('man-page')) -if scdoc.found() - scdoc = find_program(scdoc.get_pkgconfig_variable('scdoc'), native: true) - sh = find_program('sh', native: true) - mandir = get_option('mandir') - scdfile = 'wob.1.scd' - manfile = scdfile.split('.scd')[0] - - custom_target( - manfile, - input: scdfile, - output: manfile, - command: [ - sh, '-c', '@0@ < @INPUT@ > @1@'.format(scdoc.path(), manfile) - ], - install: true, - install_dir: join_paths(mandir, 'man1') - ) -endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wob-0.8/meson_options.txt new/wob-0.8/meson_options.txt --- old/wob-0.8/meson_options.txt 2020-03-01 12:25:07.000000000 +0100 +++ new/wob-0.8/meson_options.txt 1970-01-01 01:00:00.000000000 +0100 @@ -1,2 +0,0 @@ -option('man-page', type: 'feature', value: 'auto', description: 'Generate and install man page') -option('seccomp', type: 'feature', value: 'disabled', description: 'Use seccomp on Linux') \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wob-0.8/test.c new/wob-0.8/test.c --- old/wob-0.8/test.c 2020-03-01 12:25:07.000000000 +0100 +++ new/wob-0.8/test.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,41 +0,0 @@ -#define WOB_TEST -#include "wob.c" - -int -main(int argc, char **argv) -{ - unsigned long percentage; - struct wob_colors colors = {0, 0, 0}; - char *input; - bool result; - - printf("running 1\n"); - input = "25 #FF000000 #FFFFFFFF #FFFFFFFF\n"; - result = wob_parse_input(input, &percentage, &colors); - if (!result || percentage != 25 || colors.background != 0xFF000000 || colors.border != 0xFFFFFFFF || colors.bar != 0xFFFFFFFF) { - return EXIT_FAILURE; - } - - printf("running 2\n"); - input = "25 #FF000000\n"; - result = wob_parse_input(input, &percentage, &colors); - if (result) { - return EXIT_FAILURE; - } - - printf("running 3\n"); - input = "25\n"; - result = wob_parse_input(input, &percentage, &colors); - if (!result || percentage != 25) { - return EXIT_FAILURE; - } - - printf("running 4\n"); - input = "25 #FF000000 #FFFFFFFF #FFFFFFFF \n"; - result = wob_parse_input(input, &percentage, &colors); - if (result) { - return EXIT_FAILURE; - } - - return EXIT_SUCCESS; -} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wob-0.8/wlr-layer-shell-unstable-v1.xml new/wob-0.8/wlr-layer-shell-unstable-v1.xml --- old/wob-0.8/wlr-layer-shell-unstable-v1.xml 2020-03-01 12:25:07.000000000 +0100 +++ new/wob-0.8/wlr-layer-shell-unstable-v1.xml 1970-01-01 01:00:00.000000000 +0100 @@ -1,301 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<protocol name="wlr_layer_shell_unstable_v1"> - <copyright> - Copyright © 2017 Drew DeVault - - Permission to use, copy, modify, distribute, and sell this - software and its documentation for any purpose is hereby granted - without fee, provided that the above copyright notice appear in - all copies and that both that copyright notice and this permission - notice appear in supporting documentation, and that the name of - the copyright holders not be used in advertising or publicity - pertaining to distribution of the software without specific, - written prior permission. The copyright holders make no - representations about the suitability of this software for any - purpose. It is provided "as is" without express or implied - warranty. - - THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY - SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, - ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF - THIS SOFTWARE. - </copyright> - - <interface name="zwlr_layer_shell_v1" version="2"> - <description summary="create surfaces that are layers of the desktop"> - Clients can use this interface to assign the surface_layer role to - wl_surfaces. Such surfaces are assigned to a "layer" of the output and - rendered with a defined z-depth respective to each other. They may also be - anchored to the edges and corners of a screen and specify input handling - semantics. This interface should be suitable for the implementation of - many desktop shell components, and a broad number of other applications - that interact with the desktop. - </description> - - <request name="get_layer_surface"> - <description summary="create a layer_surface from a surface"> - Create a layer surface for an existing surface. This assigns the role of - layer_surface, or raises a protocol error if another role is already - assigned. - - Creating a layer surface from a wl_surface which has a buffer attached - or committed is a client error, and any attempts by a client to attach - or manipulate a buffer prior to the first layer_surface.configure call - must also be treated as errors. - - You may pass NULL for output to allow the compositor to decide which - output to use. Generally this will be the one that the user most - recently interacted with. - - Clients can specify a namespace that defines the purpose of the layer - surface. - </description> - <arg name="id" type="new_id" interface="zwlr_layer_surface_v1"/> - <arg name="surface" type="object" interface="wl_surface"/> - <arg name="output" type="object" interface="wl_output" allow-null="true"/> - <arg name="layer" type="uint" enum="layer" summary="layer to add this surface to"/> - <arg name="namespace" type="string" summary="namespace for the layer surface"/> - </request> - - <enum name="error"> - <entry name="role" value="0" summary="wl_surface has another role"/> - <entry name="invalid_layer" value="1" summary="layer value is invalid"/> - <entry name="already_constructed" value="2" summary="wl_surface has a buffer attached or committed"/> - </enum> - - <enum name="layer"> - <description summary="available layers for surfaces"> - These values indicate which layers a surface can be rendered in. They - are ordered by z depth, bottom-most first. Traditional shell surfaces - will typically be rendered between the bottom and top layers. - Fullscreen shell surfaces are typically rendered at the top layer. - Multiple surfaces can share a single layer, and ordering within a - single layer is undefined. - </description> - - <entry name="background" value="0"/> - <entry name="bottom" value="1"/> - <entry name="top" value="2"/> - <entry name="overlay" value="3"/> - </enum> - </interface> - - <interface name="zwlr_layer_surface_v1" version="2"> - <description summary="layer metadata interface"> - An interface that may be implemented by a wl_surface, for surfaces that - are designed to be rendered as a layer of a stacked desktop-like - environment. - - Layer surface state (layer, size, anchor, exclusive zone, - margin, interactivity) is double-buffered, and will be applied at the - time wl_surface.commit of the corresponding wl_surface is called. - </description> - - <request name="set_size"> - <description summary="sets the size of the surface"> - Sets the size of the surface in surface-local coordinates. The - compositor will display the surface centered with respect to its - anchors. - - If you pass 0 for either value, the compositor will assign it and - inform you of the assignment in the configure event. You must set your - anchor to opposite edges in the dimensions you omit; not doing so is a - protocol error. Both values are 0 by default. - - Size is double-buffered, see wl_surface.commit. - </description> - <arg name="width" type="uint"/> - <arg name="height" type="uint"/> - </request> - - <request name="set_anchor"> - <description summary="configures the anchor point of the surface"> - Requests that the compositor anchor the surface to the specified edges - and corners. If two orthogonal edges are specified (e.g. 'top' and - 'left'), then the anchor point will be the intersection of the edges - (e.g. the top left corner of the output); otherwise the anchor point - will be centered on that edge, or in the center if none is specified. - - Anchor is double-buffered, see wl_surface.commit. - </description> - <arg name="anchor" type="uint" enum="anchor"/> - </request> - - <request name="set_exclusive_zone"> - <description summary="configures the exclusive geometry of this surface"> - Requests that the compositor avoids occluding an area with other - surfaces. The compositor's use of this information is - implementation-dependent - do not assume that this region will not - actually be occluded. - - A positive value is only meaningful if the surface is anchored to one - edge or an edge and both perpendicular edges. If the surface is not - anchored, anchored to only two perpendicular edges (a corner), anchored - to only two parallel edges or anchored to all edges, a positive value - will be treated the same as zero. - - A positive zone is the distance from the edge in surface-local - coordinates to consider exclusive. - - Surfaces that do not wish to have an exclusive zone may instead specify - how they should interact with surfaces that do. If set to zero, the - surface indicates that it would like to be moved to avoid occluding - surfaces with a positive exclusive zone. If set to -1, the surface - indicates that it would not like to be moved to accommodate for other - surfaces, and the compositor should extend it all the way to the edges - it is anchored to. - - For example, a panel might set its exclusive zone to 10, so that - maximized shell surfaces are not shown on top of it. A notification - might set its exclusive zone to 0, so that it is moved to avoid - occluding the panel, but shell surfaces are shown underneath it. A - wallpaper or lock screen might set their exclusive zone to -1, so that - they stretch below or over the panel. - - The default value is 0. - - Exclusive zone is double-buffered, see wl_surface.commit. - </description> - <arg name="zone" type="int"/> - </request> - - <request name="set_margin"> - <description summary="sets a margin from the anchor point"> - Requests that the surface be placed some distance away from the anchor - point on the output, in surface-local coordinates. Setting this value - for edges you are not anchored to has no effect. - - The exclusive zone includes the margin. - - Margin is double-buffered, see wl_surface.commit. - </description> - <arg name="top" type="int"/> - <arg name="right" type="int"/> - <arg name="bottom" type="int"/> - <arg name="left" type="int"/> - </request> - - <request name="set_keyboard_interactivity"> - <description summary="requests keyboard events"> - Set to 1 to request that the seat send keyboard events to this layer - surface. For layers below the shell surface layer, the seat will use - normal focus semantics. For layers above the shell surface layers, the - seat will always give exclusive keyboard focus to the top-most layer - which has keyboard interactivity set to true. - - Layer surfaces receive pointer, touch, and tablet events normally. If - you do not want to receive them, set the input region on your surface - to an empty region. - - Events is double-buffered, see wl_surface.commit. - </description> - <arg name="keyboard_interactivity" type="uint"/> - </request> - - <request name="get_popup"> - <description summary="assign this layer_surface as an xdg_popup parent"> - This assigns an xdg_popup's parent to this layer_surface. This popup - should have been created via xdg_surface::get_popup with the parent set - to NULL, and this request must be invoked before committing the popup's - initial state. - - See the documentation of xdg_popup for more details about what an - xdg_popup is and how it is used. - </description> - <arg name="popup" type="object" interface="xdg_popup"/> - </request> - - <request name="ack_configure"> - <description summary="ack a configure event"> - When a configure event is received, if a client commits the - surface in response to the configure event, then the client - must make an ack_configure request sometime before the commit - request, passing along the serial of the configure event. - - If the client receives multiple configure events before it - can respond to one, it only has to ack the last configure event. - - A client is not required to commit immediately after sending - an ack_configure request - it may even ack_configure several times - before its next surface commit. - - A client may send multiple ack_configure requests before committing, but - only the last request sent before a commit indicates which configure - event the client really is responding to. - </description> - <arg name="serial" type="uint" summary="the serial from the configure event"/> - </request> - - <request name="destroy" type="destructor"> - <description summary="destroy the layer_surface"> - This request destroys the layer surface. - </description> - </request> - - <event name="configure"> - <description summary="suggest a surface change"> - The configure event asks the client to resize its surface. - - Clients should arrange their surface for the new states, and then send - an ack_configure request with the serial sent in this configure event at - some point before committing the new surface. - - The client is free to dismiss all but the last configure event it - received. - - The width and height arguments specify the size of the window in - surface-local coordinates. - - The size is a hint, in the sense that the client is free to ignore it if - it doesn't resize, pick a smaller size (to satisfy aspect ratio or - resize in steps of NxM pixels). If the client picks a smaller size and - is anchored to two opposite anchors (e.g. 'top' and 'bottom'), the - surface will be centered on this axis. - - If the width or height arguments are zero, it means the client should - decide its own window dimension. - </description> - <arg name="serial" type="uint"/> - <arg name="width" type="uint"/> - <arg name="height" type="uint"/> - </event> - - <event name="closed"> - <description summary="surface should be closed"> - The closed event is sent by the compositor when the surface will no - longer be shown. The output may have been destroyed or the user may - have asked for it to be removed. Further changes to the surface will be - ignored. The client should destroy the resource after receiving this - event, and create a new surface if they so choose. - </description> - </event> - - <enum name="error"> - <entry name="invalid_surface_state" value="0" summary="provided surface state is invalid"/> - <entry name="invalid_size" value="1" summary="size is invalid"/> - <entry name="invalid_anchor" value="2" summary="anchor bitfield is invalid"/> - </enum> - - <enum name="anchor" bitfield="true"> - <entry name="top" value="1" summary="the top edge of the anchor rectangle"/> - <entry name="bottom" value="2" summary="the bottom edge of the anchor rectangle"/> - <entry name="left" value="4" summary="the left edge of the anchor rectangle"/> - <entry name="right" value="8" summary="the right edge of the anchor rectangle"/> - </enum> - - <!-- Version 2 additions --> - - <request name="set_layer" since="2"> - <description summary="change the layer of the surface"> - Change the layer that the surface is rendered on. - - Layer is double-buffered, see wl_surface.commit. - </description> - <arg name="layer" type="uint" enum="layer" summary="layer to move this surface to"/> - </request> - </interface> -</protocol> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wob-0.8/wob.1.scd new/wob-0.8/wob.1.scd --- old/wob-0.8/wob.1.scd 2020-03-01 12:25:07.000000000 +0100 +++ new/wob-0.8/wob.1.scd 1970-01-01 01:00:00.000000000 +0100 @@ -1,109 +0,0 @@ -wob(1) - -# NAME - -wob - Wayland Overlay Bar - -# DESCRIPTION - -wob is a lightweight overlay volume/backlight/progress/anything bar for Wayland. - -# SYNOPSIS - -*wob* [options...] - -# OPTIONS - -*-h* - Show help message and quit. - -*-v* - Show the version number and quit. - -*-t* <ms> - Hide wob after <ms> milliseconds, defaults to 1000. - -*-m* <%> - Define the maximum percentage, defaults to 100. - -*-W* <px> - Define bar width in pixels, defaults to 400. - -*-H* <px> - Define bar height in pixels, defaults to 50. - -*-o* <px> - Define border offset in pixels, defaults to 4. - -*-b* <px> - Define border size in pixels, defaults to 4. - -*-p* <px> - Define bar padding in pixels, defaults to 4. - -*-a* <side> - Define anchor point, one of 'top', 'left', 'right', 'bottom', 'center' (default). - May be specified multiple times. - -*-M* <px> - Define anchor margin in pixels, defaults to 0. - -*-O* <name> - Define output to show bar on or '\*' for all. If ommited, focused output is chosen. - May be specified multiple times. - -# USAGE - -Launch wob in a terminal, enter a value (positive integer), press return. - -## General case - -You may manage a bar for audio volume, backlight intensity, or whatever, using a named pipe. Create a named pipe, e.g. /tmp/wobpipe, on your filesystem using. - -``` -mkfifo /tmp/wobpipe -``` - -Connect the named pipe to the standard input of an wob instance. - -``` -tail -f /tmp/wobpipe | wob -``` - -Set up your environment so that after updating audio volume, backlight intensity, or whatever, to a new value like 43, it writes that value into the pipe: - -``` -echo 43 > /tmp/wobpipe -``` - -Adapt this use-case to your workflow (scripts, callbacks, or keybindings handled by the window manager). - -## Sway WM example - -Add these lines to your Sway config file: - -``` -exec mkfifo $SWAYSOCK.wob && tail -f $SWAYSOCK.wob | wob -``` - -Volume using alsa: - -``` -bindsym XF86AudioRaiseVolume exec amixer -q set Master 2%+ unmute && amixer sget Master | grep 'Right:' | awk -F'[][]' '{ print substr($2, 0, length($2)-1) }' > $SWAYSOCK.wob++ -bindsym XF86AudioLowerVolume exec amixer -q set Master 2%- unmute && amixer sget Master | grep 'Right:' | awk -F'[][]' '{ print substr($2, 0, length($2)-1) }' > $SWAYSOCK.wob++ -bindsym XF86AudioMute exec (amixer get Master | grep off > /dev/null && amixer -q set Master unmute && amixer sget Master | grep 'Right:' | awk -F'[][]' '{ print substr($2, 0, length($2)-1) }' > $SWAYSOCK.wob) || (amixer -q set Master mute && echo 0 > $SWAYSOCK.wob) -``` - -Volume using pulse audio: - -``` -bindsym XF86AudioRaiseVolume exec pamixer -ui 2 && pamixer --get-volume > $SWAYSOCK.wob -bindsym XF86AudioLowerVolume exec pamixer -ud 2 && pamixer --get-volume > $SWAYSOCK.wob -``` - -Brightness using haikarainen/light: - -``` -bindsym XF86MonBrightnessUp exec light -A 5 && light -G | cut -d'.' -f1 > $SWAYSOCK.wob -bindsym XF86MonBrightnessDown exec light -U 5 && light -G | cut -d'.' -f1 > $SWAYSOCK.wob -``` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wob-0.8/wob.c new/wob-0.8/wob.c --- old/wob-0.8/wob.c 2020-03-01 12:25:07.000000000 +0100 +++ new/wob-0.8/wob.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,843 +0,0 @@ -#define DEFAULT_WIDTH 400 -#define DEFAULT_HEIGHT 50 -#define DEFAULT_BORDER_OFFSET 4 -#define DEFAULT_BORDER_SIZE 4 -#define DEFAULT_BAR_PADDING 4 -#define DEFAULT_ANCHOR 0 -#define DEFAULT_MARGIN 0 -#define MIN_PERCENTAGE_BAR_WIDTH 1 -#define MIN_PERCENTAGE_BAR_HEIGHT 1 - -#define BLACK 0xFF000000 -#define WHITE 0xFFFFFFFF - -// sizeof already includes NULL byte -#define INPUT_BUFFER_LENGTH (3 * sizeof(unsigned long) + sizeof(" #FF000000 #FFFFFFFF #FFFFFFFF\n")) - -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) - -#define _POSIX_C_SOURCE 200809L -#include <errno.h> -#include <fcntl.h> // shm -#include <limits.h> -#include <poll.h> -#include <stdbool.h> // true, false -#include <stdio.h> // NULL -#include <stdlib.h> // EXIT_FAILURE -#include <string.h> // strcmp -#include <sys/mman.h> // shm -#include <unistd.h> // shm, ftruncate - -#ifdef WOB_USE_SECCOMP -#include <linux/audit.h> -#include <linux/filter.h> -#include <linux/seccomp.h> -#include <linux/signal.h> -#include <seccomp.h> -#include <sys/ptrace.h> -#endif - -#include "wlr-layer-shell-unstable-v1-client-protocol.h" -#include "xdg-output-unstable-v1-client-protocol.h" - -typedef uint32_t argb_color; - -struct wob_geom { - unsigned long width; - unsigned long height; - unsigned long border_offset; - unsigned long border_size; - unsigned long bar_padding; - unsigned long stride; - unsigned long size; - unsigned long anchor; - unsigned long margin; -}; - -struct wob_colors { - argb_color bar; - argb_color background; - argb_color border; -}; - -struct wob_output_config { - char *name; - struct wl_list link; -}; - -struct wob_surface { - struct zwlr_layer_surface_v1 *wlr_layer_surface; - struct wl_surface *wl_surface; -}; - -struct wob_output { - char *name; - struct wl_list link; - struct wl_output *wl_output; - struct wob *app; - struct wob_surface *wob_surface; - struct zxdg_output_v1 *xdg_output; - uint32_t wl_name; -}; - -struct wob { - int shmid; - struct wl_buffer *wl_buffer; - struct wl_compositor *wl_compositor; - struct wl_display *wl_display; - struct wl_list wob_outputs; - struct wl_list output_configs; - struct wl_registry *wl_registry; - struct wl_shm *wl_shm; - struct wob_geom *wob_geom; - struct zwlr_layer_shell_v1 *wlr_layer_shell; - struct zxdg_output_manager_v1 *xdg_output_manager; - struct wob_surface *fallback_wob_surface; -}; - -void -noop() -{ - /* intentionally left blank */ -} - -void -layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface, uint32_t serial, uint32_t w, uint32_t h) -{ - zwlr_layer_surface_v1_ack_configure(surface, serial); -} - -void -xdg_output_handle_name(void *data, struct zxdg_output_v1 *xdg_output, const char *name) -{ - struct wob_output *output = (struct wob_output *) data; - output->name = strdup(name); - if (output->name == NULL) { - fprintf(stderr, "strdup failed\n"); - exit(EXIT_FAILURE); - } -} - -struct wob_surface * -wob_surface_create(struct wob *app, struct wl_output *wl_output) -{ - const static struct zwlr_layer_surface_v1_listener zwlr_layer_surface_listener = { - .configure = layer_surface_configure, - .closed = noop, - }; - - struct wob_surface *wob_surface = calloc(1, sizeof(struct wob_surface)); - if (wob_surface == NULL) { - fprintf(stderr, "calloc failed\n"); - exit(EXIT_FAILURE); - } - - wob_surface->wl_surface = wl_compositor_create_surface(app->wl_compositor); - if (wob_surface->wl_surface == NULL) { - fprintf(stderr, "wl_compositor_create_surface failed\n"); - exit(EXIT_FAILURE); - } - wob_surface->wlr_layer_surface = zwlr_layer_shell_v1_get_layer_surface(app->wlr_layer_shell, wob_surface->wl_surface, wl_output, ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY, "wob"); - if (wob_surface->wlr_layer_surface == NULL) { - fprintf(stderr, "wlr_layer_shell_v1_get_layer_surface failed\n"); - exit(EXIT_FAILURE); - } - zwlr_layer_surface_v1_set_size(wob_surface->wlr_layer_surface, app->wob_geom->width, app->wob_geom->height); - zwlr_layer_surface_v1_set_anchor(wob_surface->wlr_layer_surface, app->wob_geom->anchor); - zwlr_layer_surface_v1_set_margin(wob_surface->wlr_layer_surface, app->wob_geom->margin, app->wob_geom->margin, app->wob_geom->margin, app->wob_geom->margin); - zwlr_layer_surface_v1_add_listener(wob_surface->wlr_layer_surface, &zwlr_layer_surface_listener, app); - wl_surface_commit(wob_surface->wl_surface); - - return wob_surface; -} - -void -wob_surface_destroy(struct wob_surface *wob_surface) -{ - if (wob_surface == NULL) { - return; - } - - zwlr_layer_surface_v1_destroy(wob_surface->wlr_layer_surface); - wl_surface_destroy(wob_surface->wl_surface); - - wob_surface->wl_surface = NULL; - wob_surface->wlr_layer_surface = NULL; -} - -void -wob_output_destroy(struct wob_output *output) -{ - wob_surface_destroy(output->wob_surface); - zxdg_output_v1_destroy(output->xdg_output); - wl_output_destroy(output->wl_output); - - free(output->name); - free(output->wob_surface); - - output->wob_surface = NULL; - output->wl_output = NULL; - output->xdg_output = NULL; - output->name = NULL; -} - -void -xdg_output_handle_done(void *data, struct zxdg_output_v1 *xdg_output) -{ - struct wob_output *output = (struct wob_output *) data; - struct wob *app = output->app; - - struct wob_output_config *output_config, *tmp; - wl_list_for_each_safe (output_config, tmp, &app->output_configs, link) { - if (strcmp(output->name, output_config->name) == 0 || strcmp("*", output_config->name) == 0) { - wl_list_insert(&output->app->wob_outputs, &output->link); - return; - } - } - - wob_output_destroy(output); - free(output); -} - -void -handle_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) -{ - const static struct zxdg_output_v1_listener xdg_output_listener = { - .logical_position = noop, - .logical_size = noop, - .name = xdg_output_handle_name, - .description = noop, - .done = xdg_output_handle_done, - }; - - struct wob *app = (struct wob *) data; - - if (strcmp(interface, wl_shm_interface.name) == 0) { - app->wl_shm = wl_registry_bind(registry, name, &wl_shm_interface, 1); - } - else if (strcmp(interface, wl_compositor_interface.name) == 0) { - app->wl_compositor = wl_registry_bind(registry, name, &wl_compositor_interface, 1); - } - else if (strcmp(interface, "wl_output") == 0) { - if (!wl_list_empty(&(app->output_configs))) { - struct wob_output *output = calloc(1, sizeof(struct wob_output)); - output->wl_output = wl_registry_bind(registry, name, &wl_output_interface, 1); - output->app = app; - output->wl_name = name; - - output->xdg_output = zxdg_output_manager_v1_get_xdg_output(app->xdg_output_manager, output->wl_output); - zxdg_output_v1_add_listener(output->xdg_output, &xdg_output_listener, output); - - if (wl_display_roundtrip(app->wl_display) == -1) { - fprintf(stderr, "wl_display_roundtrip failed\n"); - exit(EXIT_FAILURE); - } - } - } - else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) { - app->wlr_layer_shell = wl_registry_bind(registry, name, &zwlr_layer_shell_v1_interface, 1); - } - else if (strcmp(interface, zxdg_output_manager_v1_interface.name) == 0) { - app->xdg_output_manager = wl_registry_bind(registry, name, &zxdg_output_manager_v1_interface, 2); - } -} - -void -handle_global_remove(void *data, struct wl_registry *registry, uint32_t name) -{ - struct wob *app = (struct wob *) data; - struct wob_output *output, *tmp; - wl_list_for_each_safe (output, tmp, &(app->wob_outputs), link) { - if (output->wl_name == name) { - wob_output_destroy(output); - break; - } - } -} - -argb_color * -wob_create_argb_buffer(struct wob *app) -{ - int shmid = -1; - char shm_name[NAME_MAX]; - for (unsigned char i = 0; i < UCHAR_MAX; ++i) { - if (snprintf(shm_name, NAME_MAX, "/wob-%hhu", i) >= NAME_MAX) { - break; - } - shmid = shm_open(shm_name, O_RDWR | O_CREAT | O_EXCL, 0600); - if (shmid > 0 || errno != EEXIST) { - break; - } - } - - if (shmid < 0) { - perror("shm_open"); - exit(EXIT_FAILURE); - } - - if (shm_unlink(shm_name) != 0) { - perror("shm_unlink"); - exit(EXIT_FAILURE); - } - - if (ftruncate(shmid, app->wob_geom->size) != 0) { - perror("ftruncate"); - exit(EXIT_FAILURE); - } - - void *shm_data = mmap(NULL, app->wob_geom->size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0); - if (shm_data == MAP_FAILED) { - perror("mmap"); - exit(EXIT_FAILURE); - } - - app->shmid = shmid; - - return (argb_color *) shm_data; -} - -void -wob_flush(struct wob *app) -{ - - if (wl_list_empty(&(app->wob_outputs))) { - wl_surface_attach(app->fallback_wob_surface->wl_surface, app->wl_buffer, 0, 0); - wl_surface_damage(app->fallback_wob_surface->wl_surface, 0, 0, app->wob_geom->width, app->wob_geom->height); - wl_surface_commit(app->fallback_wob_surface->wl_surface); - } - else { - struct wob_output *output, *tmp; - wl_list_for_each_safe (output, tmp, &(app->wob_outputs), link) { - wl_surface_attach(output->wob_surface->wl_surface, app->wl_buffer, 0, 0); - wl_surface_damage(output->wob_surface->wl_surface, 0, 0, app->wob_geom->width, app->wob_geom->height); - wl_surface_commit(output->wob_surface->wl_surface); - } - } - - if (wl_display_dispatch(app->wl_display) == -1) { - fprintf(stderr, "wl_display_dispatch failed\n"); - exit(EXIT_FAILURE); - } -} - -void -wob_hide(struct wob *app) -{ - if (wl_list_empty(&(app->wob_outputs))) { - wob_surface_destroy(app->fallback_wob_surface); - free(app->fallback_wob_surface); - app->fallback_wob_surface = NULL; - } - else { - struct wob_output *output, *tmp; - wl_list_for_each_safe (output, tmp, &app->wob_outputs, link) { - wob_surface_destroy(output->wob_surface); - free(output->wob_surface); - output->wob_surface = NULL; - } - } - - if (wl_display_roundtrip(app->wl_display) == -1) { - fprintf(stderr, "wl_display_roundtrip failed\n"); - exit(EXIT_FAILURE); - } -} - -void -wob_show(struct wob *app) -{ - if (wl_list_empty(&(app->wob_outputs))) { - app->fallback_wob_surface = wob_surface_create(app, NULL); - } - else { - struct wob_output *output, *tmp; - wl_list_for_each_safe (output, tmp, &app->wob_outputs, link) { - output->wob_surface = wob_surface_create(app, output->wl_output); - } - } - - if (wl_display_roundtrip(app->wl_display) == -1) { - fprintf(stderr, "wl_display_roundtrip failed\n"); - exit(EXIT_FAILURE); - } -} - -void -wob_destroy(struct wob *app) -{ - struct wob_output *output, *output_tmp; - wl_list_for_each_safe (output, output_tmp, &app->wob_outputs, link) { - wob_output_destroy(output); - free(output); - } - - struct wob_output_config *config, *config_tmp; - wl_list_for_each_safe (config, config_tmp, &app->output_configs, link) { - free(config->name); - free(config); - } - - zwlr_layer_shell_v1_destroy(app->wlr_layer_shell); - wl_registry_destroy(app->wl_registry); - wl_buffer_destroy(app->wl_buffer); - wl_compositor_destroy(app->wl_compositor); - wl_shm_destroy(app->wl_shm); - zxdg_output_manager_v1_destroy(app->xdg_output_manager); - - wl_display_disconnect(app->wl_display); -} - -void -wob_connect(struct wob *app) -{ - const static struct wl_registry_listener wl_registry_listener = { - .global = handle_global, - .global_remove = noop, - }; - - app->wl_display = wl_display_connect(NULL); - if (app->wl_display == NULL) { - fprintf(stderr, "wl_display_connect failed\n"); - exit(EXIT_FAILURE); - } - - app->wl_registry = wl_display_get_registry(app->wl_display); - if (app->wl_registry == NULL) { - fprintf(stderr, "wl_display_get_registry failed\n"); - exit(EXIT_FAILURE); - } - - wl_registry_add_listener(app->wl_registry, &wl_registry_listener, app); - - wl_list_init(&app->wob_outputs); - if (wl_display_roundtrip(app->wl_display) == -1) { - fprintf(stderr, "wl_display_roundtrip failed\n"); - exit(EXIT_FAILURE); - } - - struct wl_shm_pool *pool = wl_shm_create_pool(app->wl_shm, app->shmid, app->wob_geom->size); - if (pool == NULL) { - fprintf(stderr, "wl_shm_create_pool failed\n"); - exit(EXIT_FAILURE); - } - - app->wl_buffer = wl_shm_pool_create_buffer(pool, 0, app->wob_geom->width, app->wob_geom->height, app->wob_geom->stride, WL_SHM_FORMAT_ARGB8888); - wl_shm_pool_destroy(pool); - if (app->wl_buffer == NULL) { - fprintf(stderr, "wl_shm_pool_create_buffer failed\n"); - exit(EXIT_FAILURE); - } -} - -/* -Input format: -percentage bgColor borderColor barColor -25 #FF000000 #FFFFFFFF #FFFFFFFF -*/ -bool -wob_parse_input(const char *input_buffer, unsigned long *percentage, struct wob_colors *colors) -{ - char *input_ptr, *newline_position; - - newline_position = strchr(input_buffer, '\n'); - if (newline_position == NULL) { - return false; - } - - if (newline_position == input_buffer) { - return false; - } - - *percentage = strtoul(input_buffer, &input_ptr, 10); - if (input_ptr == newline_position) { - return true; - } - - if (input_ptr + 10 > newline_position || input_ptr[0] != ' ' || input_ptr[1] != '#') { - return false; - } - input_ptr += 2; - colors->background = strtoul(input_ptr, &input_ptr, 16); - - if (input_ptr + 10 > newline_position || input_ptr[0] != ' ' || input_ptr[1] != '#') { - return false; - } - input_ptr += 2; - colors->border = strtoul(input_ptr, &input_ptr, 16); - - if (input_ptr + 10 > newline_position || input_ptr[0] != ' ' || input_ptr[1] != '#') { - return false; - } - input_ptr += 2; - colors->bar = strtoul(input_ptr, &input_ptr, 16); - - if (*input_ptr != '\n') { - return false; - } - - return true; -} - -void -wob_draw_background(const struct wob_geom *geom, argb_color *argb, argb_color color) -{ - for (size_t i = 0; i < geom->width * geom->height; ++i) { - argb[i] = color; - } -} - -void -wob_draw_border(const struct wob_geom *geom, argb_color *argb, argb_color color) -{ - // create top and bottom line - size_t i = geom->width * geom->border_offset; - size_t k = geom->width * (geom->height - geom->border_offset - geom->border_size); - for (size_t line = 0; line < geom->border_size; ++line) { - i += geom->border_offset; - k += geom->border_offset; - for (size_t pixel = 0; pixel < geom->width - 2 * geom->border_offset; ++pixel) { - argb[i++] = color; - argb[k++] = color; - } - i += geom->border_offset; - k += geom->border_offset; - } - - // create left and right horizontal line - i = geom->width * (geom->border_offset + geom->border_size); - k = geom->width * (geom->border_offset + geom->border_size); - for (size_t line = 0; line < geom->height - 2 * (geom->border_size + geom->border_offset); ++line) { - i += geom->border_offset; - k += geom->width - geom->border_offset - geom->border_size; - for (size_t pixel = 0; pixel < geom->border_size; ++pixel) { - argb[i++] = color; - argb[k++] = color; - } - i += geom->width - geom->border_offset - geom->border_size; - k += geom->border_offset; - } -} - -void -wob_draw_percentage(const struct wob_geom *geom, argb_color *argb, argb_color bar_color, argb_color background_color, unsigned long percentage, unsigned long maximum) -{ - size_t offset_border_padding = geom->border_offset + geom->border_size + geom->bar_padding; - size_t bar_width = geom->width - 2 * offset_border_padding; - size_t bar_height = geom->height - 2 * offset_border_padding; - size_t bar_colored_width = (bar_width * percentage) / maximum; - - // draw 1px horizontal line - argb_color *start, *end, *pixel; - start = &argb[offset_border_padding * (geom->width + 1)]; - end = start + bar_colored_width; - for (pixel = start; pixel < end; ++pixel) { - *pixel = bar_color; - } - for (end = start + bar_width; pixel < end; ++pixel) { - *pixel = background_color; - } - - // copy it to make full percentage bar - argb_color *source = &argb[offset_border_padding * geom->width]; - argb_color *destination = source + geom->width; - end = &argb[geom->width * (bar_height + offset_border_padding)]; - while (destination != end) { - memcpy(destination, source, MIN(destination - source, end - destination) * sizeof(argb_color)); - destination += MIN(destination - source, end - destination); - } -} - -void -wob_pledge(void) -{ -#ifdef WOB_USE_SECCOMP - const int scmp_sc[] = { - SCMP_SYS(close), - SCMP_SYS(exit), - SCMP_SYS(exit_group), - SCMP_SYS(fcntl), - SCMP_SYS(fstat), - SCMP_SYS(poll), - SCMP_SYS(read), - SCMP_SYS(readv), - SCMP_SYS(recvmsg), - SCMP_SYS(restart_syscall), - SCMP_SYS(sendmsg), - SCMP_SYS(write), - SCMP_SYS(writev), - }; - - int ret; - scmp_filter_ctx scmp_ctx = seccomp_init(SCMP_ACT_KILL); - if (scmp_ctx == NULL) { - fprintf(stderr, "seccomp_init(SCMP_ACT_KILL) failed\n"); - exit(EXIT_FAILURE); - } - - for (size_t i = 0; i < sizeof(scmp_sc) / sizeof(int); ++i) { - if ((ret = seccomp_rule_add(scmp_ctx, SCMP_ACT_ALLOW, scmp_sc[i], 0)) < 0) { - fprintf(stderr, "seccomp_rule_add(scmp_ctxm, SCMP_ACT_ALLOW, %d) failed with return value %d\n", scmp_sc[i], ret); - seccomp_release(scmp_ctx); - exit(EXIT_FAILURE); - } - } - - if ((ret = seccomp_load(scmp_ctx)) < 0) { - fprintf(stderr, "seccomp_load(scmp_ctx) failed with return value %d\n", ret); - seccomp_release(scmp_ctx); - exit(EXIT_FAILURE); - } - - seccomp_release(scmp_ctx); -#endif -} - -#ifndef WOB_TEST -int -main(int argc, char **argv) -{ - const char *usage = - "Usage: wob [options]\n" - "\n" - " -h Show help message and quit.\n" - " -v Show the version number and quit.\n" - " -t <ms> Hide wob after <ms> milliseconds, defaults to 1000.\n" - " -m <%> Define the maximum percentage, defaults to 100. \n" - " -W <px> Define display width in pixels, defaults to 400. \n" - " -H <px> Define display height in pixels, defaults to 50. \n" - " -o <px> Define border offset in pixels, defaults to 4. \n" - " -b <px> Define border size in pixels, defaults to 4. \n" - " -p <px> Define bar padding in pixels, defaults to 4. \n" - " -a <s> Define anchor point; one of 'top', 'left', 'right', 'bottom', 'center' (default). \n" - " May be specified multiple times. \n" - " -M <px> Define anchor margin in pixels, defaults to 0. \n" - " -O <name> Define output to show bar on or '*' for all. If ommited, focused output is chosen.\n" - " May be specified multiple times.\n" - "\n"; - - struct wob app = {0}; - wl_list_init(&(app.output_configs)); - - // Parse arguments - int c; - unsigned long maximum = 100; - unsigned long timeout_msec = 1000; - struct wob_geom geom = { - .width = DEFAULT_WIDTH, - .height = DEFAULT_HEIGHT, - .border_offset = DEFAULT_BORDER_OFFSET, - .border_size = DEFAULT_BORDER_SIZE, - .bar_padding = DEFAULT_BAR_PADDING, - .anchor = DEFAULT_ANCHOR, - .margin = DEFAULT_MARGIN, - }; - char *strtoul_end; - struct wob_output_config *output_config; - - while ((c = getopt(argc, argv, "t:m:W:H:o:b:p:a:M:O:vh")) != -1) { - switch (c) { - case 't': - timeout_msec = strtoul(optarg, &strtoul_end, 10); - if (*strtoul_end != '\0' || errno == ERANGE || timeout_msec == 0) { - fprintf(stderr, "Timeout must be a value between 1 and %lu.\n", ULONG_MAX); - return EXIT_FAILURE; - } - break; - case 'm': - maximum = strtoul(optarg, &strtoul_end, 10); - if (*strtoul_end != '\0' || errno == ERANGE || maximum == 0) { - fprintf(stderr, "Maximum must be a value between 1 and %lu.\n", ULONG_MAX); - return EXIT_FAILURE; - } - break; - case 'W': - geom.width = strtoul(optarg, &strtoul_end, 10); - if (*strtoul_end != '\0' || errno == ERANGE) { - fprintf(stderr, "Width must be a positive value."); - return EXIT_FAILURE; - } - break; - case 'H': - geom.height = strtoul(optarg, &strtoul_end, 10); - if (*strtoul_end != '\0' || errno == ERANGE) { - fprintf(stderr, "Height must be a positive value."); - return EXIT_FAILURE; - } - break; - case 'o': - geom.border_offset = strtoul(optarg, &strtoul_end, 10); - if (*strtoul_end != '\0' || errno == ERANGE) { - fprintf(stderr, "Border offset must be a positive value."); - return EXIT_FAILURE; - } - break; - case 'b': - geom.border_size = strtoul(optarg, &strtoul_end, 10); - if (*strtoul_end != '\0' || errno == ERANGE) { - fprintf(stderr, "Border size must be a positive value."); - return EXIT_FAILURE; - } - break; - case 'p': - geom.bar_padding = strtoul(optarg, &strtoul_end, 10); - if (*strtoul_end != '\0' || errno == ERANGE) { - fprintf(stderr, "Bar padding must be a positive value."); - return EXIT_FAILURE; - } - break; - case 'a': - if (strcmp(optarg, "left") == 0) { - geom.anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT; - } - else if (strcmp(optarg, "right") == 0) { - geom.anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; - } - else if (strcmp(optarg, "top") == 0) { - geom.anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP; - } - else if (strcmp(optarg, "bottom") == 0) { - geom.anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM; - } - else if (strcmp(optarg, "center") != 0) { - fprintf(stderr, "Anchor must be one of 'top', 'bottom', 'left', 'right', 'center'."); - return EXIT_FAILURE; - } - break; - case 'M': - geom.margin = strtoul(optarg, &strtoul_end, 10); - if (*strtoul_end != '\0' || errno == ERANGE) { - fprintf(stderr, "Anchor margin must be a positive value."); - return EXIT_FAILURE; - } - break; - case 'O': - output_config = calloc(1, sizeof(struct wob_output_config)); - if (output_config == NULL) { - fprintf(stderr, "calloc failed\n"); - return EXIT_FAILURE; - } - - output_config->name = strdup(optarg); - if (output_config->name == NULL) { - fprintf(stderr, "strdup failed\n"); - return EXIT_FAILURE; - } - - wl_list_insert(&(app.output_configs), &(output_config->link)); - break; - case 'v': - fprintf(stdout, "wob version: " WOB_VERSION "\n"); - return EXIT_SUCCESS; - case 'h': - fprintf(stdout, "%s", usage); - return EXIT_SUCCESS; - default: - fprintf(stderr, "%s", usage); - return EXIT_FAILURE; - } - } - - if (geom.width < MIN_PERCENTAGE_BAR_WIDTH + 2 * (geom.border_offset + geom.border_size + geom.bar_padding)) { - fprintf(stderr, "Invalid geometry: width is too small for given parameters\n"); - return EXIT_FAILURE; - } - - if (geom.height < MIN_PERCENTAGE_BAR_HEIGHT + 2 * (geom.border_offset + geom.border_size + geom.bar_padding)) { - fprintf(stderr, "Invalid geometry: height is too small for given parameters\n"); - return EXIT_FAILURE; - } - - geom.stride = geom.width * 4; - geom.size = geom.stride * geom.height; - app.wob_geom = &geom; - - argb_color *argb = wob_create_argb_buffer(&app); - - wob_connect(&app); - - wob_pledge(); - - struct wob_colors colors = { - .background = BLACK, - .bar = WHITE, - .border = WHITE, - }; - - struct wob_colors old_colors = {0}; - - // Draw these at least once - wob_draw_background(app.wob_geom, argb, colors.background); - wob_draw_border(app.wob_geom, argb, colors.border); - - struct pollfd fds[2] = { - { - .fd = wl_display_get_fd(app.wl_display), - .events = POLLIN, - }, - { - .fd = STDIN_FILENO, - .events = POLLIN, - }, - }; - - bool hidden = true; - for (;;) { - unsigned long percentage = 0; - char input_buffer[INPUT_BUFFER_LENGTH] = {0}; - char *fgets_rv; - - switch (poll(fds, 2, hidden ? -1 : timeout_msec)) { - case -1: - perror("poll"); - wob_destroy(&app); - return EXIT_FAILURE; - case 0: - if (!hidden) { - wob_hide(&app); - } - - hidden = true; - break; - default: - if (fds[0].revents & POLLIN) { - if (wl_display_dispatch(app.wl_display) == -1) { - wob_destroy(&app); - return EXIT_FAILURE; - } - } - - if (!(fds[1].revents & POLLIN)) { - break; - } - - fgets_rv = fgets(input_buffer, INPUT_BUFFER_LENGTH, stdin); - if (feof(stdin)) { - wob_destroy(&app); - return EXIT_SUCCESS; - } - - old_colors = colors; - if (fgets_rv == NULL || !wob_parse_input(input_buffer, &percentage, &colors) || percentage > maximum) { - fprintf(stderr, "Received invalid input\n"); - wob_destroy(&app); - return EXIT_FAILURE; - } - - if (hidden) { - wob_show(&app); - } - - if (old_colors.background != colors.background || old_colors.border != colors.border) { - wob_draw_background(app.wob_geom, argb, colors.background); - wob_draw_border(app.wob_geom, argb, colors.border); - } - wob_draw_percentage(app.wob_geom, argb, colors.bar, colors.background, percentage, maximum); - - wob_flush(&app); - hidden = false; - - break; - } - } -} -#endif