diff --git a/CMakeLists.txt b/CMakeLists.txt index d450514..242885a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,28 @@ find_package(X11 REQUIRED) set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fsanitize=address -pg") +include(FetchContent) + +FetchContent_Declare( + unity + GIT_REPOSITORY https://github.com/ThrowTheSwitch/Unity.git + GIT_TAG v2.6.1 +) + +FetchContent_Declare( + zlog + GIT_REPOSITORY https://github.com/HardySimpson/zlog.git + GIT_TAG 1.2.18 +) + +FetchContent_Declare( + argparse + GIT_REPOSITORY https://github.com/cofyc/argparse.git + GIT_TAG 682d4520b4bc2b646cdfcf078b2fed00b3d2da30 +) + +FetchContent_MakeAvailable(unity zlog argparse) + add_library(libaswm src/aswm/aswm.c src/aswm/mapper/mapper.c @@ -21,27 +43,20 @@ add_library(libaswm src/aswm/event_handlers/message.c src/aswm/log/log.c ) -target_include_directories(libaswm PUBLIC ${X11_INCLUDE_DIR} src) -target_link_libraries(libaswm ${X11_LIBRARIES}) +target_include_directories(libaswm PUBLIC ${X11_INCLUDE_DIR} src + ${zlog_SOURCE_DIR}/src) +target_link_libraries(libaswm ${X11_LIBRARIES} zlog) -add_executable(aswm src/aswm/main.c) +add_executable(aswm src/aswm/main.c ${argparse_SOURCE_DIR}/argparse.c) +target_include_directories(aswm PUBLIC ${argparse_SOURCE_DIR}) target_link_libraries(aswm libaswm) -include(FetchContent) - -FetchContent_Declare( - unity - GIT_REPOSITORY https://github.com/ThrowTheSwitch/Unity.git - GIT_TAG v2.6.1 -) - -FetchContent_MakeAvailable(unity) - +add_compile_definitions(ASWM_TEST_DIR="${CMAKE_CURRENT_SOURCE_DIR}/test/") add_executable(test_aswm test/test_set_up.c test/aswm/test_aswm.c ) -target_include_directories(test_aswm PUBLIC unity) +target_include_directories(test_aswm PUBLIC ${unity_SOURCE_DIR}/src) target_link_libraries(test_aswm libaswm unity) enable_testing() diff --git a/src/aswm/aswm.c b/src/aswm/aswm.c index ff5dbfe..a87e8b7 100644 --- a/src/aswm/aswm.c +++ b/src/aswm/aswm.c @@ -16,8 +16,9 @@ Aswm _aswm; +void aswm_open(const char* zlog_conf) { + set_up_logger(zlog_conf); -void aswm_open() { _aswm.display = XOpenDisplay(NULL); _aswm.desktops = malloc(0); _aswm.desktops_count = 0; @@ -44,14 +45,11 @@ void aswm_open() { XMapWindow(_aswm.display, _aswm.root_window); XSync(_aswm.display, 0); - printf("PointerRoot %lu\n", PointerRoot); - printf("Useful constants:\n"); - printf("\tNone: %lu\n", None); - printf("\tTrue / False: %i / %i\n", True, False); - printf("X Root window %lu\n", x_root_window); - printf("ASWM Root window %lu\n", _aswm.root_window); + aswm_debug("PointerRoot %lu", PointerRoot); + aswm_debug("X Root window %lu", x_root_window); + aswm_debug("ASWM Root window %lu", _aswm.root_window); - log_tree(&_aswm, DefaultRootWindow(_aswm.display), 1); + aswm_log_tree(aswm_debug, &_aswm, DefaultRootWindow(_aswm.display), 1); atexit(aswm_close); } @@ -84,39 +82,10 @@ void aswm_create_workspace() { XSelectInput(_aswm.display, _aswm.current_desktop.stack_root, SubstructureNotifyMask); XMapWindow(_aswm.display, _aswm.current_desktop.root_window); XMapWindow(_aswm.display, _aswm.current_desktop.tile_root); - printf("Create workspace %lu\n", _aswm.current_desktop.root_window); + aswm_notice("Create workspace %lu", _aswm.current_desktop.root_window); } void aswm_event_loop() { - printf("MotionNofity %i\n", MotionNotify); - printf("ButtonPress %i\n", ButtonPress); - printf("ButtonRelease %i\n", ButtonRelease); - printf("ColormapNotify %i\n", ColormapNotify); - printf("EnterNotify %i\n", EnterNotify); - printf("LeaveNotify %i\n", LeaveNotify); - printf("Expose %i\n", Expose); - printf("GraphicsExpose %i\n", GraphicsExpose); - printf("NoExpose %i\n", NoExpose); - printf("FocusIn %i\n", FocusIn); - printf("FocusOut %i\n", FocusOut); - printf("KeymapNotify %i\n", KeymapNotify); - printf("KeyPress %i\n", KeyPress); - printf("KeyRelease %i\n", KeyRelease); - printf("MotionNofity %i\n", MotionNotify); - printf("PropertyNotify %i\n", PropertyNotify); - printf("ResizeRequest %i\n", ResizeRequest); - printf("CirculateNotify %i\n", CirculateNotify); - printf("ConfigureNotify %i\n", ConfigureNotify); - printf("DestroyNotify %i\n", DestroyNotify); - printf("GravityNotify %i\n", GravityNotify); - printf("MapNotify %i\n", MapNotify); - printf("ReparentNotify %i\n", ReparentNotify); - printf("UnmapNotify %i\n", UnmapNotify); - printf("CirculateRequest %i\n", CirculateRequest); - printf("ConfigureRequest %i\n", ConfigureRequest); - printf("MapRequest %i\n", MapRequest); - printf("VisibilityNotify %i\n", VisibilityNotify); - for (;;) { XEvent e; XNextEvent(_aswm.display, &e); @@ -128,7 +97,7 @@ void aswm_event_loop() { if(e.xcreatewindow.override_redirect == False) OnCreateNotify(&_aswm, &e.xcreatewindow); else - printf("Ignored create notify %lu\n", e.xcreatewindow.window); + aswm_notice("Ignored create notify %lu", e.xcreatewindow.window); break; case ConfigureRequest: OnConfigureRequest(&e.xconfigurerequest); @@ -146,26 +115,26 @@ void aswm_event_loop() { OnReparentNotify(&e.xreparent); break; case FocusIn: - printf("FocusIn %lu\n", (&e.xfocus)->window); + aswm_debug("FocusIn %lu", (&e.xfocus)->window); break; case FocusOut: - printf("FocusOut %lu\n", e.xfocus.window); + aswm_debug("FocusOut %lu", e.xfocus.window); break; case EnterNotify: int revert_to; Window window; XGetInputFocus(e.xcrossing.display, &window, &revert_to); - printf("Enter %lu\n", e.xcrossing.window); - printf("Input focus %lu\n", window); + aswm_debug("Enter %lu", e.xcrossing.window); + aswm_debug("Input focus %lu", window); break; case LeaveNotify: - printf("Leave %lu\n", e.xcrossing.window); + aswm_debug("Leave %lu", e.xcrossing.window); break; case ButtonPress: - printf("Press %lu\n", e.xbutton.window); + aswm_debug("Press %lu", e.xbutton.window); break; case ButtonRelease: - printf("Release %lu\n", e.xbutton.window); + aswm_debug("Release %lu", e.xbutton.window); break; case ClientMessage: OnClientMessage(&_aswm, &e.xclient); @@ -174,7 +143,7 @@ void aswm_event_loop() { OnPropertyNotify(&_aswm, &e.xproperty); break; default: - printf("Unknown event: %i\n", e.type); + aswm_debug("Unknown event: %i", e.type); break; /* LOG(WARNING) << "Ignored event"; */ } @@ -183,6 +152,7 @@ void aswm_event_loop() { void aswm_close() { free(_aswm.desktops); + tear_down_logger(); XCloseDisplay(_aswm.display); } @@ -203,7 +173,7 @@ void aswm_activate_window(Window window) { /* event.xclient.data.l[1] = 1; // Timestamp // Currently not set */ /* event.xclient.data.l[2] = 0; // Requestor's currently active window: TODO */ - printf("Activate window %lu (currently active: %lu)\n", window, aswm_currently_active()); + aswm_notice("Activate window %lu (currently active: %lu)", window, aswm_currently_active()); /* XSendEvent(_aswm.display, _aswm.root_window, True, 0 [> N. A. <], &event); */ XSetInputFocus(_aswm.display, window, RevertToParent, CurrentTime); } diff --git a/src/aswm/aswm.h b/src/aswm/aswm.h index 80a2134..d7fc833 100644 --- a/src/aswm/aswm.h +++ b/src/aswm/aswm.h @@ -1,6 +1,7 @@ #ifndef ASWM #define ASWM +#include "zlog.h" #include "mapper/mapper.h" typedef struct { @@ -17,7 +18,7 @@ typedef struct { Desktop current_desktop; } Aswm; -void aswm_open(); +void aswm_open(const char* zlog_conf); void aswm_create_workspace(); void aswm_event_loop(); void aswm_close(); diff --git a/src/aswm/event_handlers/configure.c b/src/aswm/event_handlers/configure.c index 937211b..732b87d 100644 --- a/src/aswm/event_handlers/configure.c +++ b/src/aswm/event_handlers/configure.c @@ -1,10 +1,10 @@ #include "configure.h" -#include +#include "aswm/log/log.h" void OnConfigureRequest(const XConfigureRequestEvent* e) { - printf("XConfigureRequestEvent %lu (ignored)\n", e->window); - printf("\tx = %i\n", e->x); - printf("\ty = %i\n", e->y); - printf("\tw = %i\n", e->width); - printf("\th = %i\n", e->height); + aswm_info("XConfigureRequestEvent %lu (ignored)", e->window); + aswm_info("\tx = %i", e->x); + aswm_info("\ty = %i", e->y); + aswm_info("\tw = %i", e->width); + aswm_info("\th = %i", e->height); } diff --git a/src/aswm/event_handlers/create.c b/src/aswm/event_handlers/create.c index ee0d56c..586f86e 100644 --- a/src/aswm/event_handlers/create.c +++ b/src/aswm/event_handlers/create.c @@ -1,20 +1,19 @@ #include "create.h" -#include -#include +#include "aswm/log/log.h" #include void OnCreateNotify(Aswm* aswm, const XCreateWindowEvent* e) { - printf("XCreateWindowEvent %lu on parent %lu\n", e->window, e->parent); - printf("\tx = %i\n", e->x); - printf("\ty = %i\n", e->y); - printf("\tw = %i\n", e->width); - printf("\th = %i\n", e->height); - printf("\toverride_redirect = %i\n", e->override_redirect); + aswm_info("XCreateWindowEvent %lu on parent %lu", e->window, e->parent); + aswm_info("\tx = %i", e->x); + aswm_info("\ty = %i", e->y); + aswm_info("\tw = %i", e->width); + aswm_info("\th = %i", e->height); + aswm_info("\toverride_redirect = %i", e->override_redirect); XWMHints* hints = XGetWMHints(aswm->display, e->window); if(hints != NULL) { - printf("\tWM_HINTS\n"); - printf("\t\tinitial_state: %i\n", hints->initial_state); + aswm_info("\tWM_HINTS"); + aswm_info("\t\tinitial_state: %i", hints->initial_state); } // The WM must subscribe to property changes, notably to implement the @@ -24,13 +23,13 @@ void OnCreateNotify(Aswm* aswm, const XCreateWindowEvent* e) { { XTextProperty text_property; if(XGetWMName(e->display, e->window, &text_property)) { - printf("\tname: %s\n", text_property.value); + aswm_info("\tname: %s", text_property.value); } } { XClassHint class; if(XGetClassHint(e->display, e->window, &class)) { - printf("\tclass: %s, %s\n", class.res_class, class.res_name); + aswm_info("\tclass: %s, %s", class.res_class, class.res_name); XFree(class.res_class); XFree(class.res_name); } diff --git a/src/aswm/event_handlers/destroy.c b/src/aswm/event_handlers/destroy.c index 635c844..19b9080 100644 --- a/src/aswm/event_handlers/destroy.c +++ b/src/aswm/event_handlers/destroy.c @@ -1,7 +1,7 @@ #include "destroy.h" -#include +#include "aswm/log/log.h" void OnDestroyNotify(const XDestroyWindowEvent* e) { - printf("XDestroyWindowEvent %lu\n", e->window); + aswm_notice("XDestroyWindowEvent %lu", e->window); // TODO: destroy frame } diff --git a/src/aswm/event_handlers/map.c b/src/aswm/event_handlers/map.c index 60d940a..a4f43e5 100644 --- a/src/aswm/event_handlers/map.c +++ b/src/aswm/event_handlers/map.c @@ -1,22 +1,22 @@ #include "map.h" -#include #include "aswm/log/log.h" #include "aswm/mapper/mapper.h" +#include "aswm/log/log.h" #include "X11/Xutil.h" void OnMapRequest(Aswm* aswm, const XMapRequestEvent* e) { - printf("XMapRequestEvent %lu\n", e->window); + aswm_notice("XMapRequestEvent %lu", e->window); XSizeHints* size = XAllocSizeHints(); long supplied; bool stacked = false; if(XGetWMNormalHints(aswm->display, e->window, size, &supplied)) { if((supplied & (PMinSize | PMaxSize)) && !aswm_is_resizeable(size)) { - printf("\tWMNormalHints:\n"); - printf("\t\tMin w:%i\n", size->min_width); - printf("\t\tMin h:%i\n", size->min_height); - printf("\t\tMax w:%i\n", size->max_width); - printf("\t\tMax h:%i\n", size->max_height); + aswm_notice("\tWMNormalHints:"); + aswm_notice("\t\tMin w:%i", size->min_width); + aswm_notice("\t\tMin h:%i", size->min_height); + aswm_notice("\t\tMax w:%i", size->max_width); + aswm_notice("\t\tMax h:%i", size->max_height); aswm_stack_window(e->display, aswm->current_desktop.stack_root, e->window, size->max_width, size->max_height); stacked = true; } @@ -26,6 +26,6 @@ void OnMapRequest(Aswm* aswm, const XMapRequestEvent* e) { if(!stacked) aswm_tile_window(e->display, aswm->current_desktop.tile_root, e->window); - printf("Map tree:\n"); - log_tree(aswm, DefaultRootWindow(aswm->display), 1); + aswm_info("Map tree:\n"); + aswm_log_tree(aswm_info, aswm, DefaultRootWindow(aswm->display), 1); } diff --git a/src/aswm/event_handlers/message.c b/src/aswm/event_handlers/message.c index 6f0b083..2a806a6 100644 --- a/src/aswm/event_handlers/message.c +++ b/src/aswm/event_handlers/message.c @@ -1,20 +1,19 @@ #include "message.h" -#include -#include +#include "aswm/log/log.h" void OnClientMessage(Aswm* aswm, XClientMessageEvent* e) { // TODO: handle this - printf("Client message for window %lu:\n", e->window); + aswm_notice("Client message for window %lu:", e->window); char* message_type = XGetAtomName(e->display, e->message_type); - printf("\t%s\n", message_type); + aswm_notice("\t%s", message_type); if(strcmp(message_type, "_NET_ACTIVE_WINDOW") == 0) { - printf("\t\twindow to activate: %lu\n", e->window); - printf("\t\tsource indication: %lu\n", e->data.l[0]); - printf("\t\ttimestamp: %lu\n", e->data.l[1]); - printf("\t\trequestor's currently active window: %lu\n", e->data.l[2]); + aswm_notice("\t\twindow to activate: %lu", e->window); + aswm_notice("\t\tsource indication: %lu", e->data.l[0]); + aswm_notice("\t\ttimestamp: %lu", e->data.l[1]); + aswm_notice("\t\trequestor's currently active window: %lu", e->data.l[2]); aswm_activate_window(e->window); } else { - printf("\t-> Unhandled\n"); + aswm_notice("\t-> Unhandled"); } XFree(message_type); } diff --git a/src/aswm/event_handlers/property.c b/src/aswm/event_handlers/property.c index be4c4db..528b828 100644 --- a/src/aswm/event_handlers/property.c +++ b/src/aswm/event_handlers/property.c @@ -1,78 +1,78 @@ #include "property.h" -#include #include +#include "aswm/mapper/mapper.h" +#include "aswm/log/log.h" #include #include -#include "aswm/mapper/mapper.h" void OnPropertyNotify(Aswm* aswm, XPropertyEvent* e) { - printf("Property change for window %lu:\n", e->window); + aswm_notice("Property change for window %lu:", e->window); char* property_name = XGetAtomName(e->display, e->atom); - printf("\t%s\n", property_name); + aswm_notice("\t%s", property_name); if(strcmp(property_name, "_NET_WM_NAME") == 0) { - printf("\t-> Unhandled\n"); + aswm_notice("\t-> Unhandled"); XTextProperty wm_name_property; char** wm_name; int wm_name_count; XGetTextProperty(e->display, e->window, &wm_name_property, e->atom); Xutf8TextPropertyToTextList(e->display, &wm_name_property, &wm_name, &wm_name_count); for(auto i = 0; i < wm_name_count; i++) - printf("\t_NET_WM_NAME: %s\n", wm_name[i]); + aswm_notice("\t_NET_WM_NAME: %s", wm_name[i]); XFreeStringList(wm_name); } else if(strcmp(property_name, "WM_NAME") == 0) { - printf("\t-> Unhandled\n"); + aswm_notice("\t-> Unhandled"); XTextProperty text_property; if(XGetWMName(e->display, e->window, &text_property)) { - printf("\tWM_NAME: %s\n", text_property.value); + aswm_notice("\tWM_NAME: %s", text_property.value); } } else if(strcmp(property_name, "WM_NORMAL_HINTS") == 0) { XSizeHints* size = XAllocSizeHints(); long supplied; if(XGetWMNormalHints(e->display, e->window, size, &supplied)) { - printf("\tWMNormalHints:\n"); - printf("\t\tMin w:%i\n", size->min_width); - printf("\t\tMin h:%i\n", size->min_height); - printf("\t\tMax w:%i\n", size->max_width); - printf("\t\tMax h:%i\n", size->max_height); - printf("\t\tBase w:%i\n", size->base_width); - printf("\t\tBase h:%i\n", size->base_height); + aswm_notice("\tWMNormalHints:"); + aswm_notice("\t\tMin w:%i", size->min_width); + aswm_notice("\t\tMin h:%i", size->min_height); + aswm_notice("\t\tMax w:%i", size->max_width); + aswm_notice("\t\tMax h:%i", size->max_height); + aswm_notice("\t\tBase w:%i", size->base_width); + aswm_notice("\t\tBase h:%i", size->base_height); aswm_handle_normal_hints( aswm->display, aswm->current_desktop.stack_root, e->window, size, supplied); } XFree(size); } else if(strcmp(property_name, "WM_HINTS") == 0) { - printf("\t-> Unhandled\n"); + aswm_notice("\t-> Unhandled"); XWMHints* hints = XGetWMHints(aswm->display, e->window); - printf("\t\tflags Input: %li\n", hints->flags & InputHint); - printf("\t\tflags Input: %li\n", hints->flags & StateHint); - printf("\t\tflags IconPixmap: %li\n", hints->flags & IconPixmapHint); - printf("\t\tflags WindowHint: %li\n", hints->flags & IconWindowHint); - printf("\t\tflags IconPosition: %li\n", hints->flags & IconPositionHint); - printf("\t\tflags IconMask: %li\n", hints->flags & IconMaskHint); - printf("\t\tflags WindowGroup: %li\n", hints->flags & WindowGroupHint); - printf("\t\tflags XUrgency: %li\n", hints->flags & XUrgencyHint); - printf("\t\tflags AllHints: %li\n", hints->flags & AllHints); - printf("\t\tinitial_state: %i\n", hints->initial_state); + aswm_notice("\t\tflags Input: %li", hints->flags & InputHint); + aswm_notice("\t\tflags Input: %li", hints->flags & StateHint); + aswm_notice("\t\tflags IconPixmap: %li", hints->flags & IconPixmapHint); + aswm_notice("\t\tflags WindowHint: %li", hints->flags & IconWindowHint); + aswm_notice("\t\tflags IconPosition: %li", hints->flags & IconPositionHint); + aswm_notice("\t\tflags IconMask: %li", hints->flags & IconMaskHint); + aswm_notice("\t\tflags WindowGroup: %li", hints->flags & WindowGroupHint); + aswm_notice("\t\tflags XUrgency: %li", hints->flags & XUrgencyHint); + aswm_notice("\t\tflags AllHints: %li", hints->flags & AllHints); + aswm_notice("\t\tinitial_state: %i", hints->initial_state); XFree(hints); } else if(strcmp(property_name, "WM_PROTOCOLS") == 0) { - printf("\t-> Unhandled\n"); + aswm_notice("\t-> Unhandled"); Atom* protocols; int count; XGetWMProtocols(aswm->display, e->window, &protocols, &count); if(count > 0) - printf("\t\t"); + aswm_notice("\t\t"); for(auto i = 0; i < count; i++) { char* name = XGetAtomName(aswm->display, protocols[i]); - printf("%s ", name); + aswm_notice("%s ", name); XFree(name); } if(count > 0) - printf("\n"); + aswm_notice(""); XFree(protocols); } else { - printf("\t-> Unhandled\n"); + aswm_notice("\t-> Unhandled"); } XFree(property_name); } diff --git a/src/aswm/event_handlers/reparent.c b/src/aswm/event_handlers/reparent.c index e3b5675..8c0c941 100644 --- a/src/aswm/event_handlers/reparent.c +++ b/src/aswm/event_handlers/reparent.c @@ -1,6 +1,6 @@ #include "reparent.h" -#include +#include "aswm/log/log.h" void OnReparentNotify(const XReparentEvent* e) { - printf("XReparentEvent from %lu: %lu to %lu\n", e->event, e->window, e->parent); + aswm_notice("XReparentEvent from %lu: %lu to %lu", e->event, e->window, e->parent); } diff --git a/src/aswm/event_handlers/unmap.c b/src/aswm/event_handlers/unmap.c index c70bad2..5d06f57 100644 --- a/src/aswm/event_handlers/unmap.c +++ b/src/aswm/event_handlers/unmap.c @@ -4,11 +4,11 @@ #include void OnUnmapNotify(Aswm* aswm, const XUnmapEvent* e) { - printf("XUnmapWindow %lu tiled in %lu\n", e->window, e->event); + aswm_notice("XUnmapWindow %lu tiled in %lu", e->window, e->event); XWMHints* hints = XGetWMHints(aswm->display, e->window); if(hints != NULL) { - printf("\tWM_HINTS\n"); - printf("\t\tinitial_state: %i\n", hints->initial_state); + aswm_notice("\tWM_HINTS"); + aswm_notice("\t\tinitial_state: %i", hints->initial_state); } // Since SubstructureNotify is selected on each frame, e->event corresponds // to the parent of the unmapped window (e->window) @@ -17,13 +17,13 @@ void OnUnmapNotify(Aswm* aswm, const XUnmapEvent* e) { // windows are children of aswm->root_window. if(e->event != XDefaultRootWindow(e->display)) { if(e->event == aswm->current_desktop.tile_root) { - printf("aswm untile\n"); + aswm_notice("aswm untile"); aswm_untile_window(e->display, e->event, e->window); } else if(e->event == aswm->current_desktop.stack_root) { - printf("aswm unstack\n"); + aswm_notice("aswm unstack"); aswm_unstack_window(e->display, e->event); } - printf("Unmap tree:\n"); - log_tree(aswm, DefaultRootWindow(aswm->display), 1); + aswm_info("Unmap tree:"); + aswm_log_tree(aswm_info, aswm, DefaultRootWindow(aswm->display), 1); } } diff --git a/src/aswm/log/aswm_log.conf b/src/aswm/log/aswm_log.conf new file mode 100644 index 0000000..f13badf --- /dev/null +++ b/src/aswm/log/aswm_log.conf @@ -0,0 +1,7 @@ +[formats] + +simple = "[%c %p] %d(%m-%d %T) %-5V %f:%L %m%n" + +[rules] + +aswm.DEBUG >stdout; simple diff --git a/src/aswm/log/log.c b/src/aswm/log/log.c index 0cdebac..fa0d8f0 100644 --- a/src/aswm/log/log.c +++ b/src/aswm/log/log.c @@ -1,6 +1,14 @@ #include "log.h" #include +zlog_category_t* aswm_cat; + +_ASWM_LOG_TREE_DEF(aswm_info) +_ASWM_LOG_TREE_DEF(aswm_warn) +_ASWM_LOG_TREE_DEF(aswm_debug) +_ASWM_LOG_TREE_DEF(aswm_notice) +_ASWM_LOG_TREE_DEF(aswm_fatal) + void log_tree(Aswm* aswm, Window window, int indent) { XWindowAttributes window_attributes; XGetWindowAttributes(aswm->display, window, &window_attributes); @@ -29,3 +37,22 @@ void log_tree(Aswm* aswm, Window window, int indent) { log_tree(aswm, children[i], indent+1); XFree(children); } + +void set_up_logger(const char* zlog_conf) { + int rc; + + rc = zlog_init(zlog_conf); + if (rc) { + printf("Init zlog from %s failed\n", zlog_conf); + } + + aswm_cat = zlog_get_category("aswm"); + if (!aswm_cat) { + printf("Get zlog aswm category failed\n"); + } +} + +void tear_down_logger(void) { + zlog_fini(); +} + diff --git a/src/aswm/log/log.h b/src/aswm/log/log.h index 1253e34..06ef572 100644 --- a/src/aswm/log/log.h +++ b/src/aswm/log/log.h @@ -3,7 +3,64 @@ #include #include "aswm/aswm.h" +#include "zlog.h" +#include + +extern zlog_category_t* aswm_cat; + +#define aswm_fatal(format, ...) zlog_fatal(aswm_cat, format __VA_OPT__(,) __VA_ARGS__) +#define aswm_error(format, ...) zlog_error(aswm_cat, format __VA_OPT__(,) __VA_ARGS__) +#define aswm_warn(format, ...) zlog_warn(aswm_cat, format __VA_OPT__(,) __VA_ARGS__) +#define aswm_notice(format, ...) zlog_notice(aswm_cat, format __VA_OPT__(,) __VA_ARGS__) +#define aswm_info(format, ...) zlog_info(aswm_cat, format __VA_OPT__(,) __VA_ARGS__) +#define aswm_debug(format, ...) zlog_debug(aswm_cat, format __VA_OPT__(,) __VA_ARGS__) + +void set_up_logger(const char* zlog_conf); +void tear_down_logger(); void log_tree(Aswm* aswm, Window window, int indent); + +#define _ASWM_LOG_TREE_DEC(logger)\ + void _aswm_log_tree_##logger(Aswm* aswm, Window window, int indent); + +#define _ASWM_LOG_TREE_DEF(logger)\ + void _aswm_log_tree_##logger(Aswm* aswm, Window window, int indent) {\ + XWindowAttributes window_attributes;\ + XGetWindowAttributes(aswm->display, window, &window_attributes);\ + char format[80];\ + strcpy(format, "");\ + for(int i = 0; i < indent; i++)\ + strcat(format, " ");\ + strcat(format, "%lu ");\ + if(window == XDefaultRootWindow(aswm->display)) {\ + strcat(format,"(X root) ");\ + } else if (window == aswm->root_window) {\ + strcat(format,"(ASWM root) ");\ + } else if (window == aswm->current_desktop.root_window) {\ + strcat(format,"(current workspace) ");\ + } else if (window == aswm->current_desktop.tile_root) {\ + strcat(format,"(tile root) ");\ + } else if (window == aswm->current_desktop.stack_root) {\ + strcat(format,"(stack root) ");\ + }\ + strcat(format, "at (%i, %i): %ix%i");\ + logger(format, window, window_attributes.x, window_attributes.y, window_attributes.width, window_attributes.height);\ + Window root_window;\ + Window parent_tile;\ + Window* children;\ + unsigned int children_count;\ + XQueryTree(aswm->display, window, &root_window, &parent_tile, &children, &children_count);\ + for(auto i = 0; i < children_count; i++)\ + _aswm_log_tree_##logger(aswm, children[i], indent+1);\ + XFree(children);\ + } + +_ASWM_LOG_TREE_DEC(aswm_info) +_ASWM_LOG_TREE_DEC(aswm_warn) +_ASWM_LOG_TREE_DEC(aswm_debug) +_ASWM_LOG_TREE_DEC(aswm_notice) +_ASWM_LOG_TREE_DEC(aswm_fatal) + +#define aswm_log_tree(logger, aswm, window, indent) _aswm_log_tree_##logger(aswm, window, indent) #endif diff --git a/src/aswm/main.c b/src/aswm/main.c index 6535ada..5ffc2d6 100644 --- a/src/aswm/main.c +++ b/src/aswm/main.c @@ -1,7 +1,34 @@ #include "aswm.h" +#include "argparse.h" -int main(int argc, char** argv) { - aswm_open(); +#ifndef ASWM_LOG_CONF +#define ASWM_LOG_CONF NULL +#endif + +static const char *const usages[] = { + "aswm [options]", + NULL, +}; + +int main(int argc, const char** argv) { + const char *zlog_conf = NULL; + struct argparse_option options[] = { + OPT_HELP(), + OPT_GROUP("Config options"), + OPT_STRING('l', "log", &zlog_conf, "path to zlog config file", NULL, 0, 0), + OPT_END(), + }; + + struct argparse argparse; + argparse_init(&argparse, options, usages, 0); + argparse_describe(&argparse, "\nLaunches ASWM", "\nASWM is an Arcade Station Window Manager"); + argc = argparse_parse(&argparse, argc, argv); + + if (zlog_conf == NULL) { + zlog_conf = ASWM_LOG_CONF; + } + + aswm_open(zlog_conf); aswm_event_loop(); aswm_close(); } diff --git a/src/aswm/mapper/mapper.c b/src/aswm/mapper/mapper.c index b6722a6..49e69ed 100644 --- a/src/aswm/mapper/mapper.c +++ b/src/aswm/mapper/mapper.c @@ -68,10 +68,9 @@ void resize_children_to_parent(Display* display, Window parent) { display, parent, &_root_window, &_grand_parent, &children, &children_count); - printf(" Resize children of %lu:\n", parent); + aswm_debug(" Resize children of %lu:\n", parent); for(auto i = 0; i < children_count; i++) - printf("%lu ", children[i]); - printf("\n"); + aswm_debug("\t%lu", children[i]); // Resize new children of the parent tile XWindowAttributes parent_attributes; @@ -113,10 +112,9 @@ void aswm_untile_window(Display* display, Window parent, Window window) { display, parent, &_root_window, &_grand_parent, &children, &children_count); - printf(" Current children of %lu:\n", parent); + aswm_debug(" Current children of %lu:", parent); for(auto i = 0; i < children_count; i++) - printf("%lu ", children[i]); - printf("\n"); + aswm_debug("\t%lu", children[i]); for(auto i = 0; i < children_count; i++) { if(children[i] == window) // If the unmap request does not come from a destroy window, we @@ -212,10 +210,10 @@ void aswm_unstack_window(Display* display, Window stack) { XFree(children); if(visible_child) { - printf("Resize stack %lu\n", stack); + aswm_debug("Resize stack %lu\n", stack); resize_stack(display, stack); } else { - printf("Nothing in stack, unmap %lu\n", stack); + aswm_debug("Nothing in stack, unmap %lu\n", stack); XWindowAttributes parent_size; XGetWindowAttributes(display, parent, &parent_size); @@ -235,7 +233,7 @@ bool is_in_stack(Display* display, Window stack_root, Window window) { } void aswm_handle_normal_hints(Display* display, Window stack_root, Window window, XSizeHints* size, long supplied) { - printf("Handle normal hints for %lu\n", window); + aswm_info("Handle normal hints for %lu", window); XWindowAttributes win_attributes; XGetWindowAttributes(display, window, &win_attributes); diff --git a/test/aswm/test_aswm.c b/test/aswm/test_aswm.c index bd4bd24..db3c2c7 100644 --- a/test/aswm/test_aswm.c +++ b/test/aswm/test_aswm.c @@ -138,8 +138,10 @@ void create_multiple_resizeable_top_level_window(void) { // not needed when using generate_test_runner.rb int main(void) { UNITY_BEGIN(); + set_up_test_logger(); RUN_TEST(run_aswm); - RUN_TEST(create_single_resizeable_top_level_window); + RUN_TEST(create_single_resizeable_top_level_window); RUN_TEST(create_multiple_resizeable_top_level_window); + tear_down_test_logger(); return UNITY_END(); } diff --git a/test/aswm_log.conf b/test/aswm_log.conf new file mode 100644 index 0000000..387235e --- /dev/null +++ b/test/aswm_log.conf @@ -0,0 +1,7 @@ +[formats] + +simple = "[%c %p] %d(%m-%d %T) %-5V %-8f:%-3L %m%n" + +[rules] + +aswm.NOTICE >stdout; simple diff --git a/test/log.conf b/test/log.conf new file mode 100644 index 0000000..24ae044 --- /dev/null +++ b/test/log.conf @@ -0,0 +1,8 @@ +[formats] + +simple = "[%c %p] %d(%m-%d %T) %-5V %f:%L %m%n" + +[rules] + +aswm.INFO >stdout; simple +test.DEBUG >stdout; simple diff --git a/test/test_set_up.c b/test/test_set_up.c index e6aa1fc..8a7a280 100644 --- a/test/test_set_up.c +++ b/test/test_set_up.c @@ -9,6 +9,7 @@ char display_name[5]; int aswm_pid; Display* test_display; Window test_root; +zlog_category_t *test_log; // Local variables unsigned int display_count = 100; @@ -25,6 +26,24 @@ void run_xephyr() { execvp(args[0], args); } +void set_up_test_logger(void) { + int rc; + + rc = zlog_init(ASWM_TEST_DIR "/log.conf"); + if (rc) { + printf("Init test zlog failed\n"); + } + + test_log = zlog_get_category("test_log"); + if (!test_log) { + printf("Get zlog test_log category failed\n"); + } +} + +void tear_down_test_logger(void) { + zlog_fini(); +} + void setUp(void) { tmpnam(display_fd); // Creates a temporary file name sprintf(display_name, ":%u", display_count); // Loads initial display count @@ -34,7 +53,7 @@ void setUp(void) { if(xephyr_pid == 0) { run_xephyr(); } else { - printf("Trying to run Xephyr instance on :%u...\n", display_count); + zlog_info(test_log, "Trying to run Xephyr instance on :%u...", display_count); } // The following loop waits for one of those two things: @@ -60,7 +79,7 @@ void setUp(void) { if(xephyr_pid == 0) { run_xephyr(); } else { - printf("Trying to run Xephyr instance on :%u...\n", display_count); + zlog_info(test_log, "Trying to run Xephyr instance on :%u...", display_count); } } } @@ -68,8 +87,8 @@ void setUp(void) { aswm_pid = fork(); if(aswm_pid == 0) { - printf("Running aswm instance on %s...\n", display_name); - char* args[] = {"./aswm", NULL}; + zlog_info(test_log, "Running aswm instance on %s...", display_name); + char* args[] = {"./aswm", "--log", ASWM_TEST_DIR "/aswm_log.conf", NULL}; char display_env[256]; sprintf(display_env, "DISPLAY=%s", display_name); char* envp[] = {display_env, NULL}; diff --git a/test/test_set_up.h b/test/test_set_up.h index 1d61493..53a95ca 100644 --- a/test/test_set_up.h +++ b/test/test_set_up.h @@ -2,13 +2,22 @@ #define ASWM_TEST_SET_UP #include "unity.h" +#include "zlog.h" #include "X11/Xlib.h" +#ifndef ASWM_TEST_DIR +#define ASWM_TEST_DIR "." +#endif + // Extern variables accessible from any test. // Defined in test_set_up.c extern char display_name[5]; extern int aswm_pid; extern Display* test_display; extern Window test_root; +extern zlog_category_t *test_log; + +void set_up_test_logger(); +void tear_down_test_logger(); #endif