чување 89126953f393400b1b585b4beab4ed05d363e59b
родитељ 257a53365ddeac52986313075734f73cc4cb69d9
Аутор: Страхиња Радић <contact@strahinja.org>
Датум: Tue, 12 Dec 2023 16:07:52 +0100
Add manpage; redesign Info panel; add copyright holder, email, version
Signed-off-by: Страхиња Радић <contact@strahinja.org>
Diffstat:
| M | Makefile | | | 40 | ++++++++++++++++++++++++++-------------- |
| M | TODO | | | 2 | +- |
| A | WMNewApp.1 | | | 32 | ++++++++++++++++++++++++++++++++ |
| M | config.def.h | | | 2 | ++ |
| M | infopanel.c | | | 273 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------- |
| M | infopanel.h | | | 8 | +++++++- |
| M | main.c | | | 2 | +- |
| M | wmgen | | | 58 | ++++++++++++++++++++++++++++++++++++++++++++++++++++------ |
измењених датотека: 8, додавања: 341(+), брисања: 76(-)
diff --git a/Makefile b/Makefile
@@ -1,19 +1,25 @@
-CC = cc
-CFLAGS = -g -Wall
-INSTALL = install
-LIBS = -lWMaker -lWINGs -lWUtil -lwraster -lX11
-OBJS = infopanel.o main.o menu.o windowmanager.o
-PREFIX = /usr/local
-PROG = WMNewApp
-
-BINDIR = $(PREFIX)/bin
-
-.SUFFIXES: .def.h .h .c .o
+CC = cc
+CFLAGS = -g -Wall
+FALLBACKDATE = unknown
+FALLBACKVER = unknown
+INSTALL = install
+LIBS = -lWMaker -lWINGs -lWUtil -lwraster -lX11
+OBJS = infopanel.o main.o menu.o windowmanager.o
+PREFIX = /usr/local
+PROG = WMNewApp
+
+BINDIR = $(PREFIX)/bin
+MANPREFIX = $(PREFIX)/share/man
+# OpenBSD
+#MANPREFIX = $(PREFIX)/man
+MANPAGE = $(PROG).1
+
+.SUFFIXES: .1 .def.h .h .c .o
.def.h.h:
cp $< $@
-all: $(PROG)
+all: $(PROG) $(MANPAGE)
$(PROG): config.h $(OBJS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS)
@@ -22,7 +28,13 @@ clean:
rm -f *.o *~ $(PROG)
install: all
- mkdir -p $(BINDIR)
$(INSTALL) -Dm 0755 $(PROG) $(BINDIR)/$(PROG)
+ $(INSTALL) -Dm 0644 $(MANPAGE) $(MANPREFIX)/man1/$(MANPAGE)
+
+uninstall:
+ rm -f $(BINDIR)/$(PROG)
+ rmdir $(BINDIR) 2>/dev/null || true
+ rm -f $(MANPREFIX)/man1/$(MANPAGE)
+ rmdir $(MANPREFIX)/man1 2>/dev/null || true
-.PHONY: all clean install
+.PHONY: all clean install uninstall
diff --git a/TODO b/TODO
@@ -2,6 +2,6 @@ TODO
====
[x] Info panel
-[ ] Manpage
+[x] Manpage
[x] Resizeable windows
[x] Dialogs open in screen center?
diff --git a/WMNewApp.1 b/WMNewApp.1
@@ -0,0 +1,32 @@
+.\" This program is licensed under the terms of GNU GPL v3 or (at your option)
+.\" any later version. Copyright (C) 2020-2023 Yourname Here.
+.\" See the file LICENSE for exact copyright and license details.
+.Dd January 1, 2023
+.Dt WMNEWAPP 1
+.Os
+.Sh NAME
+.Nm WMNewApp
+.Nd Describe your newly generated application
+.Sh SYNOPSIS
+.Nm
+.Op Fl dh
+.Sh DESCRIPTION
+.Nm
+is an example app generated with
+.Sy wmgen .
+.
+.Ss Command line options
+.Bl -tag -width ".Nm Fl h" -offset indent
+.
+.It Nm Fl d
+Turns on debug mode.
+.
+.It Nm Fl h
+Prints usage information.
+.
+.El
+.Sh SEE ALSO
+.Xr wmaker 1
+.Sh AUTHORS
+.An "Yourname Here" Aq address@example.com ,
+2020-2023
diff --git a/config.def.h b/config.def.h
@@ -2,4 +2,6 @@
#define mainwin_title_fmt "%s - [%s%s]"
#define program_name "WMNewApp"
#define program_author "Yourname Here"
+#define program_version "0.1"
#define copy_years "2020-2023"
+#define copy_holder "Yoyodyne, Inc."
diff --git a/infopanel.c b/infopanel.c
@@ -7,60 +7,144 @@
#include "config.h"
+#define KERNEL_NAME_MAX 512
+#define KERNEL_RELEASE_MAX 512
+#define MEM_FREE_MAX 512
+#define UPTIME_MAX 512
+
static struct WMInfoPanel* ip = NULL;
+static char kernel_name[KERNEL_NAME_MAX];
+static char kernel_release[KERNEL_RELEASE_MAX];
+static char mem_free[MEM_FREE_MAX];
+static char uptime[UPTIME_MAX];
-static size_t
-format_author(char** buf, const char* name)
+void
+close_info_panel(WMWidget* self, void* data)
{
- size_t size = 0;
+ struct WMInfoPanel* ip = (struct WMInfoPanel*)data;
+ ip->done = 1;
+}
- *buf = NULL;
- size = strlen("Author") + 2 + strlen(name) + 1 + 1;
- if (!(*buf = calloc(1, size)))
- exit(error(1, "calloc failed"));
- snprintf(*buf, size, "%s: %s", "Author", name);
+static char*
+get_kernel_name()
+{
+ FILE* uname = NULL;
+ char* eol = NULL;
+
+ if (*kernel_name)
+ return kernel_name;
+
+ if (!(uname = popen("uname -s", "r")))
+ strcpy(kernel_name, "(Unknown kernel)");
+ else
+ {
+ fgets(kernel_name, KERNEL_NAME_MAX, uname);
+ eol = strchr(kernel_name, '\n');
+ if (eol)
+ *eol = 0;
+ pclose(uname);
+ }
- return size;
+ return kernel_name;
}
-static size_t
-format_copy(char** buf, const char* years)
+static char*
+get_kernel_release()
{
- size_t size = 0;
+ FILE* uname = NULL;
+ char* eol = NULL;
- *buf = NULL;
- size = strlen("Copyright (C)") + 1 + strlen(years) + 1 + 1;
- if (!(*buf = calloc(1, size)))
- exit(error(1, "calloc failed"));
- snprintf(*buf, size, "%s %s", "Copyright (C) ", years);
+ if (*kernel_release)
+ return kernel_release;
- return size;
+ if (!(uname = popen("uname -r", "r")))
+ strcpy(kernel_release, "(Unknown release)");
+ else
+ {
+ fgets(kernel_release, KERNEL_RELEASE_MAX, uname);
+ eol = strchr(kernel_release, '\n');
+ if (eol)
+ *eol = 0;
+ pclose(uname);
+ }
+
+ return kernel_release;
}
-void
-close_info_panel(WMWidget* self, void* data)
+static char*
+get_mem_free()
{
- struct WMInfoPanel* ip = (struct WMInfoPanel*)data;
- ip->done = 1;
+ FILE* cmd = NULL;
+ char* eol = NULL;
+
+ if (!(cmd = popen("free -g | awk '/^(Mem|Swap)/ { f += $4 } "
+ "END {print f}'",
+ "r")))
+ strcpy(mem_free, "N/A");
+ else
+ {
+ fgets(mem_free, MEM_FREE_MAX, cmd);
+ eol = strchr(mem_free, '\n');
+ if (eol)
+ *eol = 0;
+ pclose(cmd);
+ }
+
+ return mem_free;
}
+static char*
+get_uptime()
+{
+ FILE* cmd = NULL;
+ char* eol = NULL;
+
+ if (!(cmd = popen("uptime | awk '{gsub(\",\", \"\", $3); print $3}'",
+ "r")))
+ strcpy(uptime, "N/A");
+ else
+ {
+ fgets(uptime, UPTIME_MAX, cmd);
+ eol = strchr(uptime, '\n');
+ if (eol)
+ *eol = 0;
+ pclose(cmd);
+ }
+
+ return uptime;
+}
+
+#define LABEL_BUF_MAX 512
+
static struct WMInfoPanel*
create_info_panel(struct WMNewApp* wma)
{
struct WMInfoPanel* ip = NULL;
WMSize icon_size;
WMFont* title_font;
+ WMFont* bold_font;
WMFont* normal_font;
int offset, width, height;
- char* author = NULL;
- char* copy = NULL;
+ int title_width;
+ int icon_frame_offset;
+ int icon_frame_width, icon_frame_height;
+ int info_frame_offset, info_frame_second_col_offset;
+ int info_frame_width, info_frame_height;
+ int info_offset_delta;
+ int padding;
+ char buffer[LABEL_BUF_MAX];
if (!(ip = (struct WMInfoPanel*)calloc(sizeof(struct WMInfoPanel), 1)))
exit(error(1, "calloc failed"));
memset((void*)ip, 0, sizeof(struct WMInfoPanel));
- width = 500;
- height = 300;
+ width = 500;
+ height = 300;
+ padding = 15;
+
+ title_font = WMBoldSystemFontOfSize(wma->scr, 24);
+ bold_font = WMBoldSystemFontOfSize(wma->scr, 12);
+ normal_font = WMSystemFontOfSize(wma->scr, 12);
ip->app = wma;
ip->window = WMCreateWindow(wma->scr, "info");
@@ -68,53 +152,136 @@ create_info_panel(struct WMNewApp* wma)
WMSetWindowTitle(ip->window, "Info");
WMSetWindowCloseAction(ip->window, close_info_panel, ip);
- icon_size = WMGetPixmapSize(wma->wmpixmap);
- ip->icon_label = WMCreateLabel(ip->window);
+ offset = padding;
+ title_width = WMWidthOfString(title_font, program_name,
+ strlen(program_name));
+
+ icon_size = WMGetPixmapSize(wma->wmpixmap);
+ icon_frame_width = width - 2 * padding;
+ icon_frame_height = icon_size.height + padding + 24;
+
+ /* / Icon frame \ */
+ icon_frame_offset = 0;
+
+ ip->icon_frame = WMCreateFrame(ip->window);
+ WMMoveWidget(ip->icon_frame, padding, offset);
+ WMResizeWidget(ip->icon_frame, icon_frame_width, icon_frame_height);
+ WMSetFrameRelief(ip->icon_frame, WRFlat);
+
+ ip->icon_label = WMCreateLabel(ip->icon_frame);
WMResizeWidget(ip->icon_label, icon_size.width, icon_size.height);
- WMMoveWidget(ip->icon_label, 80 - icon_size.width,
- 80 - icon_size.height);
+ WMMoveWidget(ip->icon_label, (icon_frame_width - icon_size.width) / 2,
+ icon_frame_offset);
WMSetLabelImage(ip->icon_label, wma->wmpixmap);
WMSetLabelImagePosition(ip->icon_label, WIPImageOnly);
+ icon_frame_offset += icon_size.height + padding;
- title_font = WMBoldSystemFontOfSize(wma->scr, 24);
- normal_font = WMBoldSystemFontOfSize(wma->scr, 12);
-
- ip->title_label = WMCreateLabel(ip->window);
- offset = 55;
- WMMoveWidget(ip->title_label, 90, (80 - 24) / 2);
- WMResizeWidget(ip->title_label, width - 70, 2 * (24 + 6));
+ ip->title_label = WMCreateLabel(ip->icon_frame);
+ WMMoveWidget(ip->title_label, (icon_frame_width - title_width) / 2,
+ icon_frame_offset);
+ WMResizeWidget(ip->title_label, icon_frame_width, 24);
WMSetLabelText(ip->title_label, program_name);
WMSetLabelFont(ip->title_label, title_font);
- offset += 24 + 6;
+ /* \ Icon frame / */
+
+ offset += icon_frame_height + padding;
ip->author_label = WMCreateLabel(ip->window);
- WMMoveWidget(ip->author_label, 80 - icon_size.width, offset);
- WMResizeWidget(ip->author_label, width - (80 - icon_size.width) - 20,
- 20);
- format_author(&author, program_author);
- WMSetLabelText(ip->author_label, author);
+ WMMoveWidget(ip->author_label, padding, offset);
+ WMResizeWidget(ip->author_label, icon_frame_width, 12);
+ WMSetLabelTextAlignment(ip->author_label, WACenter);
+ snprintf(buffer, LABEL_BUF_MAX, "by %s", program_author);
+ WMSetLabelText(ip->author_label, buffer);
WMSetLabelFont(ip->author_label, normal_font);
- free(author);
- offset += 12 + 6;
+ offset += 12 + padding;
+
+ /* / Info frame \ */
+ info_frame_width = icon_frame_width;
+ info_frame_height = height - offset - (12 + padding) - padding;
+
+ ip->info_frame = WMCreateFrame(ip->window);
+ WMMoveWidget(ip->info_frame, padding, offset);
+ WMResizeWidget(ip->info_frame, info_frame_width, info_frame_height);
+ // WMSetFrameRelief(ip->info_frame, WRGroove);
+
+ info_frame_offset = padding;
+ info_offset_delta = (info_frame_height - 4 * padding) / 3 + padding;
+ info_frame_second_col_offset = info_frame_width / 2 - 2 * padding;
+
+ ip->sys_release_label = WMCreateLabel(ip->info_frame);
+ WMMoveWidget(ip->sys_release_label, padding, info_frame_offset);
+ WMResizeWidget(ip->sys_release_label, info_frame_second_col_offset, 12);
+ snprintf(buffer, LABEL_BUF_MAX, "Kernel Release %s %s",
+ get_kernel_name(), get_kernel_release());
+ WMSetLabelText(ip->sys_release_label, buffer);
+ WMSetLabelFont(ip->sys_release_label, normal_font);
+
+ ip->mem_free_label = WMCreateLabel(ip->info_frame);
+ WMMoveWidget(ip->mem_free_label,
+ padding + info_frame_second_col_offset + padding,
+ info_frame_offset);
+ WMResizeWidget(ip->mem_free_label, info_frame_second_col_offset, 12);
+ snprintf(buffer, LABEL_BUF_MAX, "Mem free: %s GB", get_mem_free());
+ WMSetLabelText(ip->mem_free_label, buffer);
+ WMSetLabelTextAlignment(ip->mem_free_label, WARight);
+ WMSetLabelFont(ip->mem_free_label, normal_font);
+ info_frame_offset += info_offset_delta;
+
+ ip->app_release_label = WMCreateLabel(ip->info_frame);
+ WMMoveWidget(ip->app_release_label, padding, info_frame_offset);
+ WMResizeWidget(ip->app_release_label,
+ (info_frame_width - 2 * padding) / 2, 12);
+ snprintf(buffer, LABEL_BUF_MAX, "%s Release %s", program_name,
+ program_version);
+ WMSetLabelText(ip->app_release_label, buffer);
+ WMSetLabelFont(ip->app_release_label, normal_font);
+
+ ip->uptime_label = WMCreateLabel(ip->info_frame);
+ WMMoveWidget(ip->uptime_label,
+ padding + info_frame_second_col_offset + padding,
+ info_frame_offset);
+ WMResizeWidget(ip->uptime_label, info_frame_second_col_offset, 12);
+ snprintf(buffer, LABEL_BUF_MAX, "Uptime: %s", get_uptime());
+ WMSetLabelText(ip->uptime_label, buffer);
+ WMSetLabelTextAlignment(ip->uptime_label, WARight);
+ WMSetLabelFont(ip->uptime_label, normal_font);
+ info_frame_offset += info_offset_delta;
+
+ ip->win_server_label = WMCreateLabel(ip->info_frame);
+ WMMoveWidget(ip->win_server_label, padding, info_frame_offset);
+ WMResizeWidget(ip->win_server_label,
+ (info_frame_width - 2 * padding) / 2, 12);
+ snprintf(buffer, LABEL_BUF_MAX, "Window Server %d",
+ VendorRelease(ip->app->dpy));
+ WMSetLabelText(ip->win_server_label, buffer);
+ WMSetLabelFont(ip->win_server_label, normal_font);
+ /* \ Info frame / */
+
+ offset += info_frame_height + padding;
ip->copy_label = WMCreateLabel(ip->window);
- WMMoveWidget(ip->copy_label, 80 - icon_size.width, offset);
- WMResizeWidget(ip->copy_label, width - (80 - icon_size.width) - 20, 20);
- format_copy(©, copy_years);
- WMLog(ip->app, copy);
- WMSetLabelText(ip->copy_label, copy);
- WMSetLabelFont(ip->copy_label, normal_font);
- free(copy);
+ WMMoveWidget(ip->copy_label, padding, offset);
+ WMResizeWidget(ip->copy_label, width - 2 * padding, 12);
+ snprintf(buffer, LABEL_BUF_MAX, "Copyright (C) %s %s", copy_years,
+ copy_holder);
+ WMSetLabelText(ip->copy_label, buffer);
+ WMSetLabelTextColor(ip->copy_label,
+ WMCreateNamedColor(ip->app->scr, "dimgray", True));
+ WMSetLabelTextAlignment(ip->copy_label, WACenter);
+ WMSetLabelFont(ip->copy_label, bold_font);
WMRealizeWidget(ip->window);
+ WMMapSubwidgets(ip->icon_frame);
+ WMMapSubwidgets(ip->info_frame);
WMMapSubwidgets(ip->window);
+ // WMMapWidget(ip->window);
WMReleaseFont(title_font);
WMReleaseFont(normal_font);
return ip;
}
-void
+static void
destroy_info_panel(struct WMInfoPanel* ip)
{
WMUnmapWidget(ip->window);
diff --git a/infopanel.h b/infopanel.h
@@ -1,13 +1,19 @@
struct WMInfoPanel {
struct WMNewApp* app;
WMWindow* window;
+ WMWidget* icon_frame;
WMWidget* icon_label;
WMWidget* title_label;
WMWidget* author_label;
+ WMWidget* info_frame;
WMWidget* copy_label;
+ WMWidget* sys_release_label;
+ WMWidget* mem_free_label;
+ WMWidget* app_release_label;
+ WMWidget* uptime_label;
+ WMWidget* win_server_label;
int done;
};
void close_info_panel(WMWidget* self, void* data);
-void destroy_info_panel(struct WMInfoPanel* ip);
void run_info_panel(struct WMNewApp* wma);
diff --git a/main.c b/main.c
@@ -75,7 +75,7 @@ create_main_window(struct WMNewApp* wma)
wma->mainwin = WMCreateWindow(wma->scr, "mainwin");
WMRealizeWidget(wma->mainwin);
set_mainwin_title(wma);
- WMSetWindowMinSize(wma->mainwin, 200, 200);
+ WMResizeWidget(wma->mainwin, 640, 480);
WMSetWindowCloseAction(wma->mainwin, exit_action, wma);
XSetClassHint(wma->dpy, WMWidgetXID(wma->mainwin), wma->class_hint);
diff --git a/wmgen b/wmgen
@@ -21,6 +21,15 @@ prompt_for_vars()
fi
fi
+ if [ ! "$app_version" ]; then
+ app_version=0.1
+ fi
+ printf "App version [%s]: " "$app_version"
+ IFS= read -r papp_version
+ if [ "$papp_version" ]; then
+ app_version="$papp_version"
+ fi
+
app_dir=$(echo "$app_name" | tr [A-Z] [a-z])
printf "Application directory [%s]: " "$app_dir"
IFS= read -r papp_dir
@@ -35,17 +44,41 @@ prompt_for_vars()
res_name="$pres_name"
fi
- printf "Author name [%s]: " "$author_name"
+ if [ ! "$author_name" ]; then
+ author_name=$(whoami)
+ fi
+ printf "Name of the author [%s]: " "$author_name"
IFS= read -r pauthor_name
if [ "$pauthor_name" ]; then
author_name="$pauthor_name"
fi
+ if [ ! "$author_email" ]; then
+ author_email="$(whoami)@localhost"
+ fi
+ printf "Author's email [%s]: " "$author_email"
+ IFS= read -r pauthor_email
+ if [ "$pauthor_email" ]; then
+ author_email="$pauthor_email"
+ fi
+
+ if [ ! "$copy_years" ]; then
+ copy_years=$(date +%Y)
+ fi
printf "Copyright years [%s]: " "$copy_years"
IFS= read -r pcopy_years
if [ "$pcopy_years" ]; then
copy_years="$pcopy_years"
fi
+
+ if [ ! "$copy_holder" ]; then
+ copy_holder="$author_name"
+ fi
+ printf "Copyright holder [%s]: " "$copy_holder"
+ IFS= read -r pcopy_holder
+ if [ "$pcopy_holder" ]; then
+ copy_holder="$pcopy_holder"
+ fi
}
while true; do
@@ -57,22 +90,25 @@ while true; do
Option summary
===========================================================================
App name: $app_name
+App version: $app_version
App directory: $full_app_dir
Leader window resource name: $res_name ($res_name.$app_name)
Main window resource name: mainwin.$app_name
Author: $author_name
+Author's Email: $author_email
Copyright years: $copy_years
+Copyright holder: $copy_holder
License: GPL v3+ (copy your own if not)
===========================================================================
ENDSUMMARY
- printf "Is this correct [y=Execute/N=Reenter]: "
+ printf "Is this correct [y/N/q]: "
IFS= read -r confirm
case "$confirm" in
y|Y) confirmed=1
break 2;;
- n|N) confirmed=1
+ q|Q) exit;;
+ *) confirmed=1
continue 2;;
- *) ;;
esac
done
done
@@ -81,16 +117,26 @@ subst_copy()
{
file=$1
app_dir=$2
+ tofile=$3
+ if [ ! "$tofile" ]; then
+ tofile=$1
+ fi
sed -e 's/WMNewApp/'"$app_name"'/g' \
+ -e 's/WMNEWAPP/'$(echo "$app_name" | tr [a-z] [A-Z])'/g' \
-e 's/wmnewapp/'"$res_name"'/g' \
+ -e 's/0\.1/'"$app_version"'/g' \
-e 's/Yourname Here/'"$author_name"'/g' \
+ -e 's/Yoyodyne, Inc./'"$copy_holder"'/g' \
+ -e 's/address@example.com/'"$author_email"'/g' \
-e 's/2020-2023/'"$copy_years"'/g' \
- "$file" > "$app_dir"/"$file"
+ "$file" > "$app_dir"/"$tofile"
}
set -x
mkdir -p "$full_app_dir"
-sed 's/^\(PROG.*= \).*/\1'$app_name'/' Makefile > "$full_app_dir"/Makefile
+#sed 's/^\(PROG.*= \).*/\1'$app_name'/' Makefile > "$full_app_dir"/Makefile
+subst_copy Makefile "$full_app_dir"
+subst_copy WMNewApp.1 "$full_app_dir" "$app_name".1
subst_copy app.h "$full_app_dir"
cp appicon.xpm "$full_app_dir"/appicon.xpm
subst_copy config.def.h "$full_app_dir"