Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37396140
en ru br
Репозитории ALT
S:3.3-alt1
5.1: 3.0-alt2
4.1: 2.0-alt2.M41.3
4.0: 0.9-alt3.M40.3
3.0: 0.3-alt3
www.altlinux.org/Changes

Группа :: Система/Настройка/Прочее
Пакет: alterator-xkb

 Главная   Изменения   Спек   Патчи   Исходники   Загрузить   Gear   Bugs and FR  Repocop 

alterator-xkb-3.0/000075500000000000000000000000001213266321200141275ustar00rootroot00000000000000alterator-xkb-3.0/Makefile000064400000000000000000000007501213266321200155710ustar00rootroot00000000000000NAME=xkb

all: build-tools
clean: clean-tools
install: install-module install-tools

include /usr/share/alterator/build/module.mak

build-tools:
for i in tools/*; do [ ! -d $$i ] || make -C $$i; done;

clean-tools:
for i in tools/*; do [ ! -d $$i ] || make -C $$i clean; done;

install-tools:build-tools
for i in tools/*; do [ ! -d $$i ] || $(INSTALL) -Dpm 755 $$i/$${i##*/} $(bindir)/$${i##*/};done
for i in tools/*; do [ -d $$i ] || $(INSTALL) -Dpm 755 $$i $(bindir)/$${i##*/};done
alterator-xkb-3.0/applications/000075500000000000000000000000001213266321200166155ustar00rootroot00000000000000alterator-xkb-3.0/applications/xkb.desktop000064400000000000000000000003561213266321200210000ustar00rootroot00000000000000[Desktop Entry]
Encoding=UTF-8
Type=Application
Categories=X-Alterator-Xorg
Icon=xkb
Terminal=false
Name=Keyboard
X-Alterator-URI=/xkb
X-Alterator-Weight=10
X-Alterator-Help=xkb
Name[ru]=п п╩п╟п╡п╦п╟я┌я┐я─п╟
Name[uk]=п п╩п╟п╡я√п╟я┌я┐я─п╟
alterator-xkb-3.0/backend3/000075500000000000000000000000001213266321200156015ustar00rootroot00000000000000alterator-xkb-3.0/backend3/xkb000075500000000000000000000106611213266321200163170ustar00rootroot00000000000000#!/bin/sh

#this module can work for all users, so I use common directories
alterator_api_version=1
po_domain="alterator-xkb"
cachedir=
ticketdir="/var/lib/alterator/tickets"

if [ -n "$TMPDIR" ]; then
cachedir="$TMPDIR/alterator-xkb"
else
cachedir="/var/cache/alterator/alterator-xkb"
fi

#turn off auto expansion
set -f

. alterator-sh-functions

dump_cache()
{
local langlist="$(write_language "$in_language")"
local firstlang="${langlist%%:*}"
LC_ALL="$firstlang" LANGUAGE="$langlist" xkbdatadump
}

clear_cache()
{
rm -rf "$cachedir"
}

init_cache()
{
local rc=0
local msg=
[ -d "$cachedir/$1" ] && return 0

mkdir -p "$cachedir/$1"

cd "$cachedir/$1"
msg="$(dump_cache 2>&1)"
rc=$?
cd - >/dev/null

[ "$rc" -eq 0 ] || write_error "$msg"

return $rc
}


read_current_layout()
{
if [ -f "$cachedir/current_layout" ];then
cat "$cachedir/current_layout"
else
xkbmapconf -l|tee "$cachedir/current_layout"
fi
}

list_current_layout()
{
read_current_layout|
while read layout; do
local name="$(grep -m1 "^$layout[[:space:]]" "$cachedir/$1/layouts" | cut -f2)"
[ -n "$name" ] || name="$layout"
printf '%s\t%s\n' "$layout" "$name"
done
}

list_avail_variant()
{
grep "^$2\((\|[[:space:]]\)" "$cachedir/$1/layouts"
}


list_avail_layout()
{
grep '^\([[:alnum:]]\+\)[[:space:]]\+' "$cachedir/$l/layouts"|
LANG="${in_language%%:*}.UTF-8" sort -k 2,2 2>/dev/null
}

write_add()
{
grep -qs "^$1\$" "$cachedir/current_layout" ||
echo "$1" >>"$cachedir/current_layout"
}

