~charles/dotfiles

c54ce808324f12a01428667c132ca00ae6dd3dee — Charles Daniels 3 years ago 8a29de4
depricate nowall
9 files changed, 7 insertions(+), 562 deletions(-)

M install.sh
D nowall/Makefile
D nowall/nowall.c
D nowall/nowall.h
M overlay/.config/i3/config
M overlay/.xprofile
D overlay/bin/desktop-spooler
M overlay/bin/restore-sanity
A overlay/bin/screenlock
M install.sh => install.sh +0 -8
@@ 79,14 79,6 @@ echo "    email = $git_email" >> "$git_config_file"
echo "" >> "$git_config_file"
cat "$DOTFILES_DIR/gitconfig" >> "$git_config_file"

# setup nowall
cd "$DOTFILES_DIR/nowall"
make
set +e
pkill nowall
set -e
cp ./nowall ~/bin/nowall

# install GTK3 theme
if [ ! -d "$HOME/.themes/clearlooks-phenix-master" ] ; then
	mkdir -p "$HOME/.themes"

D nowall/Makefile => nowall/Makefile +0 -9
@@ 1,9 0,0 @@
CFLAGS=-Wall -Wextra -pedantic -std=c89 -Og -g -lm

.PHONY: clean

nowall: nowall.c nowall.h
	$(CC) $< $(CFLAGS) $$(pkg-config --cflags --libs x11) -o $@

clean:
	rm -rf nowall *.gch *.o

D nowall/nowall.c => nowall/nowall.c +0 -323
@@ 1,323 0,0 @@
#include "nowall.h"

/**
 * @brief Get the current time and run it through strftime with fmt as the
 * format string.
 *
 * https://www.tutorialspoint.com/c_standard_library/c_function_strftime.htm
 *
 * @param fmt
 *
 * @return
 */
char* get_time(char* fmt) {
	time_t rawtime;
	struct tm *info;
	char* buffer;

	buffer = (char*) malloc(NOWALL_TIMESTAMP_MAXLEN * sizeof(char));

	/* get the current time */
	time(&rawtime);
	info = localtime(&rawtime);

	strftime(buffer, NOWALL_TIMESTAMP_MAXLEN, fmt, info);

	return buffer;
}

/**
 * @brief Get current memory usage as a percentage (0 .. 1.0)
 *
 * @return
 */
double get_memory_usage() {
	/* sysconf(_SC_PAGE_SIZE); */
	return 1.0f - (1.0f * sysconf(_SC_AVPHYS_PAGES)) / (1.0f * sysconf(_SC_PHYS_PAGES));
}

/**
 * @brief Generate the message string
 *
 * @return
 */
char* generate_message() {
	char* msg;
	double load_avg[3];
	double memory_usage;
	char* timestamp;

	msg = (char*) malloc(sizeof(char) * NOWALL_MESSAGE_MAXLEN);

	/* get load average */
	getloadavg(load_avg, 3);

	/* get memory usage */
	memory_usage = get_memory_usage() * 100.0f;

	timestamp = get_time("%m-%d");

	snprintf(
			msg,
			NOWALL_MESSAGE_MAXLEN,
			"%0.2f / %0.0f%% / %s",
			load_avg[0],
			memory_usage,
			timestamp
	);

	free(timestamp);

	return msg;

}

/**
 * @brief calculate the current score for the history vector
 *
 * @return
 */
float calculate_score() {
	double load_avg[3];
	double memory_usage;

	/* get load average */
	getloadavg(load_avg, 3);

	/* get memory usage */
	memory_usage = get_memory_usage();

	/* we normalize the load average by the number of CPU cores which
	 * are online at this moment */
	return 0.5 * memory_usage + \
		0.5 * load_avg[0] / sysconf(_SC_NPROCESSORS_ONLN);
}

