From a83fddc48687a4fb3ebd62026dd14d1fee155ae3 Mon Sep 17 00:00:00 2001 From: Scott Duensing Date: Sun, 22 May 2022 18:46:16 -0500 Subject: [PATCH] Basic window manager. Too slow! --- Makefile.djgpp | 3 +- build.sh | 3 +- client/src/gui/gui.c | 4 +- client/src/gui/gui.h | 17 ++-- client/src/gui/wmwindow.c | 169 ++++++++++++++++++++++++++------------ client/src/gui/wmwindow.h | 1 + 6 files changed, 133 insertions(+), 64 deletions(-) diff --git a/Makefile.djgpp b/Makefile.djgpp index 627db83..ed645a9 100644 --- a/Makefile.djgpp +++ b/Makefile.djgpp @@ -33,7 +33,7 @@ BINDIR = bin # CFLAGS, LDFLAGS, CPPFLAGS, PREFIX can be overriden on CLI CFLAGS := $(DEBUG) -CFLAGS += -I$(SRCDIR)/installed/dos/include -I$(SRCDIR)/client/src +CFLAGS += -I$(SRCDIR)/shared -I$(SRCDIR)/installed/dos/include -I$(SRCDIR)/client/src CPPFLAGS := LDFLAGS := -L$(SRCDIR)/installed/dos/lib LDLIBS := -lgrx20 -ljpeg -lpng -lz @@ -56,6 +56,7 @@ ALL_LDLIBS := $(LDLIBS) -lc # Source, Binaries, Dependencies SRC := $(shell find $(SRCDIR)/client -type f -name '*.c') +SRC += $(shell find $(SRCDIR)/shared -type f -name '*.c') OBJ := $(patsubst $(SRCDIR)/%,$(OBJDIR)/%,$(SRC:.c=.o)) DEP := $(OBJ:.o=.d) BIN := $(BINDIR)/$(TARGET) diff --git a/build.sh b/build.sh index cd2d62e..f2f937e 100755 --- a/build.sh +++ b/build.sh @@ -23,7 +23,8 @@ # See: https://github.com/andrewwutw/build-djgpp mkdir -p \ - obj/client/src + obj/shared/thirdparty/memwatch \ + obj/client/src/gui source /opt/cross/djgpp/setenv diff --git a/client/src/gui/gui.c b/client/src/gui/gui.c index 834f168..44f7e2c 100644 --- a/client/src/gui/gui.c +++ b/client/src/gui/gui.c @@ -117,8 +117,6 @@ void guiShutdown(void) { GrDestroyContext(_mousePointer); - DEL(__guiBaseColors); - GrDestroyContext(__guiBackBuffer); GrSetMode(GR_default_text); } @@ -134,7 +132,7 @@ void guiStartup(int16_t width, int16_t height, int16_t depth) { //***TODO*** Die } GrSetRGBcolorMode(); - __guiBaseColors = GrAllocEgaColors(); + __guiBaseColors = GrAllocEgaColors(); // This does not need released. __guiScreenBuffer = GrScreenContext(); __guiBackBuffer = GrCreateContext(GrScreenX(), GrScreenY(), NULL, NULL); diff --git a/client/src/gui/gui.h b/client/src/gui/gui.h index 3eb8e23..f41d890 100644 --- a/client/src/gui/gui.h +++ b/client/src/gui/gui.h @@ -13,16 +13,21 @@ struct WidgetS; typedef void (*GuiCallbackT)(void *data, ...); typedef void (*WidgetEventT)(struct WidgetS *widget, ...); +typedef struct PointS { + int16_t x; + int16_t y; +} PointT; + typedef struct RectS { - uint16_t x; - uint16_t y; + int16_t x; + int16_t y; union { - uint16_t w; - uint16_t x2; + int16_t w; + int16_t x2; }; union { - uint16_t h; - uint16_t y2; + int16_t h; + int16_t y2; }; } RectT; diff --git a/client/src/gui/wmwindow.c b/client/src/gui/wmwindow.c index aacbee3..cd4d581 100644 --- a/client/src/gui/wmwindow.c +++ b/client/src/gui/wmwindow.c @@ -16,6 +16,11 @@ WindowT *windowCreate(uint16_t x, uint16_t y, uint16_t w, uint16_t h, char *titl guiWidgetBaseSet((WidgetT *)win, __MAGIC_WINDOW, x, y, w, h); win->title = strdup(title); win->flags = flags; + win->close.x = win->close.y = win->close.x2 = win->close.y2 = 0; + win->titlebar.x = win->titlebar.y = win->titlebar.x2 = win->titlebar.y2 = 0; + win->minimize.x = win->minimize.y = win->minimize.x2 = win->minimize.y2 = 0; + win->maximize.x = win->maximize.y = win->maximize.x2 = win->maximize.y2 = 0; + win->bounds.x = win->bounds.y = win->bounds.x2 = win->bounds.y2 = 0; arrput(_windowList, win); @@ -83,12 +88,7 @@ void windowPaint(struct WidgetS *widget, ...) { // Set titlebar area. w->titlebar.x = w->close.x2 + 2; } else { - // No close box. - w->close.x = 0; - w->close.y = 0; - w->close.x2 = 0; - w->close.y2 = 0; - // Set titlebar area. + // No close box - set titlebar area. w->titlebar.x = x1; } w->titlebar.y = y1; @@ -118,12 +118,6 @@ void windowPaint(struct WidgetS *widget, ...) { minimizeOffset = 26; // Set titlebar area. w->titlebar.x2 -= 26; - } else { - // No maximize box. - w->maximize.x = 0; - w->maximize.y = 0; - w->maximize.x2 = 0; - w->maximize.y2 = 0; } // Minimize box? @@ -146,12 +140,6 @@ void windowPaint(struct WidgetS *widget, ...) { GrVLine(tx2, ty1, ty2, GUI_BLACK); // Set titlebar area. w->titlebar.x2 -= 26; - } else { - // No minimize box. - w->minimize.x = 0; - w->minimize.y = 0; - w->minimize.x2 = 0; - w->minimize.y2 = 0; } // Title font area is 12px high. @@ -206,6 +194,10 @@ void windowPaint(struct WidgetS *widget, ...) { GrVLine(x1, y1, y2, GUI_WHITE); GrHLine(x1, x2, y2, GUI_DARKGRAY); GrVLine(x2, y1, y2, GUI_DARKGRAY); + w->bounds.x = x1; + w->bounds.x2 = x2; + w->bounds.y = y1; + w->bounds.y2 = y2; } @@ -233,43 +225,114 @@ RegisterT *windowRegister(uint8_t magic) { void wmPaint(GrMouseEvent *event) { - uint16_t i; - WidgetT *widget; - static char text[256] = { 0 }; + uint16_t i; + WidgetT *widget; + WindowT *win; + static uint8_t dragging = 0; + static PointT dragOffset = { 0 }; - // Paint event debug info. -#define APPEND (&text[strlen(text)]) -// if (event->flags != 0) { - strcpy(text, "Events: "); - if(event->flags & GR_M_MOTION) strcpy( APPEND, "[moved] "); - if(event->flags & GR_M_LEFT_DOWN) strcpy( APPEND, "[left down] "); - if(event->flags & GR_M_MIDDLE_DOWN) strcpy( APPEND, "[middle down] "); - if(event->flags & GR_M_RIGHT_DOWN) strcpy( APPEND, "[right down] "); - if(event->flags & GR_M_P4_DOWN) strcpy( APPEND, "[p4 down] "); - if(event->flags & GR_M_P5_DOWN) strcpy( APPEND, "[p5 down] "); - if(event->flags & GR_M_LEFT_UP) strcpy( APPEND, "[left up] "); - if(event->flags & GR_M_MIDDLE_UP) strcpy( APPEND, "[middle up] "); - if(event->flags & GR_M_RIGHT_UP) strcpy( APPEND, "[right up] "); - if(event->flags & GR_M_P4_UP) strcpy( APPEND, "[p4 up] "); - if(event->flags & GR_M_P5_UP) strcpy( APPEND, "[p5 up] "); - if(event->flags & GR_M_KEYPRESS) sprintf(APPEND, "[key (0x%03x)] ", event->key); - sprintf(APPEND, "at X=%d, Y=%d, ", event->x, event->y); - sprintf(APPEND, - "buttons=%c%c%c, ", - (event->buttons & GR_M_LEFT) ? 'L' : 'l', - (event->buttons & GR_M_MIDDLE) ? 'M' : 'm', - (event->buttons & GR_M_RIGHT) ? 'R' : 'r' - ); - sprintf(APPEND, "deltaT=%ld (ms)", event->dtime); -// } - GrTextXY(0, 0, text, GUI_WHITE, GUI_BLACK); + // Do we have windows? + if (arrlen(_windowList) > 0) { + + // Paint all windows. + for (i=0; ireg->paint(widget); + } + + // Get top window. + win = _windowList[arrlen(_windowList) - 1]; + + // Wrap left button processing with a 'for' so we can 'break' out of it. + for (;;) { + // Is the left mouse button down? + if (event->buttons & GR_M_LEFT) { + + // DEBUG - draw active regions. ***TODO*** No resize grabber here. + GrBox(win->bounds.x, win->bounds.y, win->bounds.x2, win->bounds.y2, GUI_YELLOW); + GrBox(win->base.r.x, win->base.r.y, win->base.r.x + win->base.r.w - 1, win->base.r.y + win->base.r.h - 1, GUI_YELLOW); + GrBox(win->close.x, win->close.y, win->close.x2, win->close.y2, GUI_RED); + GrBox(win->titlebar.x, win->titlebar.y, win->titlebar.x2, win->titlebar.y2, GUI_RED); + GrBox(win->minimize.x, win->minimize.y, win->minimize.x2, win->minimize.y2, GUI_RED); + GrBox(win->maximize.x, win->maximize.y, win->maximize.x2, win->maximize.y2, GUI_RED); + + // Are we currently dragging? + if (dragging) { + + // Move window to new mouse location. + win->base.r.x = event->x - dragOffset.x; + win->base.r.y = event->y - dragOffset.y; + break; + + } else { // Dragging. + + // Did the button just go down? + if (event->flags & GR_M_LEFT_DOWN) { + + // Are we on the topmost window? + if (event->x <= win->bounds.x2 && event->x >= win->bounds.x && event->y <= win->bounds.y2 && event->y >= win->bounds.y) { + + //***TODO*** Are we inside the window content? Most likely, check first. + if (event->x <= (win->base.r.x + win->base.r.w - 1) && event->x >= win->base.r.x && + event->y <= (win->base.r.y + win->base.r.h - 1) && event->y >= win->base.r.y) { + //***TODO*** Send to window for processing. + } + + //***TODO*** Are we inside the close button? + + // Are we inside the title bar to begin dragging? + if (event->x <= win->titlebar.x2 && event->x >= win->titlebar.x && event->y <= win->titlebar.y2 && event->y >= win->titlebar.y) { + dragging = 1; + dragOffset.x = event->x - win->base.r.x; + dragOffset.y = event->y - win->base.r.y; + break; + } + + //***TODO*** Are we inside the minimize button? + //***TODO*** Are we inside the maximize button? + + } else { // On topmost window. + + // Not over topmost window. Search backwards to find first window we're inside. + i = arrlen(_windowList) - 2; + if (i >= 0) { + for (; i>=0; i--) { + win = _windowList[i]; + if (event->x <= win->bounds.x2 && event->x >= win->bounds.x && event->y <= win->bounds.y2 && event->y >= win->bounds.y) { + // Bring this window forward. + arrdel(_windowList, i); + arrput(_windowList, win); + // If we happened to be in the title bar, go ahead and start dragging. + if (event->x <= win->titlebar.x2 && event->x >= win->titlebar.x && event->y <= win->titlebar.y2 && event->y >= win->titlebar.y) { + dragging = 1; + dragOffset.x = event->x - win->base.r.x; + dragOffset.y = event->y - win->base.r.y; + } + break; + } + } + } + + } // On topmost window. + + } // Button just went down. + + } // Dragging. + + } else { // Left mouse button. + + // Left mouse not down. + + // Can no longer be dragging. + dragging = 0; + } + + break; + } // Left button processing. + + } // Do we have windows? - // Paint all windows. - for (i=0; ireg->paint(widget); - } } diff --git a/client/src/gui/wmwindow.h b/client/src/gui/wmwindow.h index 3c97525..69ba6f7 100644 --- a/client/src/gui/wmwindow.h +++ b/client/src/gui/wmwindow.h @@ -20,6 +20,7 @@ typedef struct WindowS { RectT titlebar; RectT minimize; RectT maximize; + RectT bounds; } WindowT;