#!/bin/ash
# Fatdog Brightness applet
# Copyright (C) James Budiono 2016
#
# License: GNU GPL Version 3 or later
#
# Note: the bits in Global Inits, which is part of GTK-server bash init code
#       is (C) Peter van Eerten. Everything else is (C) James Budiono
#
# Version 1.0 - initial release
#

# std localisation stanza
export TEXTDOMAIN=fatdog
. gettext.sh
# performance tweak - use "C" if there is no localisation
! [ -e $TEXTDOMAINDIR/${LANG%.*}/LC_MESSAGES/$TEXTDOMAIN.mo ] &&
! [ -e $TEXTDOMAINDIR/${LANG%_*}/LC_MESSAGES/$TEXTDOMAIN.mo ] && LANG=C

### configuration variables
APPTITLE="$(gettext 'Fatdog64 Brightness Control')"
APPICON="/usr/share/pixmaps/midi-icons/pc48.png"
WINDOW_SIZE="300 50"		# in pixels, startup window width x height

### load current brightness
if [ $(id -u) -eq 0 ]; then
	CTL=/etc/brightness.conf
else
	CTL=$FATDOG_STATE_DIR/brightness.conf
fi
test -r $CTL && . $CTL
[ $BRIGHTNESS -gt 100 ] && BRIGHTNESS=100
[ $BRIGHTNESS -lt 0 ] && BRIGHTNESS=0

### runtime variables 
TRUE=1 FALSE=0
MAIN_WINDOW= SCALE= LABEL=

#---------------------------------------------------------- Global Inits
### global variables for proper GTK-server
GTK= NULL="NULL"
PIPE=/tmp/gtk.bash.$$
trap 'stop-gtk-server -fifo $PIPE; exit' HUP TERM INT # stop GTK-server in case of an error

### start GTK-server
gtk-server -fifo=$PIPE &
while [ ! -p $PIPE ]; do sleep 0.1; continue; done

### GTK-server helper functions
# Assignment function
define() { $2 $3 $4 $5 $6 $7 $8 $9; eval $1=\'"$GTK"\'; }

# Communicate with GTK-server
gtk()
{
/bin/echo "$@" > $PIPE
read GTK < $PIPE
}

#---------------------------------------------------------- GUI realization

# add GTK+ API not defined in gtk-server.cfg
add_missing_gtk_api() {
	gtk gtk_server_define gdk_pixbuf_get_type NONE INT 0
	gtk gtk_server_define gtk_window_new NONE WIDGET 1 INT	# bug fix

	gtk gtk_server_define gtk_widget_grab_default NONE NONE 1 WIDGET
	gtk gtk_server_define gtk_widget_set_can_default NONE NONE 2 WIDGET BOOL

	# hack for getting unlimited string length and leak-free operation with gtk_tree_get_model
	# see below
	gtk gtk_server_define strcat NONE STRING 2 POINTER STRING
	gtk gtk_server_define memcpy NONE NONE 3 PTR_LONG POINTER INT			
}

### helper - leak-free, unlimited string length from gtk_tree_model_get with unpatched gtk-server
# $1-tree $2-iter $3-index $4-result name
# static variable to speed up stuff
STATIC_BUF=
STATIC_ADDRESS=
tree_model_get_string() {
	[ -z "$STATIC_BUF" ] && define STATIC_BUF gtk malloc 32 # gtk-server MAX_DIG is 32 bytes
	
	gtk gtk_server_define gtk_tree_model_get NONE NONE 5 WIDGET WIDGET INT POINTER INT # ensure correct definition
	gtk gtk_tree_model_get $1 $2 $3 $STATIC_BUF -1
	
	gtk memcpy NULL $STATIC_BUF 32	# print address stored in $BUF --> *buf
	STATIC_ADDRESS=$GTK
	if [ $STATIC_ADDRESS -ne 0 ]; then
		gtk strcat $STATIC_ADDRESS \"\" # get string point by address --> **buf	
		eval $4=\'"$GTK"\'				# this will be our return value	
		gtk free $STATIC_ADDRESS		# this was dynamically alloc-ed by gtk_tree_model_get, now free it
	else
		eval $4=\"\"
	fi
}


### 
# $1-GTK Scale, $2-text label
value_changed() {
	local VAL
	define VAL gtk gtk_range_get_value $1
	define VAL gtk lrint $VAL
	brightness-set $VAL
	gtk gtk_label_set_text $2 "\"$(eval_gettext 'Current setting: ${VAL}%')\""
}

################### main ###################
### init parameters - this app can be called with parameters and masquerade as launcher too!
[ "$1" ] && APPTITLE="$1" && APPICON=$APPICON2 && shift

### init gui
add_missing_gtk_api
gtk gtk_init
define GDK_TYPE_PIXBUF gtk gdk_pixbuf_get_type

define MAIN_WINDOW gtk gtk_window_new GTK_WINDOW_TOPLEVEL
gtk gtk_window_set_title $MAIN_WINDOW \"$APPTITLE\"
gtk gtk_window_set_position $MAIN_WINDOW GTK_WIN_POS_CENTER
gtk gtk_container_set_border_width $MAIN_WINDOW 10
gtk gtk_window_set_default_size $MAIN_WINDOW ${WINDOW_SIZE% *} ${WINDOW_SIZE#* }
gtk gtk_window_set_icon_from_file $MAIN_WINDOW $APPICON 

define VBOX gtk gtk_vbox_new $FALSE 0
gtk gtk_container_add $MAIN_WINDOW $VBOX

define LABEL gtk gtk_label_new "\"$(eval_gettext 'Current setting: ${BRIGHTNESS}%')\""
gtk gtk_box_pack_start $VBOX $LABEL $FALSE $TRUE 0

define SCALE gtk gtk_hscale_new_with_range 0 100 1
gtk gtk_box_pack_start $VBOX $SCALE $FALSE $TRUE 10
gtk gtk_range_set_value $SCALE $BRIGHTNESS
gtk g_object_set $SCALE "draw-value" 0 # hide value

define DONE gtk gtk_button_new_from_stock gtk-ok
define HALIGN gtk gtk_alignment_new 0.5 0.5 0 0
gtk gtk_container_add $HALIGN $DONE
gtk gtk_box_pack_start $VBOX $HALIGN $FALSE $TRUE 0
gtk gtk_widget_set_can_default $DONE $TRUE
gtk gtk_widget_grab_default $DONE

# connect signals
gtk gtk_server_connect $MAIN_WINDOW delete-event quit
gtk gtk_server_connect $SCALE value-changed changed
gtk gtk_server_connect $DONE clicked quit

### gtk main loop
gtk gtk_widget_show_all $MAIN_WINDOW

while true; do 
	define EVENT gtk gtk_server_callback wait
	case $EVENT in
		quit) break ;;
		changed) value_changed $SCALE $LABEL ;;
	esac
done
gtk gtk_server_exit 