write_remove()
{
ed -s "$cachedir/current_layout" 2>/dev/null <<EOF
/$1/d
wq
EOF
}

write_up()
{
ed -s "$cachedir/current_layout" 2>/dev/null <<EOF
/$1/m/$1/--
wq
EOF
}

write_down()
{
ed -s "$cachedir/current_layout" 2>/dev/null <<EOF
/$1/m/$1/+
wq
EOF
}

### tickets
clear_ticket()
{
find "$ticketdir" -mindepth 1 -maxdepth 1 -type f -name 'xkb-ticket-*' -delete
}

find_ticket()
{
find "$ticketdir" -mindepth 1 -maxdepth 1 -type f -name 'xkb-ticket-*' -print -quit
}

make_ticket()
{
[ -d "$ticketdir" ] || install -d -m755 "$ticketdir"

name="$ticketdir/xkb-ticket-$(uuidgen)"

cat>"$name"<<EOF
#!/bin/sh
setxkbmap -option && setxkbmap \$(cat /etc/X11/xinit/Xkbmap)
EOF
chmod 755 "$name"
echo "$name"
}

get_ticket()
{
local ticket="$(find_ticket)"
[ -n "$ticket" ] || ticket="$(make_ticket)"

echo "${ticket##*/}"
}

### main part

exit_handler()
{
local rc=$?
trap - EXIT

clear_ticket
clear_cache

exit $rc
}

trap exit_handler HUP INT QUIT TERM EXIT

clear_ticket
clear_cache

on_message()
{
case "$in_action" in
list)
[ -n "$in_language" ] || in_language="en_US"
local l="$in_language"

init_cache "$l" || return

case "$in__objects" in
avail_model) cat "$cachedir/$l/models"|write_enum ;;
avail_grp) cat "$cachedir/$l/options"|write_enum ;;
avail_layout) list_avail_layout|write_enum;;
current_layout) list_current_layout "$l"|write_enum;;
avail_variant)
[ -n "$in_name" ] || in_name="$(list_avail_layout|head -n1|cut -f1)"
list_avail_variant "$l" "$in_name"|write_enum
;;
esac
;;
read)
#firefox extension
local ticket="$(get_ticket)"
write_string_param alt_exec_description "`_ "Apply saved keyboard settings"`"
write_string_param alt_exec_error_message "`_ "Apply failed"`"
write_string_param alt_exec_command "${ticket};`_ "Apply"`"

local model="$(xkbmapconf -m)"
[ -n "$model" ] || model="pc104"

write_string_param model "$model"
write_string_param grp "$(xkbmapconf -g)"
[ -s "$cachedir/selected_layout" ] &&
write_string_param layout "$(cat "$cachedir/selected_layout")"
;;
write)
case "$in__objects" in
avail_layout*)
write_add "$in_variant"
;;
*)
[ -n "$in_layout" ] && echo "$in_layout" >"$cachedir/selected_layout"
if [ -n "$in_remove" ];then
write_remove "$in_layout"
elif [ -n "$in_up" ];then
write_up "$in_layout"
elif [ -n "$in_down" ];then
write_down "$in_layout"
elif [ -n "$in_submit" ];then
xkbmapconf -s -- \
-model "$in_model" \
-option "$in_grp" \
-layout "$(cat "$cachedir/current_layout" | tr '\n' ','| sed s/,$//)"
[ "$in_update" = "#t" ] &&
setxkbmap -option &&
setxkbmap $(cat /etc/X11/xinit/Xkbmap) >/dev/null 2>/dev/null
fi
;;
esac
;;
esac
}

message_loop
alterator-xkb-3.0/tools/000075500000000000000000000000001213266321200152675ustar00rootroot00000000000000alterator-xkb-3.0/tools/xkbdatadump/000075500000000000000000000000001213266321200175735ustar00rootroot00000000000000alterator-xkb-3.0/tools/xkbdatadump/Makefile000064400000000000000000000001431213266321200212310ustar00rootroot00000000000000CFLAGS=-Wall -pedantic $(RPM_OPT_FLAGS)
LDLIBS= -lexpat

all:xkbdatadump
clean:
$(RM) xkbdatadump
alterator-xkb-3.0/tools/xkbdatadump/xkbdatadump.c000064400000000000000000000075711213266321200222550ustar00rootroot00000000000000#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <error.h>
#include <errno.h>

