wmgen

Генератор WINGs апликација
Дневник | Датотеке | Референце | ПРОЧИТАЈМЕ | ЛИЦЕНЦА

чување 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:
MMakefile | 40++++++++++++++++++++++++++--------------
MTODO | 2+-
AWMNewApp.1 | 32++++++++++++++++++++++++++++++++
Mconfig.def.h | 2++
Minfopanel.c | 273+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
Minfopanel.h | 8+++++++-
Mmain.c | 2+-
Mwmgen | 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, 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"