literal name_enable wherever possible, and ${name}_enable when it's not, to prepare for the demise of set_rcvar(). In cases where I had to hand-edit unusual instances also modify formatting slightly to be more uniform (and in some cases, correct). This includes adding some $FreeBSD$ tags, and most importantly moving rcvar= to right after name= so it's clear that one is derived from the other.
433 lines
9.4 KiB
Bash
433 lines
9.4 KiB
Bash
#!/bin/sh
|
|
|
|
# PROVIDE: wacom
|
|
# REQUIRE: FILESYSTEMS
|
|
#
|
|
# Add the following lines to /etc/rc.conf.local or /etc/rc.conf
|
|
# to enable this service:
|
|
#
|
|
# wacom_enable (bool): Set to NO by default.
|
|
# Set it to YES to enable wacom.
|
|
# wacom_types (list): Set to "stylus eraser cursor pad touch" by
|
|
# default. A list of wacom profiles to set up.
|
|
# wacom_porttype (enum): Set to "%%PORTTYPE%%" by default.
|
|
# Set this to usb or serial.
|
|
#
|
|
# This script additionally offers setup and cleanup to configure Xorg
|
|
# for use of the driver or remove the configuration settings.
|
|
# The input devices are only added to the first ServerLayout section
|
|
# and also only removed once.
|
|
# In USB mode the file /boot/loader.conf is also adjusted.
|
|
#
|
|
|
|
. /etc/rc.subr
|
|
|
|
name="wacom"
|
|
rcvar=wacom_enable
|
|
|
|
extra_commands="setup cleanup"
|
|
setup_cmd=do_setup
|
|
start_cmd=do_start
|
|
stop_cmd=do_stop
|
|
cleanup_cmd=do_cleanup
|
|
|
|
#
|
|
# Outputs the location of the Xorg configuration file.
|
|
# Returns 1 if no file could be found.
|
|
#
|
|
get_xorg_conf() {
|
|
local config_locations config
|
|
|
|
# Possible Xorg configuration file locations, taken from the
|
|
# xorg.conf(5) manual page.
|
|
config_locations="
|
|
/etc/X11/$XORGCONFIG
|
|
%%PREFIX%%/etc/X11/$XORGCONFIG
|
|
/etc/X11/xorg.conf-4
|
|
/etc/X11/xorg.conf
|
|
/etc/xorg.conf
|
|
%%PREFIX%%/etc/X11/xorg.conf.$HOST
|
|
%%PREFIX%%/etc/X11/xorg.conf-4
|
|
%%PREFIX%%/etc/X11/xorg.conf
|
|
%%PREFIX%%/lib/X11/xorg.conf.$HOST
|
|
%%PREFIX%%/lib/X11/xorg.conf-4
|
|
%%PREFIX%%/lib/X11/xorg.conf
|
|
NONE
|
|
"
|
|
|
|
# Find the first matching config file.
|
|
for config in $config_locations; {
|
|
test -f "$config" && break
|
|
}
|
|
|
|
if [ "$config" = "NONE" ]; then
|
|
echo "No Xorg configuration has been found." 1>&2
|
|
return 1
|
|
fi
|
|
|
|
echo "$config"
|
|
return 0
|
|
}
|
|
|
|
#
|
|
# Returns the line number of the first line matching the extended regular
|
|
# expression $2 in the file $1.
|
|
#
|
|
# @param $1
|
|
# The file to get the line number from.
|
|
# @param $2
|
|
# An extend regular expression.
|
|
# @stdout
|
|
# The line number of the first line matching $2.
|
|
#
|
|
get_first() {
|
|
local result IFS
|
|
IFS='
|
|
'
|
|
result="$(/usr/bin/grep -Ein "$2" "$1")"
|
|
result="${result%%:*}"
|
|
|
|
# No match.
|
|
if [ -z "$result" ]; then
|
|
return 1
|
|
fi
|
|
|
|
echo "$result"
|
|
return 0
|
|
}
|
|
|
|
#
|
|
# Returns the line numbers of lines matching the extended regular
|
|
# expression $2 in the file $1.
|
|
#
|
|
# @param $1
|
|
# The file to get the line numbers from.
|
|
# @param $2
|
|
# An extend regular expression.
|
|
# @stdout
|
|
# The line numbers of lines matching $2.
|
|
#
|
|
get_all() {
|
|
local entry result IFS
|
|
IFS='
|
|
'
|
|
|
|
result="$(/usr/bin/grep -Ein "$2" "$1")"
|
|
|
|
# No match.
|
|
if [ -z "$result" ]; then
|
|
return 1
|
|
fi
|
|
|
|
for entry in $result; {
|
|
echo "${entry%%:*}"
|
|
}
|
|
}
|
|
|
|
#
|
|
# Returns the line number of the line before line number $2 that matches the
|
|
# extended regular expression $3 in the file $1.
|
|
#
|
|
# @param $1
|
|
# The file to get the line number from.
|
|
# @param $2
|
|
# The line before which the expression should match.
|
|
# @param $3
|
|
# An extend regular expression.
|
|
# @stdout
|
|
# The line number of the first line before line $2 matching $3.
|
|
#
|
|
get_before() {
|
|
local result IFS line length
|
|
IFS='
|
|
'
|
|
|
|
# The length is necessary to make sure the check is run once
|
|
# again for the last match.
|
|
length="$(/usr/bin/wc -l "$1")"
|
|
length=${length% *}
|
|
|
|
result=-1
|
|
for line in $(/usr/bin/grep -Ein "$3" "$1") $(($length + 1)); {
|
|
line="${line%%:*}"
|
|
|
|
# We have passed the line to look for.
|
|
if [ $line -ge $2 ]; then
|
|
|
|
# No match before this line.
|
|
if [ $result -lt 0 ]; then
|
|
return 1
|
|
fi
|
|
|
|
echo "$result"
|
|
return 0
|
|
fi
|
|
|
|
result=$line
|
|
}
|
|
|
|
# No result.
|
|
return 1
|
|
}
|
|
|
|
#
|
|
# Returns the line number of the line behind line number $2 that matches the
|
|
# extended regular expression $3 in the file $1.
|
|
#
|
|
# @param $1
|
|
# The file to get the line number from.
|
|
# @param $2
|
|
# The line behind which the expression should match.
|
|
# @param $3
|
|
# An extend regular expression.
|
|
# @stdout
|
|
# The line number of the first line behind line $2 matching $3.
|
|
#
|
|
get_behind() {
|
|
local IFS line
|
|
IFS='
|
|
'
|
|
|
|
for line in $(/usr/bin/grep -Ein "$3" "$1"); {
|
|
line="${line%%:*}"
|
|
|
|
# We have passed the line to look for.
|
|
if [ $line -gt $2 ]; then
|
|
echo "$line"
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
# No result.
|
|
return 1
|
|
}
|
|
|
|
#
|
|
# Inserts a line at the end of a section of an Xorg configuration file.
|
|
# The insertion is done on all matching sections!
|
|
#
|
|
section_insert_line() {
|
|
local file section insert sections begin end length
|
|
file="$1"
|
|
section="$2"
|
|
insert="$3"
|
|
|
|
# Find the beginning of the section.
|
|
# Start with the last section to avoid moving sections around
|
|
# before something is inserted into them.
|
|
sections="$(get_all "$file" \
|
|
"^[[:space:]]*Section[[:space:]]+\"$section\"" \
|
|
| /usr/bin/sort -nr
|
|
)"
|
|
|
|
if [ -z "$sections" ]; then
|
|
echo "Identifying section $section has failed." 1>&2
|
|
return 1
|
|
fi
|
|
|
|
for begin in $sections; {
|
|
|
|
# Find the end of the section.
|
|
end="$(get_behind "$file" "$begin" "^[[:space:]]*EndSection")"
|
|
|
|
if [ -z "$end" ]; then
|
|
echo "The section $section($begin) is not closed." 1>&2
|
|
return 2
|
|
fi
|
|
|
|
# Determine the length of the configuration file.
|
|
length="$(/usr/bin/wc -l "$file")"
|
|
length=${length% *}
|
|
|
|
# Insert the line.
|
|
/bin/cp "$file" "$file.$$"
|
|
|
|
/usr/bin/head -n$(($end - 1)) "$file.$$" > "$file"
|
|
echo "$insert" >> "$file"
|
|
/usr/bin/tail -n$(($length - $end + 1)) "$file.$$" >> "$file"
|
|
|
|
/bin/rm "$file.$$"
|
|
}
|
|
}
|
|
|
|
#
|
|
# Adds the necessary lines to the Xorg configuration.
|
|
#
|
|
do_setup() {
|
|
local config ident status
|
|
|
|
# Get the Xorg configuration file.
|
|
config="$(get_xorg_conf)"
|
|
status=$?
|
|
test $status -ne 0 && return $status
|
|
|
|
echo "Setting up configuration in $config."
|
|
|
|
# Add all the necessary sections.
|
|
for ident in $(eval "echo \${${name}_types}"); {
|
|
if /usr/bin/grep -Eqi "^[[:space:]]*Identifier[[:space:]]+\"$ident\"" "$config"; then
|
|
echo "Skipping $ident, because it already exists in $config."
|
|
continue
|
|
fi
|
|
|
|
echo "Inserting $ident."
|
|
|
|
echo "Section \"InputDevice\"
|
|
Driver \"wacom\"
|
|
Identifier \"$ident\"
|
|
Option \"Type\" \"$ident\"" >> "$config"
|
|
|
|
if [ "$(eval "echo \${${name}_porttype}")" = "usb" ]; then
|
|
echo " Option \"Device\" \"/dev/event0\"
|
|
Option \"USB\" \"on\"" >> "$config"
|
|
else
|
|
echo " Option \"Device\" \"/dev/ttyd0\"
|
|
Option \"ForceDevice\" \"ISDV4\"" >> "$config"
|
|
fi
|
|
|
|
echo "EndSection
|
|
" >> "$config"
|
|
|
|
section_insert_line "$config" "ServerLayout" " InputDevice \"$ident\" \"SendCoreEvents\""
|
|
}
|
|
|
|
if [ "$(eval "echo \${${name}_porttype}")" = "usb" ]; then
|
|
if ! /usr/bin/grep -qx 'uwacom_load="YES"' \
|
|
/boot/loader.conf; then
|
|
echo "Setting up /boot/loader.conf"
|
|
/bin/cp /boot/loader.conf /boot/loader.conf.orig
|
|
echo 'uwacom_load="YES"' >> /boot/loader.conf
|
|
fi
|
|
fi
|
|
}
|
|
|
|
#
|
|
# Removes all wacom stuff from the Xorg configuration file. Beware,
|
|
# this also affects handwritten content.
|
|
#
|
|
do_cleanup() {
|
|
local config status driver i begin last_begin end length ident IFS
|
|
|
|
# Get the Xorg configuration file.
|
|
config="$(get_xorg_conf)"
|
|
status=$?
|
|
test $status -ne 0 && return $status
|
|
|
|
echo "Removing wacom entries from $config."
|
|
|
|
IFS='
|
|
'
|
|
while true; do
|
|
# Find a wacom section.
|
|
driver="$(get_first "$config" \
|
|
"^[[:space:]]*Driver[[:space:]]+\"wacom\"" \
|
|
)"
|
|
|
|
# Not a numeric, no more wacom sections left.
|
|
test -z "$driver" && break
|
|
|
|
# Find the beginning of the section.
|
|
begin="$(get_before "$config" "$driver" \
|
|
"^[[:space:]]*Section[[:space:]]+\"InputDevice\"" \
|
|
)"
|
|
|
|
if [ -z "$begin" ]; then
|
|
echo "Beginning of wacom driver section" \
|
|
"could not be found!" 1>&2
|
|
return 1
|
|
fi
|
|
|
|
# Find the end of the section.
|
|
end="$(get_behind "$config" "$driver" \
|
|
"^[[:space:]]*EndSection" \
|
|
)"
|
|
|
|
if [ -z "$end" ]; then
|
|
echo "The Wacom driver section is" \
|
|
"not closed properly." 1>&2
|
|
return 2
|
|
fi
|
|
|
|
# Determine the length of the configuration file.
|
|
length="$(/usr/bin/wc -l "$config")"
|
|
length=${length% *}
|
|
|
|
# Adjust the end by trailing newlines.
|
|
while [ $end -lt $length -a \
|
|
-z "$(/usr/bin/tail -n$(($length - $end)) "$config" \
|
|
| /usr/bin/head -n1)" ]; do
|
|
end=$(($end + 1))
|
|
done
|
|
|
|
# Remove the section.
|
|
/bin/cp "$config" "$config.$$"
|
|
|
|
/usr/bin/head -n$(($begin - 1)) "$config.$$" > "$config"
|
|
/usr/bin/tail -n$(($length - $end)) "$config.$$" >> "$config"
|
|
|
|
/bin/rm "$config.$$"
|
|
done
|
|
IFS='
|
|
'
|
|
|
|
echo "Cleaning up ServerLayout section."
|
|
|
|
for ident in $(eval "echo \${${name}_types}"); {
|
|
while true; do
|
|
driver="$(get_first "$config" \
|
|
"[[:space:]]*InputDevice[[:space:]]+\"$ident\"" \
|
|
)"
|
|
|
|
# There is no line matching this driver.
|
|
test -z "$driver" && break
|
|
|
|
# Determine the length of the configuration file.
|
|
length="$(/usr/bin/wc -l "$config")"
|
|
length=${length% *}
|
|
|
|
# Remove the section.
|
|
/bin/cp "$config" "$config.$$"
|
|
|
|
/usr/bin/head -n$(($driver - 1)) "$config.$$" > "$config"
|
|
/usr/bin/tail -n$(($length - $driver)) "$config.$$" >> "$config"
|
|
|
|
/bin/rm "$config.$$"
|
|
done
|
|
}
|
|
|
|
if [ "$(eval "echo \${${name}_porttype}")" = "usb" ]; then
|
|
if /usr/bin/grep -qx 'uwacom_load="YES"' \
|
|
/boot/loader.conf; then
|
|
echo "Cleaning up /boot/loader.conf"
|
|
/bin/cp /boot/loader.conf /boot/loader.conf.orig
|
|
/usr/bin/grep -xv 'uwacom_load="YES"' \
|
|
/boot/loader.conf.orig > /boot/loader.conf
|
|
fi
|
|
fi
|
|
|
|
}
|
|
|
|
do_start() {
|
|
if /sbin/kldstat | /usr/bin/grep -q uwacom; then
|
|
return 0
|
|
fi
|
|
echo "Starting ${name}."
|
|
/sbin/kldload %%KMODDIR%%/uwacom.ko
|
|
}
|
|
|
|
do_stop() {
|
|
if ! /sbin/kldstat | /usr/bin/grep -q uwacom; then
|
|
echo "${name} is not running."
|
|
return 0
|
|
fi
|
|
echo "Stopping ${name}."
|
|
/sbin/kldunload %%KMODDIR%%/uwacom.ko
|
|
}
|
|
|
|
load_rc_config $name
|
|
|
|
eval ": \${${name}_enable=\"NO\"}"
|
|
eval ": \${${name}_types=\"stylus eraser cursor pad touch\"}"
|
|
eval ": \${${name}_porttype=\"%%PORTTYPE%%\"}"
|
|
|
|
run_rc_command "$1"
|