#include <unistd.h>
#include <fcntl.h>

#include <locale.h>
#include <libintl.h>

#include <expat.h>

#define _(string) gettext (string)


const char datafile[]="/usr/share/X11/xkb/rules/xorg.xml";
const char po_domain[]="xkeyboard-config";

typedef struct user_data_struct {
char *el;
FILE *file;

int mode;

char *layname;
char *name;

char *laydescription;
char *description;
} user_data;

void
do_free(char **item)
{
if (*item) free(*item);
*item = 0;
}

void
do_assign(char **target,const char *destination,int len)
{
do_free(target);

if (destination && (len > 0))
{
*target=malloc(len+1);
strncpy(*target,destination,len);
(*target)[len]=0;
}
}

FILE *
xfopen(const char *name,const char *mode)
{
FILE *f=fopen(name,mode);
if (!f)
error(EXIT_FAILURE,errno,"unable to open file %s for writing",name);
return f;
}

void
do_reset(user_data *u)
{
do_free(&u->description);
}

static void XMLCALL
element_start(void *data, const char *el, const char **attr)
{
user_data *u = data;

u->el = strdup(el);

if (!strcmp(el,"modelList"))
u->file = xfopen("./models","w");
else if (!strcmp(el,"layoutList"))
u->file = xfopen("./layouts","w");
else if (!strcmp(el,"optionList"))
u->file = xfopen("./options","w");
else if (!strcmp(el,"layout") || !strcmp(el,"group"))
u->mode = 1;
else if (!strcmp(el,"variant") || !strcmp(el,"option"))
u->mode = 0;
}

static void XMLCALL
element_stop(void *data, const char *el)
{
user_data *u = data;

do_free(&u->el);

if (!strcmp(el,"modelList") || !strcmp(el,"layoutList") || !strcmp(el,"optionList"))
fclose(u->file);
else if (!strcmp(el,"layout"))
{
fprintf(u->file,"%s\t%s\n",
u->layname,
_(u->laydescription));
do_reset(u);
}
else if (!strcmp(el,"variant"))
{
u->mode = 1;
fprintf(u->file,"%s(%s)\t%s - %s\n",
u->layname,
u->name,
_(u->laydescription),
_(u->description));
do_reset(u);
}
else if (!strcmp(el,"option") && !strcmp(u->layname,"grp"))
{
u->mode = 1;
fprintf(u->file,"%s\t%s\n",
u->name,
_(u->description));
do_reset(u);
}
else if (!strcmp(el,"model"))
{
fprintf(u->file,"%s\t%s\n",
u->name,
_(u->description));
do_reset(u);
}
}

static void XMLCALL
cdata_handler(void *data,const char *buffer, int len)
{
user_data *u = data;

if (!u->el) return;

if (!strcmp(u->el,"name"))
do_assign(u->mode?&u->layname:&u->name,buffer,len);
else if (!strcmp(u->el,"description"))
do_assign(u->mode?&u->laydescription:&u->description,buffer,len);
}

int
main(int argc,char **argv)
{
int fd;
char buffer[BUFSIZ];
size_t len;
XML_Parser parser;
user_data *data;

setlocale(LC_ALL,"");
textdomain(po_domain);
bindtextdomain(po_domain, "/usr/share/locale");

if (!(parser = XML_ParserCreate(NULL)))
error(EXIT_FAILURE,0,"couldn't allocate memory for parser");

if (!(data = calloc(1,sizeof(user_data))))
error(EXIT_FAILURE,errno,"couldn't allocate memory for user_data");

if ((fd = open(datafile,O_RDONLY)) < 0)
error(EXIT_FAILURE,errno,"unable to open database file %s",datafile);

XML_SetElementHandler(parser, element_start, element_stop);
XML_SetCharacterDataHandler(parser,cdata_handler);
XML_SetUserData(parser, data);

while ((len = read(fd,buffer,(sizeof buffer) - 1)) > 0)
{
if (XML_Parse(parser, buffer, len, XML_FALSE) == XML_STATUS_ERROR)
{
fprintf(stderr,"Parse error at line %lu:%s",
XML_GetCurrentLineNumber(parser),
XML_ErrorString(XML_GetErrorCode(parser)));
return EXIT_FAILURE;
}
}
XML_Parse(parser, buffer, 0, XML_TRUE);
XML_ParserFree(parser);

return EXIT_SUCCESS;
}
alterator-xkb-3.0/tools/xkbmapconf000075500000000000000000000057051213266321200173540ustar00rootroot00000000000000#!/bin/sh