void draw_frame(Display* disp, int screen_num, float* history,
		XColor bg_color, XColor fg_color, XColor text_color) {

	Window root;
	Screen* screen;
	Colormap cmap;
	Pixmap pmap;
	Atom prop;
	GC gc;
	unsigned int depth;
	char* msg;
	int history_index = 0;
	double x_base, y_base, x_centered, y_centered, horizontal_pos;
	double horizontal_offset, bar_height, msg_x;
	Cursor cursor;
	struct tm *info;
	time_t rawtime;
	double clock_center_x, clock_center_y;
	double minute_hand_x, minute_hand_y, hour_hand_x, hour_hand_y;

	/* gather information about the display and screen to manipulate */
	root   = RootWindow(disp, screen_num);		/* root window      */
	screen = ScreenOfDisplay(disp, screen_num);	/* screen "object"  */
	cmap   = DefaultColormap(disp, screen_num);	/* screen color map */
	depth  = DefaultDepth(disp, screen_num);	/* screen depth     */

	/* allocate provided color values or die */
	SAFE_ALLOC_COLOR(disp, cmap, &fg_color);
	SAFE_ALLOC_COLOR(disp, cmap, &bg_color);
	SAFE_ALLOC_COLOR(disp, cmap, &text_color);

	/* create the pixmap - this serves as the intermediary between our GC
	 * and the root window */
	pmap = XCreatePixmap(
			disp,			/* display */
			root,			/* drawable */
			screen->width,		/* width */
			screen->height,		/* height */
			depth			/* depth */
	);

	/* create the graphics context for us to draw into */
	gc = XCreateGC(disp, pmap, 0, NULL);

	/* fill in the background */
	XSetForeground(disp, gc, bg_color.pixel);
	XFillRectangle(
			disp,		/* display */
			pmap,		/* drawable */
			gc,		/* graphics context */
			0,		/* x position */
			0,		/* y position */
			screen->width,	/* width */
			screen->height	/* height */
	);

	/* draw the text */
	XSetForeground(disp, gc, text_color.pixel);
	msg = generate_message();
	msg_x = screen->width / 2 - (strlen(msg) * NOWALL_HORIZ_PIX_PER_CHAR / 2);
	XDrawString(
			disp,			/* display */
			pmap,			/* drawable */
			gc,			/* graphics context */
			msg_x,			/* x position */
			screen->height / 1.75,	/* y position */
			msg,			/* string */
			strlen(msg)		/* string length */
	);
	free(msg);

	/* draw the history visualization */
	XSetForeground(disp, gc, fg_color.pixel);
	for (history_index = 0;
		history_index < NOWALL_HISTORY_LEN;
		history_index ++) {

		/* note that x, y identifies the upper left of the rectangle */

		horizontal_pos = history_index - (NOWALL_HISTORY_LEN / 2);
		horizontal_offset = \
			horizontal_pos * (NOWALL_HISTORY_BAR_WIDTH + \
					NOWALL_HISTORY_BAR_SEP);
		x_base = screen->width / 2 + horizontal_offset;
		y_base = screen->height / 2.0 ;
		bar_height = screen->height * 0.1 * history[history_index];
		x_centered = x_base + NOWALL_HISTORY_BAR_WIDTH / 2;
		y_centered = y_base - bar_height / 2;


		XFillRectangle(
				disp,		/* display */
				pmap,		/* drawable */
				gc,		/* graphics context */
				x_centered,	/* x position */
				y_centered,	/* y position */
				NOWALL_HISTORY_BAR_WIDTH,	/* width */
				bar_height	/* height */
		);
	}

	/* draw the clock */

	/* get the current time */
	time(&rawtime);
	info = localtime(&rawtime);

	/* clock center */
	clock_center_x = screen->width / 2.0f;
	clock_center_y = screen->height / 3.5f;

	/* hour hand */
	hour_hand_x = clock_center_x + HOUR_HAND_LENGTH * sin( \
			((12 - (info->tm_hour % 12)) / 12.0f) * 2 * 3.14159 - 3.14159 );
	hour_hand_y = clock_center_y + HOUR_HAND_LENGTH * cos( \
			((12 - (info->tm_hour % 12)) / 12.0f) * 2 * 3.14159 - 3.14159 );
	XDrawLine(
			disp,		/* display */
			pmap,		/* drawable */
			gc,		/* graphics context */
			clock_center_x,	/* x1 */
			clock_center_y, /* y1 */
			hour_hand_x,	/* x2 */
			hour_hand_y	/* y2 */
	);

	/* minute hand */
	minute_hand_x = clock_center_x + MINUTE_HAND_LENGTH * sin(
			((60 - info->tm_min) / 60.0f) * 2 * 3.14159 - 3.14159 );
	minute_hand_y = clock_center_y + MINUTE_HAND_LENGTH * cos(
			((60 - info->tm_min) / 60.0f) * 2 * 3.14159 - 3.14159 );
	XDrawLine(
			disp,		/* display */
			pmap,		/* drawable */
			gc,		/* graphics context */
			clock_center_x,	/* x1 */
			clock_center_y, /* y1 */
			minute_hand_x,	/* x2 */
			minute_hand_y	/* y2 */
	);


	/* setup the cursor settings */
	cursor = XCreateFontCursor(disp, XC_top_left_arrow);
	XDefineCursor(disp, root, cursor);

	/* set the root window background to what we just drew */
	XSetWindowBackgroundPixmap(disp, root, pmap);

	/* do the right magic to keep what we draw persistent even after
	 * we exit */
	prop = XInternAtom(disp, "_XROOTPMAP_ID", False);
	XChangeProperty(
			disp,				/* display    */
			root,				/* window     */
			prop,				/* properties */
			XA_PIXMAP,			/* type       */
			32,				/* format     */
			PropModeReplace,		/* mode       */
			(unsigned char *) &pmap,	/* data       */
			1				/* nelements  */
	);

	/* tidy up */
	XFreeGC(disp, gc);
	XClearWindow(disp, root);
	XSetCloseDownMode(disp, RetainPermanent);


}

