wmgen

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

чување 1f6afd0fbad25d3b8be5876e34eb01159fcc11b2
родитељ cb9efda7ef130c71f8e6b8c83a54ffa85ff6467f
Аутор: Страхиња Радић <contact@strahinja.org>
Датум:   Mon, 11 Dec 2023 20:27:50 +0100

Dialogs open in screen center; resizeable main window

Signed-off-by: Страхиња Радић <contact@strahinja.org>

Diffstat:
M.gitignore | 1+
MMakefile | 2+-
MTODO | 4++--
Mapp.h | 13+++++++------
Minfopanel.c | 8++++----
Minfopanel.h | 2+-
Mmain.c | 224+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Mmake-new-app.sh | 2++
Mmenu.c | 20++++++++++----------
Mmenu.h | 2+-
Awindowmanager.c | 12++++++++++++
Awindowmanager.h | 23+++++++++++++++++++++++
измењених датотека: 12, додавања: 185(+), брисања: 128(-)

diff --git a/.gitignore b/.gitignore @@ -5,3 +5,4 @@ *.swp WMNewApp config.h +cscope.out diff --git a/Makefile b/Makefile @@ -2,7 +2,7 @@ CC = cc CFLAGS = -g -Wall INSTALL = install LIBS = -lWMaker -lWINGs -lWUtil -lwraster -lX11 -OBJS = infopanel.o main.o menu.o +OBJS = infopanel.o main.o menu.o windowmanager.o PREFIX = /usr/local PROG = WMNewApp diff --git a/TODO b/TODO @@ -3,5 +3,5 @@ TODO [ ] Info panel [ ] Manpage -[ ] Resizeable windows -[ ] Dialogs open in screen center? +[x] Resizeable windows +[x] Dialogs open in screen center? diff --git a/app.h b/app.h @@ -8,6 +8,7 @@ struct State { }; struct WMNewApp { + struct State state; WMAppContext* app; Pixmap app_icon; RImage* app_image; @@ -25,12 +26,13 @@ struct WMNewApp { XContext xctx; }; -extern struct State state; extern struct WMNewApp wma; void cleanup(); -void create_icon(); -void debug_print_state(struct State* state); +void create_icon(struct WMNewApp* wma); +void create_leader_window(struct WMNewApp* wma); +void create_main_window(struct WMNewApp* wma); +void debug_print_state(struct WMNewApp* wma); int error(const int code, const char* msg, ...); void exit_action(WMWidget* self, void* data); void handle_keypress(XEvent* event, void* data); @@ -39,7 +41,6 @@ void init_state(struct State* state); void not_implemented(WMWidget* self, void* data); void open_action(WMWidget* self, void* data); void save_action(WMWidget* self, void* data); -void set_mainwin_title(struct State* state, char* buf, const size_t size); +void set_mainwin_title(struct WMNewApp* wma); void usage(const char* arg0); -void WMLog(const char* msg, ...); - +void WMLog(const struct WMNewApp* wma, const char* msg, ...); diff --git a/infopanel.c b/infopanel.c @@ -2,22 +2,22 @@ #include "infopanel.h" void -create_info_panel(struct WMInfoPanel* ip) +create_info_panel(struct WMNewApp* wma, struct WMInfoPanel* ip) { WMSize icon_size; - ip->window = WMCreateWindow(wma.scr, "info"); + ip->window = WMCreateWindow(wma->scr, "info"); WMResizeWidget(ip->window, 400, 300); WMSetWindowTitle(ip->window, "Info"); WMSetWindowCloseAction(ip->window, hide_info_panel, NULL); - icon_size = WMGetPixmapSize(wma.wmpixmap); + icon_size = WMGetPixmapSize(wma->wmpixmap); ip->icon_label = WMCreateLabel(ip->window); WMResizeWidget(ip->icon_label, icon_size.width, icon_size.height); WMMoveWidget(ip->icon_label, 80 - icon_size.width, 80 - icon_size.height); - WMSetLabelImage(ip->icon_label, wma.wmpixmap); + WMSetLabelImage(ip->icon_label, wma->wmpixmap); WMSetLabelImagePosition(ip->icon_label, WIPImageOnly); WMRealizeWidget(ip->window); WMMapSubwidgets(ip->window); diff --git a/infopanel.h b/infopanel.h @@ -3,6 +3,6 @@ struct WMInfoPanel { WMWidget* icon_label; }; -void create_info_panel(struct WMInfoPanel* ip); +void create_info_panel(struct WMNewApp* wma, struct WMInfoPanel* ip); void hide_info_panel(); void show_info_panel(); diff --git a/main.c b/main.c @@ -7,32 +7,18 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> + #include "app.h" #include "infopanel.h" #include "menu.h" +#include "windowmanager.h" + #include "config.h" #include "appicon.xpm" -struct State state; -struct WMNewApp wma; - -void -cleanup() -{ - XFree(wma.wmpixmap); - XFree(wma.scr); - XFree(wma.rctx); - XFree(wma.mainwin); - XFree(wma.main_menu); - XFree(wma.hints); - XFree(wma.dpy); - XFree(wma.class_hint); - XFree(wma.app_image); - XFree(wma.app); -} - +/* Assumes leader window has been created */ void -create_icon() +create_icon(struct WMNewApp* wma) { RContextAttributes attr; @@ -41,32 +27,84 @@ create_icon() attr.render_mode = 0; attr.colors_per_channel = 4; - if (!(wma.rctx = RCreateContext(wma.dpy, DefaultScreen(wma.dpy), &attr))) + if (!(wma->rctx + = RCreateContext(wma->dpy, DefaultScreen(wma->dpy), &attr))) exit(error(1, "RCreateContext failed\n")); - if (!(wma.app_image = RGetImageFromXPMData(wma.rctx, appicon_xpm))) + if (!(wma->app_image = RGetImageFromXPMData(wma->rctx, appicon_xpm))) exit(error(1, "RGetImageFromXPMData failed\n")); - if (!RConvertImageMask(wma.rctx, wma.app_image, &wma.app_icon, - &wma.app_mask, 0)) + if (!RConvertImageMask(wma->rctx, wma->app_image, &wma->app_icon, + &wma->app_mask, 0)) exit(error(1, "RConvertImageMask failed\n")); - wma.hints->icon_pixmap = wma.app_icon; - wma.hints->icon_mask = wma.app_mask; - wma.hints->flags |= (IconPixmapHint | IconMaskHint); - XSetWMHints(wma.dpy, wma.leader, wma.hints); + wma->hints->icon_pixmap = wma->app_icon; + wma->hints->icon_mask = wma->app_mask; + wma->hints->flags |= (IconPixmapHint | IconMaskHint); + XSetWMHints(wma->dpy, wma->leader, wma->hints); - if (!(wma.wmpixmap - = WMCreatePixmapFromRImage(wma.scr, wma.app_image, 0))) + if (!(wma->wmpixmap + = WMCreatePixmapFromRImage(wma->scr, wma->app_image, 0))) exit(error(1, "WMCreatePixmapFromRImage failed")); - WMSetApplicationIconPixmap(wma.scr, wma.wmpixmap); + WMSetApplicationIconPixmap(wma->scr, wma->wmpixmap); +} + +void +create_leader_window(struct WMNewApp* wma) +{ + wma->leader = XCreateSimpleWindow(wma->dpy, DefaultRootWindow(wma->dpy), + 10, 10, 10, 10, 0, 0, 0); + + if (!(wma->class_hint = XAllocClassHint())) + exit(error(1, "XAllocClassHint(leader) failed")); + wma->class_hint->res_name = "wmnewapp"; + wma->class_hint->res_class = "WMNewApp"; + XSetClassHint(wma->dpy, wma->leader, wma->class_hint); + + if (!(wma->hints = XAllocWMHints())) + exit(error(1, "XAllocWMHints failed")); + wma->hints->window_group = wma->leader; + wma->hints->flags = WindowGroupHint; + XSetWMHints(wma->dpy, wma->leader, wma->hints); +} + +/* Assumes create_leader_window has previously been called */ +void +create_main_window(struct WMNewApp* wma) +{ + MyGNUstepWMAttributes attributes; + + wma->mainwin = WMCreateWindow(wma->scr, "mainwin"); + WMLog(wma, "before WMRealizeWidget\n"); + WMRealizeWidget(wma->mainwin); + WMLog(wma, "after WMRealizeWidget\n"); + set_mainwin_title(wma); + WMSetWindowMinSize(wma->mainwin, 200, 200); + WMSetWindowCloseAction(wma->mainwin, exit_action, wma); + + XSetClassHint(wma->dpy, WMWidgetXID(wma->mainwin), wma->class_hint); + XSetWMHints(wma->dpy, WMWidgetXID(wma->mainwin), wma->hints); + + memset((void*)&attributes, 0, sizeof(MyGNUstepWMAttributes)); + attributes.window_style = (WMTitledWindowMask + | WMMiniaturizableWindowMask | WMResizableWindowMask); + attributes.window_level = WMNormalWindowLevel; + attributes.extra_flags = GSFullKeyboardEventsFlag; + attributes.flags + = (GSWindowStyleAttr | GSWindowLevelAttr | GSExtraFlagsAttr); + MyWMSetWindowAttributes(wma->dpy, WMWidgetXID(wma->mainwin), + &attributes); + + WMMapSubwidgets(wma->mainwin); + WMLog(wma, "WMRealizeWidget\n"); + WMMapWidget(wma->mainwin); } void -debug_print_state(struct State* state) +debug_print_state(struct WMNewApp* wma) { - WMLog("State dump:\n"); - WMLog("===================================\n"); - WMLog("dirty:\t\t%s\n", state->dirty ? "YES" : "NO"); - WMLog("filename:\t[%s]\n", state->filename); + WMLog(wma, "State dump:\n"); + WMLog(wma, "===================================\n"); + WMLog(wma, "dirty:\t\t%s\n", wma->state.dirty ? "YES" : "NO"); + WMLog(wma, "filename:\t[%s]\n", wma->state.filename); } int @@ -84,19 +122,21 @@ error(const int code, const char* msg, ...) void exit_action(WMWidget* self, void* data) { - WMLog("exit_action called\n"); - if (!state.dirty) + struct WMNewApp* wma = (struct WMNewApp*)data; + WMLog(wma, "exit_action called\n"); + if (!wma->state.dirty) exit(0); - if (WMRunAlertPanel(wma.scr, wma.mainwin, "Confirm", - "Document %s is modified. Save changes?", - "Yes", "No", NULL) == 0) + if (WMRunAlertPanel(wma->scr, NULL, "Confirm", + "Document %s is modified. Save changes?", "Yes", "No", NULL) + == 0) exit(0); } void handle_keypress(XEvent* event, void* data) { + struct WMNewApp* wma = (struct WMNewApp*)data; int count; char buffer[64]; KeySym ksym; @@ -104,39 +144,39 @@ handle_keypress(XEvent* event, void* data) int meta_pressed = 0; int shift_pressed = 0; - WMLog("handle_keypress called\n"); + WMLog(wma, "handle_keypress called\n"); count = XLookupString(&event->xkey, buffer, 63, &ksym, NULL); buffer[count] = 0; - WMLog("\tbuffer: %s\n", buffer); - WMLog("\tksym: 0x%lX\n", ksym); - WMLog("\tstate: %d\n", event->xkey.state); + WMLog(wma, "\tbuffer: %s\n", buffer); + WMLog(wma, "\tksym: 0x%lX\n", ksym); + WMLog(wma, "\tstate: %d\n", event->xkey.state); ctrl_pressed = event->xkey.state & ControlMask; meta_pressed = event->xkey.state & Mod1Mask; shift_pressed = event->xkey.state & ShiftMask; - WMLog("\tctrl_pressed: %s\n", ctrl_pressed ? "YES" : "NO"); - WMLog("\tmeta_pressed: %s\n", meta_pressed ? "YES" : "NO"); - WMLog("\tshift_pressed: %s\n", shift_pressed ? "YES" : "NO"); + WMLog(wma, "\tctrl_pressed: %s\n", ctrl_pressed ? "YES" : "NO"); + WMLog(wma, "\tmeta_pressed: %s\n", meta_pressed ? "YES" : "NO"); + WMLog(wma, "\tshift_pressed: %s\n", shift_pressed ? "YES" : "NO"); switch (ksym) { case XK_F1: - info_panel_action(wma.mainwin, wma.app); + info_panel_action(wma->mainwin, wma); break; case XK_o: if (ctrl_pressed && !meta_pressed && !shift_pressed) - open_action(wma.mainwin, NULL); + open_action(wma->mainwin, wma); break; case XK_s: if (ctrl_pressed && !meta_pressed && !shift_pressed) - save_action(wma.mainwin, NULL); + save_action(wma->mainwin, wma); break; case XK_q: if (ctrl_pressed && !meta_pressed && !shift_pressed) - exit_action(wma.mainwin, NULL); + exit_action(wma->mainwin, wma); break; } } @@ -144,9 +184,10 @@ handle_keypress(XEvent* event, void* data) void info_panel_action(WMWidget* self, void* data) { - WMLog("info_panel_action called\n"); + struct WMNewApp* wma = (struct WMNewApp*)data; + WMLog(wma, "info_panel_action called\n"); show_info_panel(); - not_implemented(self, data); + not_implemented(self, wma); } void @@ -159,31 +200,34 @@ init_state(struct State* state) void not_implemented(WMWidget* self, void* data) { - WMRunAlertPanel(wma.scr, wma.mainwin, "Sorry", + struct WMNewApp* wma = (struct WMNewApp*)data; + WMRunAlertPanel(wma->scr, NULL, "Sorry", "Function is not yet implemented", "Ok", NULL, NULL); } void open_action(WMWidget* self, void* data) { - WMLog("open_action called\n"); + struct WMNewApp* wma = (struct WMNewApp*)data; + WMLog(wma, "open_action called\n"); not_implemented(self, data); } void save_action(WMWidget* self, void* data) { - WMLog("save_action called\n"); + struct WMNewApp* wma = (struct WMNewApp*)data; + WMLog(wma, "save_action called\n"); not_implemented(self, data); } void -set_mainwin_title(struct State* state, char* buf, const size_t size) +set_mainwin_title(struct WMNewApp* wma) { - snprintf(buf, size, mainwin_title_fmt, program_name, - state->dirty ? "*" : "", - *state->filename ? state->filename : default_filename); - WMSetWindowTitle(wma.mainwin, wma.mainwin_title); + snprintf(wma->mainwin_title, 4095, mainwin_title_fmt, program_name, + wma->state.dirty ? "*" : "", + *(wma->state.filename) ? wma->state.filename : default_filename); + WMSetWindowTitle(wma->mainwin, wma->mainwin_title); } void @@ -195,11 +239,11 @@ usage(const char* arg0) } void -WMLog(const char* msg, ...) +WMLog(const struct WMNewApp* wma, const char* msg, ...) { va_list arg; - if (!state.debug) + if (!wma->state.debug) return; va_start(arg, msg); @@ -210,12 +254,13 @@ WMLog(const char* msg, ...) int main(int argc, char** argv) { + struct WMNewApp wma; int dbg = 0; int opt; while ((opt = getopt(argc, argv, "dh")) != -1) { - switch(opt) + switch (opt) { case 'd': dbg = 1; @@ -229,58 +274,31 @@ main(int argc, char** argv) } } - init_state(&state); - state.debug = dbg; - - atexit(&cleanup); + init_state(&wma.state); + wma.state.debug = dbg; WMInitializeApplication("WMNewApp", &argc, argv); if (!(wma.dpy = XOpenDisplay(""))) - return error(1, "XOpenDisplay failed"); + exit(error(1, "XOpenDisplay failed")); - wma.leader = XCreateSimpleWindow(wma.dpy, DefaultRootWindow(wma.dpy), - 10, 10, 10, 10, 0, 0, 0); - - if (!(wma.class_hint = XAllocClassHint())) - exit(error(1, "XAllocClassHint(leader) failed")); - wma.class_hint->res_name = "wmnewapp"; - wma.class_hint->res_class = "WMNewApp"; - XSetClassHint(wma.dpy, wma.leader, wma.class_hint); - - if (!(wma.hints = XAllocWMHints())) - exit(error(1, "XAllocWMHints failed")); - wma.hints->window_group = wma.leader; - wma.hints->flags = WindowGroupHint; - XSetWMHints(wma.dpy, wma.leader, wma.hints); + create_leader_window(&wma); XSetCommand(wma.dpy, wma.leader, argv, argc); wma.xctx = XUniqueContext(); + wma.scr = WMCreateScreen(wma.dpy, DefaultScreen(wma.dpy)); + wma.app = WMAppCreateWithMain(wma.dpy, DefaultScreen(wma.dpy), + wma.leader); - WMInitializeApplication("WMPoe", &argc, argv); - wma.scr = WMCreateScreen(wma.dpy, DefaultScreen(wma.dpy)); - wma.app = WMAppCreateWithMain(wma.dpy, DefaultScreen(wma.dpy), - wma.leader); - - wma.mainwin = WMCreateWindow(wma.scr, "mainwin"); - WMRealizeWidget(wma.mainwin); - - XSetClassHint(wma.dpy, WMWidgetXID(wma.mainwin), wma.class_hint); - XSetWMHints(wma.dpy, WMWidgetXID(wma.mainwin), wma.hints); - - create_icon(); - //create_info_panel(); - create_main_menu(wma.app); + create_main_window(&wma); + create_icon(&wma); + create_main_menu(&wma); + // create_info_panel(); - set_mainwin_title(&state, wma.mainwin_title, 4095); - WMSetWindowMinSize(wma.mainwin, 200, 200); - WMSetWindowCloseAction(wma.mainwin, exit_action, NULL); - WMMapSubwidgets(wma.mainwin); - WMMapWidget(wma.mainwin); WMSetFocusToWidget(wma.mainwin); XSaveContext(wma.dpy, WMWidgetXID(wma.mainwin), wma.xctx, NULL); WMCreateEventHandler(WMWidgetView(wma.mainwin), KeyPressMask, - handle_keypress, NULL); + handle_keypress, &wma); XFlush(wma.dpy); diff --git a/make-new-app.sh b/make-new-app.sh @@ -77,6 +77,8 @@ sed 's/WMNewApp/'$app_name'/g;s/wmnewapp/'$res_name'/g' main.c \ > "$full_app_dir"/main.c cp menu.c "$full_app_dir"/menu.c cp menu.h "$full_app_dir"/menu.h +cp windowmanager.c "$full_app_dir"/windowmanager.c +cp windowmanager.h "$full_app_dir"/windowmanager.h cp LICENSE "$full_app_dir"/LICENSE cat <<ENDREADME > "$full_app_dir"/README $app_name diff --git a/menu.c b/menu.c @@ -2,24 +2,24 @@ #include "config.h" void -create_main_menu(WMAppContext* app) +create_main_menu(struct WMNewApp* wma) { WMMenu* submenu; - wma.main_menu = WMMenuCreate(wma.app, (char*)program_name); + wma->main_menu = WMMenuCreate(wma->app, (char*)program_name); - submenu = WMMenuCreate(wma.app, "Info"); - WMMenuAddSubmenu(wma.main_menu, "Info", submenu); + submenu = WMMenuCreate(wma->app, "Info"); + WMMenuAddSubmenu(wma->main_menu, "Info", submenu); WMMenuAddItem(submenu, "Info Panel...", (WMMenuAction)info_panel_action, - app, NULL, "f1"); + wma->app, NULL, "f1"); - WMMenuAddItem(wma.main_menu, "Open...", (WMMenuAction)open_action, NULL, + WMMenuAddItem(wma->main_menu, "Open...", (WMMenuAction)open_action, NULL, NULL, "^o"); - WMMenuAddItem(wma.main_menu, "Save...", (WMMenuAction)save_action, NULL, + WMMenuAddItem(wma->main_menu, "Save...", (WMMenuAction)save_action, NULL, NULL, "^s"); - WMMenuAddItem(wma.main_menu, "Quit", (WMMenuAction)exit_action, NULL, + WMMenuAddItem(wma->main_menu, "Quit", (WMMenuAction)exit_action, NULL, NULL, "^q"); - WMAppSetMainMenu(wma.app, wma.main_menu); - WMRealizeMenus(wma.app); + WMAppSetMainMenu(wma->app, wma->main_menu); + WMRealizeMenus(wma->app); } diff --git a/menu.h b/menu.h @@ -1 +1 @@ -void create_main_menu(WMAppContext* app); +void create_main_menu(struct WMNewApp* app); diff --git a/windowmanager.c b/windowmanager.c @@ -0,0 +1,11 @@ +#include "windowmanager.h" + +void MyWMSetWindowAttributes(Display* dpy, Window window, MyGNUstepWMAttributes* attributes) +{ + Atom atom; + + atom = XInternAtom(dpy, "_GNUSTEP_WM_ATTR", False); + XChangeProperty(dpy, window, atom, atom, 32, PropModeReplace, + (unsigned char*)attributes, + sizeof(MyGNUstepWMAttributes) / sizeof(unsigned long)); +} +\ No newline at end of file diff --git a/windowmanager.h b/windowmanager.h @@ -0,0 +1,22 @@ +#ifndef _WINDOWMANAGER_H_ +#define _WINDOWMANAGER_H_ + +#include <X11/Xlib.h> + +typedef struct +{ + unsigned long flags; + unsigned long window_style; + unsigned long window_level; + unsigned long reserved; + Pixmap miniaturize_pixmap; /* pixmap for miniaturize button */ + Pixmap close_pixmap; /* pixmap for close button */ + Pixmap miniaturize_mask; /* miniaturize pixmap mask */ + Pixmap close_mask; /* close pixmap mask */ + unsigned long extra_flags; +} MyGNUstepWMAttributes; + +void MyWMSetWindowAttributes(Display* dpy, Window window, + MyGNUstepWMAttributes* attributes); + +#endif +\ No newline at end of file