PROG="${0##*/}"

SYSTEM_CONFIG="/etc/X11/xinit/Xkbmap"
LOCAL_CONFIG="$HOME/.Xkbmap"

### config

cat_config()
{
touch "$SYSTEM_CONFIG" 2>/dev/null
if [ -w "$SYSTEM_CONFIG" ];then
cat "$SYSTEM_CONFIG"
else
cat "$LOCAL_CONFIG"
fi
}

echo_config()
{
if [ -w "$SYSTEM_CONFIG" ];then
echo "$@" > "$SYSTEM_CONFIG"
else
echo "$@" > "$LOCAL_CONFIG"
fi
}

### read operations

read_layout()
{
local layout="$1";shift
local variant="$1";shift
local count=1

local IFS=,
set -- $variant

for lay in $layout;do
local var="$(eval echo \$$count)"
if [ -n "$var" ];then
printf '%s(%s)\n' "$lay" "$var"
else
printf '%s\n' "$lay"
fi
count=$((count + 1))
done
}

read_grp()
{
local IFS=,
set -- $1
for i in "$@";do
if [ "$i" != "${i#grp:}" ];then
echo "$i"
break
fi
done
}

read_config()
{
local action="$1"
local layout= variant= model= option=
eval set -- $(cat_config)

while [ $# -gt 0 ];do
case "$1" in
-layout) layout="$2";shift;shift;;
-variant) variant="$2";shift;shift;;
-model) model="$2";shift;shift;;
-option) option="$2";shift;shift;;
esac
done

case "$action" in
model) echo "$model";;
grp) read_grp "$option";;
layout) read_layout "$layout" "$variant";;
esac

exit
}

# write operations

write_variant()
{
echo "$1"|sed -r 's/([^,()]+)\(?([^,()]*)\)?/\2/g'
}

write_layout()
{
echo "$1"|sed -r 's/([^,()]+)\(?([^,()]*)\)?/\1/g'
}

write_config()
{
local layout= variant= model=

while [ $# -gt 0 ];do
case "$1" in
-layout) layout="$2";shift;shift;;
-variant) variant="$2";shift;shift;;
-model) model="$2";shift;shift;;
*) args="$args $1 $2";shift;shift;;
esac
done

#try to extract variant from layout
if [ -z "$variant" -a -n "$layout" ];then
variant="$(write_variant "$layout")"
layout="$(write_layout "$layout")"
fi

[ -z "$variant" ] || args="$args -variant $variant"
[ -z "$layout" ] || args="$args -layout $layout"
[ -z "$model" ] || args="$args -model $model"

eval echo_config $args
}

show_help()
{
cat <<EOF
xkbmapconf - read and write ~/.Xkbmap and /etc/X11/xinit/Xkbmap config files

Usage: $PROG [option]

Read options

-h, --help show this text and exit;

-m, --get-model read keyboard model;
-g, --get-grp read keyboard switch;
-l, --get-layout read keyboard layout;

-s, --save save parameters.

Report bugs to http://bugs.altlinux.ru/

EOF
exit
}

### main

save=
short_opt="h,m,l,g,s"
long_opt="help,get-model,get-layout,get-grp,save"
temp=`getopt -n $PROG -o "$short_opt" -l "$long_opt" -- "$@"` || show_help
eval set -- "$temp"

while :; do
case "$1" in
-h|--help) show_help;;
-m|--get-model) read_config "model";;
-l|--get-layout) read_config "layout";;
-g|--get-grp) read_config "grp";;
-s|--save) save=1;;
--)shift; break ;;
*) echo "$1";show_help;;
esac
shift
done
[ -n "$save" ] && write_config "$@"
alterator-xkb-3.0/ui/000075500000000000000000000000001213266321200145445ustar00rootroot00000000000000alterator-xkb-3.0/ui/xkb/000075500000000000000000000000001213266321200153305ustar00rootroot00000000000000alterator-xkb-3.0/ui/xkb/ajax.scm000064400000000000000000000023221213266321200167560ustar00rootroot00000000000000(define-module (ui xkb ajax)
:use-module (alterator ajax)
:use-module (alterator woo)
:export (init))

