Compare commits
28 Commits
d0dd41c080
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b88a59a420 | ||
|
|
0af0d8e561 | ||
|
|
1a8a68a631 | ||
|
|
58ef75e455 | ||
|
|
b3b86808ea | ||
|
|
d34e7fdc88 | ||
|
|
37f0d6d0ae | ||
|
|
a538ed14a2 | ||
|
|
463be06955 | ||
|
|
794f7216cd | ||
|
|
0dd701da37 | ||
|
|
80d28f7004 | ||
|
|
1c1331e166 | ||
|
|
03290f61e7 | ||
|
|
720ddd3d99 | ||
|
|
75b2b6e0b2 | ||
|
|
d14b748536 | ||
|
|
318e35242d | ||
|
|
be6d44343e | ||
|
|
7badf24576 | ||
|
|
b1f13bdcac | ||
| 2aff2ff45a | |||
|
|
0b6ba024aa | ||
|
|
a7fc1a84d2 | ||
|
|
4e6e0cad5e | ||
|
|
45425c91d1 | ||
|
|
b341fbe6ca | ||
|
|
51278b9d8f |
38
INSTALL.md
38
INSTALL.md
@@ -1,14 +1,18 @@
|
||||
# Installing
|
||||
|
||||
## Dependencies
|
||||
## Mandatory dependencies
|
||||
|
||||
- Xlib
|
||||
- Xt
|
||||
- Motif
|
||||
- MWM
|
||||
- A C compiler
|
||||
- brightnessctl (for xmbrightness)
|
||||
- xwallpaper
|
||||
|
||||
# Optional dependencies
|
||||
|
||||
- MWM (the reccomended window manager for Xmd)
|
||||
- xsct (display-temperature)
|
||||
- brightnessctl (xmbrightness)
|
||||
- xwallpaper (xmd-load-wallpaper)
|
||||
|
||||
Installing via APK:
|
||||
|
||||
@@ -47,8 +51,28 @@ in their respective subdirectories:
|
||||
# ./build.sh install
|
||||
```
|
||||
|
||||
## Glue
|
||||
|
||||
Xmd includes some scripts to provide a standard interface for common graphical
|
||||
tasks like taking screenshots. These can be installed using `./install.sh` in
|
||||
the `glue` directory.
|
||||
|
||||
## Session
|
||||
|
||||
Xmd includes a startup script and assorted "glue code" to facilitate using it as
|
||||
a desktop environment. It can be installed using `./install.sh` in the `session`
|
||||
directory.
|
||||
Xmd includes several scripts to facilitate using it as a desktop environment. It
|
||||
can be installed using `./install.sh` in the `session` directory. Note that
|
||||
without a configuration in place, the session scripts don't really do anything
|
||||
useful. The next section of this document describes how to install a default
|
||||
configuration.
|
||||
|
||||
## Default configuration
|
||||
|
||||
A default configuration can be installed by running `./install.sh` in the
|
||||
`defaults` directory. It contains:
|
||||
|
||||
- An MWM configuration
|
||||
- .xinitrc and .xsession files
|
||||
- Default startup items
|
||||
- MWM
|
||||
- XMPanel
|
||||
- Default panel replicants
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Xmd
|
||||
|
||||
An X11/Motif desktop environment written in C99.
|
||||
An X11/Motif desktop environment written in C99 and POSIX shell.
|
||||
|
||||

|
||||
|
||||
BIN
assets/screenshot.png
Normal file
BIN
assets/screenshot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 185 KiB |
4
defaults/Xmd/panel/10 Terminal.replicant
Normal file
4
defaults/Xmd/panel/10 Terminal.replicant
Normal file
@@ -0,0 +1,4 @@
|
||||
[Launcher]
|
||||
Name=Terminal
|
||||
Exec=uxterm
|
||||
Icon=Terminal
|
||||
2
defaults/Xmd/panel/80 Battery.replicant
Normal file
2
defaults/Xmd/panel/80 Battery.replicant
Normal file
@@ -0,0 +1,2 @@
|
||||
[Battery]
|
||||
Interval=2
|
||||
3
defaults/Xmd/panel/90 Clock.replicant
Normal file
3
defaults/Xmd/panel/90 Clock.replicant
Normal file
@@ -0,0 +1,3 @@
|
||||
[Clock]
|
||||
Type=Digital
|
||||
Format=%a, %b %d\n%H:%M
|
||||
1
defaults/Xmd/startup/mwm.sh
Executable file
1
defaults/Xmd/startup/mwm.sh
Executable file
@@ -0,0 +1 @@
|
||||
mwm
|
||||
1
defaults/Xmd/startup/panel.sh
Executable file
1
defaults/Xmd/startup/panel.sh
Executable file
@@ -0,0 +1 @@
|
||||
xmpanel
|
||||
5
defaults/install.sh
Executable file
5
defaults/install.sh
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
. ../scripts/flags.sh
|
||||
mkdir -p ~/.Xmd
|
||||
cp -r misc/. ~
|
||||
cp -r Xmd/. ~/.Xmd
|
||||
74
defaults/misc/.mwmrc
Normal file
74
defaults/misc/.mwmrc
Normal file
@@ -0,0 +1,74 @@
|
||||
Menu DefaultRootMenu
|
||||
{
|
||||
"Root Menu" f.title
|
||||
"Terminal" f.exec "uxterm &"
|
||||
"Shuffle Up" f.circle_up
|
||||
"Shuffle Down" f.circle_down
|
||||
"Refresh" f.refresh
|
||||
"Pack Icons" f.pack_icons
|
||||
no-label f.separator
|
||||
"Screen Shot" f.exec "screenshot selection clipboard"
|
||||
no-label f.separator
|
||||
"Restart MWM" f.restart
|
||||
"Quit..." f.exec "xmd-end-session"
|
||||
}
|
||||
|
||||
Menu DefaultWindowMenu
|
||||
{
|
||||
Restore _R Shift Mod4<Key>m f.restore
|
||||
Move _M Mod4<Key>g f.move
|
||||
Size _S Mod4<Key>s f.resize
|
||||
Minimize _n Mod4<Key>h f.minimize
|
||||
Maximize _x Mod4<Key>m f.maximize
|
||||
no-label f.separator
|
||||
"Screen Shot" _e Alt Ctrl<Key>Print f.exec "screenshot window clipboard"
|
||||
no-label f.separator
|
||||
Close _C Mod4<Key>q f.kill
|
||||
}
|
||||
|
||||
Keys DefaultKeyBindings
|
||||
{
|
||||
Mod4<Key>Escape window|icon f.post_wmenu
|
||||
Mod4<Key>Tab root|icon|window f.next_key
|
||||
Mod4 Shift<Key>Tab root|icon|window f.prev_key
|
||||
Mod4<Key>Right root|icon|window f.next_key window
|
||||
Mod4<Key>Left root|icon|window f.prev_key window
|
||||
<Key>Tab icon f.next_key icon
|
||||
Shift<Key>Tab icon f.prev_key icon
|
||||
<Key>Right icon f.next_key icon
|
||||
<Key>Left icon f.prev_key icon
|
||||
Alt Shift Ctrl<Key>exclam root|icon|window f.set_behavior
|
||||
Mod4 Shift<Key>r root|icon|window f.restart
|
||||
Mod4 Shift<Key>q root|icon|window f.quit_mwm
|
||||
Mod4<Key>Return root|icon|window f.exec "uxterm &"
|
||||
Mod4<Key>R root|icon|window f.exec "rofi -show run &"
|
||||
Mod4<Key>space root|icon|window f.exec "rofi -show drun &"
|
||||
<Key>Return icon f.restore
|
||||
<Key>space icon f.post_wmenu
|
||||
|
||||
<Key>XF86MonBrightnessUp root|icon|window f.exec "brightnessctl s --exponent=10 +5%"
|
||||
<Key>XF86MonBrightnessDown root|icon|window f.exec "brightnessctl s --exponent=10 5%-"
|
||||
<Key>XF86AudioRaiseVolume root|icon|window f.exec "pamixer -i 2"
|
||||
<Key>XF86AudioLowerVolume root|icon|window f.exec "pamixer -d 2"
|
||||
Mod4<Key>period root|icon|window f.exec "pamixer -i 2"
|
||||
Mod4<Key>comma root|icon|window f.exec "pamixer -d 2"
|
||||
|
||||
<Key>Print root|icon|window f.exec "screenshot"
|
||||
Ctrl<Key>Print root|icon|window f.exec "screenshot clipboard"
|
||||
Shift<Key>Print root|icon|window f.exec "screenshot selection"
|
||||
Shift Ctrl<Key>Print root|icon|window f.exec "screenshot selection clipboard"
|
||||
Alt<Key>Print icon|window f.exec "screenshot window"
|
||||
|
||||
Mod4<Key>grave window f.next_key icon
|
||||
Mod4<Key>grave root|icon f.next_key window
|
||||
}
|
||||
|
||||
Buttons DefaultButtonBindings
|
||||
{
|
||||
<Btn1Down> icon|frame f.raise
|
||||
<Btn3Down> icon|frame f.post_wmenu
|
||||
<Btn1Down> root f.menu DefaultRootMenu
|
||||
Mod4<Btn1Down> window|icon f.move
|
||||
Mod4<Btn2Down> window|icon f.lower
|
||||
Mod4<Btn3Down> window|icon f.resize
|
||||
}
|
||||
1
defaults/misc/.xinitrc
Normal file
1
defaults/misc/.xinitrc
Normal file
@@ -0,0 +1 @@
|
||||
. ~/.xsession
|
||||
1
defaults/misc/.xsession
Normal file
1
defaults/misc/.xsession
Normal file
@@ -0,0 +1 @@
|
||||
exec dbus-run-session xmd
|
||||
3
glue/install.sh
Executable file
3
glue/install.sh
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
. ../scripts/flags.sh
|
||||
cp src/* "$PREFIX/bin"
|
||||
61
glue/src/display-temperature
Executable file
61
glue/src/display-temperature
Executable file
@@ -0,0 +1,61 @@
|
||||
#!/bin/sh
|
||||
|
||||
name=`basename "$0"`
|
||||
|
||||
isInstalled() {
|
||||
type "$1" > /dev/null
|
||||
}
|
||||
|
||||
mustHaveInstalled() {
|
||||
if ! isInstalled "$1"; then
|
||||
echo "$name: $1 is not installed" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "Usage: $name day | night | daemon" >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
dayTemp=6500
|
||||
nightTemp=4000
|
||||
sunset=17
|
||||
sunrise=7
|
||||
|
||||
if isInstalled xsct
|
||||
then SCT=xsct
|
||||
elif isInstalled sct
|
||||
then SCT=sct
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
"day" | "night" | "daemon")
|
||||
mode="$1"
|
||||
shift 1
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
|
||||
[ "$#" -gt 0 ] && usage
|
||||
|
||||
case "$mode" in
|
||||
"day")
|
||||
$SCT "$dayTemp"
|
||||
;;
|
||||
"night")
|
||||
$SCT "$nightTemp"
|
||||
;;
|
||||
"daemon")
|
||||
while
|
||||
hour=`date +%H`
|
||||
if [ "$hour" -gt "$sunset" ] || [ "$hour" -lt "$sunrise" ]
|
||||
then temp="$nightTemp"
|
||||
else temp="$dayTemp"
|
||||
fi
|
||||
$SCT "$temp"
|
||||
do sleep 4; done
|
||||
;;
|
||||
esac
|
||||
41
glue/src/mount-sftp
Executable file
41
glue/src/mount-sftp
Executable file
@@ -0,0 +1,41 @@
|
||||
#!/bin/sh
|
||||
|
||||
name=`basename $0`
|
||||
|
||||
isInstalled() {
|
||||
type "$1" > /dev/null
|
||||
}
|
||||
|
||||
mustHaveInstalled() {
|
||||
if ! isInstalled "$1"; then
|
||||
echo "$name: $1 is not installed" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "Usage: $name" >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
[ "$#" -gt 0 ] && usage
|
||||
|
||||
sshfsOptions="reconnect,ServerAliveInterval=4,ServerAliveCountMax=10"
|
||||
|
||||
mustHaveInstalled sshfs
|
||||
mustHaveInstalled mountpoint
|
||||
mustHaveInstalled fusermount
|
||||
|
||||
mountsDir="$HOME/Remote"
|
||||
[ -n "$XMD_SFTP_DIR" ] && mountsDir="$XMD_SFTP_DIR"
|
||||
|
||||
for point in "$mountsDir"/*; do
|
||||
# do not deal with files
|
||||
[ -d "$point" ] || continue
|
||||
|
||||
mountpoint "$point" > /dev/null && fusermount -u "$point"
|
||||
|
||||
address=`basename "$point"`
|
||||
echo "mounting $address on $point" >&2
|
||||
sshfs "$address:/" "$point" -o $sshfsOptions
|
||||
done
|
||||
58
glue/src/screenshot
Executable file
58
glue/src/screenshot
Executable file
@@ -0,0 +1,58 @@
|
||||
#!/bin/sh
|
||||
|
||||
name=`basename "$0"`
|
||||
|
||||
isInstalled() {
|
||||
type "$1" > /dev/null
|
||||
}
|
||||
|
||||
mustHaveInstalled() {
|
||||
if ! isInstalled "$1"; then
|
||||
echo "$name: $1 is not installed" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "Usage: $name [selection | window | screen] [clipboard]" >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
picturesDir=`xdg-user-dir PICTURES`
|
||||
test -z "$picturesDir" && picturesDir="$HOME/Pictures"
|
||||
picturesDir="$picturesDir/Screen Shots"
|
||||
|
||||
if ! mkdir -p "$picturesDir"; then
|
||||
echo "$name: can't create $picturesDir" >&2
|
||||
exit 1
|
||||
fi
|
||||
outputFilePath="$picturesDir/`date -Iseconds`.png"
|
||||
|
||||
mustHaveInstalled scrot
|
||||
case "$1" in
|
||||
"selection" | "window" | "screen")
|
||||
mode="$1"
|
||||
shift 1
|
||||
;;
|
||||
*)
|
||||
mode="screen"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ "$1" = "clipboard" ]; then
|
||||
clipboard=true
|
||||
shift 1
|
||||
fi
|
||||
|
||||
[ "$#" -gt 0 ] && usage
|
||||
|
||||
case "$mode" in
|
||||
"selection") scrot --select --line style=dash --freeze --file "$outputFilePath";;
|
||||
"window" ) scrot --focused --border --file "$outputFilePath";;
|
||||
"screen" ) scrot --file "$outputFilePath";;
|
||||
esac
|
||||
|
||||
if [ -n "$copyToClipboard" ]; then
|
||||
mustHaveInstalled xclip
|
||||
xclip -selection clipboard -target image/png -i "$outputFilePath"
|
||||
fi
|
||||
@@ -5,23 +5,26 @@ BUILDFLAGS="$CFLAGS -Iinclude"
|
||||
LINTCHECKS="-checks=-*,clang-analyzer-*,bugprone-*,portability-*,cert-*"
|
||||
SOURCE="src/*.c"
|
||||
|
||||
function build() {
|
||||
build() {
|
||||
mkdir -p lib
|
||||
cc $SOURCE -o "lib/libXmd.so" -shared $BUILDFLAGS || \
|
||||
echo "XXX FAIL!"
|
||||
}
|
||||
|
||||
function lint() {
|
||||
lint() {
|
||||
clang-tidy $SOURCE $LINTCHECKS -- $BUILDFLAGS || \
|
||||
echo "XXX FAIL!"
|
||||
}
|
||||
|
||||
function clean() {
|
||||
clean() {
|
||||
rm -f lib/*
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
install)
|
||||
clean; build
|
||||
mkdir -p "$PREFIX/lib"
|
||||
mkdir -p "$PREFIX/include/Xmd"
|
||||
cp lib/*.so "$PREFIX/lib"
|
||||
cp include/Xmd/*.h "$PREFIX/include/Xmd"
|
||||
clean
|
||||
|
||||
@@ -41,9 +41,9 @@ void XmdBufferResize (XmdBuffer *buffer, Cardinal length) {
|
||||
void XmdBufferFit (XmdBuffer *buffer) {
|
||||
if (buffer->length > buffer->capacity) {
|
||||
buffer->capacity *= XmdBUFFER_GROWTH_FACTOR;
|
||||
void *data = XtReallocArray (
|
||||
void *data = XtRealloc (
|
||||
buffer->data,
|
||||
buffer->capacity,
|
||||
buffer->capacity *
|
||||
buffer->size);
|
||||
if (data == NULL) {
|
||||
/* TODO return error */
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "icons/appWebBrowser.xbm"
|
||||
#include "icons/unknown.xbm"
|
||||
|
||||
void activateLauncher (Widget button, XtPointer clientData, XtPointer callData) {
|
||||
static void activateLauncher (Widget button, XtPointer clientData, XtPointer callData) {
|
||||
(void)(button);
|
||||
(void)(callData);
|
||||
XmdReplicantState *state = (XmdReplicantState *)(clientData);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
. `dirname $0`/flags.sh
|
||||
|
||||
function build() {
|
||||
build() {
|
||||
if
|
||||
mkdir -p bin && \
|
||||
cc $CFLAGS -c -o "bin/$1.o" src/*.c && \
|
||||
@@ -16,7 +16,7 @@ function build() {
|
||||
fi
|
||||
}
|
||||
|
||||
function clean() {
|
||||
clean() {
|
||||
rm -f bin/*
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
. `dirname $0`/flags.sh
|
||||
|
||||
function build() {
|
||||
build() {
|
||||
if
|
||||
mkdir -p lib && \
|
||||
cc src/*.c -o "lib/$1.so" -shared $CFLAGS
|
||||
@@ -15,7 +15,7 @@ function build() {
|
||||
fi
|
||||
}
|
||||
|
||||
function clean() {
|
||||
clean() {
|
||||
rm -f bin/*
|
||||
}
|
||||
|
||||
|
||||
@@ -1,29 +1,48 @@
|
||||
#!/bin/sh
|
||||
|
||||
name=`basename "$0"`
|
||||
|
||||
usage() {
|
||||
echo "Usage: $name" >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
[ "$#" -gt 0 ] && usage
|
||||
|
||||
# basic Xmd environment variables
|
||||
export XMD_SESSION_PID="$$"
|
||||
export XMD_USERDIR="${HOME}/.Xmd"
|
||||
mkdir -p "${XMD_USERDIR}"
|
||||
|
||||
# environment vars that X applications tend to expect
|
||||
export XDG_CURRENT_DESKTOP=Xmd
|
||||
export XDG_SESSION_DESKTOP=Xmd
|
||||
export XDG_SESSION_TYPE=X11
|
||||
|
||||
# replicant path
|
||||
export XMD_REPLICANT_PATH="/usr/lib/Xmd/replicants:/usr/local/lib/Xmd/replicants"
|
||||
localReplicantDir="$HOME/.local/lib/Xmd/replicants"
|
||||
if [ -d "$localReplicantDir" ]; then
|
||||
export XMD_REPLICANT_PATH="$localReplicantDir:$XMD_REPLICANT_PATH"
|
||||
fi
|
||||
|
||||
# load desktop configuration
|
||||
xmd-load-xresources
|
||||
appDefaults="${XMD_USERDIR}/app-defaults"
|
||||
if [ -d "$appDefaults" ]; then
|
||||
export XAPPLRESDIR="$appDefaults"
|
||||
else
|
||||
echo "!!! cant find $appDefaults"
|
||||
echo "$name cant find $appDefaults" >&2
|
||||
fi
|
||||
xmd-load-wallpaper
|
||||
|
||||
# run startup items
|
||||
startupDir="$XMD_USERDIR/startup"
|
||||
if [ -d "$startupDir" ]; then
|
||||
export XMD_STARTUPDIR="$startupDir"
|
||||
xmd-run-startup-items
|
||||
else
|
||||
echo "!!! cant find $startupDir"
|
||||
echo "$name cant find $startupDir" >&2
|
||||
fi
|
||||
|
||||
exec mwm
|
||||
sleep infinity
|
||||
|
||||
17
session/src/xmd-end-session
Executable file
17
session/src/xmd-end-session
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
|
||||
name=`basename "$0"`
|
||||
|
||||
usage() {
|
||||
echo "Usage: $name" >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
[ "$#" -gt 0 ] && usage
|
||||
|
||||
if [ -z "$XMD_SESSION_PID" ]; then
|
||||
echo "$name: session is not running (\$XMD_SESSION_PID not set)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
kill "$XMD_SESSION_PID"
|
||||
@@ -1,9 +1,55 @@
|
||||
#!/bin/sh
|
||||
|
||||
if type "$XMD_USERDIR/wallpaper" > /dev/null; then
|
||||
. "$XMD_USERDIR/wallpaper"
|
||||
|
||||
if type xwallpaper > /dev/null; then
|
||||
xwallpaper "--${mode}" "$file"
|
||||
name=`basename "$0"`
|
||||
configFilePath="$XMD_USERDIR/wallpaper"
|
||||
|
||||
isInstalled() {
|
||||
type "$1" > /dev/null
|
||||
}
|
||||
|
||||
shouldHaveInstalled() {
|
||||
if ! isInstalled "$1"; then
|
||||
echo "$name: $1 is not installed" >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "Usage: $name" >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
[ "$#" -gt 0 ] && usage
|
||||
|
||||
echo $configFilePath
|
||||
if type "$configFilePath" > /dev/null; then
|
||||
color="black"
|
||||
|
||||
while read -r line; do
|
||||
line=`echo $line | sed s/\#.\*$//g`
|
||||
[ -z "$line" ] && continue
|
||||
|
||||
IFS="=" read key value << EOF
|
||||
$line
|
||||
EOF
|
||||
case "$key" in
|
||||
"mode") mode="$value";;
|
||||
"file") file="$value";;
|
||||
"color") color="$value";;
|
||||
*) echo "$name: bad key $key in $configFilePath" >&2;;
|
||||
esac
|
||||
done < "$configFilePath"
|
||||
|
||||
case "$mode" in
|
||||
"" | center | focus | maximize | stretch | tile | zoom) ;;
|
||||
*)
|
||||
echo "$name: bad mode $mode" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
[ -n "$color" ] && shouldHaveInstalled xsetroot && \
|
||||
xsetroot -solid "$color"
|
||||
[ -n "$mode" ] && shouldHaveInstalled xwallpaper && \
|
||||
xwallpaper "--${mode}" "$file"
|
||||
fi
|
||||
|
||||
@@ -1,10 +1,30 @@
|
||||
#!/bin/sh
|
||||
|
||||
xrdb -remove
|
||||
|
||||
name=`basename "$0"`
|
||||
xResources="${XMD_USERDIR}/Xresources"
|
||||
|
||||
isInstalled() {
|
||||
type "$1" > /dev/null
|
||||
}
|
||||
|
||||
mustHaveInstalled() {
|
||||
if ! isInstalled "$1"; then
|
||||
echo "$name: $1 is not installed" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "Usage: $name" >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
[ "$#" -gt 0 ] && usage
|
||||
|
||||
cd ~
|
||||
if [ -r "$xResources" ]; then
|
||||
mustHaveInstalled xrdb
|
||||
xrdb -cpp /usr/bin/cpp < "$xResources"
|
||||
else
|
||||
echo "!!! can't find $xResources"
|
||||
echo "$name: can't find $xResources" >&2
|
||||
fi
|
||||
|
||||
@@ -1,10 +1,19 @@
|
||||
#!/bin/sh
|
||||
|
||||
name=`basename "$0"`
|
||||
|
||||
usage() {
|
||||
echo "Usage: $name" >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
[ "$#" -gt 0 ] && usage
|
||||
|
||||
if [ -z "$XMD_STARTUPDIR" ]; then
|
||||
echo "!!! \$XMD_STARTUPDIR not set"
|
||||
echo "$name \$XMD_STARTUPDIR not set" >&2
|
||||
exit 1
|
||||
fi
|
||||
for item in $XMD_STARTUPDIR/*; do
|
||||
for item in "$XMD_STARTUPDIR"/*; do
|
||||
if [ -x "$item" ]; then
|
||||
"$item" &
|
||||
fi
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
if ! type scrot > /dev/null; then
|
||||
>&2 echo "!!! scrot is not installed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
picturesDir=`xdg-user-dir PICTURES`
|
||||
test -z "$picturesDir" && picturesDir="$HOME/Pictures"
|
||||
picturesDir="$picturesDir/Screen Shots"
|
||||
|
||||
if ! mkdir -p "$picturesDir"; then
|
||||
>&2 echo "!!! can't create $picturesDir"
|
||||
exit 1
|
||||
fi
|
||||
output="$picturesDir/`date -Iseconds`.png"
|
||||
|
||||
case "$1" in
|
||||
"selection")
|
||||
scrot --select --line style=dash --freeze --file "$output"
|
||||
clipArg="$2"
|
||||
;;
|
||||
"window")
|
||||
scrot --focused --border --file "$output"
|
||||
clipArg="$2"
|
||||
;;
|
||||
*)
|
||||
scrot --file "$output"
|
||||
clipArg="$1"
|
||||
;;
|
||||
esac
|
||||
|
||||
if test "$clipArg" = "clipboard"; then
|
||||
xclip -selection clipboard -target image/png -i "$output"
|
||||
fi
|
||||
9
xmdev/src/icons/mount.xbm
Normal file
9
xmdev/src/icons/mount.xbm
Normal file
@@ -0,0 +1,9 @@
|
||||
#define mount_width 24
|
||||
#define mount_height 24
|
||||
static unsigned char mount_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x80, 0xff, 0x01,
|
||||
0xe0, 0x81, 0x07, 0x70, 0x00, 0x0e, 0x30, 0x00, 0x0c, 0x18, 0x00, 0x19,
|
||||
0x18, 0x80, 0x18, 0x0c, 0x40, 0x30, 0x0c, 0x00, 0x30, 0x0c, 0xd8, 0x37,
|
||||
0xec, 0x1b, 0x30, 0x0c, 0x00, 0x30, 0x0c, 0x02, 0x30, 0x18, 0x01, 0x1c,
|
||||
0x98, 0x00, 0x14, 0x30, 0x00, 0x14, 0x70, 0x80, 0xf7, 0xe0, 0x81, 0x80,
|
||||
0x80, 0xff, 0xf7, 0x00, 0x7e, 0x14, 0x00, 0x00, 0x14, 0x00, 0x00, 0x1c };
|
||||
9
xmdev/src/icons/refresh.xbm
Normal file
9
xmdev/src/icons/refresh.xbm
Normal file
@@ -0,0 +1,9 @@
|
||||
#define refresh_width 24
|
||||
#define refresh_height 24
|
||||
static unsigned char refresh_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0xc0, 0xff, 0x00,
|
||||
0xf0, 0xff, 0x03, 0xf8, 0xc0, 0x07, 0x38, 0x00, 0x07, 0x1c, 0x00, 0x0e,
|
||||
0x1c, 0x00, 0x0e, 0x0e, 0x00, 0x1c, 0x0e, 0x00, 0x1c, 0x0e, 0x00, 0x7f,
|
||||
0x0e, 0x00, 0x3e, 0x0e, 0x00, 0x1c, 0x0e, 0x00, 0x08, 0x1c, 0x00, 0x00,
|
||||
0x1c, 0x00, 0x06, 0x38, 0x00, 0x07, 0xf8, 0xc0, 0x07, 0xf0, 0xff, 0x03,
|
||||
0xc0, 0xff, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
9
xmdev/src/icons/unmount.xbm
Normal file
9
xmdev/src/icons/unmount.xbm
Normal file
@@ -0,0 +1,9 @@
|
||||
#define unmount_width 24
|
||||
#define unmount_height 24
|
||||
static unsigned char unmount_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x18, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x7e, 0x00, 0x00, 0xff, 0x00,
|
||||
0x80, 0xff, 0x01, 0xc0, 0xff, 0x03, 0xe0, 0xff, 0x07, 0xf0, 0xff, 0x0f,
|
||||
0xf8, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x1f,
|
||||
0xf8, 0xff, 0x1f, 0xf8, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
317
xmdev/src/main.c
317
xmdev/src/main.c
@@ -1,8 +1,10 @@
|
||||
#define _XOPEN_SOURCE
|
||||
#define _XOPEN_SOURCE 700
|
||||
#include <Xm/Xm.h>
|
||||
#include <Xm/Form.h>
|
||||
#include <Xm/PushB.h>
|
||||
#include <Xm/MainW.h>
|
||||
#include <Xm/Container.h>
|
||||
#include <Xm/IconG.h>
|
||||
#include <Xm/Container.h>
|
||||
#include <Xm/ScrolledW.h>
|
||||
|
||||
#include <Xmd/Icon.h>
|
||||
@@ -12,10 +14,16 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <dirent.h>
|
||||
#include <libgen.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "icons/refresh.xbm"
|
||||
#include "icons/mount.xbm"
|
||||
#include "icons/unmount.xbm"
|
||||
#include "icons/generic.xbm"
|
||||
#include "icons/generic-small.xbm"
|
||||
#include "icons/icon.xbm"
|
||||
@@ -45,6 +53,7 @@ typedef enum {
|
||||
typedef struct {
|
||||
Widget widget;
|
||||
DeviceKind kind;
|
||||
Bool orphaned;
|
||||
String name;
|
||||
String mountPoint;
|
||||
String label;
|
||||
@@ -52,6 +61,7 @@ typedef struct {
|
||||
|
||||
void loadIconPixmaps (void);
|
||||
void refreshDevices (void);
|
||||
void refreshDisks (void);
|
||||
Device * DeviceNew (String name, DeviceKind kind);
|
||||
void DeviceDelete (ConstString name);
|
||||
void DeviceFree (Device *this);
|
||||
@@ -60,6 +70,7 @@ void DeviceSetMountPoint (Device *this, ConstString mountPoint);
|
||||
void DeviceSetLabel (Device *this, ConstString label);
|
||||
int readBlockDevice (FILE *stream, Device **);
|
||||
int readLsblkPair (FILE *stream, String *key, String *value);
|
||||
void handleRefresh (Widget, XtPointer, XtPointer);
|
||||
|
||||
int main (int argc, char *argv[]) {
|
||||
devices = XmdStringMapNew();
|
||||
@@ -69,16 +80,74 @@ int main (int argc, char *argv[]) {
|
||||
NULL, 0,
|
||||
&argc, argv,
|
||||
NULL,
|
||||
XmNtitle, "Devices",
|
||||
XmNtitle, "Devices",
|
||||
XmNiconName, "Devices",
|
||||
XmNwidth, 256,
|
||||
XmNheight, 256,
|
||||
NULL);
|
||||
Pixmap iconPixmap = XmdLoadBitmapIcon(window, icon);
|
||||
|
||||
Widget layout = XtVaCreateWidget (
|
||||
"layout", xmFormWidgetClass, window,
|
||||
XmNorientation, XmVERTICAL,
|
||||
NULL);
|
||||
Pixmap iconPixmap = XmdLoadBitmapIcon(layout, icon);
|
||||
XtVaSetValues (
|
||||
window,
|
||||
XmNiconPixmap, iconPixmap,
|
||||
NULL);
|
||||
|
||||
Pixmap refreshPixmap = XmdLoadBitmapIcon(layout, refresh);
|
||||
XmString string = XmStringCreateLocalized("Refresh");
|
||||
Widget refreshButton = XtVaCreateManagedWidget (
|
||||
"refreshButton", xmPushButtonWidgetClass, layout,
|
||||
XmNleftAttachment, XmATTACH_FORM,
|
||||
XmNbottomAttachment, XmATTACH_FORM,
|
||||
XmNlabelType, XmPIXMAP_AND_STRING,
|
||||
XmNlabelPixmap, refreshPixmap,
|
||||
XmNlabelString, string,
|
||||
NULL);
|
||||
XmStringFree(string);
|
||||
XtAddCallback (
|
||||
refreshButton, XmNactivateCallback,
|
||||
handleRefresh, NULL);
|
||||
|
||||
Pixmap mountPixmap = XmdLoadBitmapIcon(layout, mount);
|
||||
string = XmStringCreateLocalized("Mount");
|
||||
Widget mountButton = XtVaCreateManagedWidget (
|
||||
"mountButton", xmPushButtonWidgetClass, layout,
|
||||
XmNleftAttachment, XmATTACH_WIDGET,
|
||||
XmNleftWidget, refreshButton,
|
||||
XmNbottomAttachment, XmATTACH_FORM,
|
||||
XmNlabelType, XmPIXMAP_AND_STRING,
|
||||
XmNlabelPixmap, mountPixmap,
|
||||
XmNlabelString, string,
|
||||
NULL);
|
||||
XmStringFree(string);
|
||||
|
||||
Pixmap unmountPixmap = XmdLoadBitmapIcon(layout, unmount);
|
||||
string = XmStringCreateLocalized("Unmount");
|
||||
/*Widget unmountButton = */XtVaCreateManagedWidget (
|
||||
"unmountButton", xmPushButtonWidgetClass, layout,
|
||||
XmNleftAttachment, XmATTACH_WIDGET,
|
||||
XmNleftWidget, mountButton,
|
||||
XmNbottomAttachment, XmATTACH_FORM,
|
||||
XmNlabelType, XmPIXMAP_AND_STRING,
|
||||
XmNlabelPixmap, unmountPixmap,
|
||||
XmNlabelString, string,
|
||||
NULL);
|
||||
XmStringFree(string);
|
||||
|
||||
Widget scroller = XtVaCreateWidget (
|
||||
"scroll", xmScrolledWindowWidgetClass, layout,
|
||||
XmNscrollingPolicy, XmAUTOMATIC,
|
||||
XmNleftAttachment, XmATTACH_FORM,
|
||||
XmNtopAttachment, XmATTACH_FORM,
|
||||
XmNrightAttachment, XmATTACH_FORM,
|
||||
XmNbottomAttachment, XmATTACH_WIDGET,
|
||||
XmNbottomWidget, refreshButton,
|
||||
NULL);
|
||||
container = XtVaCreateManagedWidget (
|
||||
"container", xmContainerWidgetClass, window,
|
||||
"container", xmContainerWidgetClass, scroller,
|
||||
XmNlayoutType, XmSPATIAL,
|
||||
XmNspatialStyle, XmGRID,
|
||||
NULL);
|
||||
@@ -86,6 +155,8 @@ int main (int argc, char *argv[]) {
|
||||
loadIconPixmaps();
|
||||
refreshDevices();
|
||||
|
||||
XtManageChild(scroller);
|
||||
XtManageChild(layout);
|
||||
XtRealizeWidget(window);
|
||||
XtAppMainLoop(application);
|
||||
}
|
||||
@@ -101,145 +172,123 @@ void loadIconPixmaps (void) {
|
||||
dev(TTY, tty);
|
||||
}
|
||||
|
||||
void handleRefresh (Widget button, XtPointer clientData, XtPointer callData) {
|
||||
(void)(button);
|
||||
(void)(clientData);
|
||||
(void)(callData);
|
||||
refreshDevices();
|
||||
}
|
||||
|
||||
Bool markDevice (XmdStringMap *map, ConstString key, void *value, void *data) {
|
||||
(void)(map);
|
||||
(void)(key);
|
||||
(void)(data);
|
||||
Device *this = value;
|
||||
this->orphaned = True;
|
||||
return True;
|
||||
}
|
||||
|
||||
Bool transferDevice (XmdStringMap *map, ConstString key, void *value, void *data) {
|
||||
(void)(map);
|
||||
(void)(key);
|
||||
(void)(data);
|
||||
Device *this = value;
|
||||
if (this->orphaned) {
|
||||
DeviceFree(this);
|
||||
} else {
|
||||
XmdStringMapSet(devices, key, value);
|
||||
}
|
||||
return True;
|
||||
}
|
||||
|
||||
void refreshDevices (void) {
|
||||
XtUnmanageChild(container);
|
||||
|
||||
pid_t child = 0;
|
||||
FILE *stream = XmdVaPipedExecPath (
|
||||
"lsblk", &child, "r",
|
||||
"", "-P", "-o", "NAME,TYPE,MOUNTPOINTS,LABEL", NULL);
|
||||
if (stream == NULL) {
|
||||
/* TODO error */
|
||||
return;
|
||||
}
|
||||
Device *device = NULL;
|
||||
while (readBlockDevice(stream, &device) != EOF) {
|
||||
/* do something with device? */
|
||||
}
|
||||
fclose(stream);
|
||||
waitpid(child, NULL, 0);
|
||||
|
||||
/* pre-mark all devices as orphaned */
|
||||
XmdStringMapIterate(devices, markDevice, NULL);
|
||||
|
||||
/* refresh devices by category */
|
||||
refreshDisks();
|
||||
|
||||
/* create a new map, only moving over extant devices */
|
||||
XmdStringMap *oldMap = devices;
|
||||
devices = XmdStringMapNew();
|
||||
XmdStringMapIterate(oldMap, transferDevice, NULL);
|
||||
XmdStringMapFree(oldMap);
|
||||
|
||||
XtManageChild(container);
|
||||
}
|
||||
|
||||
int readBlockDevice (FILE *stream, Device **device) {
|
||||
DeviceKind kind = DeviceKindGeneric;
|
||||
String name = NULL;
|
||||
String mountPoint = NULL;
|
||||
String label = NULL;
|
||||
|
||||
int ch = 0;
|
||||
while (1) {
|
||||
String key = NULL;
|
||||
String value = NULL;
|
||||
ch = readLsblkPair(stream, &key, &value);
|
||||
|
||||
if (strcmp(key, "NAME") == 0) {
|
||||
XtFree(name);
|
||||
name = value;
|
||||
} else if (strcmp(key, "TYPE") == 0) {
|
||||
if (strcmp(value, "disk") == 0) {
|
||||
kind = DeviceKindDisk;
|
||||
} else if (strcmp(value, "rom") == 0) {
|
||||
kind = DeviceKindRom;
|
||||
} else if (strcmp(value, "part") == 0) {
|
||||
kind = DeviceKindFilesystem;
|
||||
}
|
||||
XtFree(value);
|
||||
} else if (strcmp(key, "MOUNTPOINTS") == 0) {
|
||||
XtFree(mountPoint);
|
||||
mountPoint = value;
|
||||
} else if (strcmp(key, "LABEL") == 0) {
|
||||
XtFree(label);
|
||||
label = value;
|
||||
} else {
|
||||
XtFree(value);
|
||||
}
|
||||
XtFree(key);
|
||||
|
||||
while ((ch = fgetc(stream)) == ' ');
|
||||
if (ch == EOF || ch == '\n') break;
|
||||
ungetc(ch, stream);
|
||||
}
|
||||
|
||||
if (name != NULL) {
|
||||
*device = XmdStringMapGet(devices, name);
|
||||
if (*device == NULL) {
|
||||
*device = DeviceNew(name, kind);
|
||||
} else {
|
||||
DeviceSetKind(*device, kind);
|
||||
}
|
||||
DeviceSetMountPoint(*device, mountPoint);
|
||||
DeviceSetLabel(*device, label);
|
||||
}
|
||||
|
||||
XtFree(name);
|
||||
XtFree(mountPoint);
|
||||
XtFree(label);
|
||||
return ch;
|
||||
String diskName (ConstString directory, ConstString name) {
|
||||
char fullpath[PATH_MAX];
|
||||
snprintf(fullpath, XtNumber(fullpath), "%s/%s", directory, name);
|
||||
char resolved[PATH_MAX];
|
||||
return XtNewString(basename(realpath(fullpath, resolved)));
|
||||
}
|
||||
|
||||
int readLsblkPair (FILE *stream, String *key, String *value) {
|
||||
int ch = 0;
|
||||
int escapeCh = 0;
|
||||
char null = 0;
|
||||
void refreshDisks (void) {
|
||||
/* get disks */
|
||||
ConstString disksById = "/dev/disk/by-id";
|
||||
ConstString disksByLabel = "/dev/disk/by-label";
|
||||
ConstString disksByPartuuid = "/dev/disk/by-partuuid";
|
||||
|
||||
*key = NULL;
|
||||
*value = NULL;
|
||||
|
||||
XmdBuffer *keyBuffer = XmdBufferNew(char);
|
||||
while (isalpha(ch = fgetc(stream))) XmdBufferPush(keyBuffer, &ch);
|
||||
XmdBufferPush(keyBuffer, &null);
|
||||
*key = XmdBufferBreak(keyBuffer);
|
||||
|
||||
fgetc(stream); /* skip = */
|
||||
|
||||
XmdBuffer *valueBuffer = XmdBufferNew(char);
|
||||
enum {
|
||||
stateGetString,
|
||||
stateGetEscape,
|
||||
|
||||
} state = stateGetString;
|
||||
while (1) {
|
||||
ch = fgetc(stream);
|
||||
if (ch == EOF) goto end;
|
||||
|
||||
switch (state) {
|
||||
case stateGetString:
|
||||
switch (ch) {
|
||||
case '"': goto end;
|
||||
case '\\': state = stateGetEscape; break;
|
||||
default: XmdBufferPush(valueBuffer, &ch); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case stateGetEscape:
|
||||
ch = fgetc(stream); /* skip x */
|
||||
int digit = tolower(ch);
|
||||
if (
|
||||
(digit < '0' || digit > '9') &&
|
||||
(digit < 'a' || digit > 'f')
|
||||
) {
|
||||
ungetc(ch, stream);
|
||||
XmdBufferPush(valueBuffer, &escapeCh);
|
||||
state = stateGetString;
|
||||
break;
|
||||
}
|
||||
digit -= '0';
|
||||
if (digit > 9) digit -= 'a' - '9' - 1;
|
||||
escapeCh *= 16;
|
||||
escapeCh += digit;
|
||||
break;
|
||||
struct dirent **entries = NULL;
|
||||
int entriesCount = scandir(disksById, &entries, NULL, alphasort);
|
||||
if (entriesCount < 0) {
|
||||
/* TODO error message */
|
||||
return;
|
||||
}
|
||||
for (int index = 0; index < entriesCount; index ++) {
|
||||
struct dirent *entry = entries[index];
|
||||
if (entry->d_name[0] == '.') {
|
||||
XtFree((char *)(entry));
|
||||
continue;
|
||||
}
|
||||
String deviceName = diskName(disksById, entry->d_name);
|
||||
XtFree((char *)(entry));
|
||||
|
||||
Device *device = XmdStringMapGet(devices, deviceName);
|
||||
if (device == NULL) {
|
||||
device = DeviceNew(deviceName, DeviceKindDisk);
|
||||
} else {
|
||||
device->orphaned = False;
|
||||
DeviceSetKind(device, DeviceKindDisk);
|
||||
}
|
||||
|
||||
XtFree(deviceName);
|
||||
}
|
||||
end:
|
||||
XmdBufferPush(valueBuffer, &null);
|
||||
*value = XmdBufferBreak(valueBuffer);
|
||||
if (strlen(*value) == 0) {
|
||||
XtFree(*value);
|
||||
*value = NULL;
|
||||
XtFree((char *)(entries));
|
||||
|
||||
/* determine disk types */
|
||||
DIR *dir = opendir(disksByPartuuid);
|
||||
if (dir == NULL) {
|
||||
/* TODO error message */
|
||||
return;
|
||||
}
|
||||
return ch;
|
||||
struct dirent *entry;
|
||||
while ((entry = readdir(dir)) != NULL) {
|
||||
if (entry->d_name[0] == '.') continue;
|
||||
String deviceName = diskName(disksByPartuuid, entry->d_name);
|
||||
Device *device = XmdStringMapGet(devices, deviceName);
|
||||
if (device != NULL) DeviceSetKind(device, DeviceKindFilesystem);
|
||||
XtFree(deviceName);
|
||||
}
|
||||
closedir(dir);
|
||||
|
||||
/* determine partition labels */
|
||||
dir = opendir(disksByLabel);
|
||||
if (dir == NULL) {
|
||||
/* TODO error message */
|
||||
return;
|
||||
}
|
||||
while ((entry = readdir(dir)) != NULL) {
|
||||
if (entry->d_name[0] == '.') continue;
|
||||
String deviceName = diskName(disksByLabel, entry->d_name);
|
||||
Device *device = XmdStringMapGet(devices, deviceName);
|
||||
if (device != NULL) DeviceSetLabel(device, entry->d_name);
|
||||
XtFree(deviceName);
|
||||
}
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
Device *DeviceNew (String name, DeviceKind kind) {
|
||||
@@ -247,10 +296,11 @@ Device *DeviceNew (String name, DeviceKind kind) {
|
||||
this->mountPoint = NULL;
|
||||
this->label = NULL;
|
||||
this->name = XtNewString(name);
|
||||
this->orphaned = False;
|
||||
XmString string = XmStringCreateLocalized(name);
|
||||
this->widget = XtVaCreateManagedWidget (
|
||||
"device", xmIconGadgetClass, container,
|
||||
XmNalignment, XmALIGNMENT_CENTER,
|
||||
XmNalignment, XmALIGNMENT_BEGINNING,
|
||||
XmNlabelString, string,
|
||||
NULL);
|
||||
XmStringFree(string);
|
||||
@@ -265,6 +315,7 @@ void DeviceDelete (ConstString name) {
|
||||
|
||||
void DeviceFree (Device *this) {
|
||||
if (this == NULL) return;
|
||||
XtUnmanageChild(this->widget);
|
||||
XtDestroyWidget(this->widget);
|
||||
XtFree((char *)(this->name));
|
||||
XtFree((char *)(this->mountPoint));
|
||||
|
||||
2
xmfile/build.sh
Executable file
2
xmfile/build.sh
Executable file
@@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
../scripts/buildapp.sh xmpackage "$@"
|
||||
9
xmfile/src/icons/block-small.xbm
Normal file
9
xmfile/src/icons/block-small.xbm
Normal file
@@ -0,0 +1,9 @@
|
||||
#define block_small_width 24
|
||||
#define block_small_height 24
|
||||
static unsigned char block_small_bits[] = {
|
||||
0xff, 0xff, 0x0f, 0x01, 0x00, 0x10, 0x01, 0x3c, 0x20, 0x81, 0xc3, 0x41,
|
||||
0xc1, 0x00, 0x83, 0x21, 0x00, 0x84, 0x11, 0x00, 0x88, 0x19, 0x00, 0x99,
|
||||
0x09, 0x80, 0x90, 0x09, 0x40, 0x90, 0xe5, 0x00, 0xa0, 0x05, 0x1b, 0xa0,
|
||||
0x05, 0xd8, 0xa0, 0x05, 0x00, 0xa7, 0x09, 0x02, 0x90, 0x09, 0x01, 0x90,
|
||||
0x99, 0x0c, 0x98, 0x11, 0xf8, 0x88, 0x21, 0xe0, 0x8f, 0xc1, 0x80, 0xbf,
|
||||
0x81, 0xc3, 0xbf, 0x01, 0x3c, 0xbc, 0x01, 0x00, 0x80, 0xff, 0xff, 0xff };
|
||||
27
xmfile/src/icons/block.xbm
Normal file
27
xmfile/src/icons/block.xbm
Normal file
@@ -0,0 +1,27 @@
|
||||
#define block_width 48
|
||||
#define block_height 48
|
||||
static unsigned char block_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xfc, 0xff, 0xff, 0xff, 0xff, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02,
|
||||
0xf4, 0xff, 0xff, 0xff, 0xff, 0x04, 0x14, 0x00, 0xf0, 0x0f, 0x00, 0x09,
|
||||
0xf4, 0xff, 0xff, 0xff, 0xff, 0x13, 0x14, 0x80, 0x0f, 0xf0, 0x01, 0x24,
|
||||
0xf4, 0xff, 0x01, 0x80, 0xff, 0x2f, 0x14, 0x70, 0x00, 0x00, 0x0e, 0x28,
|
||||
0xf4, 0x3f, 0x00, 0x00, 0xfc, 0x2f, 0x14, 0x0c, 0x00, 0x00, 0x30, 0x28,
|
||||
0xf4, 0x07, 0x00, 0x00, 0xe0, 0x2f, 0x14, 0x07, 0x00, 0x00, 0xe4, 0x28,
|
||||
0xf4, 0x03, 0x00, 0x00, 0xc2, 0x2f, 0x94, 0x01, 0x00, 0x00, 0x81, 0x29,
|
||||
0xf4, 0x01, 0x00, 0x80, 0x80, 0x2f, 0xd4, 0x00, 0x00, 0x40, 0x00, 0x2b,
|
||||
0xf4, 0x00, 0x00, 0x20, 0x30, 0x2f, 0xd4, 0x00, 0x00, 0x10, 0x0c, 0x2b,
|
||||
0x74, 0x00, 0xc0, 0x03, 0x03, 0x2e, 0x74, 0x00, 0x60, 0xc5, 0x00, 0x2e,
|
||||
0x74, 0x00, 0x30, 0x0a, 0x00, 0x2e, 0x74, 0x00, 0x90, 0x0d, 0x00, 0x2e,
|
||||
0x74, 0x00, 0xb0, 0x09, 0x00, 0x2e, 0x74, 0x00, 0x50, 0x0c, 0x00, 0x2e,
|
||||
0x74, 0x00, 0xa6, 0x06, 0x00, 0x2e, 0x74, 0xe0, 0xc1, 0x03, 0x00, 0x2e,
|
||||
0xf4, 0x1c, 0x08, 0x00, 0x00, 0x2f, 0xd4, 0x00, 0x04, 0x00, 0x00, 0x2b,
|
||||
0xf4, 0x00, 0x02, 0x00, 0x00, 0x2f, 0x94, 0x01, 0x01, 0x00, 0x80, 0x29,
|
||||
0xf4, 0x81, 0xc0, 0x01, 0x80, 0x2f, 0x14, 0x43, 0x80, 0x0f, 0xc0, 0x28,
|
||||
0xf4, 0x27, 0x00, 0xf6, 0xe0, 0x2f, 0x14, 0x06, 0x00, 0x18, 0x6f, 0x28,
|
||||
0xf4, 0x0f, 0x00, 0x20, 0xf0, 0x2f, 0x14, 0x38, 0x00, 0xc0, 0x00, 0x2b,
|
||||
0xf4, 0x7f, 0x00, 0x00, 0x43, 0x2e, 0x14, 0xe0, 0x01, 0x80, 0x87, 0x2a,
|
||||
0xf4, 0xff, 0x0f, 0xf0, 0x1f, 0x2e, 0x14, 0x00, 0xfe, 0x7f, 0xe0, 0x29,
|
||||
0xf4, 0xff, 0xff, 0xff, 0xff, 0x2f, 0xf4, 0xff, 0xff, 0xff, 0xff, 0x2f,
|
||||
0x04, 0x00, 0x00, 0x00, 0x00, 0x20, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x3f,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
9
xmfile/src/icons/character-small.xbm
Normal file
9
xmfile/src/icons/character-small.xbm
Normal file
@@ -0,0 +1,9 @@
|
||||
#define character_small_width 24
|
||||
#define character_small_height 24
|
||||
static unsigned char character_small_bits[] = {
|
||||
0x80, 0xff, 0x01, 0x40, 0x00, 0x02, 0x40, 0x00, 0x02, 0xf8, 0xff, 0x1f,
|
||||
0x44, 0x00, 0x22, 0x44, 0x00, 0x22, 0xfc, 0xaa, 0x3e, 0x4c, 0x00, 0x32,
|
||||
0x4c, 0x00, 0x32, 0x48, 0xff, 0x12, 0x48, 0x81, 0x12, 0x68, 0xff, 0x16,
|
||||
0x68, 0x81, 0x16, 0xf8, 0x7e, 0x1f, 0x80, 0x81, 0x01, 0x00, 0xff, 0x00,
|
||||
0x00, 0x3e, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x32, 0x00, 0x00, 0x26, 0x00,
|
||||
0x00, 0x08, 0x00, 0x00, 0x32, 0x00, 0x00, 0x26, 0x00, 0x00, 0x14, 0x00 };
|
||||
27
xmfile/src/icons/character.xbm
Normal file
27
xmfile/src/icons/character.xbm
Normal file
@@ -0,0 +1,27 @@
|
||||
#define character_width 48
|
||||
#define character_height 48
|
||||
static unsigned char character_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xe0, 0xff, 0xff, 0x07, 0x00, 0x00, 0x30, 0x00, 0x00, 0x0c, 0x00,
|
||||
0x00, 0x30, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x30, 0x00, 0x20, 0x0d, 0x00,
|
||||
0x00, 0x30, 0x00, 0x00, 0x0c, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07,
|
||||
0x30, 0x20, 0x00, 0x00, 0x04, 0x0c, 0x10, 0x20, 0x00, 0x00, 0x04, 0x08,
|
||||
0x10, 0x20, 0x00, 0x00, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00, 0x04, 0x08,
|
||||
0x10, 0x20, 0x00, 0x00, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00, 0x04, 0x08,
|
||||
0x10, 0xf0, 0xff, 0xff, 0x0f, 0x08, 0xd0, 0xff, 0xff, 0xff, 0xff, 0x0b,
|
||||
0xf0, 0x1f, 0x00, 0x00, 0xf8, 0x0f, 0x70, 0x18, 0x00, 0x00, 0x18, 0x0e,
|
||||
0x70, 0x18, 0x00, 0x00, 0x18, 0x0e, 0x60, 0x98, 0xff, 0xff, 0x19, 0x06,
|
||||
0x40, 0x98, 0x00, 0x00, 0x19, 0x02, 0x40, 0x98, 0xff, 0xff, 0x19, 0x02,
|
||||
0xc0, 0x9c, 0x00, 0x00, 0x39, 0x03, 0xc0, 0x9c, 0xff, 0xff, 0x39, 0x03,
|
||||
0xc0, 0x9c, 0x00, 0x00, 0x39, 0x03, 0x80, 0x34, 0xff, 0xff, 0x2c, 0x01,
|
||||
0x80, 0x74, 0x02, 0x40, 0x2e, 0x01, 0x80, 0xe7, 0xfc, 0x3f, 0xe7, 0x01,
|
||||
0x80, 0xc7, 0x01, 0x80, 0xe3, 0x01, 0x00, 0x83, 0xff, 0xff, 0xc1, 0x00,
|
||||
0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x1f, 0x00, 0x00,
|
||||
0x00, 0x00, 0x58, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x98, 0x1c, 0x00, 0x00,
|
||||
0x00, 0x00, 0x38, 0x19, 0x00, 0x00, 0x00, 0x00, 0x58, 0x1a, 0x00, 0x00,
|
||||
0x00, 0x00, 0x98, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x38, 0x19, 0x00, 0x00,
|
||||
0x00, 0x00, 0x58, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x90, 0x14, 0x00, 0x00,
|
||||
0x00, 0x00, 0x38, 0x19, 0x00, 0x00, 0x00, 0x00, 0x48, 0x0a, 0x00, 0x00,
|
||||
0x00, 0x00, 0x90, 0x14, 0x00, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
9
xmfile/src/icons/directory-small.xbm
Normal file
9
xmfile/src/icons/directory-small.xbm
Normal file
@@ -0,0 +1,9 @@
|
||||
#define directory_small_width 24
|
||||
#define directory_small_height 24
|
||||
static unsigned char directory_small_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x56, 0xff, 0x1f,
|
||||
0xaa, 0xaa, 0x2a, 0xfe, 0xff, 0x7f, 0x02, 0x00, 0x40, 0x02, 0x00, 0x40,
|
||||
0x02, 0x00, 0x40, 0x02, 0x00, 0x40, 0x02, 0x00, 0x40, 0x02, 0x00, 0x40,
|
||||
0x02, 0x00, 0x40, 0x02, 0x00, 0x40, 0x02, 0x00, 0x40, 0x02, 0x00, 0x40,
|
||||
0x02, 0x00, 0x40, 0x02, 0x00, 0x40, 0x02, 0x00, 0x40, 0xfa, 0xff, 0x5f,
|
||||
0x02, 0x00, 0x40, 0xfe, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
27
xmfile/src/icons/directory.xbm
Normal file
27
xmfile/src/icons/directory.xbm
Normal file
@@ -0,0 +1,27 @@
|
||||
#define directory_width 48
|
||||
#define directory_height 48
|
||||
static unsigned char directory_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x07, 0x00, 0x00, 0x00,
|
||||
0xf8, 0xff, 0x0f, 0x00, 0x00, 0x00, 0xb8, 0xaa, 0xfe, 0xff, 0xff, 0x0f,
|
||||
0x58, 0x55, 0xfd, 0xff, 0xff, 0x1f, 0xb8, 0xaa, 0xaa, 0xaa, 0xaa, 0x1a,
|
||||
0xf8, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x3f,
|
||||
0x0c, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x30,
|
||||
0x0c, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x30,
|
||||
0x0c, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x30,
|
||||
0x0c, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x30,
|
||||
0x0c, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x30,
|
||||
0x0c, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x30,
|
||||
0x0c, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x30,
|
||||
0x0c, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x30,
|
||||
0x0c, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x30,
|
||||
0x0c, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x30,
|
||||
0x0c, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x30,
|
||||
0x0c, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x30,
|
||||
0x0c, 0x00, 0x00, 0x00, 0x00, 0x30, 0xec, 0xff, 0xff, 0xff, 0xff, 0x37,
|
||||
0x0c, 0x00, 0x00, 0x00, 0x00, 0x30, 0xec, 0xff, 0xff, 0xff, 0xff, 0x37,
|
||||
0x0c, 0x00, 0x00, 0x00, 0x00, 0x30, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x3f,
|
||||
0xf8, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
9
xmfile/src/icons/file-small.xbm
Normal file
9
xmfile/src/icons/file-small.xbm
Normal file
@@ -0,0 +1,9 @@
|
||||
#define file_small_width 24
|
||||
#define file_small_height 24
|
||||
static unsigned char file_small_bits[] = {
|
||||
0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x10, 0x80, 0x01, 0x10, 0x80, 0x02,
|
||||
0x90, 0xaf, 0x04, 0x10, 0x80, 0x0f, 0x90, 0x3b, 0x08, 0x10, 0x00, 0x08,
|
||||
0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08,
|
||||
0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08,
|
||||
0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0x10, 0x00, 0x08,
|
||||
0x10, 0x00, 0x08, 0x10, 0x00, 0x08, 0xf0, 0xff, 0x0f, 0x00, 0x00, 0x00 };
|
||||
27
xmfile/src/icons/file.xbm
Normal file
27
xmfile/src/icons/file.xbm
Normal file
@@ -0,0 +1,27 @@
|
||||
#define file_width 48
|
||||
#define file_height 48
|
||||
static unsigned char file_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0xff, 0x03, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00, 0x07, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0d, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00, 0x19, 0x00, 0x00, 0x03, 0x00, 0x00, 0x31, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00, 0x61, 0x00, 0x00, 0xc3, 0xff, 0x2b, 0xff, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xc3, 0xf7, 0x3f, 0xc0, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00, 0xc0, 0x00, 0x00, 0xc3, 0xfb, 0x37, 0xc0, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x03, 0x00, 0x00, 0xc0, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x03, 0x00, 0x00, 0xc0, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x03, 0x00, 0x00, 0xc0, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x03, 0x00, 0x00, 0xc0, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x03, 0x00, 0x00, 0xc0, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x03, 0x00, 0x00, 0xc0, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x03, 0x00, 0x00, 0xc0, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x03, 0x00, 0x00, 0xc0, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x03, 0x00, 0x00, 0xc0, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x03, 0x00, 0x00, 0xc0, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x03, 0x00, 0x00, 0xc0, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x03, 0x00, 0x00, 0xc0, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x03, 0x00, 0x00, 0xc0, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x03, 0x00, 0x00, 0xc0, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x03, 0x00, 0x00, 0xc0, 0x00,
|
||||
0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
27
xmfile/src/icons/icon.xbm
Normal file
27
xmfile/src/icons/icon.xbm
Normal file
@@ -0,0 +1,27 @@
|
||||
#define icon_width 48
|
||||
#define icon_height 48
|
||||
static unsigned char icon_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xfe, 0xff, 0xff, 0x7f, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x7f, 0x00,
|
||||
0x00, 0x06, 0x00, 0x00, 0x60, 0x00, 0x00, 0xf6, 0xff, 0xff, 0x6f, 0x00,
|
||||
0x00, 0x16, 0x00, 0x00, 0x68, 0x00, 0x00, 0x56, 0x00, 0x00, 0x6a, 0x00,
|
||||
0x00, 0x16, 0x00, 0x00, 0x68, 0x00, 0x00, 0x16, 0x00, 0x00, 0x68, 0x00,
|
||||
0x00, 0x16, 0x00, 0x00, 0x68, 0x00, 0x00, 0x16, 0xf8, 0x1f, 0x68, 0x00,
|
||||
0x00, 0x16, 0x08, 0x10, 0x68, 0x00, 0x00, 0x16, 0x08, 0x10, 0x68, 0x00,
|
||||
0x00, 0x16, 0xf8, 0x1f, 0x68, 0x00, 0x00, 0x16, 0x00, 0x00, 0x68, 0x00,
|
||||
0x00, 0x16, 0x08, 0x10, 0x68, 0x00, 0x00, 0x16, 0xf8, 0x1f, 0x68, 0x00,
|
||||
0x00, 0x16, 0x00, 0x00, 0x68, 0x00, 0x00, 0x16, 0x00, 0x00, 0x68, 0x00,
|
||||
0x00, 0x56, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x16, 0x00, 0x00, 0x68, 0x00,
|
||||
0x00, 0xf6, 0xff, 0xff, 0x6f, 0x00, 0x00, 0x06, 0x00, 0x00, 0x60, 0x00,
|
||||
0x00, 0xf6, 0xff, 0xff, 0x6f, 0x00, 0x00, 0x36, 0x00, 0x00, 0x6c, 0x00,
|
||||
0x00, 0xf6, 0xff, 0xff, 0x6f, 0x00, 0x00, 0x36, 0x00, 0x00, 0x6c, 0x00,
|
||||
0x00, 0xf6, 0xff, 0xff, 0x6f, 0x00, 0x00, 0x16, 0x00, 0x00, 0x68, 0x00,
|
||||
0x00, 0x56, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x16, 0x00, 0x00, 0x68, 0x00,
|
||||
0x00, 0x16, 0x00, 0x00, 0x68, 0x00, 0x00, 0x16, 0x00, 0x00, 0x68, 0x00,
|
||||
0x00, 0x16, 0xf8, 0x1f, 0x68, 0x00, 0x00, 0x16, 0x08, 0x10, 0x68, 0x00,
|
||||
0x00, 0x16, 0x08, 0x10, 0x68, 0x00, 0x00, 0x16, 0xf8, 0x1f, 0x68, 0x00,
|
||||
0x00, 0x16, 0x00, 0x00, 0x68, 0x00, 0x00, 0x16, 0x08, 0x10, 0x68, 0x00,
|
||||
0x00, 0x16, 0xf8, 0x1f, 0x68, 0x00, 0x00, 0x16, 0x00, 0x00, 0x68, 0x00,
|
||||
0x00, 0x16, 0x00, 0x00, 0x68, 0x00, 0x00, 0x56, 0x00, 0x00, 0x6a, 0x00,
|
||||
0x00, 0x1e, 0x00, 0x00, 0x78, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x7f, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
9
xmfile/src/icons/link-small.xbm
Normal file
9
xmfile/src/icons/link-small.xbm
Normal file
@@ -0,0 +1,9 @@
|
||||
#define link_small_width 24
|
||||
#define link_small_height 24
|
||||
static unsigned char link_small_bits[] = {
|
||||
0x00, 0x00, 0x0c, 0x00, 0x00, 0x33, 0x00, 0x80, 0x4c, 0x00, 0x40, 0x52,
|
||||
0x00, 0x20, 0xa1, 0x00, 0x90, 0xa0, 0x00, 0x48, 0xa0, 0x00, 0x24, 0x90,
|
||||
0x00, 0x12, 0x48, 0x00, 0x79, 0x24, 0x80, 0x95, 0x12, 0x40, 0xa5, 0x09,
|
||||
0x20, 0x45, 0x05, 0x90, 0x4a, 0x03, 0x48, 0xb2, 0x01, 0x24, 0x9c, 0x00,
|
||||
0x12, 0x48, 0x00, 0x0a, 0x24, 0x00, 0x05, 0x12, 0x00, 0x05, 0x09, 0x00,
|
||||
0x8a, 0x04, 0x00, 0x72, 0x02, 0x00, 0x0c, 0x01, 0x00, 0xf0, 0x00, 0x00 };
|
||||
27
xmfile/src/icons/link.xbm
Normal file
27
xmfile/src/icons/link.xbm
Normal file
@@ -0,0 +1,27 @@
|
||||
#define link_width 48
|
||||
#define link_height 48
|
||||
static unsigned char link_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x87, 0x07, 0x00, 0x00, 0x00, 0x80, 0x01, 0x0e,
|
||||
0x00, 0x00, 0x00, 0xc0, 0x70, 0x18, 0x00, 0x00, 0x00, 0x60, 0xdc, 0x31,
|
||||
0x00, 0x00, 0x00, 0x30, 0x06, 0x33, 0x00, 0x00, 0x00, 0x18, 0x03, 0x66,
|
||||
0x00, 0x00, 0x00, 0x8c, 0x01, 0x64, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xcc,
|
||||
0x00, 0x00, 0x00, 0x63, 0x00, 0xc8, 0x00, 0x00, 0x80, 0x31, 0x00, 0xcc,
|
||||
0x00, 0x00, 0xc0, 0x18, 0x00, 0xc4, 0x00, 0x00, 0x60, 0x0c, 0x00, 0x66,
|
||||
0x00, 0x00, 0x30, 0x06, 0x00, 0x63, 0x00, 0x00, 0x18, 0x03, 0x80, 0x31,
|
||||
0x00, 0x00, 0x8c, 0x03, 0xc0, 0x18, 0x00, 0x00, 0xc6, 0x0f, 0x60, 0x0c,
|
||||
0x00, 0x00, 0xe3, 0x1d, 0x30, 0x06, 0x00, 0x80, 0xf3, 0x30, 0x18, 0x03,
|
||||
0x00, 0xc0, 0xb1, 0x63, 0x8c, 0x01, 0x00, 0xe0, 0x19, 0x66, 0xc6, 0x00,
|
||||
0x00, 0xb0, 0x09, 0xcc, 0x63, 0x00, 0x00, 0x98, 0x19, 0xc8, 0x31, 0x00,
|
||||
0x00, 0x8c, 0x13, 0x98, 0x19, 0x00, 0x00, 0xc6, 0x33, 0x90, 0x0f, 0x00,
|
||||
0x00, 0x63, 0x66, 0x98, 0x07, 0x00, 0x80, 0x31, 0xc6, 0x89, 0x03, 0x00,
|
||||
0xc0, 0x18, 0x0c, 0xcf, 0x01, 0x00, 0x60, 0x0c, 0x38, 0xc7, 0x00, 0x00,
|
||||
0x30, 0x06, 0xf0, 0x63, 0x00, 0x00, 0x18, 0x03, 0xc0, 0x31, 0x00, 0x00,
|
||||
0x8c, 0x01, 0xc0, 0x18, 0x00, 0x00, 0xc6, 0x00, 0x60, 0x0c, 0x00, 0x00,
|
||||
0x66, 0x00, 0x30, 0x06, 0x00, 0x00, 0x23, 0x00, 0x18, 0x03, 0x00, 0x00,
|
||||
0x33, 0x00, 0x8c, 0x01, 0x00, 0x00, 0x13, 0x00, 0xc6, 0x00, 0x00, 0x00,
|
||||
0x33, 0x00, 0x63, 0x00, 0x00, 0x00, 0x26, 0x80, 0x31, 0x00, 0x00, 0x00,
|
||||
0x66, 0xc0, 0x18, 0x00, 0x00, 0x00, 0xcc, 0x60, 0x0c, 0x00, 0x00, 0x00,
|
||||
0x8c, 0x3b, 0x06, 0x00, 0x00, 0x00, 0x18, 0x0e, 0x03, 0x00, 0x00, 0x00,
|
||||
0x70, 0x80, 0x01, 0x00, 0x00, 0x00, 0xe0, 0xe1, 0x00, 0x00, 0x00, 0x00,
|
||||
0x80, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00 };
|
||||
9
xmfile/src/icons/pipe-small.xbm
Normal file
9
xmfile/src/icons/pipe-small.xbm
Normal file
@@ -0,0 +1,9 @@
|
||||
#define pipe_small_width 24
|
||||
#define pipe_small_height 24
|
||||
static unsigned char pipe_small_bits[] = {
|
||||
0x00, 0x00, 0xff, 0x00, 0x00, 0x81, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x81,
|
||||
0x00, 0x00, 0xff, 0x00, 0x00, 0x52, 0x00, 0x00, 0x52, 0x00, 0x00, 0x52,
|
||||
0x00, 0x7e, 0x52, 0xe0, 0xc3, 0x51, 0x18, 0x42, 0x40, 0x04, 0x42, 0x28,
|
||||
0x84, 0x52, 0x23, 0x22, 0x5a, 0x18, 0x82, 0xc3, 0x07, 0x52, 0x7e, 0x00,
|
||||
0x52, 0x00, 0x00, 0x52, 0x00, 0x00, 0x52, 0x00, 0x00, 0xff, 0x00, 0x00,
|
||||
0x81, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x81, 0x00, 0x00, 0xff, 0x00, 0x00 };
|
||||
27
xmfile/src/icons/pipe.xbm
Normal file
27
xmfile/src/icons/pipe.xbm
Normal file
@@ -0,0 +1,27 @@
|
||||
#define pipe_width 48
|
||||
#define pipe_height 48
|
||||
static unsigned char pipe_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x7f,
|
||||
0x00, 0x00, 0x00, 0x80, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x80, 0x01, 0x60,
|
||||
0x00, 0x00, 0x00, 0x80, 0x01, 0x6d, 0x00, 0x00, 0x00, 0x80, 0x01, 0x6e,
|
||||
0x00, 0x00, 0x00, 0x80, 0x41, 0x6d, 0x00, 0x00, 0x00, 0x80, 0x01, 0x60,
|
||||
0x00, 0x00, 0x00, 0x80, 0x57, 0x7d, 0x00, 0x00, 0x00, 0x80, 0x03, 0x70,
|
||||
0x00, 0x00, 0x00, 0x00, 0x03, 0x34, 0x00, 0x00, 0x00, 0x00, 0x03, 0x34,
|
||||
0x00, 0x00, 0x00, 0x00, 0x03, 0x34, 0x00, 0x00, 0x00, 0x00, 0x03, 0x34,
|
||||
0x00, 0x00, 0x00, 0x00, 0x03, 0x34, 0x00, 0x00, 0x00, 0x00, 0x03, 0x34,
|
||||
0x00, 0x00, 0xf8, 0x1f, 0x03, 0x34, 0x00, 0xf8, 0xff, 0xff, 0x03, 0x34,
|
||||
0x00, 0xff, 0x1f, 0xf8, 0x01, 0x34, 0xc0, 0x07, 0x18, 0x18, 0x00, 0x34,
|
||||
0xe0, 0x00, 0x10, 0x08, 0x00, 0x34, 0x70, 0x00, 0x18, 0x18, 0x00, 0x32,
|
||||
0x30, 0x00, 0x10, 0x08, 0x00, 0x1a, 0x18, 0x00, 0x18, 0x18, 0x00, 0x18,
|
||||
0x18, 0x00, 0x10, 0x0a, 0x00, 0x19, 0x18, 0x00, 0x58, 0x19, 0x80, 0x0c,
|
||||
0x0c, 0x00, 0x90, 0x0a, 0x30, 0x0e, 0x0c, 0x80, 0xdf, 0xfb, 0x0f, 0x07,
|
||||
0x0c, 0x20, 0xd0, 0x0b, 0xe0, 0x03, 0x0c, 0x80, 0x1f, 0xf8, 0xff, 0x00,
|
||||
0x0c, 0xd0, 0xff, 0xff, 0x1f, 0x00, 0x0c, 0xd0, 0xf8, 0x1f, 0x00, 0x00,
|
||||
0x0c, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xd0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0c, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xd0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0c, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xd0, 0x00, 0x00, 0x00, 0x00,
|
||||
0xee, 0xff, 0x01, 0x00, 0x00, 0x00, 0x5e, 0xf5, 0x01, 0x00, 0x00, 0x00,
|
||||
0x06, 0x80, 0x01, 0x00, 0x00, 0x00, 0x06, 0xb4, 0x01, 0x00, 0x00, 0x00,
|
||||
0x06, 0xb8, 0x01, 0x00, 0x00, 0x00, 0x06, 0xb5, 0x01, 0x00, 0x00, 0x00,
|
||||
0x06, 0x80, 0x01, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0x00, 0x00,
|
||||
0xfe, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
9
xmfile/src/icons/socket-small.xbm
Normal file
9
xmfile/src/icons/socket-small.xbm
Normal file
@@ -0,0 +1,9 @@
|
||||
#define socket_small_width 24
|
||||
#define socket_small_height 24
|
||||
static unsigned char socket_small_bits[] = {
|
||||
0x00, 0x41, 0x00, 0x00, 0x51, 0x00, 0x00, 0x41, 0x00, 0x00, 0x51, 0x00,
|
||||
0x00, 0x51, 0x00, 0x00, 0x51, 0x00, 0x00, 0x51, 0x00, 0x80, 0xd1, 0x00,
|
||||
0xc0, 0xc1, 0x01, 0xc0, 0xa2, 0x01, 0x40, 0x5d, 0x01, 0x40, 0x3e, 0x01,
|
||||
0x80, 0x80, 0x00, 0x00, 0x51, 0x00, 0x00, 0x41, 0x00, 0x00, 0x51, 0x00,
|
||||
0x00, 0x51, 0x00, 0x00, 0x51, 0x00, 0x00, 0x41, 0x00, 0x80, 0xff, 0x00,
|
||||
0x80, 0x80, 0x00, 0x80, 0xb8, 0x00, 0x80, 0x80, 0x00, 0x80, 0xff, 0x00 };
|
||||
27
xmfile/src/icons/socket.xbm
Normal file
27
xmfile/src/icons/socket.xbm
Normal file
@@ -0,0 +1,27 @@
|
||||
#define socket_width 48
|
||||
#define socket_height 48
|
||||
static unsigned char socket_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00,
|
||||
0x00, 0x00, 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x00, 0x00,
|
||||
0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x00, 0x00, 0x04, 0x48, 0x00, 0x00,
|
||||
0x00, 0x00, 0x06, 0x68, 0x00, 0x00, 0x00, 0x00, 0x06, 0x68, 0x00, 0x00,
|
||||
0x00, 0x00, 0x06, 0x68, 0x00, 0x00, 0x00, 0x00, 0x06, 0x68, 0x00, 0x00,
|
||||
0x00, 0x00, 0x06, 0x68, 0x00, 0x00, 0x00, 0x00, 0x06, 0x68, 0x00, 0x00,
|
||||
0x00, 0x00, 0x06, 0x68, 0x00, 0x00, 0x00, 0x00, 0x06, 0x68, 0x00, 0x00,
|
||||
0x00, 0x00, 0x07, 0xe8, 0x00, 0x00, 0x00, 0x80, 0x06, 0x68, 0x01, 0x00,
|
||||
0x00, 0xc0, 0x07, 0xe8, 0x03, 0x00, 0x00, 0xe0, 0x06, 0x68, 0x07, 0x00,
|
||||
0x00, 0xb0, 0x07, 0xe4, 0x0d, 0x00, 0x00, 0xb0, 0x0c, 0x32, 0x0d, 0x00,
|
||||
0x00, 0x30, 0x1f, 0xf8, 0x0c, 0x00, 0x00, 0x30, 0xf3, 0xcf, 0x0c, 0x00,
|
||||
0x00, 0x60, 0xfe, 0x7f, 0x06, 0x00, 0x00, 0x60, 0x0c, 0x30, 0x06, 0x00,
|
||||
0x00, 0xc0, 0xf0, 0x0f, 0x03, 0x00, 0x00, 0x80, 0x01, 0x80, 0x03, 0x00,
|
||||
0x00, 0x00, 0x03, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00,
|
||||
0x00, 0x00, 0x06, 0x68, 0x00, 0x00, 0x00, 0x00, 0x06, 0x68, 0x00, 0x00,
|
||||
0x00, 0x00, 0x06, 0x68, 0x00, 0x00, 0x00, 0x00, 0x06, 0x68, 0x00, 0x00,
|
||||
0x00, 0x00, 0x06, 0x68, 0x00, 0x00, 0x00, 0x00, 0x06, 0x68, 0x00, 0x00,
|
||||
0x00, 0x00, 0x06, 0x68, 0x00, 0x00, 0x00, 0x00, 0x06, 0x68, 0x00, 0x00,
|
||||
0x00, 0x00, 0x06, 0x68, 0x00, 0x00, 0x00, 0x00, 0x06, 0x68, 0x00, 0x00,
|
||||
0x00, 0x00, 0xf7, 0xff, 0x00, 0x00, 0x00, 0x00, 0xaf, 0xfa, 0x00, 0x00,
|
||||
0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xda, 0x00, 0x00,
|
||||
0x00, 0x00, 0x03, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x83, 0xda, 0x00, 0x00,
|
||||
0x00, 0x00, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
|
||||
0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
386
xmfile/src/main.c
Normal file
386
xmfile/src/main.c
Normal file
@@ -0,0 +1,386 @@
|
||||
#define _XOPEN_SOURCE 700
|
||||
|
||||
#include <Xm/Xm.h>
|
||||
#include <Xm/Form.h>
|
||||
#include <Xm/PushB.h>
|
||||
#include <Xm/MainW.h>
|
||||
#include <Xm/IconG.h>
|
||||
#include <Xm/Container.h>
|
||||
#include <Xm/ScrolledW.h>
|
||||
|
||||
#include <Xmd/Icon.h>
|
||||
#include <Xmd/Exec.h>
|
||||
#include <Xmd/Buffer.h>
|
||||
#include <Xmd/StringMap.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <dirent.h>
|
||||
#include <libgen.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "icons/icon.xbm"
|
||||
#include "icons/directory.xbm"
|
||||
#include "icons/directory-small.xbm"
|
||||
#include "icons/file.xbm"
|
||||
#include "icons/file-small.xbm"
|
||||
#include "icons/link.xbm"
|
||||
#include "icons/link-small.xbm"
|
||||
#include "icons/block.xbm"
|
||||
#include "icons/block-small.xbm"
|
||||
#include "icons/character.xbm"
|
||||
#include "icons/character-small.xbm"
|
||||
#include "icons/socket.xbm"
|
||||
#include "icons/socket-small.xbm"
|
||||
#include "icons/pipe.xbm"
|
||||
#include "icons/pipe-small.xbm"
|
||||
|
||||
static XtAppContext application;
|
||||
static XmdStringMap *trailFiles;
|
||||
static XmdStringMap *viewFiles;
|
||||
static Widget topLevel;
|
||||
static Widget viewContainer;
|
||||
static Widget trailContainer;
|
||||
static Pixmap iconPixmap;
|
||||
static Pixmap iconsLarge[7] = { 0 };
|
||||
static Pixmap iconsSmall[7] = { 0 };
|
||||
|
||||
typedef enum {
|
||||
FileKindFile,
|
||||
FileKindDirectory,
|
||||
FileKindLink,
|
||||
FileKindBlock,
|
||||
FileKindCharacter,
|
||||
FileKindSocket,
|
||||
FileKindPipe
|
||||
} FileKind;
|
||||
|
||||
typedef struct {
|
||||
Widget widget;
|
||||
FileKind kind;
|
||||
String name;
|
||||
String label;
|
||||
String path;
|
||||
} File;
|
||||
|
||||
void loadIconPixmaps (void);
|
||||
int refreshDirectory ();
|
||||
int makeTrailIn (ConstString path);
|
||||
int makeFilesIn (ConstString directory, Bool showHidden);
|
||||
int changeDirectory (ConstString path);
|
||||
void handleActivate (Widget, XtPointer, XtPointer);
|
||||
FileKind fileKind (ConstString path);
|
||||
File * FileNew (XmdStringMap *set, Widget container, String name, ConstString path);
|
||||
File * FileOfWidget (Widget widget);
|
||||
void FileDelete (XmdStringMap *set, ConstString name);
|
||||
void FileFree (File *this);
|
||||
void FileSetLabel (File *this, ConstString label);
|
||||
|
||||
int main (int argc, char *argv[]) {
|
||||
trailFiles = XmdStringMapNew();
|
||||
viewFiles = XmdStringMapNew();
|
||||
|
||||
topLevel = XtVaAppInitialize (
|
||||
&application, "FileBrowser",
|
||||
NULL, 0,
|
||||
&argc, argv,
|
||||
NULL,
|
||||
XmNtitle, "File Browser",
|
||||
XmNiconName, "File Browser",
|
||||
XmNwidth, 400,
|
||||
XmNheight, 300,
|
||||
NULL);
|
||||
Widget window = XtVaCreateManagedWidget (
|
||||
"window", xmMainWindowWidgetClass, topLevel,
|
||||
NULL);
|
||||
|
||||
/* menu bar */
|
||||
XmString fileString = XmStringCreateLocalized("File");
|
||||
XmString helpString = XmStringCreateLocalized("Help");
|
||||
Widget menuBar = XmVaCreateSimpleMenuBar (
|
||||
window, "menuBar",
|
||||
XmVaCASCADEBUTTON, fileString, 'F',
|
||||
XmVaCASCADEBUTTON, helpString, 'H',
|
||||
NULL);
|
||||
XmStringFree(fileString);
|
||||
XmStringFree(helpString);
|
||||
XtManageChild(menuBar);
|
||||
|
||||
/* layout form */
|
||||
Widget layout = XtVaCreateWidget (
|
||||
"layout", xmFormWidgetClass, window,
|
||||
XmNorientation, XmVERTICAL,
|
||||
NULL);
|
||||
iconPixmap = XmdLoadBitmapIcon(layout, icon);
|
||||
XtVaSetValues (
|
||||
topLevel,
|
||||
XmNiconPixmap, iconPixmap,
|
||||
NULL);
|
||||
|
||||
/* trail container */
|
||||
Widget trailScroller = XtVaCreateWidget (
|
||||
"trailScroller", xmScrolledWindowWidgetClass, layout,
|
||||
XmNscrollingPolicy, XmAUTOMATIC,
|
||||
XmNscrolledWindowChildType, XmSCROLL_HOR,
|
||||
XmNleftAttachment, XmATTACH_FORM,
|
||||
XmNtopAttachment, XmATTACH_FORM,
|
||||
XmNrightAttachment, XmATTACH_FORM,
|
||||
NULL);
|
||||
trailContainer = XtVaCreateManagedWidget (
|
||||
"trailContainer", xmContainerWidgetClass, trailScroller,
|
||||
XmNlayoutType, XmOUTLINE,
|
||||
XmNentryViewType, XmSMALL_ICON,
|
||||
NULL);
|
||||
XtAddCallback (
|
||||
trailContainer, XmNdefaultActionCallback,
|
||||
handleActivate,
|
||||
NULL);
|
||||
|
||||
/* file object container */
|
||||
Widget viewScroller = XtVaCreateWidget (
|
||||
"viewScroller", xmScrolledWindowWidgetClass, layout,
|
||||
XmNscrollingPolicy, XmAUTOMATIC,
|
||||
XmNscrolledWindowChildType, XmSCROLL_VERT,
|
||||
XmNleftAttachment, XmATTACH_FORM,
|
||||
XmNtopAttachment, XmATTACH_WIDGET,
|
||||
XmNtopWidget, trailScroller,
|
||||
XmNrightAttachment, XmATTACH_FORM,
|
||||
XmNbottomAttachment, XmATTACH_FORM,
|
||||
NULL);
|
||||
viewContainer = XtVaCreateManagedWidget (
|
||||
"viewContainer", xmContainerWidgetClass, viewScroller,
|
||||
XmNlayoutType, XmSPATIAL,
|
||||
XmNspatialStyle, XmGRID,
|
||||
XmNspatialIncludeModel, XmFIRST_FIT,
|
||||
XmNspatialResizeModel, XmGROW_MINOR,
|
||||
NULL);
|
||||
XtAddCallback (
|
||||
viewContainer, XmNdefaultActionCallback,
|
||||
handleActivate,
|
||||
NULL);
|
||||
|
||||
loadIconPixmaps();
|
||||
refreshDirectory();
|
||||
|
||||
XtManageChild(viewScroller);
|
||||
XtManageChild(trailScroller);
|
||||
XtManageChild(layout);
|
||||
|
||||
XtVaSetValues (
|
||||
window,
|
||||
XmNmenuBar, menuBar,
|
||||
XmNworkWindow, layout,
|
||||
NULL);
|
||||
|
||||
XtRealizeWidget(topLevel);
|
||||
XtAppMainLoop(application);
|
||||
}
|
||||
|
||||
void loadIconPixmaps (void) {
|
||||
#define kind(kind, name) \
|
||||
iconsLarge[FileKind##kind] = XmdLoadBitmapIcon(viewContainer, name); \
|
||||
iconsSmall[FileKind##kind] = XmdLoadBitmapIcon(viewContainer, name##_small)
|
||||
kind(File, file);
|
||||
kind(Directory, directory);
|
||||
kind(Link, link);
|
||||
kind(Block, block);
|
||||
kind(Character, character);
|
||||
kind(Socket, socket);
|
||||
kind(Pipe, pipe);
|
||||
}
|
||||
|
||||
Bool freeFile (XmdStringMap *map, ConstString key, void *value, void *data) {
|
||||
(void)(map);
|
||||
(void)(key);
|
||||
(void)(data);
|
||||
File *this = value;
|
||||
FileFree(this);
|
||||
return True;
|
||||
}
|
||||
|
||||
int refreshDirectory () {
|
||||
char directory[PATH_MAX];
|
||||
getcwd(directory, XtNumber(directory));
|
||||
XtVaSetValues (
|
||||
topLevel,
|
||||
XmNtitle, directory,
|
||||
XmNiconName, directory,
|
||||
NULL);
|
||||
|
||||
int err = 0;
|
||||
XtUnmanageChild(trailContainer); {
|
||||
XmdStringMapIterate(trailFiles, freeFile, NULL);
|
||||
XmdStringMapFree(trailFiles);
|
||||
trailFiles = XmdStringMapNew();
|
||||
err |= makeTrailIn(directory);
|
||||
} XtManageChild(trailContainer);
|
||||
|
||||
XtUnmanageChild(viewContainer); {
|
||||
XmdStringMapIterate(viewFiles, freeFile, NULL);
|
||||
XmdStringMapFree(viewFiles);
|
||||
viewFiles = XmdStringMapNew();
|
||||
err |= makeFilesIn(directory, True);
|
||||
} XtManageChild(viewContainer);
|
||||
return err;
|
||||
}
|
||||
|
||||
int changeDirectory (ConstString path) {
|
||||
int err = chdir(path);
|
||||
if (err) return err;
|
||||
refreshDirectory();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void handleActivate (Widget container, XtPointer clientData, XtPointer callData) {
|
||||
(void)(container);
|
||||
(void)(clientData);
|
||||
XmContainerSelectCallbackStruct *event = callData;
|
||||
if (event->selected_item_count < 1) return;
|
||||
|
||||
/* first, if a directory is selected, try to go into it */
|
||||
for (int index = 0; index < event->selected_item_count; index ++) {
|
||||
File *file = FileOfWidget(event->selected_items[index]);
|
||||
if (file == NULL) continue;
|
||||
if (file->kind == FileKindDirectory) {
|
||||
changeDirectory(file->path);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* if not, we worry about opening files and stuff */
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
FileKind fileKind (ConstString path) {
|
||||
struct stat info = { 0 };
|
||||
stat(path, &info);
|
||||
if (S_ISDIR (info.st_mode)) return FileKindDirectory;
|
||||
if (S_ISCHR (info.st_mode)) return FileKindCharacter;
|
||||
if (S_ISBLK (info.st_mode)) return FileKindBlock;
|
||||
if (S_ISFIFO(info.st_mode)) return FileKindPipe;
|
||||
if (S_ISLNK (info.st_mode)) return FileKindLink;
|
||||
if (S_ISSOCK(info.st_mode)) return FileKindSocket;
|
||||
return FileKindFile;
|
||||
}
|
||||
|
||||
int makeTrailIn (ConstString cwd) {
|
||||
char name[PATH_MAX] = { 0 }; Cardinal nameIndex = 0;
|
||||
char path[PATH_MAX] = { 0 }; Cardinal pathIndex = 0;
|
||||
|
||||
while (True) {
|
||||
char ch = *(cwd ++);
|
||||
|
||||
if (nameIndex >= XtNumber(name)) return -1;
|
||||
if (pathIndex >= XtNumber(path)) return -1;
|
||||
|
||||
name[ nameIndex] = ch;
|
||||
name[++ nameIndex] = 0;
|
||||
path[ pathIndex] = ch;
|
||||
path[++ pathIndex] = 0;
|
||||
|
||||
if (ch == '/' || ch == 0) {
|
||||
if (nameIndex == 0) {
|
||||
name[0] = '/';
|
||||
name[1] = 0;
|
||||
}
|
||||
|
||||
FileNew(trailFiles, trailContainer, name, path);
|
||||
name[(nameIndex = 0)] = 0;
|
||||
if (ch == 0) return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int makeFilesIn (ConstString directory, Bool showHidden) {
|
||||
struct dirent **entries = NULL;
|
||||
int entriesCount = scandir(directory, &entries, NULL, alphasort);
|
||||
if (entriesCount < 0) {
|
||||
return -1;
|
||||
}
|
||||
for (int index = 0; index < entriesCount; index ++) {
|
||||
struct dirent *entry = entries[index];
|
||||
if (entry->d_name[0] == '.' && !showHidden) {
|
||||
XtFree((char *)(entry));
|
||||
continue;
|
||||
}
|
||||
char filePath[PATH_MAX];
|
||||
snprintf (
|
||||
filePath, XtNumber(filePath),
|
||||
"%s/%s", directory, entry->d_name);
|
||||
|
||||
String fileName = XtNewString(entry->d_name);
|
||||
XtFree((char *)(entry));
|
||||
|
||||
FileNew(viewFiles, viewContainer, fileName, filePath);
|
||||
XtFree(fileName);
|
||||
}
|
||||
XtFree((char *)(entries));
|
||||
return 0;
|
||||
}
|
||||
|
||||
File *FileNew (XmdStringMap *set, Widget container, String name, ConstString path) {
|
||||
File *this = XtNew(File);
|
||||
this->label = NULL;
|
||||
this->name = XtNewString(name);
|
||||
this->path = XtNewString(path);
|
||||
XmString string = XmStringCreateLocalized(name);
|
||||
this->widget = XtVaCreateManagedWidget (
|
||||
"file", xmIconGadgetClass, container,
|
||||
XmNalignment, XmALIGNMENT_BEGINNING,
|
||||
XmNlabelString, string,
|
||||
XmNuserData, (XtPointer)(this),
|
||||
NULL);
|
||||
XmStringFree(string);
|
||||
|
||||
FileKind kind = fileKind(path);
|
||||
XtVaSetValues (
|
||||
this->widget,
|
||||
XmNlargeIconPixmap, iconsLarge[kind],
|
||||
XmNsmallIconPixmap, iconsSmall[kind],
|
||||
NULL);
|
||||
this->kind = kind;
|
||||
|
||||
XmdStringMapSet(set, name, this);
|
||||
return this;
|
||||
}
|
||||
|
||||
File *FileOfWidget (Widget widget) {
|
||||
File *file = NULL;
|
||||
XtVaGetValues(widget, XmNuserData, &file, NULL);
|
||||
return file;
|
||||
}
|
||||
|
||||
void FileDelete (XmdStringMap *set, ConstString name) {
|
||||
FileFree(XmdStringMapSet(set, name, NULL));
|
||||
}
|
||||
|
||||
void FileFree (File *this) {
|
||||
if (this == NULL) return;
|
||||
XtUnmanageChild(this->widget);
|
||||
XtDestroyWidget(this->widget);
|
||||
XtFree((char *)(this->name));
|
||||
XtFree((char *)(this->label));
|
||||
XtFree((char *)(this->path));
|
||||
XtFree((char *)(this));
|
||||
}
|
||||
|
||||
void FileSetLabel (File *this, ConstString label) {
|
||||
XtFree(this->label);
|
||||
this->label = XtNewString(label);
|
||||
|
||||
XmString string = NULL;
|
||||
if (label == NULL) {
|
||||
string = XmStringCreateLocalized(this->name);
|
||||
} else {
|
||||
string = XmStringCreateLocalized(this->label);
|
||||
}
|
||||
XtVaSetValues (
|
||||
this->widget,
|
||||
XmNlabelString, string,
|
||||
NULL);
|
||||
XmStringFree(string);
|
||||
}
|
||||
2
xmpackage/build.sh
Executable file
2
xmpackage/build.sh
Executable file
@@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
../scripts/buildapp.sh xmpackage "$@"
|
||||
27
xmpackage/src/icons/icon.xbm
Normal file
27
xmpackage/src/icons/icon.xbm
Normal file
@@ -0,0 +1,27 @@
|
||||
#define icon_width 48
|
||||
#define icon_height 48
|
||||
static unsigned char icon_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00,
|
||||
0x00, 0x00, 0x78, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x78, 0x00, 0x00,
|
||||
0x00, 0x80, 0x07, 0xe0, 0x03, 0x00, 0x00, 0xe0, 0x01, 0x80, 0x0e, 0x00,
|
||||
0x00, 0x78, 0x00, 0x40, 0x38, 0x00, 0x00, 0x1e, 0x80, 0x31, 0x60, 0x00,
|
||||
0x80, 0x07, 0x40, 0x0e, 0x80, 0x01, 0xc0, 0x01, 0x20, 0x04, 0x00, 0x03,
|
||||
0xe0, 0x00, 0xc0, 0x08, 0x00, 0x07, 0x60, 0x03, 0x30, 0x07, 0x80, 0x06,
|
||||
0x60, 0x0c, 0x0c, 0x00, 0x20, 0x06, 0x60, 0x30, 0x03, 0x00, 0x08, 0x06,
|
||||
0x60, 0xc0, 0x06, 0x00, 0x02, 0x06, 0x60, 0x00, 0x0b, 0x80, 0x60, 0x06,
|
||||
0x60, 0x00, 0x3c, 0x20, 0x58, 0x06, 0x60, 0x00, 0xf0, 0x08, 0x46, 0x06,
|
||||
0x60, 0x00, 0xc0, 0x83, 0x41, 0x06, 0x60, 0x00, 0x00, 0x81, 0x60, 0x06,
|
||||
0x60, 0x00, 0x00, 0x80, 0x18, 0x06, 0x60, 0x00, 0x00, 0x81, 0x06, 0x06,
|
||||
0x60, 0x00, 0x00, 0x80, 0x01, 0x06, 0x60, 0x00, 0x00, 0x01, 0x00, 0x06,
|
||||
0x60, 0x00, 0x00, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x01, 0x00, 0x06,
|
||||
0x60, 0x00, 0x00, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x01, 0x02, 0x06,
|
||||
0x60, 0x00, 0x00, 0x80, 0x02, 0x06, 0x60, 0x00, 0x00, 0xa1, 0x02, 0x06,
|
||||
0xc0, 0x01, 0x00, 0xa8, 0x82, 0x03, 0x80, 0x07, 0x00, 0xa9, 0xe0, 0x01,
|
||||
0x00, 0x1e, 0x00, 0x28, 0x78, 0x00, 0x00, 0x78, 0x00, 0x09, 0x1e, 0x00,
|
||||
0x00, 0xe0, 0x01, 0x80, 0x07, 0x00, 0x00, 0x80, 0x07, 0xe1, 0x01, 0x00,
|
||||
0x00, 0x00, 0x1e, 0x78, 0x00, 0x00, 0x00, 0x00, 0x78, 0x1f, 0x00, 0x00,
|
||||
0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
640
xmpackage/src/main.c
Normal file
640
xmpackage/src/main.c
Normal file
@@ -0,0 +1,640 @@
|
||||
#define _XOPEN_SOURCE
|
||||
|
||||
#include <Xm/Xm.h>
|
||||
#include <Xm/MainW.h>
|
||||
#include <Xm/RowColumn.h>
|
||||
#include <Xm/PushB.h>
|
||||
#include <Xm/Text.h>
|
||||
#include <Xm/Form.h>
|
||||
#include <Xm/PanedW.h>
|
||||
#include <Xm/TabStack.h>
|
||||
#include <Xm/List.h>
|
||||
#include <Xm/Frame.h>
|
||||
#include <Xm/TextF.h>
|
||||
#include <Xm/Separator.h>
|
||||
#include <Xm/ScrolledW.h>
|
||||
#include <Xm/LabelG.h>
|
||||
|
||||
#include <Xmd/Icon.h>
|
||||
#include <Xmd/Buffer.h>
|
||||
#include <Xmd/Exec.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "icons/icon.xbm"
|
||||
|
||||
Widget createLabeledTextForm (Widget, String, String, XmString);
|
||||
Widget createScrolledInfoText (Widget, String);
|
||||
void selectPackage (String);
|
||||
void updatePackageList (void);
|
||||
void readPackageList (FILE *);
|
||||
void handleListModeSelectionChange (Widget, XtPointer, XtPointer);
|
||||
void handlePackageSelectionChange (Widget, XtPointer, XtPointer);
|
||||
void handleSearchQueryActivate (Widget, XtPointer, XtPointer);
|
||||
String parsePackageName (String);
|
||||
void parseInfoOutput (FILE *, String *, String *, String *, String *);
|
||||
|
||||
static XtAppContext application;
|
||||
static Pixmap iconPixmap;
|
||||
|
||||
static struct {
|
||||
Widget name;
|
||||
Widget description;
|
||||
Widget dependencies;
|
||||
Widget provides;
|
||||
Widget contents;
|
||||
String selected;
|
||||
} packageInfo = { 0 };
|
||||
|
||||
static struct {
|
||||
Widget query;
|
||||
Widget list;
|
||||
Widget modeMenu;
|
||||
enum {
|
||||
viewModeWorld,
|
||||
viewModeInstalled,
|
||||
viewModeUpgradable,
|
||||
viewModeOrphaned,
|
||||
viewModeSearch
|
||||
} viewMode;
|
||||
XmString viewModeStrings[4];
|
||||
} packageList = { 0 };
|
||||
|
||||
int main (int argc, char *argv[]) {
|
||||
Widget topLevel = XtVaAppInitialize (
|
||||
&application, "PackageManager",
|
||||
NULL, 0,
|
||||
&argc, argv,
|
||||
NULL,
|
||||
XmNtitle, "Package Manager",
|
||||
XmNiconName, "Package Manager",
|
||||
NULL);
|
||||
iconPixmap = XmdLoadBitmapIcon(topLevel, icon);
|
||||
XtVaSetValues (
|
||||
topLevel,
|
||||
XmNiconPixmap, iconPixmap,
|
||||
NULL);
|
||||
Widget window = XtVaCreateManagedWidget (
|
||||
"window", xmMainWindowWidgetClass, topLevel,
|
||||
NULL);
|
||||
Widget pane = XtVaCreateWidget (
|
||||
"pane", xmPanedWindowWidgetClass, window,
|
||||
XmNorientation, XmHORIZONTAL,
|
||||
NULL);
|
||||
|
||||
/* menu bar */
|
||||
XmString fileString = XmStringCreateLocalized("File");
|
||||
XmString systemString = XmStringCreateLocalized("System");
|
||||
XmString helpString = XmStringCreateLocalized("Help");
|
||||
Widget menuBar = XmVaCreateSimpleMenuBar (
|
||||
window, "menuBar",
|
||||
XmVaCASCADEBUTTON, fileString, 'F',
|
||||
XmVaCASCADEBUTTON, systemString, 'S',
|
||||
XmVaCASCADEBUTTON, helpString, 'H',
|
||||
NULL);
|
||||
XmStringFree(fileString);
|
||||
XmStringFree(systemString);
|
||||
XmStringFree(helpString);
|
||||
XtManageChild(menuBar);
|
||||
|
||||
/* package list pane */
|
||||
Widget packageListPane = XtVaCreateWidget (
|
||||
"packageListPane", xmFormWidgetClass, pane,
|
||||
XmNhorizontalSpacing, 4,
|
||||
XmNverticalSpacing, 4,
|
||||
XmNmarginHeight, 2,
|
||||
XmNmarginWidth, 2,
|
||||
NULL);
|
||||
XmString packageSearchLabelString = XmStringCreateLocalized("Search:");
|
||||
packageList.query = createLabeledTextForm (
|
||||
packageListPane,
|
||||
"packageSearchLabel",
|
||||
"packageSearchText",
|
||||
packageSearchLabelString);
|
||||
XmStringFree(packageSearchLabelString);
|
||||
XtAddCallback (
|
||||
packageList.query,
|
||||
XmNactivateCallback, handleSearchQueryActivate,
|
||||
NULL);
|
||||
XtVaSetValues (
|
||||
XtParent(packageList.query),
|
||||
XmNrightAttachment, XmATTACH_FORM,
|
||||
XmNtopAttachment, XmATTACH_FORM,
|
||||
XmNleftAttachment, XmATTACH_FORM,
|
||||
NULL);
|
||||
|
||||
/* list mode selector */
|
||||
Widget listModeFrame = XtVaCreateWidget (
|
||||
"listModeFrame", xmFrameWidgetClass, packageListPane,
|
||||
XmNshadowType, XmSHADOW_IN,
|
||||
XmNshadowThickness, 1,
|
||||
XmNleftAttachment, XmATTACH_FORM,
|
||||
XmNrightAttachment, XmATTACH_FORM,
|
||||
XmNbottomAttachment, XmATTACH_FORM,
|
||||
NULL);
|
||||
Widget listModeRc = XtVaCreateWidget (
|
||||
"listModeRc", xmRowColumnWidgetClass, listModeFrame,
|
||||
XmNmarginWidth, 0,
|
||||
XmNmarginHeight, 0,
|
||||
NULL);
|
||||
XmString listModeString = XmStringCreateLocalized("List:");
|
||||
packageList.viewModeStrings[viewModeWorld] = XmStringCreateLocalized("World");
|
||||
packageList.viewModeStrings[viewModeInstalled] = XmStringCreateLocalized("Installed");
|
||||
packageList.viewModeStrings[viewModeUpgradable] = XmStringCreateLocalized("Upgradable");
|
||||
packageList.viewModeStrings[viewModeOrphaned] = XmStringCreateLocalized("Orphaned");
|
||||
packageList.viewModeStrings[viewModeSearch] = XmStringCreateLocalized("Search");
|
||||
packageList.modeMenu = XmVaCreateSimpleOptionMenu (
|
||||
listModeRc, "packageListMode",
|
||||
listModeString, 'L', 0, handleListModeSelectionChange,
|
||||
XmVaPUSHBUTTON, packageList.viewModeStrings[viewModeWorld], 'W', NULL, NULL,
|
||||
XmVaPUSHBUTTON, packageList.viewModeStrings[viewModeInstalled], 'I', NULL, NULL,
|
||||
XmVaPUSHBUTTON, packageList.viewModeStrings[viewModeUpgradable], 'U', NULL, NULL,
|
||||
XmVaPUSHBUTTON, packageList.viewModeStrings[viewModeOrphaned], 'O', NULL, NULL,
|
||||
XmVaPUSHBUTTON, packageList.viewModeStrings[viewModeSearch], 'S', NULL, NULL,
|
||||
XmNtearOffModel, XmTEAR_OFF_ENABLED,
|
||||
NULL);
|
||||
XmStringFree(listModeString);
|
||||
XtManageChild(packageList.modeMenu);
|
||||
XtManageChild(listModeFrame);
|
||||
XtManageChild(listModeRc);
|
||||
|
||||
/* packageList */
|
||||
packageList.list = XmCreateScrolledList(packageListPane, "packageList", NULL, 0);
|
||||
XtVaSetValues (
|
||||
XtParent(packageList.list),
|
||||
XmNtopAttachment, XmATTACH_WIDGET,
|
||||
XmNtopWidget, XtParent(packageList.query),
|
||||
XmNleftAttachment, XmATTACH_FORM,
|
||||
XmNrightAttachment, XmATTACH_FORM,
|
||||
XmNbottomAttachment, XmATTACH_WIDGET,
|
||||
XmNbottomWidget, listModeFrame,
|
||||
NULL);
|
||||
XtAddCallback (
|
||||
packageList.list,
|
||||
XmNbrowseSelectionCallback, handlePackageSelectionChange,
|
||||
NULL);
|
||||
XtManageChild(packageList.list);
|
||||
|
||||
/* package viewer */
|
||||
Widget descriptionPane = XtVaCreateWidget (
|
||||
"descriptionPane", xmFormWidgetClass, pane,
|
||||
XmNhorizontalSpacing, 4,
|
||||
XmNverticalSpacing, 4,
|
||||
XmNmarginHeight, 2,
|
||||
XmNmarginWidth, 2,
|
||||
NULL);
|
||||
|
||||
/* package actions */
|
||||
Widget packageActionsFrame = XtVaCreateWidget (
|
||||
"packageActionsFrame", xmFrameWidgetClass, descriptionPane,
|
||||
XmNshadowType, XmSHADOW_OUT,
|
||||
XmNleftAttachment, XmATTACH_FORM,
|
||||
XmNrightAttachment, XmATTACH_FORM,
|
||||
XmNbottomAttachment, XmATTACH_FORM,
|
||||
NULL);
|
||||
Widget packageActionsRc = XtVaCreateWidget (
|
||||
"packageActionsRc", xmRowColumnWidgetClass, packageActionsFrame,
|
||||
XmNorientation, XmHORIZONTAL,
|
||||
NULL);
|
||||
XmString packageAddString = XmStringCreateLocalized("Install");
|
||||
Widget packageAdd = XtVaCreateManagedWidget (
|
||||
"packageAdd", xmPushButtonWidgetClass, packageActionsRc,
|
||||
XmNlabelString, packageAddString,
|
||||
NULL);
|
||||
XmStringFree(packageAddString);
|
||||
XmString packageDeleteString = XmStringCreateLocalized("Remove");
|
||||
XtVaCreateManagedWidget (
|
||||
"packageDelete", xmPushButtonWidgetClass, packageActionsRc,
|
||||
XmNlabelString, packageDeleteString,
|
||||
NULL);
|
||||
XmStringFree(packageDeleteString);
|
||||
XmString packageUpgradeString = XmStringCreateLocalized("Upgrade");
|
||||
XtVaCreateManagedWidget (
|
||||
"packageUpgrade", xmPushButtonWidgetClass, packageActionsRc,
|
||||
XmNlabelString, packageUpgradeString,
|
||||
NULL);
|
||||
XmStringFree(packageUpgradeString);
|
||||
XmString packageFixString = XmStringCreateLocalized("Fix");
|
||||
XtVaCreateManagedWidget (
|
||||
"packageFix", xmPushButtonWidgetClass, packageActionsRc,
|
||||
XmNlabelString, packageFixString,
|
||||
NULL);
|
||||
XmStringFree(packageFixString);
|
||||
XtManageChild(packageActionsRc);
|
||||
XtManageChild(packageActionsFrame);
|
||||
|
||||
/* visually separate package description and actions */
|
||||
Widget descriptionSeparator = XtVaCreateManagedWidget (
|
||||
"descriptionSeparator", xmSeparatorWidgetClass, descriptionPane,
|
||||
XmNleftAttachment, XmATTACH_FORM,
|
||||
XmNrightAttachment, XmATTACH_FORM,
|
||||
XmNbottomAttachment, XmATTACH_WIDGET,
|
||||
XmNbottomWidget, packageAdd,
|
||||
NULL);
|
||||
|
||||
/* package description */
|
||||
packageInfo.name = XtVaCreateManagedWidget (
|
||||
"name", xmLabelGadgetClass, descriptionPane,
|
||||
XmNleftAttachment, XmATTACH_FORM,
|
||||
XmNrightAttachment, XmATTACH_FORM,
|
||||
XmNtopAttachment, XmATTACH_FORM,
|
||||
NULL);
|
||||
Widget descriptionTabStack = XtVaCreateWidget (
|
||||
"descriptionTabStack", xmTabStackWidgetClass, descriptionPane,
|
||||
XmNleftAttachment, XmATTACH_FORM,
|
||||
XmNrightAttachment, XmATTACH_FORM,
|
||||
XmNtopAttachment, XmATTACH_WIDGET,
|
||||
XmNtopWidget, packageInfo.name,
|
||||
XmNbottomAttachment, XmATTACH_WIDGET,
|
||||
XmNbottomWidget, descriptionSeparator,
|
||||
XmNtabMarginWidth, 0,
|
||||
XmNtabMarginHeight, 0,
|
||||
XmNtabLabelSpacing, 0,
|
||||
XmNmarginWidth, 4,
|
||||
XmNmarginHeight, 4,
|
||||
XmNtabMode, XmTABS_STACKED,
|
||||
NULL);
|
||||
packageInfo.description = createScrolledInfoText(descriptionTabStack, "Description");
|
||||
packageInfo.dependencies = createScrolledInfoText(descriptionTabStack, "Dependencies");
|
||||
packageInfo.provides = createScrolledInfoText(descriptionTabStack, "Provides");
|
||||
packageInfo.contents = createScrolledInfoText(descriptionTabStack, "Contents");
|
||||
XtManageChild(descriptionTabStack);
|
||||
|
||||
/* final setup */
|
||||
|
||||
XtManageChild(packageListPane);
|
||||
XtManageChild(descriptionPane);
|
||||
XtManageChild(pane);
|
||||
|
||||
XtVaSetValues (
|
||||
window,
|
||||
XmNmenuBar, menuBar,
|
||||
XmNworkWindow, pane,
|
||||
NULL);
|
||||
|
||||
updatePackageList();
|
||||
selectPackage(NULL);
|
||||
|
||||
XtRealizeWidget(topLevel);
|
||||
XtAppMainLoop(application);
|
||||
}
|
||||
|
||||
Widget createLabeledTextForm (
|
||||
Widget parent,
|
||||
String labelName,
|
||||
String textName,
|
||||
XmString labelString
|
||||
) {
|
||||
Widget form = XtVaCreateWidget (
|
||||
"form", xmFormWidgetClass, parent,
|
||||
XmNorientation, XmHORIZONTAL,
|
||||
NULL);
|
||||
Widget label = XtVaCreateManagedWidget (
|
||||
labelName, xmLabelGadgetClass, form,
|
||||
XmNleftAttachment, XmATTACH_FORM,
|
||||
XmNtopAttachment, XmATTACH_FORM,
|
||||
XmNbottomAttachment, XmATTACH_FORM,
|
||||
XmNlabelString, labelString,
|
||||
NULL);
|
||||
Widget text = XtVaCreateManagedWidget (
|
||||
textName, xmTextWidgetClass, form,
|
||||
XmNleftAttachment, XmATTACH_WIDGET,
|
||||
XmNleftWidget, label,
|
||||
XmNtopAttachment, XmATTACH_FORM,
|
||||
XmNrightAttachment, XmATTACH_FORM,
|
||||
XmNbottomAttachment, XmATTACH_FORM,
|
||||
NULL);
|
||||
XtManageChild (form);
|
||||
return text;
|
||||
}
|
||||
|
||||
Widget createScrolledInfoText (Widget parent, String name) {
|
||||
Widget scroll = XtVaCreateWidget (
|
||||
name, xmScrolledWindowWidgetClass, parent,
|
||||
NULL);
|
||||
Widget info = XtVaCreateManagedWidget (
|
||||
"info", xmTextWidgetClass, scroll,
|
||||
XmNrows, 10,
|
||||
XmNcolumns, 60,
|
||||
XmNpaneMinimum, 35,
|
||||
XmNeditMode, XmMULTI_LINE_EDIT,
|
||||
XmNeditable, False,
|
||||
XmNwordWrap, True,
|
||||
XmNscrollHorizontal, False,
|
||||
NULL);
|
||||
XtManageChild(scroll);
|
||||
return info;
|
||||
}
|
||||
|
||||
void selectPackage (String name) {
|
||||
if (packageInfo.selected) XtFree(packageInfo.selected);
|
||||
packageInfo.selected = name;
|
||||
|
||||
XmString packageNameString = NULL;
|
||||
|
||||
if (name == NULL) {
|
||||
packageNameString = XmStringCreateLocalized("No package selected");
|
||||
XtVaSetValues (
|
||||
packageInfo.description,
|
||||
XmNvalue, "",
|
||||
NULL);
|
||||
} else {
|
||||
/* instruct apk to describe package */
|
||||
pid_t child;
|
||||
FILE *stream = XmdVaPipedExecPath (
|
||||
"apk", &child, "r",
|
||||
"apk", "info", name, "-dswLPR", "--license",
|
||||
NULL);
|
||||
if (stream == NULL) {
|
||||
/* TODO: error popup */
|
||||
return;
|
||||
}
|
||||
|
||||
/* parse data*/
|
||||
String description = NULL;
|
||||
String dependencies = NULL;
|
||||
String provides = NULL;
|
||||
String contents = NULL;
|
||||
parseInfoOutput (
|
||||
stream,
|
||||
&description, &dependencies,
|
||||
&provides, &contents);
|
||||
fclose(stream);
|
||||
waitpid(child, NULL, 0);
|
||||
|
||||
/* set tab contents to parsed data */
|
||||
packageNameString = XmStringCreateLocalized(name);
|
||||
XtVaSetValues (
|
||||
packageInfo.description,
|
||||
XmNvalue, description,
|
||||
NULL);
|
||||
XtVaSetValues (
|
||||
packageInfo.dependencies,
|
||||
XmNvalue, dependencies,
|
||||
NULL);
|
||||
XtVaSetValues (
|
||||
packageInfo.provides,
|
||||
XmNvalue, provides,
|
||||
NULL);
|
||||
XtVaSetValues (
|
||||
packageInfo.contents,
|
||||
XmNvalue, contents,
|
||||
NULL);
|
||||
XtFree(description);
|
||||
XtFree(dependencies);
|
||||
XtFree(provides);
|
||||
XtFree(contents);
|
||||
}
|
||||
|
||||
XtVaSetValues (
|
||||
packageInfo.name,
|
||||
XmNlabelString, packageNameString,
|
||||
NULL);
|
||||
XmStringFree(packageNameString);
|
||||
}
|
||||
|
||||
void parseInfoOutput (
|
||||
FILE *stream,
|
||||
String *description,
|
||||
String *dependencies,
|
||||
String *provides,
|
||||
String *contents
|
||||
) {
|
||||
char nullTerminator = 0;
|
||||
|
||||
enum {
|
||||
stateSkipUntilSpace,
|
||||
stateGetHeading,
|
||||
stateGetSection
|
||||
} state = stateSkipUntilSpace;
|
||||
int consecutiveNewlines = 0;
|
||||
XmdBuffer *activeBuffer = NULL;
|
||||
XmdBuffer *headingBuffer = NULL;
|
||||
|
||||
XmdBuffer *descriptionBuffer = XmdBufferNew(char);
|
||||
XmdBuffer *dependenciesBuffer = XmdBufferNew(char);
|
||||
XmdBuffer *providesBuffer = XmdBufferNew(char);
|
||||
XmdBuffer *contentsBuffer = XmdBufferNew(char);
|
||||
|
||||
int ch;
|
||||
while ((ch = fgetc(stream)) != EOF) switch (state) {
|
||||
/* discard stream until there is a space */
|
||||
case stateSkipUntilSpace:
|
||||
if (ch == ' ') {
|
||||
headingBuffer = XmdBufferNew(char);
|
||||
state = stateGetHeading;
|
||||
}
|
||||
break;
|
||||
|
||||
/* what is the next section about? */
|
||||
case stateGetHeading:
|
||||
if (ch == ':') {
|
||||
XmdBufferPush(headingBuffer, &nullTerminator);
|
||||
String heading = XmdBufferBreak(headingBuffer);
|
||||
|
||||
if (strcmp(heading, "depends on") == 0) {
|
||||
activeBuffer = dependenciesBuffer;
|
||||
} else if (strcmp(heading, "provides") == 0) {
|
||||
activeBuffer = providesBuffer;
|
||||
} else if (strcmp(heading, "contains") == 0) {
|
||||
activeBuffer = contentsBuffer;
|
||||
} else {
|
||||
activeBuffer = descriptionBuffer;
|
||||
}
|
||||
|
||||
XtFree(heading);
|
||||
consecutiveNewlines = 1;
|
||||
state = stateGetSection;
|
||||
fgetc(stream); /* skip newline */
|
||||
} else {
|
||||
XmdBufferPush(headingBuffer, &ch);
|
||||
}
|
||||
break;
|
||||
|
||||
/* read the section data into the active buffer */
|
||||
case stateGetSection:
|
||||
if (ch == '\n') {
|
||||
if (consecutiveNewlines > 0) {
|
||||
state = stateSkipUntilSpace;
|
||||
break;
|
||||
}
|
||||
consecutiveNewlines ++;
|
||||
} else {
|
||||
consecutiveNewlines = 0;
|
||||
}
|
||||
XmdBufferPush(activeBuffer, &ch);
|
||||
break;
|
||||
}
|
||||
|
||||
XmdBufferPush(descriptionBuffer, &nullTerminator);
|
||||
XmdBufferPush(dependenciesBuffer, &nullTerminator);
|
||||
XmdBufferPush(providesBuffer, &nullTerminator);
|
||||
XmdBufferPush(contentsBuffer, &nullTerminator);
|
||||
|
||||
*description = XmdBufferBreak(descriptionBuffer);
|
||||
*dependencies = XmdBufferBreak(dependenciesBuffer);
|
||||
*provides = XmdBufferBreak(providesBuffer);
|
||||
*contents = XmdBufferBreak(contentsBuffer);
|
||||
}
|
||||
|
||||
void updatePackageList (void) {
|
||||
FILE *stream = NULL;
|
||||
pid_t child = 0;
|
||||
|
||||
switch (packageList.viewMode) {
|
||||
case viewModeWorld:
|
||||
stream = fopen("/etc/apk/world", "r");
|
||||
break;
|
||||
case viewModeInstalled:
|
||||
stream = XmdVaPipedExecPath (
|
||||
"apk", &child, "r",
|
||||
"apk", "list", "--installed",
|
||||
NULL);
|
||||
break;
|
||||
case viewModeUpgradable:
|
||||
stream = XmdVaPipedExecPath (
|
||||
"apk", &child, "r",
|
||||
"apk", "list", "--upgradable",
|
||||
NULL);
|
||||
break;
|
||||
case viewModeOrphaned:
|
||||
stream = XmdVaPipedExecPath (
|
||||
"apk", &child, "r",
|
||||
"apk", "list", "--orphaned",
|
||||
NULL);
|
||||
break;
|
||||
case viewModeSearch:
|
||||
;String query = NULL;
|
||||
XtVaGetValues (
|
||||
packageList.query,
|
||||
XmNvalue, &query,
|
||||
NULL);
|
||||
stream = XmdVaPipedExecPath (
|
||||
"apk", &child, "r",
|
||||
"apk", "search", query,
|
||||
NULL);
|
||||
XtFree(query);
|
||||
break;
|
||||
}
|
||||
|
||||
if (stream == NULL) {
|
||||
/* TODO: error popup */
|
||||
return;
|
||||
}
|
||||
|
||||
readPackageList(stream);
|
||||
fclose(stream);
|
||||
if (child != 0) waitpid(child, NULL, 0);
|
||||
}
|
||||
|
||||
void readPackageList (FILE *list) {
|
||||
String line = NULL;
|
||||
size_t lineLength = 0;
|
||||
|
||||
char packageName[256] = { 0 };
|
||||
|
||||
XmdBuffer *itemsBuffer = XmdBufferNew(XmString);
|
||||
|
||||
while (getline(&line, &lineLength, list) != -1) {
|
||||
sscanf(line, "%256s", packageName);
|
||||
free(line);
|
||||
line = NULL;
|
||||
XmString packageNameString = XmStringCreateLocalized(packageName);
|
||||
XmdBufferPush(itemsBuffer, &packageNameString);
|
||||
}
|
||||
|
||||
Cardinal length = XmdBufferLength(itemsBuffer);
|
||||
XmStringTable items = (XmStringTable)(XmdBufferBreak(itemsBuffer));
|
||||
|
||||
XtVaSetValues (
|
||||
packageList.list,
|
||||
XmNitemCount, length,
|
||||
XmNitems, items,
|
||||
NULL);
|
||||
|
||||
/* free everything */
|
||||
if (line) free(line);
|
||||
for (size_t index = 0; index < length; index ++) {
|
||||
XmStringFree(items[index]);
|
||||
}
|
||||
XtFree((String)(items));
|
||||
}
|
||||
|
||||
void handleListModeSelectionChange (
|
||||
Widget widget,
|
||||
XtPointer clientData,
|
||||
XtPointer callData
|
||||
) {
|
||||
(void)(widget);
|
||||
(void)(callData);
|
||||
|
||||
int selected = *(int *)(&clientData);
|
||||
packageList.viewMode = selected;
|
||||
updatePackageList();
|
||||
}
|
||||
|
||||
void handlePackageSelectionChange (
|
||||
Widget widget,
|
||||
XtPointer clientData,
|
||||
XtPointer callData
|
||||
) {
|
||||
(void)(widget);
|
||||
(void)(clientData);
|
||||
|
||||
XmListCallbackStruct *event = (XmListCallbackStruct*)(callData);
|
||||
if (event->event == NULL) return;
|
||||
|
||||
String choice = (String)(XmStringUnparse (
|
||||
event->item,
|
||||
XmFONTLIST_DEFAULT_TAG,
|
||||
XmCHARSET_TEXT,
|
||||
XmCHARSET_TEXT,
|
||||
NULL, 0,
|
||||
XmOUTPUT_ALL));
|
||||
selectPackage(parsePackageName(choice));
|
||||
XtFree(choice);
|
||||
}
|
||||
|
||||
void handleSearchQueryActivate (
|
||||
Widget widget,
|
||||
XtPointer clientData,
|
||||
XtPointer callData
|
||||
) {
|
||||
(void)(widget);
|
||||
(void)(clientData);
|
||||
(void)(callData);
|
||||
|
||||
packageList.viewMode = viewModeSearch;
|
||||
|
||||
/* FIXME do this by activating the appropriate button. that way we dont
|
||||
have to call updatePackageList manually as well. */
|
||||
Widget button = XmOptionButtonGadget(packageList.modeMenu);
|
||||
XtVaSetValues (
|
||||
button,
|
||||
XmNlabelString, packageList.viewModeStrings[packageList.viewMode],
|
||||
NULL);
|
||||
|
||||
updatePackageList();
|
||||
}
|
||||
|
||||
String parsePackageName (String input) {
|
||||
XmdBuffer *output = XmdBufferNew(char);
|
||||
char ch;
|
||||
Boolean wasDash = False;
|
||||
for (size_t index = 0; (ch = input[index]); index ++) {
|
||||
if (wasDash && isdigit(ch)) {
|
||||
XmdBufferPop(output, NULL);
|
||||
break;
|
||||
} else {
|
||||
wasDash = ch == '-';
|
||||
XmdBufferPush(output, &ch);
|
||||
}
|
||||
}
|
||||
char nullTerminator = 0;
|
||||
XmdBufferPush(output, &nullTerminator);
|
||||
return XmdBufferBreak(output);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
#define _XOPEN_SOURCE
|
||||
#define _XOPEN_SOURCE 700
|
||||
#include <Xm/Xm.h>
|
||||
#include <Xm/RowColumn.h>
|
||||
#include <Xm/PushB.h>
|
||||
|
||||
2
xmshelf/build.sh
Executable file
2
xmshelf/build.sh
Executable file
@@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
../scripts/buildapp.sh xmshell "$@"
|
||||
27
xmshelf/src/icons/icon.xbm
Normal file
27
xmshelf/src/icons/icon.xbm
Normal file
@@ -0,0 +1,27 @@
|
||||
#define icon_width 48
|
||||
#define icon_height 48
|
||||
static unsigned char icon_bits[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xfc, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x3f,
|
||||
0xfc, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x0c, 0x1e, 0x00, 0xf0, 0x03, 0x30,
|
||||
0xfc, 0xf3, 0xff, 0x0f, 0xfc, 0x3f, 0x0c, 0x09, 0x00, 0xf2, 0x13, 0x30,
|
||||
0xfc, 0xf9, 0xff, 0x0d, 0xec, 0x3f, 0x0c, 0x09, 0x80, 0x02, 0x50, 0x30,
|
||||
0xfc, 0xf9, 0xff, 0x02, 0xd0, 0x3f, 0x8c, 0x04, 0x40, 0x01, 0xa6, 0x30,
|
||||
0xfc, 0xfc, 0x7f, 0x81, 0xa1, 0x3f, 0x8c, 0xfc, 0x4f, 0xe1, 0xa0, 0x30,
|
||||
0xfc, 0x04, 0x78, 0x41, 0xa0, 0x3f, 0x4c, 0x06, 0x48, 0x41, 0xa0, 0x30,
|
||||
0x7c, 0x06, 0x78, 0x81, 0xa0, 0x3f, 0x4c, 0x06, 0x88, 0x82, 0x50, 0x30,
|
||||
0x7c, 0x06, 0xf8, 0x03, 0xf0, 0x3f, 0x2c, 0x05, 0x28, 0x0c, 0x0c, 0x31,
|
||||
0x3c, 0x07, 0x38, 0xf0, 0x03, 0x3f, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x3f,
|
||||
0xac, 0x00, 0x00, 0x00, 0x00, 0x35, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x3f,
|
||||
0xfc, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x0c, 0x00, 0x00, 0x22, 0x00, 0x30,
|
||||
0xfc, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x0c, 0x00, 0x00, 0x7f, 0x00, 0x30,
|
||||
0xfc, 0xff, 0xff, 0xc1, 0xff, 0x3f, 0xcc, 0x3f, 0x00, 0x41, 0x3e, 0x31,
|
||||
0x7c, 0xc0, 0xff, 0xe3, 0x23, 0x3f, 0x4c, 0xc0, 0x1f, 0x14, 0x22, 0x31,
|
||||
0x7c, 0x00, 0xf0, 0xf7, 0x23, 0x31, 0x4c, 0x00, 0xf0, 0x94, 0x22, 0x31,
|
||||
0x7c, 0x00, 0xd0, 0xf7, 0x22, 0x31, 0x4c, 0x00, 0xf0, 0x94, 0x22, 0x31,
|
||||
0x7c, 0x00, 0xd0, 0xf7, 0xe2, 0x31, 0x4c, 0x00, 0xf0, 0x94, 0x22, 0x3f,
|
||||
0x7c, 0x00, 0xd0, 0xf7, 0x36, 0x31, 0x4c, 0xff, 0xf7, 0x94, 0x22, 0x31,
|
||||
0x7c, 0x00, 0xd0, 0xf7, 0x22, 0x31, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x3f,
|
||||
0xac, 0x00, 0x00, 0x00, 0x00, 0x35, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x3f,
|
||||
0xcc, 0xff, 0xff, 0xff, 0xff, 0x33, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x3f,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
336
xmshelf/src/main.c
Normal file
336
xmshelf/src/main.c
Normal file
@@ -0,0 +1,336 @@
|
||||
#define _XOPEN_SOURCE
|
||||
#include <Xm/Xm.h>
|
||||
#include <Xm/Form.h>
|
||||
#include <Xm/PushB.h>
|
||||
#include <Xm/MainW.h>
|
||||
#include <Xm/IconG.h>
|
||||
#include <Xm/Container.h>
|
||||
#include <Xm/ScrolledW.h>
|
||||
|
||||
#include <Xmd/Icon.h>
|
||||
#include <Xmd/Exec.h>
|
||||
#include <Xmd/Buffer.h>
|
||||
#include <Xmd/StringMap.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <dirent.h>
|
||||
#include <libgen.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "icons/icon.xbm"
|
||||
|
||||
XtAppContext application;
|
||||
typedef enum {
|
||||
DeviceKindGeneric,
|
||||
DeviceKindDisk,
|
||||
DeviceKindRom,
|
||||
DeviceKindFilesystem,
|
||||
DeviceKindTTY
|
||||
} DeviceKind;
|
||||
|
||||
typedef struct {
|
||||
Widget widget;
|
||||
DeviceKind kind;
|
||||
Bool orphaned;
|
||||
String name;
|
||||
String mountPoint;
|
||||
String label;
|
||||
} Device;
|
||||
|
||||
void loadIconPixmaps (void);
|
||||
void refreshDevices (void);
|
||||
void refreshDisks (void);
|
||||
Device * DeviceNew (String name, DeviceKind kind);
|
||||
void DeviceDelete (ConstString name);
|
||||
void DeviceFree (Device *this);
|
||||
void DeviceSetKind (Device *this, DeviceKind kind);
|
||||
void DeviceSetMountPoint (Device *this, ConstString mountPoint);
|
||||
void DeviceSetLabel (Device *this, ConstString label);
|
||||
int readBlockDevice (FILE *stream, Device **);
|
||||
int readLsblkPair (FILE *stream, String *key, String *value);
|
||||
void handleRefresh (Widget, XtPointer, XtPointer);
|
||||
|
||||
int main (int argc, char *argv[]) {
|
||||
devices = XmdStringMapNew();
|
||||
|
||||
Widget window = XtVaAppInitialize (
|
||||
&application, "Shelf",
|
||||
NULL, 0,
|
||||
&argc, argv,
|
||||
NULL,
|
||||
XmNtitle, "Shelf",
|
||||
XmNiconName, "Shelf",
|
||||
XmNwidth, 256,
|
||||
XmNheight, 256,
|
||||
NULL);
|
||||
|
||||
Widget layout = XtVaCreateWidget (
|
||||
"layout", xmFormWidgetClass, window,
|
||||
XmNorientation, XmVERTICAL,
|
||||
NULL);
|
||||
Pixmap iconPixmap = XmdLoadBitmapIcon(layout, icon);
|
||||
XtVaSetValues (
|
||||
window,
|
||||
XmNiconPixmap, iconPixmap,
|
||||
NULL);
|
||||
|
||||
Pixmap refreshPixmap = XmdLoadBitmapIcon(layout, refresh);
|
||||
XmString string = XmStringCreateLocalized("Refresh");
|
||||
Widget refreshButton = XtVaCreateManagedWidget (
|
||||
"refreshButton", xmPushButtonWidgetClass, layout,
|
||||
XmNleftAttachment, XmATTACH_FORM,
|
||||
XmNbottomAttachment, XmATTACH_FORM,
|
||||
XmNlabelType, XmPIXMAP_AND_STRING,
|
||||
XmNlabelPixmap, refreshPixmap,
|
||||
XmNlabelString, string,
|
||||
NULL);
|
||||
XmStringFree(string);
|
||||
XtAddCallback (
|
||||
refreshButton, XmNactivateCallback,
|
||||
handleRefresh, NULL);
|
||||
|
||||
Pixmap mountPixmap = XmdLoadBitmapIcon(layout, mount);
|
||||
string = XmStringCreateLocalized("Mount");
|
||||
Widget mountButton = XtVaCreateManagedWidget (
|
||||
"mountButton", xmPushButtonWidgetClass, layout,
|
||||
XmNleftAttachment, XmATTACH_WIDGET,
|
||||
XmNleftWidget, refreshButton,
|
||||
XmNbottomAttachment, XmATTACH_FORM,
|
||||
XmNlabelType, XmPIXMAP_AND_STRING,
|
||||
XmNlabelPixmap, mountPixmap,
|
||||
XmNlabelString, string,
|
||||
NULL);
|
||||
XmStringFree(string);
|
||||
|
||||
Pixmap unmountPixmap = XmdLoadBitmapIcon(layout, unmount);
|
||||
string = XmStringCreateLocalized("Unmount");
|
||||
/*Widget unmountButton = */XtVaCreateManagedWidget (
|
||||
"unmountButton", xmPushButtonWidgetClass, layout,
|
||||
XmNleftAttachment, XmATTACH_WIDGET,
|
||||
XmNleftWidget, mountButton,
|
||||
XmNbottomAttachment, XmATTACH_FORM,
|
||||
XmNlabelType, XmPIXMAP_AND_STRING,
|
||||
XmNlabelPixmap, unmountPixmap,
|
||||
XmNlabelString, string,
|
||||
NULL);
|
||||
XmStringFree(string);
|
||||
|
||||
Widget scroller = XtVaCreateWidget (
|
||||
"scroll", xmScrolledWindowWidgetClass, layout,
|
||||
XmNscrollingPolicy, XmAUTOMATIC,
|
||||
XmNleftAttachment, XmATTACH_FORM,
|
||||
XmNtopAttachment, XmATTACH_FORM,
|
||||
XmNrightAttachment, XmATTACH_FORM,
|
||||
XmNbottomAttachment, XmATTACH_WIDGET,
|
||||
XmNbottomWidget, refreshButton,
|
||||
NULL);
|
||||
container = XtVaCreateManagedWidget (
|
||||
"container", xmContainerWidgetClass, scroller,
|
||||
XmNlayoutType, XmSPATIAL,
|
||||
XmNspatialStyle, XmGRID,
|
||||
NULL);
|
||||
|
||||
loadIconPixmaps();
|
||||
refreshDevices();
|
||||
|
||||
XtManageChild(scroller);
|
||||
XtManageChild(layout);
|
||||
XtRealizeWidget(window);
|
||||
XtAppMainLoop(application);
|
||||
}
|
||||
|
||||
void loadIconPixmaps (void) {
|
||||
#define dev(kind, name) \
|
||||
iconsLarge[DeviceKind##kind] = XmdLoadBitmapIcon(container, name); \
|
||||
iconsSmall[DeviceKind##kind] = XmdLoadBitmapIcon(container, name##_small)
|
||||
dev(Generic, generic);
|
||||
dev(Disk, disk);
|
||||
dev(Rom, rom);
|
||||
dev(Filesystem, filesystem);
|
||||
dev(TTY, tty);
|
||||
}
|
||||
|
||||
void handleRefresh (Widget button, XtPointer clientData, XtPointer callData) {
|
||||
(void)(button);
|
||||
(void)(clientData);
|
||||
(void)(callData);
|
||||
refreshDevices();
|
||||
}
|
||||
|
||||
Bool markDevice (XmdStringMap *map, ConstString key, void *value, void *data) {
|
||||
(void)(map);
|
||||
(void)(key);
|
||||
(void)(data);
|
||||
Device *this = value;
|
||||
this->orphaned = True;
|
||||
return True;
|
||||
}
|
||||
|
||||
Bool transferDevice (XmdStringMap *map, ConstString key, void *value, void *data) {
|
||||
(void)(map);
|
||||
(void)(key);
|
||||
(void)(data);
|
||||
Device *this = value;
|
||||
if (this->orphaned) {
|
||||
DeviceFree(this);
|
||||
} else {
|
||||
XmdStringMapSet(devices, key, value);
|
||||
}
|
||||
return True;
|
||||
}
|
||||
|
||||
void refreshDevices (void) {
|
||||
XtUnmanageChild(container);
|
||||
|
||||
/* pre-mark all devices as orphaned */
|
||||
XmdStringMapIterate(devices, markDevice, NULL);
|
||||
|
||||
/* refresh devices by category */
|
||||
refreshDisks();
|
||||
|
||||
/* create a new map, only moving over extant devices */
|
||||
XmdStringMap *oldMap = devices;
|
||||
devices = XmdStringMapNew();
|
||||
XmdStringMapIterate(oldMap, transferDevice, NULL);
|
||||
XmdStringMapFree(oldMap);
|
||||
|
||||
XtManageChild(container);
|
||||
}
|
||||
|
||||
String diskName (ConstString directory, ConstString name) {
|
||||
char fullpath[PATH_MAX];
|
||||
snprintf(fullpath, XtNumber(fullpath), "%s/%s", directory, name);
|
||||
char resolved[PATH_MAX];
|
||||
return XtNewString(basename(realpath(fullpath, resolved)));
|
||||
}
|
||||
|
||||
void refreshDisks (void) {
|
||||
/* get disks */
|
||||
ConstString disksById = "/dev/disk/by-id";
|
||||
ConstString disksByLabel = "/dev/disk/by-label";
|
||||
ConstString disksByPartuuid = "/dev/disk/by-partuuid";
|
||||
|
||||
struct dirent **entries = NULL;
|
||||
int entriesCount = scandir(disksById, &entries, NULL, alphasort);
|
||||
if (entriesCount < 0) {
|
||||
/* TODO error message */
|
||||
return;
|
||||
}
|
||||
for (int index = 0; index < entriesCount; index ++) {
|
||||
struct dirent *entry = entries[index];
|
||||
if (entry->d_name[0] == '.') {
|
||||
XtFree((char *)(entry));
|
||||
continue;
|
||||
}
|
||||
String deviceName = diskName(disksById, entry->d_name);
|
||||
XtFree((char *)(entry));
|
||||
|
||||
Device *device = XmdStringMapGet(devices, deviceName);
|
||||
if (device == NULL) {
|
||||
device = DeviceNew(deviceName, DeviceKindDisk);
|
||||
} else {
|
||||
device->orphaned = False;
|
||||
DeviceSetKind(device, DeviceKindDisk);
|
||||
}
|
||||
|
||||
XtFree(deviceName);
|
||||
}
|
||||
XtFree((char *)(entries));
|
||||
|
||||
/* determine disk types */
|
||||
DIR *dir = opendir(disksByPartuuid);
|
||||
if (dir == NULL) {
|
||||
/* TODO error message */
|
||||
return;
|
||||
}
|
||||
struct dirent *entry;
|
||||
while ((entry = readdir(dir)) != NULL) {
|
||||
if (entry->d_name[0] == '.') continue;
|
||||
String deviceName = diskName(disksByPartuuid, entry->d_name);
|
||||
Device *device = XmdStringMapGet(devices, deviceName);
|
||||
if (device != NULL) DeviceSetKind(device, DeviceKindFilesystem);
|
||||
XtFree(deviceName);
|
||||
}
|
||||
closedir(dir);
|
||||
|
||||
/* determine partition labels */
|
||||
dir = opendir(disksByLabel);
|
||||
if (dir == NULL) {
|
||||
/* TODO error message */
|
||||
return;
|
||||
}
|
||||
while ((entry = readdir(dir)) != NULL) {
|
||||
if (entry->d_name[0] == '.') continue;
|
||||
String deviceName = diskName(disksByLabel, entry->d_name);
|
||||
Device *device = XmdStringMapGet(devices, deviceName);
|
||||
if (device != NULL) DeviceSetLabel(device, entry->d_name);
|
||||
XtFree(deviceName);
|
||||
}
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
Device *DeviceNew (String name, DeviceKind kind) {
|
||||
Device *this = XtNew(Device);
|
||||
this->mountPoint = NULL;
|
||||
this->label = NULL;
|
||||
this->name = XtNewString(name);
|
||||
this->orphaned = False;
|
||||
XmString string = XmStringCreateLocalized(name);
|
||||
this->widget = XtVaCreateManagedWidget (
|
||||
"device", xmIconGadgetClass, container,
|
||||
XmNalignment, XmALIGNMENT_BEGINNING,
|
||||
XmNlabelString, string,
|
||||
NULL);
|
||||
XmStringFree(string);
|
||||
DeviceSetKind(this, kind);
|
||||
XmdStringMapSet(devices, name, this);
|
||||
return this;
|
||||
}
|
||||
|
||||
void DeviceDelete (ConstString name) {
|
||||
DeviceFree(XmdStringMapSet(devices, name, NULL));
|
||||
}
|
||||
|
||||
void DeviceFree (Device *this) {
|
||||
if (this == NULL) return;
|
||||
XtDestroyWidget(this->widget);
|
||||
XtFree((char *)(this->name));
|
||||
XtFree((char *)(this->mountPoint));
|
||||
XtFree((char *)(this->label));
|
||||
XtFree((char *)(this));
|
||||
}
|
||||
|
||||
void DeviceSetKind (Device *this, DeviceKind kind) {
|
||||
XtVaSetValues (
|
||||
this->widget,
|
||||
XmNlargeIconPixmap, iconsLarge[kind],
|
||||
XmNsmallIconPixmap, iconsSmall[kind],
|
||||
NULL);
|
||||
this->kind = kind;
|
||||
}
|
||||
|
||||
void DeviceSetMountPoint (Device *this, ConstString mountPoint) {
|
||||
XtFree(this->mountPoint);
|
||||
this->mountPoint = XtNewString(mountPoint);
|
||||
}
|
||||
|
||||
void DeviceSetLabel (Device *this, ConstString label) {
|
||||
XtFree(this->label);
|
||||
this->label = XtNewString(label);
|
||||
|
||||
XmString string = NULL;
|
||||
if (label == NULL) {
|
||||
string = XmStringCreateLocalized(this->name);
|
||||
} else {
|
||||
string = XmStringCreateLocalized(this->label);
|
||||
}
|
||||
XtVaSetValues (
|
||||
this->widget,
|
||||
XmNlabelString, string,
|
||||
NULL);
|
||||
XmStringFree(string);
|
||||
}
|
||||
Reference in New Issue
Block a user