int main(void) {
	Display *dpy;
	int screen;
	XColor bg_color;
	XColor fg_color;
	XColor text_color;
	float history[NOWALL_HISTORY_LEN];
	int history_index;

	/* detect xorg information */
	dpy = XOpenDisplay(NULL);
	if (!dpy) {
		fprintf(stderr, "failed to open display!\n");
		exit (2);
	}
	screen = DefaultScreen(dpy);

	/* setup colors */
	bg_color.red   = 0 << 8;
	bg_color.blue  = 0 << 8;
	bg_color.green = 0 << 8;

	text_color.red   = 128 << 8;
	text_color.blue  = 128 << 8;
	text_color.green = 128 << 8;

	fg_color.red   = 128 << 8;
	fg_color.blue  = 128 << 8;
	fg_color.green = 128 << 8;

	/* initialize the history vector */
	for (history_index = 0 ;
		history_index < NOWALL_HISTORY_LEN;
		history_index ++) {
		history[history_index] = 0;
	}

	while (1) {
		/* update history vector */
		history[NOWALL_HISTORY_LEN-1] = calculate_score();
		for (history_index = 0 ;
			history_index < (NOWALL_HISTORY_LEN - 1);
			history_index ++) {
			history[history_index] = history[history_index + 1];
		}

		/* update rendering */
		draw_frame(dpy, screen, history,
			bg_color, fg_color, text_color);

		sleep(NOWALL_INTERVAL);
	}

	XCloseDisplay(dpy);

	return 0;
}

D nowall/nowall.h => nowall/nowall.h +0 -42
@@ 1,42 0,0 @@
#ifndef NOWALL_H
#define NOWALL_H

/* #define _POSIX_C_SOURCE 200112L */
#define _DEFAULT_SOURCE 1

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/cursorfont.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <math.h>

#define SAFE_ALLOC_COLOR(disp, cmap, color) \
	if (XAllocColor(disp, cmap, color) == 0) { \
		fprintf(stderr, "FATAL: failed to allocate color\n"); \
		exit(1); \
	}