;;; logic

(define (ui- action)
(catch/message
(lambda()
(woo-write "/xkb" action #t 'layout (form-value "layout"))
(ui-read))))

(define (ui-apply)
(catch/message
(lambda()
(woo-write "/xkb"
'submit #t
'grp (form-value "grp")
'model (form-value "model")
'language (form-value "language")))))

(define (ui-add)
(form-replace "/xkb/avail_layout"))

(define (ui-up) (ui- 'up))
(define (ui-down) (ui- 'down))
(define (ui-remove) (ui- 'remove))

(define (ui-read)
(form-update-enum "layout" (woo-list "/xkb/current_layout" 'language (form-value "language")))
(form-update-value-list
'("model" "grp" "layout")
(woo-read-first "/xkb")))

(define (init)
(form-update-enum "model" (woo-list "/xkb/avail_model" 'language (form-value "language")))
(form-update-enum "grp" (woo-list "/xkb/avail_grp" 'language (form-value "language")))
(form-bind "up_button" "click" ui-up)
(form-bind "down_button" "click" ui-down)
(form-bind "add_button" "click" ui-add)
(form-bind "remove_button" "click" ui-remove)
(form-bind "apply_button" "click" ui-apply)
(ui-read))
alterator-xkb-3.0/ui/xkb/avail_layout/000075500000000000000000000000001213266321200200215ustar00rootroot00000000000000alterator-xkb-3.0/ui/xkb/avail_layout/ajax.scm000064400000000000000000000020251213266321200214470ustar00rootroot00000000000000(define-module (ui xkb avail_layout ajax)
:use-module (alterator ajax)
:use-module (alterator woo)
:use-module (alterator algo)
:export (init))

(define (ui-cancel)
(form-replace "/xkb"))

(define (ui-ok)
(catch/message
(lambda()
(woo-write "/xkb/avail_layout" 'variant (form-value "variant") 'language (form-value "language"))
(form-replace "/xkb"))))

(define (ui-read . name)
(let* ((name (if (pair? name) (car name) (form-value "name")))
(data (woo-list "/xkb/avail_variant" 'name name 'language (form-value "language")))
(variant (woo-get-option (cond-car data) 'name #f)))
(form-update-enum "variant" data)
(and variant (form-update-value "variant" variant))))

(define (init)
(let* ((data (woo-list "/xkb/avail_layout" 'language (form-value "language")))
(name (woo-get-option (cond-car data) 'name #f)))
(form-update-enum "name" data)
(and name (ui-read name)))
(form-bind "name" "change" ui-read)
(form-bind "ok" "click" ui-ok)
(form-bind "cancel" "click" ui-cancel))
alterator-xkb-3.0/ui/xkb/avail_layout/index.html000064400000000000000000000011301213266321200220110ustar00rootroot00000000000000<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<!-- xkb administration module -->
<html wf="none">
<head/> <!-- for card-index scripts -->
<body>
<form method="POST">
<span translate="_">Country:</span>
<select name="name"/>
<br/>
<span translate="_">Available layouts:</span><br/>
<select enumref="/xkb/avail_variant" name="variant" size="10" style="width:50%"/>
<br/>
<br/>
<input type="button" name="ok" value="Add" class="btn"/>
&nbsp;
<input type="button" name="cancel" value="Cancel" class="btn"/>
</form>
</body>
</html>
alterator-xkb-3.0/ui/xkb/avail_layout/index.scm000064400000000000000000000023651213266321200216420ustar00rootroot00000000000000(document:surround "/std/frame")

;;; ui

width 650
height 400

(gridbox columns "0;100"
(label text (_ "Country:") align "right")
(combobox name "name")
(label (_ "Available layouts:") colspan 2)
(listbox colspan 2 name "variant")

(label colspan 2)

(spacer)
(hbox align "left"
(button (_ "Add") name "ok")
(button (_ "Cancel") name "cancel")))

;;; logic
(define (ui-cancel)
(document:end #f))

(define (ui-ok)
(catch/message
(lambda()
(woo-write "/xkb/avail_layout" 'variant (form-value "variant"))
(document:end #t))))

(define (ui-read . name)
(let* ((name (if (pair? name) (car name) (form-value "name")))
(data (woo-list "/xkb/avail_variant" 'name name))
(variant (woo-get-option (cond-car data) 'name #f)))
(form-update-enum "variant" data)
(and variant (form-update-value "variant" variant))))

(define (ui-init)
(let* ((data (woo-list "/xkb/avail_layout"))
(name (woo-get-option (cond-car data) 'name #f)))
(form-update-enum "name" data)
(and name (ui-read name)))
(form-bind "name" "change" ui-read)
(form-bind "ok" "click" ui-ok)
(form-bind "cancel" "click" ui-cancel))

(document:root (when loaded (ui-init)))
alterator-xkb-3.0/ui/xkb/index.html000064400000000000000000000031621213266321200173270ustar00rootroot00000000000000<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<!-- xkb administration module -->
<html wf="none">
<body>
<!-- information for extension -->
<input type="hidden" name="alt_exec_description"/>
<input type="hidden" name="alt_exec_command"/>
<input type="hidden" name="alt_exec_error_message"/>

<form method="POST">
<table class="form-table">
<tbody>
<tr>
<td colspan="2" style="text-align:left">
<span translate="_">Layouts:</span><br/>
<select enumref="/xkb/current_layout"
name="layout"
size="5"
style="width:100%"/>
</td>
</tr>
<tr>
<td style="text-align:left">
<input type="button" name="add_button" value="Add" class="btn"/>
&nbsp;
<input type="button" name="remove_button" value="Remove" class="btn"/>
</td>
<td style="text-align:right">
<input type="button" name="up_button" value="Up" class="btn"/>
&nbsp;
<input type="button" name="down_button" value="Down" class="btn"/>
</td>
</tr>
<tr><td colspan="2">&nbsp;</td></tr>
<tr>
<td><span translate="_">Layout switching:</span></td>
<td><select enumref="/xkb/avail_grp" name="grp" style="width:100%"/></td>
</tr>
<tr>
<td><span translate="_">Model:</span></td>
<td><select enumref="/xkb/avail_model" name="model"/></td>
</tr>
<tr><td colspan="2">&nbsp;</td></tr>
<tr>
<td>&nbsp;</td>
<td>
<input type="button" name="apply_button" value="Apply" class="btn"/>&nbsp;
</td>
</tr>
</tbody>
</table>
</form>
</body>
</html>
alterator-xkb-3.0/ui/xkb/index.scm000064400000000000000000000034151213266321200171460ustar00rootroot00000000000000(document:surround "/std/frame")

;;; ui

(gridbox columns "0;100"
margin 20

(label text (_ "Layouts:") align "left" colspan 2)
(listbox colspan 2 name "layout")

(hbox align "left"
(button text (_ "Add") align "left" name "add_button")
(button text (_ "Remove") align "left" name "remove_button"))
(hbox align "right"
(button text (_ "Up") align "right" name "up_button")
(button text (_ "Down") align "right" name "down_button"))

(label colspan 2)

(label text (_ "Layout switching:") align "right")
(combobox name "grp")

(label text (_ "Model:") align "right")
(combobox name "model")

(label colspan 2)

(spacer)
(button text (_ "Apply") align "left" name "apply_button"))

;;; logic

(define (ui- action)
(catch/message
(lambda()
(woo-write "/xkb" action #t 'layout (form-value "layout"))
(ui-read))))

(define (ui-apply)
(catch/message
(lambda()
(woo-write "/xkb"
'submit #t
'update #t
'grp (form-value "grp")
'model (form-value "model")))))

(define (ui-add)
(and (form-popup "/xkb/avail_layout")
(ui-read)))

(define (ui-up) (ui- 'up))
(define (ui-down) (ui- 'down))
(define (ui-remove) (ui- 'remove))

(define (ui-read)
(form-update-enum "layout" (woo-list "/xkb/current_layout"))
(form-update-value-list
'("model" "grp" "layout")
(woo-read-first "/xkb")))

(define (ui-init)
(form-update-enum "model" (woo-list "/xkb/avail_model"))
(form-update-enum "grp" (woo-list "/xkb/avail_grp"))
(form-bind "up_button" "click" ui-up)
(form-bind "down_button" "click" ui-down)
(form-bind "add_button" "click" ui-add)
(form-bind "remove_button" "click" ui-remove)
(form-bind "apply_button" "click" ui-apply)
(ui-read))

(document:root (when loaded (ui-init)))
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin