Compare commits

..

28 Commits

Author SHA1 Message Date
Sasha Koshka
b88a59a420 Big oopsie with the $outputFilePath 2024-02-28 12:04:55 -05:00
Sasha Koshka
0af0d8e561 Added a script to mount SFTP connections if yuo want 2024-02-23 23:19:10 -05:00
Sasha Koshka
1a8a68a631 Unmanage child before destroying in XmDev 2024-02-01 00:52:21 -05:00
Sasha Koshka
58ef75e455 XmShelf stub 2024-02-01 00:52:21 -05:00
Sasha Koshka
b3b86808ea XmPackage stub 2024-02-01 00:52:21 -05:00
Sasha Koshka
d34e7fdc88 XmFile stub 2024-02-01 00:52:21 -05:00
Sasha Koshka
37f0d6d0ae Launcher.activateLauncher is now static 2024-02-01 00:52:21 -05:00
Sasha Koshka
a538ed14a2 Update readme and install 2024-02-01 00:52:21 -05:00
Sasha Koshka
463be06955 Created a uniform interface accross all session scripts 2024-02-01 00:52:10 -05:00
Sasha Koshka
794f7216cd Wallpaper file now supports comments 2024-02-01 00:50:53 -05:00
Sasha Koshka
0dd701da37 Wallpaper setting script actually works now 2024-02-01 00:50:53 -05:00
Sasha Koshka
80d28f7004 Xmd session sets more X environment variables 2024-02-01 00:41:20 -05:00
Sasha Koshka
1c1331e166 oh my god 2024-02-01 00:41:20 -05:00
Sasha Koshka
03290f61e7 Wallpaper script supports color, no longer sources conf file 2024-01-31 13:23:26 -05:00
Sasha Koshka
720ddd3d99 Added a color temparature script 2024-01-31 11:52:54 -05:00
Sasha Koshka
75b2b6e0b2 Screenshot interface is way better 2024-01-31 11:35:11 -05:00
Sasha Koshka
d14b748536 Added more things to xmdev i think 2024-01-17 21:48:01 -05:00
Sasha Koshka
318e35242d Apparently scandir only works in certain POSIX versions 2024-01-18 02:44:19 +00:00
Sasha Koshka
be6d44343e XtReallocArray does not exist on Debian. Something something debian old software idk. 2024-01-18 02:36:29 +00:00
Sasha Koshka
7badf24576 This again 2024-01-18 02:36:02 +00:00
Sasha Koshka
b1f13bdcac I hate the way functions are defined in posix sh 2024-01-18 02:28:43 +00:00
2aff2ff45a Add screenshot to readme 2024-01-17 17:43:10 +00:00
Sasha Koshka
0b6ba024aa Add screenshot 2024-01-17 12:41:50 -05:00
Sasha Koshka
a7fc1a84d2 Fix defaults/install.sh 2024-01-17 12:41:34 -05:00
Sasha Koshka
4e6e0cad5e Add basic default configuration 2024-01-17 11:47:18 -05:00
Sasha Koshka
45425c91d1 Decouple screenshot script from Xmd, Xmd session from Mwm 2024-01-17 11:30:25 -05:00
Sasha Koshka
b341fbe6ca Separated session scripts from utility scripts 2024-01-17 11:12:05 -05:00
Sasha Koshka
51278b9d8f Read from /dev instead of lsblk 2023-12-12 02:12:50 -05:00
55 changed files with 2339 additions and 200 deletions

View File

@@ -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

View File

@@ -1,3 +1,5 @@
# Xmd
An X11/Motif desktop environment written in C99.
An X11/Motif desktop environment written in C99 and POSIX shell.
![Screenshot of the default configuration](assets/screenshot.png)

BIN
assets/screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

View File

@@ -0,0 +1,4 @@
[Launcher]
Name=Terminal
Exec=uxterm
Icon=Terminal

View File

@@ -0,0 +1,2 @@
[Battery]
Interval=2

View File

@@ -0,0 +1,3 @@
[Clock]
Type=Digital
Format=%a, %b %d\n%H:%M

1
defaults/Xmd/startup/mwm.sh Executable file
View File

@@ -0,0 +1 @@
mwm

1
defaults/Xmd/startup/panel.sh Executable file
View File

@@ -0,0 +1 @@
xmpanel

5
defaults/install.sh Executable file
View 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
View 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
View File

@@ -0,0 +1 @@
. ~/.xsession

1
defaults/misc/.xsession Normal file
View File

@@ -0,0 +1 @@
exec dbus-run-session xmd

3
glue/install.sh Executable file
View File

@@ -0,0 +1,3 @@
#!/bin/sh
. ../scripts/flags.sh
cp src/* "$PREFIX/bin"

61
glue/src/display-temperature Executable file
View 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
View 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
View 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

View File

@@ -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

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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/*
}

View File

@@ -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/*
}

View File

@@ -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
View 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"

View File

@@ -1,9 +1,55 @@
#!/bin/sh
if type "$XMD_USERDIR/wallpaper" > /dev/null; then
. "$XMD_USERDIR/wallpaper"
name=`basename "$0"`
configFilePath="$XMD_USERDIR/wallpaper"
if type xwallpaper > /dev/null; then
xwallpaper "--${mode}" "$file"
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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View 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 };

View 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 };

View 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 };

View File

@@ -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
View File

@@ -0,0 +1,2 @@
#!/bin/sh
../scripts/buildapp.sh xmpackage "$@"

View 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 };

View 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 };

View 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 };

View 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 };

View 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 };

View 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 };

View 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
View 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
View 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 };

View 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
View 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 };

View 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
View 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 };

View 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 };

View 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
View 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
View File

@@ -0,0 +1,2 @@
#!/bin/sh
../scripts/buildapp.sh xmpackage "$@"

View 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
View 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);
}

View File

@@ -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
View File

@@ -0,0 +1,2 @@
#!/bin/sh
../scripts/buildapp.sh xmshell "$@"

View 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
View 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);
}