#define NOWALL_TIMESTAMP_MAXLEN 128
#define NOWALL_MESSAGE_MAXLEN 512
#define NOWALL_HISTORY_LEN 25
#define NOWALL_HISTORY_BAR_WIDTH 1
#define NOWALL_HISTORY_BAR_SEP 18
#define NOWALL_HORIZ_PIX_PER_CHAR 6
#define NOWALL_INTERVAL 20
#define HOUR_HAND_LENGTH 75.0f
#define MINUTE_HAND_LENGTH 125.0f

char* get_time(char* fmt);
double get_memory_usage();
char* generate_message();
float calculate_score();
void draw_frame(Display* disp, int screen_num, float* history,
		XColor bg_color, XColor fg_color, XColor text_color);
int main(void);

#endif

M overlay/.config/i3/config => overlay/.config/i3/config +0 -2
@@ 190,10 190,8 @@ exec "nm-applet"
exec "dropbox start"
exec "pulseaudio --start"
exec "~/bin/system-launch-compositor"
exec "~/bin/desktop-spooler"
exec "~/bin/restore-sanity"
exec "blueman-applet"
exec "while true ; do ~/bin/setwallpaper ; sleep 1m ; done"

# fix broken rendering in some Java programs
exec wmname LG3D

M overlay/.xprofile => overlay/.xprofile +3 -0
@@ 1,1 1,4 @@
export XDG_CURRENT_DESKTOP=GNOME
xinput set-prop /dev/wsmouse "WS Pointer Wheel Emulation" 1
xinput set-prop /dev/wsmouse "WS Pointer Wheel Emulation Button" 2


D overlay/bin/desktop-spooler => overlay/bin/desktop-spooler +0 -176
@@ 1,176 0,0 @@
#!/usr/bin/env bash

# .SCRIPTDOC

# This script is used to hook other scripts that need to run under various
# conditions, and which I have not found better hooks for. This is highly
# specific to my setup, and probably will be of minimal use to anyone else.

# This script runs a loop every $DESKTOP_SPOOLER_INTERVAL. When this loop runs,
# it polls lsusb to see if any of the USB device IDs specified in
# ~/.dspool/dock_devices.txt exist, using this information to populate
# $DOCK_STATE. If $DOCK_STATE changes, the script restore-sanity is executed,
# and the file $DOCK_SPOOLER_DIR/dock_status is updated.

# .LICENSE

# Copyright (c) 2018, Charles Daniels (except where otherwise noted)
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
#    this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
#    contributors may be used to endorse or promote products derived from
#    this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

# .ENDOC

set -u

log_msg () {
	MSG="$(timestamp-message $@)"
	echo $MSG > /dev/stderr 2>&1
	echo $MSG >> "$LOG_FILE" 2>&1
}

DESKTOP_SPOOLER_DIR="$HOME/.dspool"
DESKTOP_SPOOLER_INTERVAL=5
DOCK_DEVICE_LIST="$DESKTOP_SPOOLER_DIR/dock_devices.txt"
LOG_FILE="$DESKTOP_SPOOLER_DIR/log"

if [ ! -d "$DESKTOP_SPOOLER_DIR" ] ; then
	log_msg "INFO" "Spooler directory '$DESKTOP_SPOOLER_DIR' does not exist, creating it..."
	mkdir -p "$DESKTOP_SPOOLER_DIR"
fi

if [ ! -d "$DESKTOP_SPOOLER_DIR" ] ; then
	log_msg "ERROR" "spooler dir '$DESKTOP_SPOOLER_DIR' does not exist and creating it failed."
	exit 1
fi

PREV_DOCK_STATE=""
DOCK_STATE=""
PREV_MONITOR_STATE=""
MONITOR_STATE=""
HID_STATE=""
PREV_HID_STATE=""

SCREENLAYOUT_DIR=$HOME/.screenlayout

# keep the log file from overflowing
if [ -e "$LOG_FILE" ] ; then
	mv "$LOG_FILE" "$LOG_FILE.prev"
fi

while true ; do

	sleep $DESKTOP_SPOOLER_INTERVAL

	# update dock state
	DOCK_STATE="UNDOCKED"
	while read -r DOCK_DEVICE  ; do
		if lsusb | grep "$DOCK_DEVICE" > /dev/null 2>&1 ; then
			DOCK_STATE="DOCKED"
			break
		else
			log_msg "INFO" $DOCK_DEVICE" not found"
		fi
	done < "$DOCK_DEVICE_LIST"

	if [ "$DOCK_STATE" = "$PREV_DOCK_STATE" ] ; then
		# nothing to do
		continue
	fi

	# this else runs on any dock state change
	LAYOUT_OK="NO"
	if [ "$DOCK_STATE" = "DOCKED" ] ; then
		# this implies we have gone from undocked to docked
		for layout in "$SCREENLAYOUT_DIR"/$(hostname).docked.screenlayout.*.sh ; do
			log_msg "INFO" "attempting to execute screenlayout file '$layout'"
			if sh "$layout" > /dev/null 2>&1 ; then
				log_msg "INFO" "layout configuration succeeded"
				LAYOUT_OK="YES"
				break
			else
				log_msg "INFO" "layout configuration failed"
			fi
		done
	fi

	if [ "$DOCK_STATE" = "UNDOCKED" ] ; then
		# this implies we have gone from docked to undocked
		for layout in "$SCREENLAYOUT_DIR"/$(hostname).undocked.screenlayout.*.sh ; do
			log_msg "INFO" "attempting to execute screenlayout file '$layout'"
			if sh "$layout" ; then
				log_msg "INFO" "layout configuration succeeded"
				LAYOUT_OK="YES"
				break
				else
				log_msg "INFO" "layout configuration failed"
			fi
		done
	fi

	if [ "$LAYOUT_OK" != "YES" ] ; then
		log_msg "WARN" "no layout worked, attempting fallback..."
		notify-send "screenlayout problme, check ~/.dspool/log"
		$SCREENLAYOUT_DIR/$(hostname).fallback.sh >> "$HOME/.dspool/log"
	fi

	# handle dock / undock events
	log_msg "INFO" "dock state $PREV_DOCK_STATE -> $DOCK_STATE"
	restore-sanity # reset wallpaper and reload xmodmap
	# write new dock state to status file for i3bar
	printf "$DOCK_STATE" > "$DESKTOP_SPOOLER_DIR/dock_status"
	sleep 2
	# run it again in case any USB devices have been enumerated
	# since we docked
	restore-sanity
	sleep 1

	# configure-dpms will detect if the new state is docked or
	# undocked.
	configure-dpms >> "$LOG_FILE"
	tail -n 1 "$LOG_FILE" > /dev/stderr

	PREV_DOCK_STATE="$DOCK_STATE"

	MONITOR_STATE="$(xrandr | shasum)"
	if [ "$MONITOR_STATE" != "$PREV_MONITOR_STATE" ] ; then
		# fix wallpaper on monitor state change
		log_msg "INFO" "monitor state changed"
		restore-sanity
	fi
	PREV_MONITOR_STATE="$MONITOR_STATE"

	HID_STATE="$(lsusb -t | grep -i 'human interface' | cut -d_ -f 3 | shasum)"
	if [ "$HID_STATE" != "$PREV_HID_STATE" ] ; then
		# fix xmodmap bindings on HID state change
		log_msg "INFO" "HID state changed"
		restore-sanity
	fi
	PREV_HID_STATE="$HID_STATE"


done

M overlay/bin/restore-sanity => overlay/bin/restore-sanity +1 -2
@@ 21,7 21,6 @@
xmodmap ~/.Xmodmap
pkill mate-settings-daemon >/dev/null 2>&1 | true
pkill mate-screensaver > /dev/null 2>&1 | true
pkill nowall
numlockx on

if [ -x "$(which redshift-qt)" ] ; then


@@ 43,4 42,4 @@ fi
		

~/bin/system-launch-compositor
disavow ~/bin/nowall
feh --bg-fill ~/.wallpapers/wallpaper

A overlay/bin/screenlock => overlay/bin/screenlock +3 -0
@@ 0,0 1,3 @@
#!/bin/sh

i3lock --tiling --image ~/.wallpapers/lockpaper