From eb87c40967903cad4ef0a6371a60394cf8402afc Mon Sep 17 00:00:00 2001 From: kojima Date: Wed, 20 Oct 1999 03:25:06 +0000 Subject: [PATCH] added nana stuff added lock option in docked icons --- WINGs/ChangeLog | 3 + WINGs/Makefile.am | 1 + WINGs/Makefile.in | 10 +- WINGs/WINGs.h | 79 +++++++- WINGs/wlist.c | 10 ++ WINGs/wpopupbutton.c | 300 ++++++++++++------------------- WINGs/wtest.c | 2 +- WPrefs.app/Makefile.in | 2 +- WPrefs.app/WPrefs.h | 2 +- WPrefs.app/Workspace.c | 195 +++++++++++++------- WPrefs.app/po/Makefile.in | 2 +- WPrefs.app/tiff/Makefile.in | 2 +- WPrefs.app/xpm/Makefile.in | 2 +- WindowMaker/Defaults/WMState.in | 1 + WindowMaker/Styles/Emerald.style | 14 +- src/DI.h | 266 +++++++++++++++++++++++++++ src/DL.h | 227 +++++++++++++++++++++++ src/GDB.h | 90 ++++++++++ src/I.h | 234 ++++++++++++++++++++++++ src/L.h | 207 +++++++++++++++++++++ src/Makefile.am | 3 +- src/Makefile.in | 5 +- src/Q.h | 160 +++++++++++++++++ src/WindowMaker.h | 2 + src/appicon.h | 3 + src/dock.c | 75 ++++---- src/dockedapp.c | 23 ++- src/event.c | 63 +++---- src/funcs.h | 8 +- src/main.c | 156 ++++++++++++++++ src/menu.c | 29 +-- src/misc.c | 94 ---------- src/nana.h | 46 +++++ src/rootmenu.c | 1 - src/session.c | 3 +- wrlib/Makefile.am | 2 +- wrlib/Makefile.in | 2 +- wrlib/nxpm.c | 6 +- wrlib/png.c | 4 +- 39 files changed, 1833 insertions(+), 501 deletions(-) create mode 100644 src/DI.h create mode 100644 src/DL.h create mode 100644 src/GDB.h create mode 100644 src/I.h create mode 100644 src/L.h create mode 100644 src/Q.h create mode 100644 src/nana.h diff --git a/WINGs/ChangeLog b/WINGs/ChangeLog index 71a7b6a3..017cf11b 100644 --- a/WINGs/ChangeLog +++ b/WINGs/ChangeLog @@ -3,6 +3,9 @@ changes since wmaker 0.61.1: - fixed WMInsertInBag(). It ignored index, and always put the new item at end. - added WMSaveUserDefaults(). +- rewrote WMPopUpButton to use WMMenuItem +- added WMGetPopUpButtonMenuItem(WMPopUpButton *bPtr, int index) +- WMSortListItemsWithComparer(WMList *lPtr, (int)(f)(const void*, const void*)) - fixed bug with sorting list items. diff --git a/WINGs/Makefile.am b/WINGs/Makefile.am index ebcc4ceb..625a82e5 100644 --- a/WINGs/Makefile.am +++ b/WINGs/Makefile.am @@ -75,6 +75,7 @@ libWINGs_a_SOURCES = \ widgets.c \ wlabel.c \ wlist.c \ + wmenuitem.c \ wmisc.c \ wpanel.c \ wpixmap.c \ diff --git a/WINGs/Makefile.in b/WINGs/Makefile.in index 9c384268..be13efbb 100644 --- a/WINGs/Makefile.in +++ b/WINGs/Makefile.in @@ -138,7 +138,7 @@ wmquery_LDADD = libWINGs.a $(LIBLIST) EXTRA_DIST = logo.xpm BUGS # wbutton.c -libWINGs_a_SOURCES = WINGs.h WINGsP.h configuration.c international.c notification.c selection.c userdefaults.c wapplication.c wappresource.c wballoon.c wbrowser.c wbutton.c wcolor.c wcolorpanel.c wcolorwell.c wevent.c wfilepanel.c wframe.c wfont.c wfontpanel.c widgets.c wlabel.c wlist.c wmisc.c wpanel.c wpixmap.c wpopupbutton.c wprogressindicator.c wscroller.c wscrollview.c wslider.c wsplitview.c wtabview.c wtextfield.c wwindow.c wview.c error.c findfile.c bag.c hashtable.c memory.c usleep.c +libWINGs_a_SOURCES = WINGs.h WINGsP.h configuration.c international.c notification.c selection.c userdefaults.c wapplication.c wappresource.c wballoon.c wbrowser.c wbutton.c wcolor.c wcolorpanel.c wcolorwell.c wevent.c wfilepanel.c wframe.c wfont.c wfontpanel.c widgets.c wlabel.c wlist.c wmenuitem.c wmisc.c wpanel.c wpixmap.c wpopupbutton.c wprogressindicator.c wscroller.c wscrollview.c wslider.c wsplitview.c wtabview.c wtextfield.c wwindow.c wview.c error.c findfile.c bag.c hashtable.c memory.c usleep.c libWUtil_a_SOURCES = WINGs.h WINGsP.h bag.c international.c notification.c userdefaults.c wapplication.c wutil.c error.c findfile.c hashtable.c memory.c usleep.c @@ -164,10 +164,10 @@ libWINGs_a_OBJECTS = configuration.o international.o notification.o \ selection.o userdefaults.o wapplication.o wappresource.o wballoon.o \ wbrowser.o wbutton.o wcolor.o wcolorpanel.o wcolorwell.o wevent.o \ wfilepanel.o wframe.o wfont.o wfontpanel.o widgets.o wlabel.o wlist.o \ -wmisc.o wpanel.o wpixmap.o wpopupbutton.o wprogressindicator.o \ -wscroller.o wscrollview.o wslider.o wsplitview.o wtabview.o \ -wtextfield.o wwindow.o wview.o error.o findfile.o bag.o hashtable.o \ -memory.o usleep.o +wmenuitem.o wmisc.o wpanel.o wpixmap.o wpopupbutton.o \ +wprogressindicator.o wscroller.o wscrollview.o wslider.o wsplitview.o \ +wtabview.o wtextfield.o wwindow.o wview.o error.o findfile.o bag.o \ +hashtable.o memory.o usleep.o libWUtil_a_LIBADD = libWUtil_a_OBJECTS = bag.o international.o notification.o \ userdefaults.o wapplication.o wutil.o error.o findfile.o hashtable.o \ diff --git a/WINGs/WINGs.h b/WINGs/WINGs.h index be2b2861..a172d4d5 100644 --- a/WINGs/WINGs.h +++ b/WINGs/WINGs.h @@ -265,7 +265,8 @@ enum { WC_Matrix = 12, /* not ready */ WC_SplitView = 13, WC_TabView = 14, - WC_ProgressIndicator = 15 + WC_ProgressIndicator = 15, + WC_MenuView = 16 }; /* All widgets must start with the following structure @@ -312,6 +313,7 @@ typedef struct W_TabView WMTabView; /* not widgets */ typedef struct W_TabViewItem WMTabViewItem; +typedef struct W_MenuItem WMMenuItem; typedef struct W_FilePanel WMFilePanel; @@ -950,6 +952,9 @@ WMListItem *WMInsertListItem(WMList *lPtr, int row, char *text); void WMSortListItems(WMList *lPtr); +void WMSortListItemsWithComparer(WMList *lPtr, + int (f)(const void*, const void*)); + int WMFindRowOfListItemWithTitle(WMList *lPtr, char *title); WMListItem *WMGetListItem(WMList *lPtr, int row); @@ -1042,6 +1047,69 @@ void WMSetBrowserDelegate(WMBrowser *bPtr, WMBrowserDelegate *delegate); /* ....................................................................... */ + +Bool WMMenuItemIsSeparator(WMMenuItem *item); + +WMMenuItem *WMCreateMenuItem(void); + +void WMDestroyMenuItem(WMMenuItem *item); + +Bool WMGetMenuItemEnabled(WMMenuItem *item); + +void WMSetMenuItemEnabled(WMMenuItem *item, Bool flag); + +char *WMGetMenuItemShortcut(WMMenuItem *item); + +unsigned WMGetMenuItemShortcutModifierMask(WMMenuItem *item); + +void WMSetMenuItemShortcut(WMMenuItem *item, char *shortcut); + +void WMSetMenuItemShortcutModifierMask(WMMenuItem *item, unsigned mask); + +void *WMGetMenuItemRepresentedObject(WMMenuItem *item); + +void WMSetMenuItemRepresentedObject(WMMenuItem *item, void *object); + +void WMSetMenuItemAction(WMMenuItem *item, WMAction *action, void *data); + +WMAction *WMGetMenuItemAction(WMMenuItem *item); + +void *WMGetMenuItemData(WMMenuItem *item); + +void WMSetMenuItemTitle(WMMenuItem *item, char *title); + +char *WMGetMenuItemTitle(WMMenuItem *item); + +void WMSetMenuItemState(WMMenuItem *item, int state); + +int WMGetMenuItemState(WMMenuItem *item); + +void WMSetMenuItemPixmap(WMMenuItem *item, WMPixmap *pixmap); + +WMPixmap *WMGetMenuItemPixmap(WMMenuItem *item); + +void WMSetMenuItemOnStatePixmap(WMMenuItem *item, WMPixmap *pixmap); + +WMPixmap *WMGetMenuItemOnStatePixmap(WMMenuItem *item); + +void WMSetMenuItemOffStatePixmap(WMMenuItem *item, WMPixmap *pixmap); + +WMPixmap *WMGetMenuItemOffStatePixmap(WMMenuItem *item); + +void WMSetMenuItemMixedStatePixmap(WMMenuItem *item, WMPixmap *pixmap); + +WMPixmap *WMGetMenuItemMixedStatePixmap(WMMenuItem *item); + +/*void WMSetMenuItemSubmenu(WMMenuItem *item, WMMenu *submenu); + + +WMMenu *WMGetMenuItemSubmenu(WMMenuItem *item); + +Bool WMGetMenuItemHasSubmenu(WMMenuItem *item); + */ + +/* ....................................................................... */ + WMPopUpButton *WMCreatePopUpButton(WMWidget *parent); void WMSetPopUpButtonAction(WMPopUpButton *sPtr, WMAction *action, @@ -1049,9 +1117,10 @@ void WMSetPopUpButtonAction(WMPopUpButton *sPtr, WMAction *action, void WMSetPopUpButtonPullsDown(WMPopUpButton *bPtr, Bool flag); -void WMAddPopUpButtonItem(WMPopUpButton *bPtr, char *title); +WMMenuItem *WMAddPopUpButtonItem(WMPopUpButton *bPtr, char *title); -void WMInsertPopUpButtonItem(WMPopUpButton *bPtr, int index, char *title); +WMMenuItem *WMInsertPopUpButtonItem(WMPopUpButton *bPtr, int index, + char *title); void WMRemovePopUpButtonItem(WMPopUpButton *bPtr, int index); @@ -1068,6 +1137,9 @@ void WMSetPopUpButtonText(WMPopUpButton *bPtr, char *text); /* don't free the returned data */ char *WMGetPopUpButtonItem(WMPopUpButton *bPtr, int index); +WMMenuItem *WMGetPopUpButtonMenuItem(WMPopUpButton *bPtr, int index); + + int WMGetPopUpButtonNumberOfItems(WMPopUpButton *bPtr); void WMSetPopUpButtonEnabled(WMPopUpButton *bPtr, Bool flag); @@ -1225,6 +1297,7 @@ void WMSelectTabViewItemAtIndex(WMTabView *tPtr, int index); void WMSetTabViewDelegate(WMTabView *tPtr, WMTabViewDelegate *delegate); +/* ....................................................................... */ WMTabViewItem *WMCreateTabViewItemWithIdentifier(int identifier); diff --git a/WINGs/wlist.c b/WINGs/wlist.c index b318e3ab..9ca7e295 100644 --- a/WINGs/wlist.c +++ b/WINGs/wlist.c @@ -152,6 +152,16 @@ WMSortListItems(WMList *lPtr) +void +WMSortListItemsWithComparer(WMList *lPtr, int (f)(const void*, const void*)) +{ + WMSortBag(lPtr->items, f); + + paintList(lPtr); +} + + + WMListItem* WMInsertListItem(WMList *lPtr, int row, char *text) { diff --git a/WINGs/wpopupbutton.c b/WINGs/wpopupbutton.c index 24f9c8f4..8fd2fcd1 100644 --- a/WINGs/wpopupbutton.c +++ b/WINGs/wpopupbutton.c @@ -4,12 +4,6 @@ #include "WINGsP.h" -typedef struct ItemList { - char *text; - struct ItemList *nextPtr; - unsigned int disabled:1; -} ItemList; - typedef struct W_PopUpButton { W_Class widgetClass; @@ -20,14 +14,11 @@ typedef struct W_PopUpButton { char *caption; - ItemList *items; - short itemCount; + WMBag *items; short selectedItemIndex; short highlightedItem; - - ItemList *selectedItem; /* selected item if it is a menu btn */ WMView *menuView; /* override redirect popup menu */ @@ -100,6 +91,8 @@ WMCreatePopUpButton(WMWidget *parent) bPtr->flags.enabled = 1; + bPtr->items = WMCreateBag(4); + bPtr->menuView = W_CreateTopView(scr); bPtr->menuView->attribs.override_redirect = True; bPtr->menuView->attribFlags |= CWOverrideRedirect; @@ -125,69 +118,36 @@ WMSetPopUpButtonAction(WMPopUpButton *bPtr, WMAction *action, void *clientData) } -void +WMMenuItem* WMAddPopUpButtonItem(WMPopUpButton *bPtr, char *title) { - ItemList *itemPtr, *tmp; + WMMenuItem *item; CHECK_CLASS(bPtr, WC_PopUpButton); - itemPtr = wmalloc(sizeof(ItemList)); - memset(itemPtr, 0, sizeof(ItemList)); - itemPtr->text = wstrdup(title); - - /* append item to list */ - tmp = bPtr->items; - if (!tmp) - bPtr->items = itemPtr; - else { - while (tmp->nextPtr!=NULL) - tmp = tmp->nextPtr; - tmp->nextPtr = itemPtr; - } - - bPtr->itemCount++; - + item = WMCreateMenuItem(); + WMSetMenuItemTitle(item, title); + + WMPutInBag(bPtr->items, item); + if (bPtr->menuView && bPtr->menuView->flags.realized) resizeMenu(bPtr); + + return item; } -void +WMMenuItem* WMInsertPopUpButtonItem(WMPopUpButton *bPtr, int index, char *title) { - ItemList *itemPtr; + WMMenuItem *item; CHECK_CLASS(bPtr, WC_PopUpButton); - if (index < 0) - index = 0; - if (index >= bPtr->itemCount) { - WMAddPopUpButtonItem(bPtr, title); - return; - } - - itemPtr = wmalloc(sizeof(ItemList)); - memset(itemPtr, 0, sizeof(ItemList)); - itemPtr->text = wstrdup(title); + item = WMCreateMenuItem(); + WMSetMenuItemTitle(item, title); - if (index == 0) { - itemPtr->nextPtr = bPtr->items; - bPtr->items = itemPtr; - } else { - ItemList *tmp; - int i = index; - - tmp = bPtr->items; - /* insert item in list */ - while (--i > 0) { - tmp = tmp->nextPtr; - } - itemPtr->nextPtr = tmp->nextPtr; - tmp->nextPtr = itemPtr; - } - - bPtr->itemCount++; + WMInsertInBag(bPtr->items, index, item); /* if there is an selected item, update it's index to match the new * position */ @@ -196,49 +156,32 @@ WMInsertPopUpButtonItem(WMPopUpButton *bPtr, int index, char *title) if (bPtr->menuView && bPtr->menuView->flags.realized) resizeMenu(bPtr); + + return item; } void WMRemovePopUpButtonItem(WMPopUpButton *bPtr, int index) { - ItemList *tmp; + WMMenuItem *item; CHECK_CLASS(bPtr, WC_PopUpButton); + + wassertr(index >= 0 && index < WMGetBagItemCount(bPtr->items)); - if (index < 0 || index >= bPtr->itemCount) - return; + item = WMGetFromBag(bPtr->items, index); + WMDeleteFromBag(bPtr->items, index); - if (index == 0) { - wfree(bPtr->items->text); - tmp = bPtr->items->nextPtr; - wfree(bPtr->items); - bPtr->items = tmp; - } else { - ItemList *next; - int i = index; - - tmp = bPtr->items; - while (--i > 0) - tmp = tmp->nextPtr; - next = tmp->nextPtr->nextPtr; - - wfree(tmp->nextPtr->text); - wfree(tmp->nextPtr); + WMDestroyMenuItem(item); - tmp->nextPtr = next; - } - - bPtr->itemCount--; - - if (bPtr->selectedItem!=NULL && !bPtr->flags.pullsDown) { + if (bPtr->selectedItemIndex >= 0 && !bPtr->flags.pullsDown) { if (index < bPtr->selectedItemIndex) bPtr->selectedItemIndex--; else if (index == bPtr->selectedItemIndex) { /* reselect first item if the removed item is the * selected one */ - bPtr->selectedItem = bPtr->items; bPtr->selectedItemIndex = 0; if (bPtr->view->flags.mapped) paintPopUpButton(bPtr); @@ -268,21 +211,13 @@ WMGetPopUpButtonEnabled(WMPopUpButton *bPtr) void WMSetPopUpButtonSelectedItem(WMPopUpButton *bPtr, int index) -{ - ItemList *itemPtr = bPtr->items; - int i = index; - +{ if (index < 0) { - bPtr->selectedItem = NULL; if (bPtr->view->flags.mapped) paintPopUpButton(bPtr); return; } - while (i-- > 0) { - itemPtr = itemPtr->nextPtr; - } - bPtr->selectedItem = itemPtr; bPtr->selectedItemIndex = index; if (bPtr->view->flags.mapped) @@ -292,7 +227,7 @@ WMSetPopUpButtonSelectedItem(WMPopUpButton *bPtr, int index) int WMGetPopUpButtonSelectedItem(WMPopUpButton *bPtr) { - if (!bPtr->flags.pullsDown && bPtr->selectedItem==NULL) + if (!bPtr->flags.pullsDown && bPtr->selectedItemIndex < 0) return -1; else return bPtr->selectedItemIndex; @@ -320,32 +255,24 @@ WMSetPopUpButtonText(WMPopUpButton *bPtr, char *text) void WMSetPopUpButtonItemEnabled(WMPopUpButton *bPtr, int index, Bool flag) { - int i; - ItemList *item = bPtr->items; + WMMenuItem *item; + + item = WMGetFromBag(bPtr->items, index); + wassertr(item != NULL); - if (index < 0 || index >= bPtr->itemCount) - return; - - for (i = 0; inextPtr; - - item->disabled = !flag; + WMSetMenuItemEnabled(item, flag); } Bool WMGetPopUpButtonItemEnabled(WMPopUpButton *bPtr, int index) { - int i; - ItemList *item = bPtr->items; - - if (index < 0 || index >= bPtr->itemCount) - return False; - - for (i = 0; inextPtr; - - return !item->disabled; + WMMenuItem *item; + + item = WMGetFromBag(bPtr->items, index); + wassertrv(item != NULL, False); + + return WMGetMenuItemEnabled(item); } @@ -353,22 +280,9 @@ void WMSetPopUpButtonPullsDown(WMPopUpButton *bPtr, Bool flag) { bPtr->flags.pullsDown = flag; - if (!flag) { - /* This code causes bugs. It should not select any item, - * since it was not asked to. -Dan - bPtr->selectedItem = bPtr->items; - if (bPtr->selectedItem) - bPtr->selectedItemIndex = 0; - else - bPtr->selectedItemIndex = -1; - */ - bPtr->selectedItem = NULL; - /* the drawing routine, still draws things wrong if we put - * the index to -1 (i.e. not selected). - * Find out why. -Dan */ - bPtr->selectedItemIndex = 0; - } else + if (flag) { bPtr->selectedItemIndex = -1; + } if (bPtr->view->flags.mapped) paintPopUpButton(bPtr); @@ -378,25 +292,35 @@ WMSetPopUpButtonPullsDown(WMPopUpButton *bPtr, Bool flag) int WMGetPopUpButtonNumberOfItems(WMPopUpButton *bPtr) { - return bPtr->itemCount; + return WMGetBagItemCount(bPtr->items); } char* WMGetPopUpButtonItem(WMPopUpButton *bPtr, int index) { - ItemList *itemPtr = bPtr->items; - - if ((index < 0) || (index >= bPtr->itemCount)) + WMMenuItem *item; + + item = WMGetFromBag(bPtr->items, index); + if (!item) return NULL; - - while (index-->0) - itemPtr = itemPtr->nextPtr; - - return itemPtr->text; + + return WMGetMenuItemTitle(item); } +WMMenuItem* +WMGetPopUpButtonMenuItem(WMPopUpButton *bPtr, int index) +{ + WMMenuItem *item; + + item = WMGetFromBag(bPtr->items, index); + + return item; +} + + + static void paintPopUpButton(PopUpButton *bPtr) { @@ -408,11 +332,11 @@ paintPopUpButton(PopUpButton *bPtr) if (bPtr->flags.pullsDown) { caption = bPtr->caption; } else { - if (bPtr->selectedItem == NULL) { + if (bPtr->selectedItemIndex < 0) { /* if no item selected, show the caption */ caption = bPtr->caption; - } else { - caption = bPtr->selectedItem->text; + } else { + caption = WMGetPopUpButtonItem(bPtr, bPtr->selectedItemIndex); } } @@ -489,12 +413,12 @@ paintMenuEntry(PopUpButton *bPtr, int index, int highlight) W_Screen *scr = bPtr->view->screen; int i; int yo; - ItemList *itemPtr; int width, height, itemHeight; + char *title; itemHeight = bPtr->view->size.height; width = bPtr->view->size.width; - height = itemHeight * bPtr->itemCount; + height = itemHeight * WMGetBagItemCount(bPtr->items); yo = (itemHeight - WMFontHeight(scr->normalFont))/2; if (!highlight) { @@ -508,16 +432,14 @@ paintMenuEntry(PopUpButton *bPtr, int index, int highlight) XFillRectangle(scr->display, bPtr->menuView->window, WMColorGC(scr->white), 1, index*itemHeight+1, width-3, itemHeight-3); - itemPtr = bPtr->items; - for (i = 0; i < index; i++) - itemPtr = itemPtr->nextPtr; - + title = WMGetPopUpButtonItem(bPtr, index); + W_DrawRelief(scr, bPtr->menuView->window, 0, index*itemHeight, width, itemHeight, WRRaised); W_PaintText(bPtr->menuView, bPtr->menuView->window, scr->normalFont, 6, - index*itemHeight + yo, width, WALeft, WMColorGC(scr->black), False, - itemPtr->text, strlen(itemPtr->text)); + index*itemHeight + yo, width, WALeft, WMColorGC(scr->black), + False, title, strlen(title)); if (!bPtr->flags.pullsDown && index == bPtr->selectedItemIndex) { XCopyArea(scr->display, scr->popUpIndicator->pixmap, @@ -536,34 +458,38 @@ makeMenuPixmap(PopUpButton *bPtr) W_Screen *scr = bPtr->view->screen; int i; int yo; - ItemList *itemPtr; int width, height, itemHeight; itemHeight = bPtr->view->size.height; width = bPtr->view->size.width; - height = itemHeight * bPtr->itemCount; + height = itemHeight * WMGetBagItemCount(bPtr->items); yo = (itemHeight - WMFontHeight(scr->normalFont))/2; pixmap = XCreatePixmap(scr->display, bPtr->view->window, width, height, scr->depth); - XFillRectangle(scr->display, pixmap, WMColorGC(scr->gray), 0, 0, width, height); - - itemPtr = bPtr->items; - for (i = 0; i < bPtr->itemCount; i++) { + XFillRectangle(scr->display, pixmap, WMColorGC(scr->gray), 0, 0, + width, height); + + for (i = 0; i < WMGetBagItemCount(bPtr->items); i++) { GC gc; - + WMMenuItem *item; + char *text; + + item = (WMMenuItem*)WMGetFromBag(bPtr->items, i); + text = WMGetMenuItemTitle(item); + W_DrawRelief(scr, pixmap, 0, i*itemHeight, width, itemHeight, WRRaised); - if (itemPtr->disabled) + if (!WMGetMenuItemEnabled(item)) gc = WMColorGC(scr->darkGray); else gc = WMColorGC(scr->black); W_PaintText(bPtr->menuView, pixmap, scr->normalFont, 6, i*itemHeight + yo, width, WALeft, gc, False, - itemPtr->text, strlen(itemPtr->text)); + text, strlen(text)); if (!bPtr->flags.pullsDown && i == bPtr->selectedItemIndex) { XCopyArea(scr->display, scr->popUpIndicator->pixmap, pixmap, @@ -571,8 +497,7 @@ makeMenuPixmap(PopUpButton *bPtr) scr->popUpIndicator->height, width-scr->popUpIndicator->width-4, i*itemHeight+(itemHeight-scr->popUpIndicator->height)/2); - } - itemPtr = itemPtr->nextPtr; + } } return pixmap; @@ -584,7 +509,7 @@ resizeMenu(PopUpButton *bPtr) { int height; - height = bPtr->itemCount * bPtr->view->size.height; + height = WMGetBagItemCount(bPtr->items) * bPtr->view->size.height; if (height > 0) W_ResizeView(bPtr->menuView, bPtr->view->size.width, height); } @@ -602,7 +527,7 @@ popUpMenu(PopUpButton *bPtr) resizeMenu(bPtr); } - if (bPtr->itemCount < 1) + if (WMGetBagItemCount(bPtr->items) < 1) return; XTranslateCoordinates(scr->display, bPtr->view->window, scr->rootWin, @@ -622,7 +547,7 @@ popUpMenu(PopUpButton *bPtr) W_MapView(bPtr->menuView); bPtr->highlightedItem = 0; - if (!bPtr->flags.pullsDown && bPtr->selectedItem != NULL) + if (!bPtr->flags.pullsDown && bPtr->selectedItemIndex < 0) paintMenuEntry(bPtr, bPtr->selectedItemIndex, True); } @@ -638,18 +563,6 @@ popDownMenu(PopUpButton *bPtr) } -static int -itemIsEnabled(PopUpButton *bPtr, int index) -{ - ItemList *item = bPtr->items; - - while (index-- > 0 && item) - item = item->nextPtr; - - return item ? !item->disabled : False; -} - - static void autoScroll(void *data) { @@ -690,9 +603,13 @@ autoScroll(void *data) / bPtr->view->size.height; if (oldItem!=bPtr->highlightedItem) { + WMMenuItem *item = + WMGetPopUpButtonMenuItem(bPtr, bPtr->highlightedItem); + paintMenuEntry(bPtr, oldItem, False); + paintMenuEntry(bPtr, bPtr->highlightedItem, - itemIsEnabled(bPtr, bPtr->highlightedItem)); + WMGetMenuItemEnabled(item)); } bPtr->timer = WMAddTimerHandler(SCROLL_DELAY, autoScroll, bPtr); @@ -711,14 +628,13 @@ handleActionEvents(XEvent *event, void *data) CHECK_CLASS(data, WC_PopUpButton); - if (bPtr->itemCount < 1) + if (WMGetBagItemCount(bPtr->items) < 1) return; switch (event->type) { /* called for menuView */ case Expose: - paintMenuEntry(bPtr, bPtr->highlightedItem, - itemIsEnabled(bPtr, bPtr->highlightedItem)); + paintMenuEntry(bPtr, bPtr->highlightedItem, True); break; case LeaveNotify: @@ -737,9 +653,12 @@ handleActionEvents(XEvent *event, void *data) oldItem = bPtr->highlightedItem; bPtr->highlightedItem = event->xmotion.y / bPtr->view->size.height; if (oldItem!=bPtr->highlightedItem) { + WMMenuItem *item; + + item = WMGetPopUpButtonMenuItem(bPtr, bPtr->highlightedItem); paintMenuEntry(bPtr, oldItem, False); paintMenuEntry(bPtr, bPtr->highlightedItem, - itemIsEnabled(bPtr, bPtr->highlightedItem)); + WMGetMenuItemEnabled(item)); } if (event->xmotion.y_root >= scrHeight-1 @@ -783,8 +702,12 @@ handleActionEvents(XEvent *event, void *data) bPtr->timer = NULL; } - if (bPtr->flags.insideMenu && bPtr->highlightedItem>=0) { - if (itemIsEnabled(bPtr, bPtr->highlightedItem)) { + if (bPtr->flags.insideMenu && bPtr->highlightedItem>=0) { + WMMenuItem *item; + + item = WMGetPopUpButtonMenuItem(bPtr, bPtr->highlightedItem); + + if (WMGetMenuItemEnabled(item)) { int i; WMSetPopUpButtonSelectedItem(bPtr, bPtr->highlightedItem); @@ -815,20 +738,19 @@ handleActionEvents(XEvent *event, void *data) static void destroyPopUpButton(PopUpButton *bPtr) { - ItemList *itemPtr, *tmp; + WMMenuItem *item; + int i; if (bPtr->timer) { WMDeleteTimerHandler(bPtr->timer); } - - itemPtr = bPtr->items; - while (itemPtr!=NULL) { - wfree(itemPtr->text); - tmp = itemPtr->nextPtr; - wfree(itemPtr); - itemPtr = tmp; + + for (i = 0; i < WMGetBagItemCount(bPtr->items); i++) { + item = WMGetFromBag(bPtr->items, i); + WMDestroyMenuItem(item); } - + WMFreeBag(bPtr->items); + if (bPtr->caption) wfree(bPtr->caption); diff --git a/WINGs/wtest.c b/WINGs/wtest.c index 9488d768..cdd183b1 100644 --- a/WINGs/wtest.c +++ b/WINGs/wtest.c @@ -513,6 +513,7 @@ int main(int argc, char **argv) */ + testPullDown(scr); testFontPanel(scr); #if 0 @@ -531,7 +532,6 @@ int main(int argc, char **argv) testSlider(scr); - testPullDown(scr); #endif /* * The main event loop. diff --git a/WPrefs.app/Makefile.in b/WPrefs.app/Makefile.in index 51b44c56..c741ef60 100644 --- a/WPrefs.app/Makefile.in +++ b/WPrefs.app/Makefile.in @@ -148,7 +148,7 @@ DIST_COMMON = README Makefile.am Makefile.in DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) -TAR = tar +TAR = gtar GZIP_ENV = --best SOURCES = $(WPrefs_SOURCES) OBJECTS = $(WPrefs_OBJECTS) diff --git a/WPrefs.app/WPrefs.h b/WPrefs.app/WPrefs.h index 9e300a11..473297d8 100644 --- a/WPrefs.app/WPrefs.h +++ b/WPrefs.app/WPrefs.h @@ -42,7 +42,7 @@ /****/ -#define WVERSION "0.41" +#define WVERSION "0.42" #define WMVERSION "0.61.x" diff --git a/WPrefs.app/Workspace.c b/WPrefs.app/Workspace.c index 7c24a490..efd51971 100644 --- a/WPrefs.app/Workspace.c +++ b/WPrefs.app/Workspace.c @@ -36,6 +36,7 @@ typedef struct _Panel { WMWindow *win; WMFrame *navF; + WMButton *linkB; WMButton *cyclB; WMButton *newB; @@ -43,6 +44,10 @@ typedef struct _Panel { WMLabel *cyclL; WMLabel *newL; + WMLabel *posiL; + WMLabel *posL; + WMPopUpButton *posP; + WMFrame *dockF; WMButton *dockB; WMButton *clipB; @@ -60,6 +65,17 @@ typedef struct _Panel { #define CLIP_FILE "clip" +static char *WSNamePositions[] = { + "none", + "center", + "top", + "bottom", + "topleft", + "topright", + "bottomleft", + "bottomright" +}; + static void createImages(WMScreen *scr, RContext *rc, RImage *xis, char *file, @@ -71,9 +87,14 @@ createImages(WMScreen *scr, RContext *rc, RImage *xis, char *file, *icon1 = WMCreatePixmapFromFile(scr, file); if (!*icon1) { wwarning(_("could not load icon %s"), file); - *icon2 = NULL; + if (icon2) + *icon2 = NULL; return; } + + if (!icon2) + return; + icon = RLoadImage(rc, file, 0); if (!icon) { wwarning(_("could not load icon %s"), file); @@ -96,6 +117,9 @@ createImages(WMScreen *scr, RContext *rc, RImage *xis, char *file, static void showData(_Panel *panel) { + int i, idx; + char *str; + WMSetButtonSelected(panel->linkB, !GetBoolForKey("DontLinkWorkspaces")); WMSetButtonSelected(panel->cyclB, GetBoolForKey("CycleWorkspaces")); @@ -105,6 +129,19 @@ showData(_Panel *panel) WMSetButtonSelected(panel->dockB, !GetBoolForKey("DisableDock")); WMSetButtonSelected(panel->clipB, !GetBoolForKey("DisableClip")); + + str = GetStringForKey("WorkspaceNameDisplayPosition"); + if (!str) + str = "center"; + + idx = 1; /* center */ + for (i = 0; i < sizeof(WSNamePositions); i++) { + if (strcmp(WSNamePositions[i], str) == 0) { + idx = i; + break; + } + } + WMSetPopUpButtonSelectedItem(panel->posP, idx); } @@ -134,94 +171,123 @@ createPanel(Panel *p) /***************** Workspace Navigation *****************/ panel->navF = WMCreateFrame(panel->frame); - WMResizeWidget(panel->navF, 365, 200); - WMMoveWidget(panel->navF, 20, 15); + WMResizeWidget(panel->navF, 365, 210); + WMMoveWidget(panel->navF, 15, 10); WMSetFrameTitle(panel->navF, _("Workspace Navigation")); - panel->linkB = WMCreateButton(panel->navF, WBTToggle); - WMResizeWidget(panel->linkB, 60, 60); - WMMoveWidget(panel->linkB, 20, 25); - WMSetButtonImagePosition(panel->linkB, WIPImageOnly); - path = LocateImage(DONT_LINK_FILE); - if (path) { - createImages(scr, rc, xis, path, &icon1, &icon2); - if (icon2) { - WMSetButtonImage(panel->linkB, icon2); - WMReleasePixmap(icon2); - } - if (icon1) { - WMSetButtonAltImage(panel->linkB, icon1); - WMReleasePixmap(icon1); - } - free(path); - } - panel->linkL = WMCreateLabel(panel->navF); - WMResizeWidget(panel->linkL, 260, 38); - WMMoveWidget(panel->linkL, 85, 25); - WMSetLabelTextAlignment(panel->linkL, WALeft); - WMSetLabelText(panel->linkL, - _("drag windows between workspaces.")); - - panel->cyclB = WMCreateButton(panel->navF, WBTToggle); - WMResizeWidget(panel->cyclB, 60, 60); - WMMoveWidget(panel->cyclB, 285, 75); - WMSetButtonImagePosition(panel->cyclB, WIPImageOnly); + panel->cyclB = WMCreateSwitchButton(panel->navF); + WMResizeWidget(panel->cyclB, 280, 34); + WMMoveWidget(panel->cyclB, 75, 30); + WMSetButtonText(panel->cyclB, + _("wrap to the first workspace after the last workspace.")); + + panel->cyclL = WMCreateLabel(panel->navF); + WMResizeWidget(panel->cyclL, 60, 60); + WMMoveWidget(panel->cyclL, 10, 15); + WMSetLabelImagePosition(panel->cyclL, WIPImageOnly); path = LocateImage(CYCLE_FILE); if (path) { - createImages(scr, rc, xis, path, &icon1, &icon2); - if (icon2) { - WMSetButtonImage(panel->cyclB, icon2); - WMReleasePixmap(icon2); - } + createImages(scr, rc, xis, path, &icon1, NULL); if (icon1) { - WMSetButtonAltImage(panel->cyclB, icon1); + WMSetLabelImage(panel->cyclL, icon1); WMReleasePixmap(icon1); } free(path); } - panel->cyclL = WMCreateLabel(panel->navF); - WMResizeWidget(panel->cyclL, 260, 38); - WMMoveWidget(panel->cyclL, 20, 85); - WMSetLabelTextAlignment(panel->cyclL, WARight); - WMSetLabelText(panel->cyclL, - _("switch to first workspace when switching past the last workspace and vice-versa")); + + /**/ + + panel->linkB = WMCreateSwitchButton(panel->navF); + WMResizeWidget(panel->linkB, 280, 34); + WMMoveWidget(panel->linkB, 75, 75); + WMSetButtonText(panel->linkB, + _("switch workspaces while dragging windows.")); + + panel->linkL = WMCreateLabel(panel->navF); + WMResizeWidget(panel->linkL, 60, 40); + WMMoveWidget(panel->linkL, 10, 80); + WMSetLabelImagePosition(panel->linkL, WIPImageOnly); + path = LocateImage(DONT_LINK_FILE); + if (path) { + createImages(scr, rc, xis, path, &icon1, NULL); + if (icon1) { + WMSetLabelImage(panel->linkL, icon1); + WMReleasePixmap(icon1); + } + free(path); + } + + /**/ - panel->newB = WMCreateButton(panel->navF, WBTToggle); - WMResizeWidget(panel->newB, 60, 60); - WMMoveWidget(panel->newB, 20, 125); - WMSetButtonImagePosition(panel->newB, WIPImageOnly); + panel->newB = WMCreateSwitchButton(panel->navF); + WMResizeWidget(panel->newB, 280, 34); + WMMoveWidget(panel->newB, 75, 120); + WMSetButtonText(panel->newB, + _("automatically create new workspaces.")); + + panel->newL = WMCreateLabel(panel->navF); + WMResizeWidget(panel->newL, 60, 20); + WMMoveWidget(panel->newL, 10, 130); + WMSetLabelImagePosition(panel->newL, WIPImageOnly); path = LocateImage(ADVANCE_FILE); if (path) { - createImages(scr, rc, xis, path, &icon1, &icon2); - if (icon2) { - WMSetButtonImage(panel->newB, icon2); - WMReleasePixmap(icon2); - } + createImages(scr, rc, xis, path, &icon1, NULL); if (icon1) { - WMSetButtonAltImage(panel->newB, icon1); + WMSetLabelImage(panel->newL, icon1); WMReleasePixmap(icon1); } free(path); } - panel->newL = WMCreateLabel(panel->navF); - WMResizeWidget(panel->newL, 260, 38); - WMMoveWidget(panel->newL, 85, 140); - WMSetLabelTextAlignment(panel->newL, WALeft); - WMSetLabelText(panel->newL, - _("create a new workspace when switching past the last workspace.")); + + /**/ + + panel->posL = WMCreateLabel(panel->navF); + WMResizeWidget(panel->posL, 140, 30); + WMMoveWidget(panel->posL, 75, 165); + WMSetLabelTextAlignment(panel->posL, WARight); + WMSetLabelText(panel->posL, + _("Position of workspace name display")); + +#if 0 + panel->posiL = WMCreateLabel(panel->navF); + WMResizeWidget(panel->posiL, 60, 40); + WMMoveWidget(panel->posiL, 10, 160); + WMSetLabelImagePosition(panel->posiL, WIPImageOnly); + path = LocateImage(ADVANCE_FILE); + if (path) { + createImages(scr, rc, xis, path, &icon1, NULL); + if (icon1) { + WMSetLabelImage(panel->posiL, icon1); + WMReleasePixmap(icon1); + } + free(path); + } +#endif + + panel->posP = WMCreatePopUpButton(panel->navF); + WMResizeWidget(panel->posP, 125, 20); + WMMoveWidget(panel->posP, 225, 175); + WMAddPopUpButtonItem(panel->posP, _("Disable")); + WMAddPopUpButtonItem(panel->posP, _("Center")); + WMAddPopUpButtonItem(panel->posP, _("Top")); + WMAddPopUpButtonItem(panel->posP, _("Bottom")); + WMAddPopUpButtonItem(panel->posP, _("Top/left")); + WMAddPopUpButtonItem(panel->posP, _("Top/right")); + WMAddPopUpButtonItem(panel->posP, _("Bottom/left")); + WMAddPopUpButtonItem(panel->posP, _("Bottom/right")); WMMapSubwidgets(panel->navF); /***************** Dock/Clip *****************/ panel->dockF = WMCreateFrame(panel->frame); - WMResizeWidget(panel->dockF, 105, 200); - WMMoveWidget(panel->dockF, 400, 15); + WMResizeWidget(panel->dockF, 115, 210); + WMMoveWidget(panel->dockF, 390, 10); WMSetFrameTitle(panel->dockF, _("Dock/Clip")); panel->dockB = WMCreateButton(panel->dockF, WBTToggle); WMResizeWidget(panel->dockB, 64, 64); - WMMoveWidget(panel->dockB, 20, 30); + WMMoveWidget(panel->dockB, 25, 35); WMSetButtonImagePosition(panel->dockB, WIPImageOnly); path = LocateImage(DOCK_FILE); if (path) { @@ -242,7 +308,7 @@ createPanel(Panel *p) panel->clipB = WMCreateButton(panel->dockF, WBTToggle); WMResizeWidget(panel->clipB, 64, 64); - WMMoveWidget(panel->clipB, 20, 110); + WMMoveWidget(panel->clipB, 25, 120); WMSetButtonImagePosition(panel->clipB, WIPImageOnly); path = LocateImage(CLIP_FILE); if (path) { @@ -281,6 +347,9 @@ storeData(_Panel *panel) SetBoolForKey(!WMGetButtonSelected(panel->dockB), "DisableDock"); SetBoolForKey(!WMGetButtonSelected(panel->clipB), "DisableClip"); + + SetStringForKey(WSNamePositions[WMGetPopUpButtonSelectedItem(panel->posP)], + "WorkspaceNameDisplayPosition"); } diff --git a/WPrefs.app/po/Makefile.in b/WPrefs.app/po/Makefile.in index 248269b1..f0cb66b0 100644 --- a/WPrefs.app/po/Makefile.in +++ b/WPrefs.app/po/Makefile.in @@ -118,7 +118,7 @@ DIST_COMMON = README Makefile.am Makefile.in DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) -TAR = tar +TAR = gtar GZIP_ENV = --best all: all-redirect .SUFFIXES: diff --git a/WPrefs.app/tiff/Makefile.in b/WPrefs.app/tiff/Makefile.in index 95e2976e..276a00a9 100644 --- a/WPrefs.app/tiff/Makefile.in +++ b/WPrefs.app/tiff/Makefile.in @@ -108,7 +108,7 @@ DIST_COMMON = README Makefile.am Makefile.in DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) -TAR = tar +TAR = gtar GZIP_ENV = --best all: all-redirect .SUFFIXES: diff --git a/WPrefs.app/xpm/Makefile.in b/WPrefs.app/xpm/Makefile.in index 8059328c..ee435710 100644 --- a/WPrefs.app/xpm/Makefile.in +++ b/WPrefs.app/xpm/Makefile.in @@ -108,7 +108,7 @@ DIST_COMMON = Makefile.am Makefile.in DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) -TAR = tar +TAR = gtar GZIP_ENV = --best all: all-redirect .SUFFIXES: diff --git a/WindowMaker/Defaults/WMState.in b/WindowMaker/Defaults/WMState.in index 07d59f7d..bdcef36d 100644 --- a/WindowMaker/Defaults/WMState.in +++ b/WindowMaker/Defaults/WMState.in @@ -22,6 +22,7 @@ AutoLaunch = No; Forced = No; Position = "0,2"; + Lock = Yes; } ); Position = "-64,0"; diff --git a/WindowMaker/Styles/Emerald.style b/WindowMaker/Styles/Emerald.style index dd4ef93f..96d54a52 100644 --- a/WindowMaker/Styles/Emerald.style +++ b/WindowMaker/Styles/Emerald.style @@ -12,16 +12,16 @@ FTitleColor = "#ffffff"; PTitleColor = "#ffffff"; UTitleColor = "#d7d7d7"; - FTitleBack = (mdgradient, "#9e9aa6", "#051626", "#7391bb"); - PTitleBack = (mdgradient, "#9e9aa6", "#212526", "#474a70"); - UTitleBack = (mdgradient, "#9e9aa6", "#051c26", "#59999f"); - ResizebarBack = (mdgradient, "#9e9aa6", "#051c26", "#59999f"); + FTitleBack = (mdgradient, "#415979", "#051626", "#7391bb"); + PTitleBack = (mdgradient, "#384161", "#212526", "#474a70"); + UTitleBack = (mdgradient, "#386569", "#051c26", "#59999f"); + ResizebarBack = (mdgradient, "#386569", "#051c26", "#59999f"); MenuTitleColor = "#ffffff"; MenuTextColor = "#ffffff"; MenuDisabledColor = "#aeaeae"; - MenuTitleBack = (mdgradient, "#9e9aa6", "#051626", "#7391bb"); - MenuTextBack = (mdgradient, "#9e9aa6", "#051c26", "#59999f"); - IconBack = (mdgradient, "#9e9aa6", "#051626", "#496c83"); + MenuTitleBack = (mdgradient, "#415979", "#051626", "#7391bb"); + MenuTextBack = (mdgradient, "#386569", "#051c26", "#59999f"); + IconBack = (mdgradient, "#384161", "#212526", "#474a70"); IconTitleColor = white; IconTitleBack = "#18191f"; } diff --git a/src/DI.h b/src/DI.h new file mode 100644 index 00000000..ae8cd77f --- /dev/null +++ b/src/DI.h @@ -0,0 +1,266 @@ +/* + * DI.h - support for invariants (assertions) using the gdb debugger. + * + * Copyright (c) 1997 Phil Maker + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Id: DI.h,v 1.1.1.1 1997/11/23 11:45:50 pjm Exp + */ + +#ifndef _DI_h_ +#define _DI_h_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef WITHOUT_NANA + +/* + * nana-config.h - the system wide configuration file; we put the ifndef + * around it to avoid the file 5 million times during a compile. + */ + +#ifndef _nana_config_h_ +#include +#endif + +/* + * DI_LEVEL sets the level of invariant analogously to NDEBUG in assert.h + * + * DI_LEVEL == 2: invariants are always evaluated. + * DI_LEVEL == 1: evaluate invariants iff they have a true GUARD. + * DI_LEVEL == 0: invariants are never evaluated. + */ + +#ifndef DI_LEVEL /* define DEFAULT for DI_LEVEL */ +#define DI_LEVEL 1 +#endif + + + +/* + * DI_DEFAULT_GUARD - the default guard expression; an invariant is checked + * iff the guard is true. By default its always true. + */ + +#ifndef DI_DEFAULT_GUARD +#define DI_DEFAULT_GUARD 1 +#endif + +/* + * DI_DEFAULT_PARAMS - the default value to be passed as the second argument + * to the handler macro when an invariant fails. + */ + +#ifndef DI_DEFAULT_PARAMS +#define DI_DEFAULT_PARAMS /* nothing */ +#endif + +/* + * DI_DEFAULT_HANDLER - called when an error is detected by DI; + */ + +#ifndef DI_DEFAULT_HANDLER /* define default handler */ + +#define DI_DEFAULT_HANDLER(e,f,l,p) \ + @@echo e has failed at f:l with p\n@@ \ + @@where@@ /* stack backtrace */ + +#endif /* DI_DEFAULT_HANDLER */ + +/* + * DI_MAKE_VALID_BREAKPOINT(e) - called whenever we generate a DI breakpoint; + * the aim is to make sure a breakpoint can be set at the current location + * and that any expressions will be evaluated by gdb correctly. + * This is the portable default; an architecture specific version + * is generated by the configure script into nana-config.h + */ + +#ifndef DI_MAKE_VALID_BREAKPOINT +static volatile int _di_target; + +#define DI_MAKE_VALID_BREAKPOINT(e) _di_target = 0 +#endif + +/* + * _DIGHPS - implements the DI macros, it comes in two variants: + * + * ifdefined(_NANA_FILTER_) then we are generating debugger commands + * else generating C text. + */ + +#if DI_LEVEL == 2 /* always check the assertion */ +#ifdef _NANA_FILTER_ +#define _DIGHPS(e,g,h,p,s) \ + @@break @__FILE__:__LINE__@@ \ + @@condition $bpnum (!(e))@@ \ + @@command $bpnum@@ \ + @@silent@@ \ + h(s,f,l,p) \ + @@end@@ +#else +#define _DIGHPS(e,g,h,p,s) DI_MAKE_VALID_BREAKPOINT(e) +#endif /* _NANA_FILTER_ */ + +#elif DI_LEVEL == 1 /* check it iff g is true */ + +#ifdef _NANA_FILTER_ +#define _DIGHPS(e,g,h,p,s) \ + @@break @__FILE__:__LINE__@@ \ + @@condition $bpnum (g) && (!(e))@@ \ + @@command $bpnum@@ \ + @@silent@@ \ + h(s,f,l,p) \ + @@end@@ +#else +#define _DIGHPS(e,g,h,p,s) DI_MAKE_VALID_BREAKPOINT(e) +#endif /* _NANA_FILTER_ */ + +#elif DI_LEVEL == 0 /* no assertions so just remove them */ +#define _DIGHPS(e,g,h,p,s) /* nothing */ +#endif /* DI_LEVEL */ + + +/* + * DSG(e,g), DS(e) - are used to set variables in the debugger from + * within C programs. These convenience variables can then be + * used in invariants later on to refer to the previous state + * of the program. + * + * DS($x = x); ....; DI($x + 10 == x); + */ + +#if DI_LEVEL == 2 +#ifdef _NANA_FILTER_ +#define DSG(e,g) \ + @@break @__FILE__:__LINE__@@ \ + @@command@@ \ + @@silent@@ \ + @@set e@@ \ + @@cont@@ \ + @@end@@ +#else +#define DSG(e,g) DI_MAKE_VALID_BREAKPOINT(e) +#endif + +#elif DI_LEVEL == 1 +#ifdef _NANA_FILTER_ +#define DSG(e,g) \ + @@break @__FILE__:__LINE__ if g@@ \ + @@command@@ \ + @@silent@@ \ + @@set e@@ \ + @@cont@@ \ + @@end@@ +#else +#define DSG(e,g) DI_MAKE_VALID_BREAKPOINT(e) +#endif /* _NANA_FILTER_ */ + +#elif DI_LEVEL == 0 +#define DSG(e,g) /* nothing */ +#else +error DI_LEVEL should be 0 or 1 or 2 +#endif + +#define DS(e) DSG(e,DI_DEFAULT_GUARD) + +/* + * And all the user macros; these are used to put in the default arguments. + * The name is used to determine the arguments; e.g. DIGH takes an expression + * to check; a guard and a handler as parameters. The letters in the names + * are in ascending order (i.e. DIGH(...) not DIHG(...)). + * + * DI[G][H][P] - it must be true (e) with an optional guard, handler and + * parameter for the handler. + * DN[G][H][P] - as for DI... except that (e) must never ever be true. + */ + +#define DI(e) \ + _DIGHPS(e,DI_DEFAULT_GUARD,DI_DEFAULT_HANDLER,DI_DEFAULT_PARAMS,"DI("#e")") +#define DIG(e,g) \ + _DIGHPS(e,g,DI_DEFAULT_HANDLER,DI_DEFAULT_PARAMS,"DI("#e")") +#define DIH(e,h) \ + _DIGHPS(e,DI_DEFAULT_GUARD,h,DI_DEFAULT_PARAMS,"DI("#e")") +#define DIP(e,p) \ + _DIGHPS(e,DI_DEFAULT_GUARD,DI_DEFAULT_HANDLER,p,"DI("#e")") +#define DIGH(e,g,h) \ + _DIGHPS(e,g,h,DI_DEFAULT_PARAMS,"DI("#e")") +#define DIGP(e,g,p) \ + _DIGHPS(e,g,DI_DEFAULT_HANDLER,p,"DI("#e")") +#define DIHP(e,h,p) \ + _DIGHPS(e,DI_DEFAULT_GUARD,h,p,"DI("#e")") +#define DIGHP(e,g,h,p) \ + _DIGHPS(e,g,h,p,"DI("#e")") + +#define DN(e) \ + _DIGHPS((!(e)),DI_DEFAULT_GUARD,DI_DEFAULT_HANDLER,DI_DEFAULT_PARAMS,"DN("#e")") +#define DNG(e,g) \ + _DIGHPS((!(e)),g,DI_DEFAULT_HANDLER,DI_DEFAULT_PARAMS,"DN("#e")") +#define DNH(e,h) \ + _DIGHPS((!(e)),DI_DEFAULT_GUARD,h,DI_DEFAULT_PARAMS,"DN("#e")") +#define DNP(e,p) \ + _DIGHPS((!(e)),DI_DEFAULT_GUARD,DI_DEFAULT_HANDLER,p,"DN("#e")") +#define DNGH(e,g,h) \ + _DIGHPS((!(e)),g,h,DI_DEFAULT_PARAMS,"DN("#e")") +#define DNGP(e,g,p) \ + _DIGHPS((!(e)),g,DI_DEFAULT_HANDLER,p,"DN("#e")") +#define DNHP(e,h,p) \ + _DIGHPS((!(e)),DI_DEFAULT_GUARD,h,p,"DN("#e")") +#define DNGHP(e,g,h,p) \ + _DIGHPS((!(e)),g,h,p,"DN("#e")") + +#else /* defined(WITHOUT_NANA) */ + +#define DI(e) /* empty */ +#define DIG(e,g) /* empty */ +#define DIH(e,h) /* empty */ +#define DIP(e,p) /* empty */ +#define DIGH(e,g,h) /* empty */ +#define DIGP(e,g,p) /* empty */ +#define DIHP(e,h,p) /* empty */ +#define DIGHP(e,g,h,p) /* empty */ + +#define DN(e) /* empty */ +#define DNG(e,g) /* empty */ +#define DNH(e,h) /* empty */ +#define DNP(e,p) /* empty */ +#define DNGH(e,g,h) /* empty */ +#define DNGP(e,g,p) /* empty */ +#define DNHP(e,h,p) /* empty */ +#define DNGHP(e,g,h,p) /* empty */ + +#define DS(e) /* empty */ +#define DSG(e,g) /* empty */ + + +#endif /* !defined(WITHOUT_NANA) */ +#ifdef __cplusplus +} +#endif + +#endif /* _DI_h_ */ + + + diff --git a/src/DL.h b/src/DL.h new file mode 100644 index 00000000..add754ed --- /dev/null +++ b/src/DL.h @@ -0,0 +1,227 @@ +/* + * DL.h - support for logging (printf...) style debugging using gdb. + * + * Copyright (c) 1997 Phil Maker + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Id: DL.h,v 1.1.1.1 1997/11/23 11:45:50 pjm Exp + */ + +#ifndef _DL_h_ +#define _DL_h_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef WITHOUT_NANA + +/* + * nana-config.h - the system wide configuration file; we put the ifndef + * around it to avoid the file 5 million times during a compile. + */ + +#ifndef _nana_config_h_ +#include +#endif + +/* + * DL_MAKE_VALID_BREAKPOINT() - used to make sure that we can put a + * breakpoint at this location. We default to a portable C expression + * which simply does an assignment. The configure script may override + * this (on an architecture basis) and replace it with something + * like asm("nop"); + */ + +#ifndef DL_MAKE_VALID_BREAKPOINT +static volatile int _dl_target; + +#define DL_MAKE_VALID_BREAKPOINT() _dl_target = 0 +#endif + +/* + * DL_LEVEL sets the level of logging analogously to NDEBUG in assert.h + * + * DL_LEVEL == 2: always print. + * DL_LEVEL == 1: print iff the guard is true. + * DL_LEVEL == 0: never print. + */ + +#ifndef DL_LEVEL /* define DEFAULT for DL_LEVEL */ +#define DL_LEVEL 1 +#endif + +/* + * DL_DEFAULT_HANDLER - the default print handler; by default we just + * the debugger printf. + * + * @@call (void) printf(f)@@ + */ + +#ifndef DL_DEFAULT_HANDLER /* define default handler */ +#define DL_DEFAULT_HANDLER(g,h,p,f...) @@printf f@@ +#endif /* DL_DEFAULT_HANDLER */ + +/* + * DL_DEFAULT_GUARD - the default guard expression; a message is printed + * iff the guard is true. By default its always true. + */ + +#ifndef DL_DEFAULT_GUARD +#define DL_DEFAULT_GUARD (1) +#endif + +/* + * DL_DEFAULT_PARAMS - the default value to be passed as the second argument + * to the handler macro when an invariant fails. + */ + + +#ifndef DL_DEFAULT_PARAMS +#define DL_DEFAULT_PARAMS stderr +#endif + +/* + * DL_SHOW_TIME - if its defined then each message gets a timestamp in front. + */ + +#ifdef DL_SHOW_TIME + +unsigned long _L_gettime(void); /* returns the current time */ + +#define _DL_SHOWTIME(h,p) @@call (void) h (p, "%-8ld ", _L_gettime())@@ +#else + +#define _DL_SHOWTIME(h,p) /* nothing */ + +#endif /* DL_SHOWTIME */ + +/* + * DLGHP(g,h,p,f...) - print a log message. + * + * g - the guard; print the message iff this is true + * h - the handler function that does the actual printing + * p - a parameter for the handler function; e.g. a file descriptor. + * f - the format and the data... + */ + +#if DL_LEVEL == 2 /* always log the message */ +#ifdef _NANA_FILTER_ +#define DLGHP(g,h,p,f...) \ + do { \ + @@break @__FILE__:__LINE__@@ \ + @@command $bpnum@@ \ + @@silent@@ \ + _DL_SHOWTIME(h,p); \ + DL_DEFAULT_HANDLER(g,h,p,##f); \ + @@cont@@ \ + @@end@@ \ + } while(0) +#else +#define DLGHP(g,h,p,f...) DL_MAKE_VALID_BREAKPOINT() +#endif + +#elif DL_LEVEL == 1 /* log it iff the guard is true */ + +#ifdef _NANA_FILTER_ +#define DLGHP(g,h,p,f...) \ + do { \ + if(g) { \ + @@break @__FILE__:__LINE__@@ \ + @@condition $bpnum g@@ \ + @@command $bpnum@@ \ + @@silent@@ \ + _DL_SHOWTIME(h,p); \ + DL_DEFAULT_HANDLER(g,h,p,##f); \ + @@cont@@ \ + @@end@@ \ + } \ + } while(0) +#else +#define DLGHP(g,h,p,f...) DL_MAKE_VALID_BREAKPOINT() +#endif + +#elif DL_LEVEL == 0 /* no logging so ignore them */ +#define DLGHP(g,h,p,f...) /* nothing */ +#endif /* DL_LEVEL */ + +/* + * And the user routines. + */ + +#define DL(f...) \ + DLGHP(DL_DEFAULT_GUARD,DL_DEFAULT_HANDLER,DL_DEFAULT_PARAMS,##f) +#define DLG(g,f...) \ + DLGHP(g,DL_DEFAULT_HANDLER,DL_DEFAULT_PARAMS,##f) +#define DLH(h,f...) \ + DLGHP(DL_DEFAULT_GUARD,h,DL_DEFAULT_PARAMS,##f) +#define DLP(p,f...) \ + DLGHP(DL_DEFAULT_GUARD,DL_DEFAULT_HANDLER,p,##f) +#define DLGP(g,p,f...) \ + DLGHP(g,DL_DEFAULT_HANDLER,p,##f) +#define DLHP(h,p,f...) \ + DLGHP(DL_DEFAULT_GUARD,h,p,##f) + + +/* + * V* - since the DL* macros take a variable numbers of arguments we + * have problems compiling calls to L with C preprocessors other + * than GNU cccp. The V* macros are called using a bracketed arglist, e.g. + * VDL((s,x,y)) + * + * if we are compiling with GNU C then they simply call the normal + * varargs macros. if we are not using GNU C then they map to empty. + */ + +#define VDL(a) DL a +#define VDLG(a) DLG a +#define VDLH(a) DLH a +#define VDLP(a) DLP a +#define VDLGP(a) DLGP a +#define VDLHP(a) DLHP a +#define VDLGHP(a) DLGHP a + +#else /* defined(WITHOUT_NANA) */ + +#define VDL(a) /* empty */ +#define VDLG(a) /* empty */ +#define VDLH(a) /* empty */ +#define VDLP(a) /* empty */ +#define VDLGP(a) /* empty */ +#define VDLHP(a) /* empty */ +#define VDLGHP(a) /* empty */ + +#endif /* !defined(WITHOUT_NANA) */ + + +#ifdef __cplusplus +} +#endif + +#endif /* _DL_h_ */ + + + + + diff --git a/src/GDB.h b/src/GDB.h new file mode 100644 index 00000000..97bc4d01 --- /dev/null +++ b/src/GDB.h @@ -0,0 +1,90 @@ +/* + * GDB.h - basic support macros for putting gdb commands in C. + * + * Copyright (c) 1997 Phil Maker + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Id: GDB.h,v 1.1.1.1 1997/11/23 11:45:50 pjm Exp + */ + +#ifndef _GDB_h_ +#define _GDB_h_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifndef WITHOUT_NANA + +/* + * nana-config.h - the system wide configuration file; we put the ifndef + * around it to avoid the file 5 million times during a compile. + */ + +#ifndef _nana_config_h_ +#include +#endif + +/* + * GDB(c) - just puts the command into the output of nana + * c should be a single line of text + */ + +#ifdef _NANA_FILTER_ +#define GDB(command) @@command@@ +#else +#define GDB(command) /* nothing */ +#endif + +/* + * GDBCALL(c) - calls a gdb command whenever control reaches the + * current line. + */ + +#ifdef _NANA_FILTER_ +#define GDBCALL(comd) \ + @@break @__FILE__:__LINE__@@ \ + @@command@@ \ + @@silent@@ \ + @@comd@@ \ + @@cont@@ \ + @@end@@ +#else +#define GDBCALL(c) DI_MAKE_VALID_BREAKPOINT(1) +#endif + +#else /* defined(WITHOUT_NANA) */ + +#define GDB(e) /* empty */ +#define GDBCALL(e) /* empty */ + +#endif /* !defined(WITHOUT_NANA) */ + +#ifdef __cplusplus +} +#endif + +#endif /* _GDB_h_ */ + diff --git a/src/I.h b/src/I.h new file mode 100644 index 00000000..054c94a4 --- /dev/null +++ b/src/I.h @@ -0,0 +1,234 @@ +/* + * I.h - support for invariants (assertions) using C code. + * + * Copyright (c) 1997 Phil Maker + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Id: I.h,v 1.1.1.1 1997/11/23 11:45:50 pjm Exp + */ + + +#ifndef _I_h_ +#define _I_h_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef WITHOUT_NANA + +/* + * nana-config.h - the system wide configuration file; we put the ifndef + * around it to avoid the file 5 million times during a compile. + */ + +#ifndef _nana_config_h_ +#include +#endif + +/* + * I_LEVEL sets the level of invariant analogously to NDEBUG in assert.h + * + * I_LEVEL == 2: invariants are always evaluated. + * I_LEVEL == 1: evaluate invariants iff they have a true GUARD. + * I_LEVEL == 0: invariants are never evaluated. + */ + +#ifndef I_LEVEL /* define DEFAULT for I_LEVEL */ +#define I_LEVEL 1 +#endif + + +/* + * I_DEFAULT_GUARD - the default guard expression; an invariant is checked + * iff the guard is true. By default its always true. + */ + +#ifndef I_DEFAULT_GUARD +#define I_DEFAULT_GUARD (1) +#endif + +/* + * I_DEFAULT_PARAMS - the default value to be passed as the second argument + * to the handler macro when an invariant fails. + */ + + +#ifndef I_DEFAULT_PARAMS +#define I_DEFAULT_PARAMS /* nothing */ +#endif + +/* + * I_DEFAULT_HANDLER(expr,file,line,param) - called when an error is detected. + */ + +#ifndef I_DEFAULT_HANDLER /* define default handler */ +void _I_default_handler(char *expr, char *file, int line); + +#define I_DEFAULT_HANDLER(expr,file,line,param) \ + _I_default_handler(expr,__FILE__,__LINE__) + +#endif /* I_DEFAULT_HANDLER */ + +/* + * _IGHPS(e,g,h,p,s) - implements the general case for invariant handling. + * + * e - expression to check + * g - guard, check only if this is true (subject to I_DEFAULT_LEVEL) + * h - handler, called when a failure is detected + * p - parameter to pass off to the handler + * s - string representation of the expression (e.g. "I(x>=i)") + * + * _ISD(e) - generates a data declaration for use in postconditions + * _ISG(e,g) - generates a guarded assignment to a data declaration + * for use in postconditions + * + * N.B. The two types are necessary since we cannot guard a C declaration + * with an if statement. + */ + +#if I_LEVEL == 2 /* always check the assertion */ +#define _IGHPS(e,g,h,p,s) \ + do { \ + if(!(e)) { \ + h (s, __FILE__, __LINE__, p); \ + } \ + } while(0) + +#define _ID(e) e +#define _ISG(e,g) e +#elif I_LEVEL == 1 /* check it iff g is true */ +#define _IGHPS(e,g,h,p,s) \ + do { \ + if(g) { \ + if(!(e)) { \ + h (s, __FILE__, __LINE__, p); \ + } \ + } \ + } while(0) +#define _ID(e) e +#define _ISG(e,g) \ + do { \ + if(g) { \ + e; \ + } \ + } while(0) +#elif I_LEVEL == 0 /* no assertions so just remove them */ +#define _IGHPS(e,g,h,p,s) /* nothing */ +#define _ID(e) /* nothing */ +#define _ISG(e,g) /* nothing */ +#endif /* I_LEVEL */ + +/* + * And all the user macros; these are used to put in the default arguments. + * The name is used to determine the arguments; e.g. IGH takes an expression + * to check; a guard and a handler as parameters. The letters in the names + * are in ascending order (i.e. IGH(...) not IHG(...)). + * + * I[G][H][P] - it must be true (e) with an optional guard, handler and + * parameter for the handler. + * N[G][H][P] - as for I... except that (e) must never ever be true. + */ + +#define I(e) \ + _IGHPS(e,I_DEFAULT_GUARD,I_DEFAULT_HANDLER,I_DEFAULT_PARAMS,"I("#e")") +#define IG(e,g) \ + _IGHPS(e,g,I_DEFAULT_HANDLER,I_DEFAULT_PARAMS,"I("#e")") +#define IH(e,h) \ + _IGHPS(e,I_DEFAULT_GUARD,h,I_DEFAULT_PARAMS,"I("#e")") +#define IP(e,p) \ + _IGHPS(e,I_DEFAULT_GUARD,I_DEFAULT_HANDLER,p,"I("#e")") +#define IGH(e,g,h) \ + _IGHPS(e,g,h,I_DEFAULT_PARAMS,"I("#e")") +#define IGP(e,g,p) \ + _IGHPS(e,g,I_DEFAULT_HANDLER,p,"I("#e")") +#define IHP(e,h,p) \ + _IGHPS(e,I_DEFAULT_GUARD,h,p,"I("#e")") +#define IGHP(e,g,h,p) \ + _IGHPS(e,g,h,p,"I("#e")") + +#define N(e) \ + _IGHPS((!(e)),I_DEFAULT_GUARD,I_DEFAULT_HANDLER,I_DEFAULT_PARAMS,"N("#e")") +#define NG(e,g) \ + _IGHPS((!(e)),g,I_DEFAULT_HANDLER,I_DEFAULT_PARAMS,"N("#e")") +#define NH(e,h) \ + _IGHPS((!(e)),I_DEFAULT_GUARD,h,I_DEFAULT_PARAMS,"N("#e")") +#define NP(e,p) \ + _IGHPS((!(e)),I_DEFAULT_GUARD,I_DEFAULT_HANDLER,p,"N("#e")") +#define NGH(e,g,h) \ + _IGHPS((!(e)),g,h,I_DEFAULT_PARAMS,"N("#e")") +#define NGP(e,g,p) \ + _IGHPS((!(e)),g,I_DEFAULT_HANDLER,p,"N("#e")") +#define NHP(e,h,p) \ + _IGHPS((!(e)),I_DEFAULT_GUARD,h,p,"N("#e")") +#define NGHP(e,g,h,p) \ + _IGHPS((!(e)),g,h,p,"N("#e")") + +/* + * ID(e) - declares a variable to be used to store values for a postcondition. + * This can include an initialiser. + * Note this declaration is not disabled by I_DEFAULT_GUARD + * IS(e) - an assignment to a variable. This statement is enabled by + * I_DEFAULT_GUARD + * ISG(e,g) - the guarded version of IS + */ + +#define ID(e) _ID(e) +#define IS(e) _ISG(e,I_DEFAULT_GUARD) +#define ISG(e,g) _ISG(e,g) + +#else /* defined(WITHOUT_NANA) */ + +#define I(e) /* empty */ +#define IG(e,g) /* empty */ +#define IH(e,h) /* empty */ +#define IP(e,p) /* empty */ +#define IGH(e,g,h) /* empty */ +#define IGP(e,g,p) /* empty */ +#define IHP(e,h,p) /* empty */ +#define IGHP(e,g,h,p) /* empty */ + +#define N(e) /* empty */ +#define NG(e,g) /* empty */ +#define NH(e,h) /* empty */ +#define NP(e,p) /* empty */ +#define NGH(e,g,h) /* empty */ +#define NGP(e,g,p) /* empty */ +#define NHP(e,h,p) /* empty */ +#define NGHP(e,g,h,p) /* empty */ + +#define ID(e) /* empty */ +#define IS(e) /* empty */ +#define ISG(e,g) /* empty */ + +#endif /* !defined(WITHOUT_NANA) */ + +#ifdef __cplusplus +} +#endif + +#endif /* _I_h_ */ + + + diff --git a/src/L.h b/src/L.h new file mode 100644 index 00000000..3777b1fd --- /dev/null +++ b/src/L.h @@ -0,0 +1,207 @@ +/* + * L.h - support for logging (printf...) style debugging. + * + * Copyright (c) 1997 Phil Maker + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Id: L.h,v 1.2 1998/01/17 10:57:03 pjm Exp + */ + + +#ifndef _L_h_ +#define _L_h_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef WITHOUT_NANA + +/* + * nana-config.h - the system wide configuration file; we put the ifndef + * around it to avoid the file 5 million times during a compile. + */ + +#ifndef _nana_config_h_ +#include +#endif + +/* + * L_LEVEL sets the level of logging analogously to NDEBUG in assert.h + * + * L_LEVEL == 2: always print. + * L_LEVEL == 1: print iff the guard is true. + * L_LEVEL == 0: never print. + */ + +#ifndef L_LEVEL /* define DEFAULT for L_LEVEL */ +#define L_LEVEL 1 +#endif + +/* + * L_DEFAULT_HANDLER - the default print handler; by default we just + * use fprintf. + */ + +#ifndef L_DEFAULT_HANDLER /* define default handler */ +#define L_DEFAULT_HANDLER fprintf +#endif /* L_DEFAULT_HANDLER */ + +/* + * L_DEFAULT_GUARD - the default guard expression; a message is printed + * iff the guard is true. By default its always true. + */ + +#ifndef L_DEFAULT_GUARD +#define L_DEFAULT_GUARD (1) +#endif + +/* + * L_DEFAULT_PARAMS - the default value to be passed as the second argument + * to the handler macro when an invariant fails. + */ + + +#ifndef L_DEFAULT_PARAMS +#define L_DEFAULT_PARAMS stderr +#endif + +/* + * L_SHOW_TIME_FORMAT - the format string for printing the time. + */ + +#ifndef L_SHOW_TIME_FORMAT +#define L_SHOW_TIME_FORMAT "%.6f:\t" +#endif + +/* + * L_SHOW_TIME_NOW - the function to measure the time. + */ + +#ifndef L_SHOW_TIME_NOW +#include +#define L_SHOW_TIME_NOW now() +#endif + +/* + * L_SHOW_TIME - if it is defined then we will put time stamps at the + * beginning of each message using L_SHOW_TIME_FORMAT and L_SHOW_TIME_NOW. + */ + +#ifdef L_SHOW_TIME +#define _L_SHOWTIME(h,p) h (p, L_SHOW_TIME_FORMAT, L_SHOW_TIME_NOW) +#else +#define _L_SHOWTIME(h,p) /* nothing */ +#endif /* L_SHOWTIME */ + +/* + * LGHP(g,h,p, f...) - print a log message. + * + * g - the guard; print the message iff this is true + * h - the handler function that does the actual printing + * p - a parameter for the handler function; e.g. a file descriptor. + * f - printf style format string; we put this at the end since we + * we need to be able have 1 or more arguments (e.g. L("x") and + * L("%d",10); we use GNU cccp preprocessor varargs extension + * to handle multiple arguments. + */ + +#ifndef __GNUC__ +error you need gcc for this stuff to work properly +#endif + +#if L_LEVEL == 2 /* always log the message */ +#define LGHP(g,h,p,f...) \ + do { \ + _L_SHOWTIME(h,p); \ + h (p, ##f); \ + } while(0) + +#elif L_LEVEL == 1 /* log it iff the guard is true */ +#define LGHP(g,h,p,f...) \ + do { \ + if(g) { \ + _L_SHOWTIME(h,p); \ + h (p, ##f); \ + } \ + } while(0) +#elif L_LEVEL == 0 /* no logging so ignore them */ +#define LGHP(g,h,p,f...) /* nothing */ +#endif /* L_LEVEL */ + +/* + * User routines. + */ + +#define L(f...) \ + LGHP(L_DEFAULT_GUARD,L_DEFAULT_HANDLER,L_DEFAULT_PARAMS,##f) +#define LG(g,f...) \ + LGHP(g,L_DEFAULT_HANDLER,L_DEFAULT_PARAMS,##f) +#define LH(h,f...) \ + LGHP(L_DEFAULT_GUARD,h,L_DEFAULT_PARAMS,##f) +#define LP(p,f...) \ + LGHP(L_DEFAULT_GUARD,L_DEFAULT_HANDLER,p,##f) +#define LGP(g,p,f...) \ + LGHP(g,L_DEFAULT_HANDLER,p,##f) +#define LHP(h,p,f...) \ + LGHP(L_DEFAULT_GUARD,h,p,##f) + +/* + * V* - since the L* macros take a variable numbers of arguments we + * have problems compiling calls to L with C preprocessors other + * than GNU cccp. The V* macros are called using a bracketed + * argument list, e.g. VL((f,x,s)); + * + * if we are compiling with GNU C then they simpily call the normal + * varargs macro. if we are not using GNU CC then they map to empty. + */ + +#define VL(a) L a +#define VLG(a) LG a +#define VLH(a) LH a +#define VLP(a) LP a +#define VLGP(a) LGP a +#define VLHP(a) LHP a +#define VLGHP(a) LGHP a + +#else /* defined(WITHOUT_NANA) */ + +#define VL(a) /* empty */ +#define VLG(a) /* empty */ +#define VLH(a) /* empty */ +#define VLP(a) /* empty */ +#define VLGP(a) /* empty */ +#define VLHP(a) /* empty */ +#define VLGHP(a) /* empty */ + +#endif /* !defined(WITHOUT_NANA) */ + +#ifdef __cplusplus +} +#endif + +#endif /* _L_h_ */ + + + diff --git a/src/Makefile.am b/src/Makefile.am index c2a283cb..5394147d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -4,7 +4,8 @@ BUILT_SOURCES = wconfig.h bin_PROGRAMS = wmaker -EXTRA_DIST = wmnotify.c wmnotdef.h wmnotify.h +EXTRA_DIST = wmnotify.c wmnotdef.h wmnotify.h\ + DI.h DL.h I.h L.h Q.h GDB.h nana.h wmaker_SOURCES = \ diff --git a/src/Makefile.in b/src/Makefile.in index a5d5dacd..58f464ee 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -98,7 +98,8 @@ BUILT_SOURCES = wconfig.h bin_PROGRAMS = wmaker -EXTRA_DIST = wmnotify.c wmnotdef.h wmnotify.h +EXTRA_DIST = wmnotify.c wmnotdef.h wmnotify.h DI.h DL.h I.h L.h Q.h GDB.h nana.h + wmaker_SOURCES = GNUstep.h WindowMaker.h actions.c actions.h appicon.c appicon.h application.c application.h appmenu.c appmenu.h balloon.c balloon.h client.c client.h colormap.c def_pixmaps.h defaults.c defaults.h dialog.c dialog.h dock.c dockedapp.c dock.h event.c extend_pixmaps.h framewin.c framewin.h gnome.c gnome.h funcs.h icon.c icon.h keybind.h kwm.h kwm.c main.c menu.c menu.h misc.c motif.c motif.h moveres.c openlook.c openlook.h pixmap.c pixmap.h placement.c plugin.c plugin.h properties.c properties.h proplist.c resources.c resources.h rootmenu.c screen.c screen.h session.h session.c shutdown.c stacking.c stacking.h startup.c superfluous.c superfluous.h switchmenu.c texture.c texture.h usermenu.c usermenu.h xdnd.h xdnd.c xmodifier.h xmodifier.c xutil.c xutil.h wconfig.h wcore.c wcore.h wdefaults.c wdefaults.h window.c window.h winmenu.c winspector.h winspector.c workspace.c workspace.h wmsound.c wmsound.h text.c text.h @@ -144,7 +145,7 @@ wconfig.h.in DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) -TAR = tar +TAR = gtar GZIP_ENV = --best SOURCES = $(wmaker_SOURCES) OBJECTS = $(wmaker_OBJECTS) diff --git a/src/Q.h b/src/Q.h new file mode 100644 index 00000000..54bd037d --- /dev/null +++ b/src/Q.h @@ -0,0 +1,160 @@ +/* + * Q.h - support for ForAll, ThereExists, Count and Sum (i.e. quantifiers). + * + * Portability: this file uses the GNU C Statement Expression extension and + * so requires GCC/C++ with extensions enabled (this is checked by the + * header file). + * + * Copyright (c) 1997 Phil Maker + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Id: Q.h,v 1.1.1.1 1997/11/23 11:45:50 pjm Exp + */ + + +#ifndef _Q_h_ +#define _Q_h_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef WITHOUT_NANA + +#ifndef __GNUC__ /* not compiling with GCC/G++ extensions */ +error +This file requires the GNU C/C++ "statement expression" extension; +so use GCC/G++ with extensions enabled. If you have not got GCC then +misery follows though we may be able to do something about it +in the future. +#endif + +/* + * A(i,c,n,a) - true iff a is true for all values generated by for(i;c;n) + * + * Note: local variables can be introduced in this statement even in C. + */ + +#define A(i,c,n,a) /* ForAll */ \ + ({ \ + int _A_result = 1; \ + i; \ + while(c) { \ + if(!(a)) { \ + _A_result = 0; \ + break; \ + } \ + n; \ + } \ + _A_result; \ + }) + +/* + * E(i,c,n,a) - true iff exists any true a for values generated by for(i;c;n) + */ + +#define E(i,c,n,a) /* Exists */ \ + ({ \ + int _E_result = 0; \ + i; \ + while(c) { \ + if(a) { \ + _E_result = 1; \ + break; \ + } \ + n; \ + } \ + _E_result; \ + }) + +/* + * C(i,c,n,a) - count the number of times a is true over the values + * generated by for(i;c;n) + */ + +#define C(i,c,n,a) /* Count */ \ + ({ \ + long _C_result = 0; \ + i; \ + while(c) { \ + if(a) { \ + _C_result++; \ + } \ + n; \ + } \ + _C_result; \ + }) + +/* + * E1(i,c,n,a) - exists a single value generated by for(i;c;n) + * suchthat i is true. + */ + +#define E1(i,c,n,a) (C(i,c,n,a) == 1) /* There Exists 1 */ + +/* + * S(i,c,n,v) - sum of v over the values generated by for(i;c;n) + */ + +#define S(i,c,n,v) \ + ({ \ + i; \ + typeof(v) _S_result = 0; \ + while(c) { \ + _S_result += (v); \ + n; \ + } \ + _S_result; \ + }) + +/* + * P(i,c,n,v) - product of v over the values generated by for(i;c;n) + */ + +#define P(i,c,n,v) \ + ({ \ + i; \ + typeof(v) _P_result = 1; \ + while(c) { \ + _P_result *= (v); \ + n; \ + } \ + _P_result; \ + }) + +#else /* defined(WITHOUT_NANA) */ + +/* + * we don't produce any empty stubs for Q.h when compiling without nana + * since calls to A(...), etc should only occur in stubbed out code such + * as I(...). + */ + +#endif /* !defined(WITHOUT_NANA) */ +#ifdef __cplusplus +} +#endif + +#endif /* _Q_h_ */ + diff --git a/src/WindowMaker.h b/src/WindowMaker.h index 5aa85b6c..fc362950 100644 --- a/src/WindowMaker.h +++ b/src/WindowMaker.h @@ -271,6 +271,8 @@ typedef struct WPreferences { /* paths to find pixmaps */ char *icon_path; /* : separated list of */ /* paths to find icons */ + + char *logger_shell; /* shell to log child stdi/o */ RImage *button_images; /* titlebar button images */ diff --git a/src/appicon.h b/src/appicon.h index a328dfef..d72371d2 100644 --- a/src/appicon.h +++ b/src/appicon.h @@ -91,6 +91,9 @@ typedef struct WAppIcon { unsigned int destroyed:1; /* appicon was destroyed */ unsigned int buggy_app:1; /* do not make dock rely on hints * set by app */ + + unsigned int lock:1; /* do not allow to be destroyed */ + #ifdef REDUCE_APPICONS unsigned int num_apps; /* length of applist */ #endif diff --git a/src/dock.c b/src/dock.c index b269e1f9..f80d25ba 100644 --- a/src/dock.c +++ b/src/dock.c @@ -100,7 +100,8 @@ static proplist_t dCommand=NULL; #ifdef OFFIX_DND static proplist_t dDropCommand=NULL; #endif -static proplist_t dAutoLaunch, dName, dForced, dBuggyApplication, dYes, dNo; +static proplist_t dAutoLaunch, dLock; +static proplist_t dName, dForced, dBuggyApplication, dYes, dNo; static proplist_t dHost, dDock, dClip; static proplist_t dAutoAttractIcons; @@ -169,6 +170,7 @@ make_keys() #ifdef OFFIX_DND dDropCommand = PLRetain(PLMakeString("DropCommand")); #endif + dLock = PLRetain(PLMakeString("Lock")); dAutoLaunch = PLRetain(PLMakeString("AutoLaunch")); dName = PLRetain(PLMakeString("Name")); dForced = PLRetain(PLMakeString("Forced")); @@ -1327,7 +1329,7 @@ static proplist_t make_icon_state(WAppIcon *btn) { proplist_t node = NULL; - proplist_t command, autolaunch, name, forced, host, position, buggy; + proplist_t command, autolaunch, lock, name, forced, host, position, buggy; proplist_t omnipresent; char *tmp; char buffer[64]; @@ -1340,6 +1342,8 @@ make_icon_state(WAppIcon *btn) autolaunch = btn->auto_launch ? dYes : dNo; + lock = btn->lock ? dYes : dNo; + tmp = EscapeWM_CLASS(btn->wm_instance, btn->wm_class); name = PLMakeString(tmp); @@ -1359,6 +1363,7 @@ make_icon_state(WAppIcon *btn) node = PLMakeDictionaryFromEntries(dCommand, command, dName, name, dAutoLaunch, autolaunch, + dLock, lock, dForced, forced, dBuggyApplication, buggy, dPosition, position, @@ -1511,6 +1516,22 @@ wClipSaveWorkspaceState(WScreen *scr, int workspace) } +static Bool +getBooleanDockValue(proplist_t value, proplist_t key) +{ + if (value) { + if (PLIsString(value)) { + if (strcasecmp(PLGetString(value), "YES")==0) + return True; + } else { + wwarning(_("bad value in docked icon state info %s"), + PLGetString(key)); + } + } + return False; +} + + static WAppIcon* restore_icon_state(WScreen *scr, proplist_t info, int type, int index) { @@ -1579,44 +1600,22 @@ restore_icon_state(WScreen *scr, proplist_t info, int type, int index) /* check auto launch */ value = PLGetDictionaryEntry(info, dAutoLaunch); - aicon->auto_launch = 0; - if (value) { - if (PLIsString(value)) { - if (strcasecmp(PLGetString(value), "YES")==0) - aicon->auto_launch = 1; - } else { - wwarning(_("bad value in docked icon state info %s"), - PLGetString(dAutoLaunch)); - } - } + aicon->auto_launch = getBooleanDockValue(value, dAutoLaunch); + + /* check lock */ + value = PLGetDictionaryEntry(info, dLock); + + aicon->lock = getBooleanDockValue(value, dLock); /* check if it wasn't normally docked */ value = PLGetDictionaryEntry(info, dForced); - aicon->forced_dock = 0; - if (value) { - if (PLIsString(value)) { - if (strcasecmp(PLGetString(value), "YES")==0) - aicon->forced_dock = 1; - } else { - wwarning(_("bad value in docked icon state info %s"), - PLGetString(dForced)); - } - } + aicon->forced_dock = getBooleanDockValue(value, dForced); /* check if we can rely on the stuff in the app */ value = PLGetDictionaryEntry(info, dBuggyApplication); - aicon->buggy_app = 0; - if (value) { - if (PLIsString(value)) { - if (strcasecmp(PLGetString(value), "YES")==0) - aicon->buggy_app = 1; - } else { - wwarning(_("bad value in docked icon state info %s"), - PLGetString(dBuggyApplication)); - } - } + aicon->buggy_app = getBooleanDockValue(value, dBuggyApplication); /* get position in the dock */ value = PLGetDictionaryEntry(info, dPosition); @@ -1642,16 +1641,7 @@ restore_icon_state(WScreen *scr, proplist_t info, int type, int index) /* check if icon is omnipresent */ value = PLGetDictionaryEntry(info, dOmnipresent); - aicon->omnipresent = 0; - if (value) { - if (PLIsString(value)) { - if (strcasecmp(PLGetString(value), "YES")==0) - aicon->omnipresent = 1; - } else { - wwarning(_("bad value in docked icon state info %s"), - PLGetString(dOmnipresent)); - } - } + aicon->omnipresent = getBooleanDockValue(value, dOmnipresent); aicon->running = 0; aicon->docked = 1; @@ -3869,6 +3859,7 @@ handleIconMove(WDock *dock, WAppIcon *aicon, XEvent *event) } } if (aicon->launching + || aicon->lock || (aicon->running && !(ev.xmotion.state & MOD_MASK)) || (!aicon->running && tmp)) { shad_x = last_dock->x_pos + ix*wPreferences.icon_size; diff --git a/src/dockedapp.c b/src/dockedapp.c index 5e247ad4..bda971f2 100644 --- a/src/dockedapp.c +++ b/src/dockedapp.c @@ -66,6 +66,7 @@ typedef struct _AppSettingsPanel { WMButton *browseBtn; WMButton *autoLaunchBtn; + WMButton *lockBtn; WMButton *okBtn; WMButton *cancelBtn; @@ -246,6 +247,9 @@ panelBtnCallback(WMWidget *self, void *data) panel->editedIcon->auto_launch = WMGetButtonSelected(panel->autoLaunchBtn); + + panel->editedIcon->lock = + WMGetButtonSelected(panel->lockBtn); } if (done) @@ -254,7 +258,7 @@ panelBtnCallback(WMWidget *self, void *data) #define PWIDTH 295 -#define PHEIGHT 345 +#define PHEIGHT 365 void @@ -298,9 +302,16 @@ ShowDockAppSettingsPanel(WAppIcon *aicon) _("Start when WindowMaker is started")); WMSetButtonSelected(panel->autoLaunchBtn, aicon->auto_launch); + panel->lockBtn = WMCreateSwitchButton(panel->win); + WMResizeWidget(panel->lockBtn, PWIDTH-30, 20); + WMMoveWidget(panel->lockBtn, 15, 100); + WMSetButtonText(panel->lockBtn, + _("Lock (prevent accidental removal)")); + WMSetButtonSelected(panel->lockBtn, aicon->lock); + panel->commandFrame = WMCreateFrame(panel->win); WMResizeWidget(panel->commandFrame, 275, 50); - WMMoveWidget(panel->commandFrame, 10, 105); + WMMoveWidget(panel->commandFrame, 10, 125); WMSetFrameTitle(panel->commandFrame, _("Application path and arguments")); panel->commandField = WMCreateTextField(panel->commandFrame); @@ -310,7 +321,7 @@ ShowDockAppSettingsPanel(WAppIcon *aicon) panel->dndCommandFrame = WMCreateFrame(panel->win); WMResizeWidget(panel->dndCommandFrame, 275, 70); - WMMoveWidget(panel->dndCommandFrame, 10, 165); + WMMoveWidget(panel->dndCommandFrame, 10, 185); WMSetFrameTitle(panel->dndCommandFrame, _("Command for files dropped with DND")); @@ -333,7 +344,7 @@ ShowDockAppSettingsPanel(WAppIcon *aicon) panel->iconFrame = WMCreateFrame(panel->win); WMResizeWidget(panel->iconFrame, 275, 50); - WMMoveWidget(panel->iconFrame, 10, 245); + WMMoveWidget(panel->iconFrame, 10, 265); WMSetFrameTitle(panel->iconFrame, _("Icon Image")); panel->iconField = WMCreateTextField(panel->iconFrame); @@ -352,13 +363,13 @@ ShowDockAppSettingsPanel(WAppIcon *aicon) panel->okBtn = WMCreateCommandButton(panel->win); WMResizeWidget(panel->okBtn, 80, 26); - WMMoveWidget(panel->okBtn, 200, 308); + WMMoveWidget(panel->okBtn, 200, 328); WMSetButtonText(panel->okBtn, _("OK")); WMSetButtonAction(panel->okBtn, panelBtnCallback, panel); panel->cancelBtn = WMCreateCommandButton(panel->win); WMResizeWidget(panel->cancelBtn, 80, 26); - WMMoveWidget(panel->cancelBtn, 110, 308); + WMMoveWidget(panel->cancelBtn, 110, 328); WMSetButtonText(panel->cancelBtn, _("Cancel")); WMSetButtonAction(panel->cancelBtn, panelBtnCallback, panel); diff --git a/src/event.c b/src/event.c index 04b1016f..4ff50117 100644 --- a/src/event.c +++ b/src/event.c @@ -29,10 +29,13 @@ #include #include +#include + + #include #include #ifdef SHAPE -#include +# include #endif #ifdef XDND #include "xdnd.h" @@ -461,9 +464,8 @@ handleMapRequest(XEvent *ev) Window window = ev->xmaprequest.window; #ifdef DEBUG - dbprintf("got map request for %x\n", (unsigned)window); + L("got map request for %x\n", (unsigned)window); #endif - if ((wwin = wWindowFor(window))) { if (wwin->flags.shaded) { wUnshadeWindow(wwin); @@ -540,9 +542,8 @@ handleDestroyNotify(XEvent *event) Window window = event->xdestroywindow.window; #ifdef DEBUG - dbputs("got destroy notify"); -#endif - + L("got destroy notify"); +#endif wwin = wWindowFor(window); if (wwin) { wUnmanageWindow(wwin, False, True); @@ -576,10 +577,9 @@ handleExpose(XEvent *event) WObjDescriptor *desc; XEvent ev; -#ifdef DEBUG - dbputs("got expose"); +#ifdef DEBUG + L("got expose"); #endif - while (XCheckTypedWindowEvent(dpy, event->xexpose.window, Expose, &ev)); if (XFindContext(dpy, event->xexpose.window, wWinContext, @@ -599,11 +599,9 @@ handleButtonPress(XEvent *event) { WObjDescriptor *desc; WScreen *scr; - -#ifdef DEBUG - dbputs("got button press"); +#ifdef DEBUG + L("got button press"); #endif - scr = wScreenForRootWindow(event->xbutton.root); #ifdef BALLOON_TEXT @@ -706,11 +704,9 @@ static void handleMapNotify(XEvent *event) { WWindow *wwin; - #ifdef DEBUG - dbputs("got map"); + L("got map"); #endif - wwin = wWindowFor(event->xmap.event); if (wwin && wwin->client_win == event->xmap.event) { if (wwin->flags.miniaturized) { @@ -731,11 +727,9 @@ handleUnmapNotify(XEvent *event) WWindow *wwin; XEvent ev; Bool withdraw = False; - #ifdef DEBUG - dbputs("got unmap"); + L("got unmap"); #endif - /* only process windows with StructureNotify selected * (ignore SubstructureNotify) */ wwin = wWindowFor(event->xunmap.window); @@ -785,9 +779,8 @@ static void handleConfigureRequest(XEvent *event) { WWindow *wwin; - #ifdef DEBUG - dbputs("got configure request"); + L("got configure request"); #endif if (!(wwin=wWindowFor(event->xconfigurerequest.window))) { /* @@ -809,9 +802,8 @@ handlePropertyNotify(XEvent *event) int ji; unsigned int ju; WScreen *scr; - #ifdef DEBUG - dbputs("got property notify"); + L("got property notify"); #endif if ((wwin=wWindowFor(event->xproperty.window))) { if (!XGetGeometry(dpy, wwin->client_win, &jr, &ji, &ji, @@ -839,9 +831,8 @@ handleClientMessage(XEvent *event) { WWindow *wwin; WObjDescriptor *desc; - #ifdef DEBUG - dbputs("got client message"); + L("got client message"); #endif /* handle transition from Normal to Iconic state */ if (event->xclient.message_type == _XA_WM_CHANGE_STATE @@ -975,12 +966,9 @@ handleEnterNotify(XEvent *event) WObjDescriptor *desc = NULL; XEvent ev; WScreen *scr = wScreenForRootWindow(event->xcrossing.root); - - #ifdef DEBUG - dbputs("got enter notify"); + L("got enter notify"); #endif - if (XCheckTypedWindowEvent(dpy, event->xcrossing.window, LeaveNotify, &ev)) { /* already left the window... */ @@ -998,11 +986,9 @@ handleEnterNotify(XEvent *event) event->xcrossing.x_root >= (scr->scr_width - 2) || event->xcrossing.y_root <= 1 || event->xcrossing.y_root >= (scr->scr_height - 2)) { - #ifdef DEBUG - dbputs("pointer at screen edge in EnterNotify event, fear"); + L("pointer at screen edge in EnterNotify event, fear"); #endif - menu = wMenuUnderPointer(scr); if (menu!=NULL) { wMenuScroll(menu, event); @@ -1128,11 +1114,9 @@ handleShapeNotify(XEvent *event) XShapeEvent *shev = (XShapeEvent*)event; WWindow *wwin; XEvent ev; - -#ifdef DEBUG - dbputs("got shape notify"); +#ifdef DEBGU + L("got shape notify"); #endif - while (XCheckTypedWindowEvent(dpy, shev->window, event->type, &ev)) { XShapeEvent *sev = (XShapeEvent*)&ev; @@ -1362,7 +1346,6 @@ doWindozeCycle(WWindow *wwin, XEvent *event, Bool next) if (!wwin) return; -/* dbputs("IN");*/ keymap = XGetModifierMapping(dpy); @@ -1398,7 +1381,6 @@ doWindozeCycle(WWindow *wwin, XEvent *event, Bool next) WMHandleEvent(&ev); continue; } -/*dbputs("EV");*/ /* ignore CapsLock */ modifiers = ev.xkey.state & ValidModMask; @@ -1439,7 +1421,6 @@ doWindozeCycle(WWindow *wwin, XEvent *event, Bool next) } } } -/*dbputs("OUT");*/ XFree(keymap); XUngrabKeyboard(dpy, CurrentTime); @@ -1834,11 +1815,9 @@ handleMotionNotify(XEvent *event) event->xmotion.x_root >= (scr->scr_width - 2) || event->xmotion.y_root <= 1 || event->xmotion.y_root >= (scr->scr_height - 2)) { - #ifdef DEBUG - dbputs("pointer at screen edge"); + L("pointer at screen edge"); #endif - menu = wMenuUnderPointer(scr); if (menu!=NULL) wMenuScroll(menu, event); diff --git a/src/funcs.h b/src/funcs.h index 1aa29bbc..f7c7f7d6 100644 --- a/src/funcs.h +++ b/src/funcs.h @@ -102,6 +102,8 @@ char *ExpandOptions(WScreen *scr, char *cmdline); void ExecuteShellCommand(WScreen *scr, char *command); +void StartLogShell(WScreen *scr); + Bool IsDoubleClick(WScreen *scr, XEvent *event); WWindow *NextFocusWindow(WScreen *scr); @@ -160,10 +162,4 @@ Bool wGetIconName(Display *dpy, Window win, char **iconname); -/* debugging stuff */ - -void dbprintf(char *, ...); -void dbputs(char *); - - #endif diff --git a/src/main.c b/src/main.c index 8f6ce605..4e5c4b9a 100644 --- a/src/main.c +++ b/src/main.c @@ -151,6 +151,9 @@ static int ArgCount; extern void EventLoop(); extern void StartUp(); +/* stdi/o for log shell */ +static int LogStdIn = -1, LogStdOut = -1, LogStdErr = -1; + void Exit(int status) @@ -224,6 +227,159 @@ SetupEnvironment(WScreen *scr) } + + +typedef struct { + WScreen *scr; + char *command; +} _tuple; + + +static void +shellCommandHandler(pid_t pid, unsigned char status, _tuple *data) +{ + if (status == 127) { + char *buffer; + + buffer = wstrappend(_("Could not execute command: "), data->command); + + wMessageDialog(data->scr, _("Error"), buffer, _("OK"), NULL, NULL); + free(buffer); + } else if (status != 127) { + /* + printf("%s: %i\n", data->command, status); + */ + } + + free(data->command); + free(data); +} + + +void +ExecuteShellCommand(WScreen *scr, char *command) +{ + static char *shell = NULL; + pid_t pid; + + /* + * This have a problem: if the shell is tcsh (not sure about others) + * and ~/.tcshrc have /bin/stty erase ^H somewhere on it, the shell + * will block and the command will not be executed. + if (!shell) { + shell = getenv("SHELL"); + if (!shell) + shell = "/bin/sh"; + } + */ + shell = "/bin/sh"; + + pid = fork(); + + if (pid==0) { + + SetupEnvironment(scr); + +#ifdef HAVE_SETPGID + setpgid(0, 0); +#endif + execl(shell, shell, "-c", command, NULL); + wsyserror("could not execute %s -c %s", shell, command); + Exit(-1); + } else if (pid < 0) { + wsyserror("cannot fork a new process"); + } else { + _tuple *data = wmalloc(sizeof(_tuple)); + + data->scr = scr; + data->command = wstrdup(command); + + wAddDeathHandler(pid, (WDeathHandler*)shellCommandHandler, data); + } +} + + +/* + *--------------------------------------------------------------------------- + * StartLogShell + * Start a shell that will receive all stdin and stdout from processes + * forked by wmaker. + *--------------------------------------------------------------------------- + */ +void +StartLogShell(WScreen *scr) +{ + int in_fd[2]; + int out_fd[2]; + int err_fd[2]; + pid_t pid; + + SetupEnvironment(scr); + + if (pipe(in_fd) < 0) { + wsyserror("could not create pipe for log shell\n"); + return; + } + if (pipe(out_fd) < 0) { + wsyserror("could not create pipe for log shell\n"); + close(in_fd[0]); + close(in_fd[1]); + return; + } + if (pipe(err_fd) < 0) { + wsyserror("could not create pipe for log shell\n"); + close(out_fd[0]); + close(out_fd[1]); + close(in_fd[0]); + close(in_fd[1]); + return; + } + + pid = fork(); + if (pid < 0) { + wsyserror("could not fork a new process for log shell\n"); + return; + } else if (pid == 0) { + close(in_fd[0]); + close(out_fd[1]); + close(err_fd[1]); + + close(0); + close(1); + close(2); + + if (dup2(in_fd[1], 0) < 0) { + wsyserror("could not redirect stdin for log shell\n"); + exit(1); + } + if (dup2(out_fd[1], 1) < 0) { + wsyserror("could not redirect stdout for log shell\n"); + exit(1); + } + if (dup2(err_fd[1], 2) < 0) { + wsyserror("could not redirect stderr for log shell\n"); + exit(1); + } + + close(in_fd[1]); + close(out_fd[1]); + close(err_fd[1]); + + execl("/bin/sh", "/bin/sh", "-c", wPreferences.logger_shell, NULL); + wsyserror("could not execute %s\n", wPreferences.logger_shell); + exit(1); + } else { + close(in_fd[1]); + close(out_fd[0]); + close(err_fd[0]); + + LogStdIn = in_fd[1]; + LogStdOut = out_fd[0]; + LogStdErr = err_fd[0]; + } +} + + /* *--------------------------------------------------------------------- * wAbort-- diff --git a/src/menu.c b/src/menu.c index 4b413ef8..c7761df2 100644 --- a/src/menu.c +++ b/src/menu.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "WindowMaker.h" #include "wcore.h" @@ -284,23 +285,13 @@ wMenuInsertCallback(WMenu *menu, int index, char *text, { WMenuEntry *entry; -#ifdef DEBUG - if (!menu) { - dbprintf("Passed NULL as menu parameter to wMenuAddCallback() \n"); - return NULL; - } -#endif - - assert(menu->flags.brother==0); menu->flags.realized = 0; menu->brother->flags.realized = 0; /* reallocate array if it's too small */ if (menu->entry_no >= menu->alloced_entries) { void *tmp; -#ifdef DEBUG - dbputs("doing wrealloc()"); -#endif + tmp = wrealloc(menu->entries, sizeof(WMenuEntry)*(menu->alloced_entries+5)); if (tmp==NULL) { @@ -1777,10 +1768,6 @@ wMenuScroll(WMenu *menu, XEvent *event) int old_frame_x = omenu->frame_x; int old_frame_y = omenu->frame_y; XEvent ev; - -#ifdef DEBUG - dbputs("Entering menu Scroll"); -#endif if (omenu->jump_back) WMDeleteTimerWithClientData(omenu->jump_back); @@ -1887,11 +1874,6 @@ wMenuScroll(WMenu *menu, XEvent *event) else delayer = omenu->jump_back; WMAddTimerHandler(MENU_JUMP_BACK_DELAY,(WMCallback*)_leaving, delayer); } - - -#ifdef DEBUG - dbputs("Leaving menu Scroll"); -#endif } @@ -2313,10 +2295,6 @@ menuTitleMouseDown(WCoreWindow *sender, void *data, XEvent *event) int i, lower; Bool started; -#ifdef DEBUG - dbprintf("Moving menu\n"); -#endif - /* can't touch the menu copy */ if (menu->flags.brother) return; @@ -2400,9 +2378,6 @@ menuTitleMouseDown(WCoreWindow *sender, void *data, XEvent *event) case ButtonRelease: if (ev.xbutton.button != event->xbutton.button) break; -#ifdef DEBUG - dbprintf("End menu move\n"); -#endif XUngrabPointer(dpy, CurrentTime); return; diff --git a/src/misc.c b/src/misc.c index b69ca206..b90dcdd9 100644 --- a/src/misc.c +++ b/src/misc.c @@ -1394,97 +1394,3 @@ SendHelperMessage(WScreen *scr, char type, int workspace, char *msg) } free(buffer); } - - - -typedef struct { - WScreen *scr; - char *command; -} _tuple; - - -static void -shellCommandHandler(pid_t pid, unsigned char status, _tuple *data) -{ - if (status == 127) { - char *buffer; - - buffer = wstrappend(_("Could not execute command: "), data->command); - - wMessageDialog(data->scr, _("Error"), buffer, _("OK"), NULL, NULL); - free(buffer); - } else if (status != 127) { - /* - printf("%s: %i\n", data->command, status); - */ - } - - free(data->command); - free(data); -} - - -void -ExecuteShellCommand(WScreen *scr, char *command) -{ - static char *shell = NULL; - pid_t pid; - - /* - * This have a problem: if the shell is tcsh (not sure about others) - * and ~/.tcshrc have /bin/stty erase ^H somewhere on it, the shell - * will block and the command will not be executed. - if (!shell) { - shell = getenv("SHELL"); - if (!shell) - shell = "/bin/sh"; - } - */ - shell = "/bin/sh"; - - pid = fork(); - - if (pid==0) { - - SetupEnvironment(scr); - -#ifdef HAVE_SETPGID - setpgid(0, 0); -#endif - execl(shell, shell, "-c", command, NULL); - wsyserror("could not execute %s -c %s", shell, command); - Exit(-1); - } else if (pid < 0) { - wsyserror("cannot fork a new process"); - } else { - _tuple *data = wmalloc(sizeof(_tuple)); - - data->scr = scr; - data->command = wstrdup(command); - - wAddDeathHandler(pid, (WDeathHandler*)shellCommandHandler, data); - } -} - - - - - -void dbprintf(char *format, ...) -{ - va_list args; - - va_start(args, format); - vprintf(format, args); - fflush(stdout); - va_end(args); -} - - - -void dbputs(char *text) -{ - puts(text); - fflush(stdout); -} - diff --git a/src/nana.h b/src/nana.h new file mode 100644 index 00000000..871eaff8 --- /dev/null +++ b/src/nana.h @@ -0,0 +1,46 @@ +/* + * nana.h - the include that includes everything else. + * + * Copyright (c) 1997 Phil Maker + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Id: nana.h,v 1.1.1.1 1997/11/23 11:45:50 pjm Exp + */ + + +#ifndef _nana_h_ +#define _nana_h_ 1 + +#include +#include + +#include +#include + +#include + +#include + +#endif /* _nana_h_ */ + diff --git a/src/rootmenu.c b/src/rootmenu.c index 4a4cb69f..125862f2 100644 --- a/src/rootmenu.c +++ b/src/rootmenu.c @@ -25,7 +25,6 @@ #ifndef LITE -#include #include #include #include diff --git a/src/session.c b/src/session.c index 8208234c..5c842d1f 100644 --- a/src/session.c +++ b/src/session.c @@ -509,7 +509,8 @@ wSessionRestoreState(WScreen *scr) btn = dock->icon_array[j]; if (btn && SAME(instance, btn->wm_instance) && SAME(class, btn->wm_class) && - SAME(command, btn->command)) { + SAME(command, btn->command) && + !btn->launching) { found = 1; break; } diff --git a/wrlib/Makefile.am b/wrlib/Makefile.am index af73d23f..5efb158a 100644 --- a/wrlib/Makefile.am +++ b/wrlib/Makefile.am @@ -4,7 +4,7 @@ AUTOMAKE_OPTIONS = no-dependencies lib_LTLIBRARIES = libwraster.la -libwraster_la_LDFLAGS = -version-info 3:0:2 +libwraster_la_LDFLAGS = -version-info 3:1:2 bin_SCRIPTS = get-wraster-flags diff --git a/wrlib/Makefile.in b/wrlib/Makefile.in index 384c727c..e04c3ae8 100644 --- a/wrlib/Makefile.in +++ b/wrlib/Makefile.in @@ -96,7 +96,7 @@ AUTOMAKE_OPTIONS = no-dependencies lib_LTLIBRARIES = libwraster.la -libwraster_la_LDFLAGS = -version-info 3:0:2 +libwraster_la_LDFLAGS = -version-info 3:1:2 bin_SCRIPTS = get-wraster-flags diff --git a/wrlib/nxpm.c b/wrlib/nxpm.c index 7c66a0e4..4bd0e151 100644 --- a/wrlib/nxpm.c +++ b/wrlib/nxpm.c @@ -140,7 +140,8 @@ RGetImageFromXPMData(RContext *context, char **data) color_table[1][i] = green; color_table[2][i] = blue; color_table[3][i] = 255; - } else if (strncmp(&(data[line][j]), "None", 4)==0) { + } else if (strncmp(&(data[line][j]), "None", 4)==0 + || strncmp(&(data[line][j]), "none", 4)==0) { color_table[3][i] = 0; transp = 1; } else { @@ -315,7 +316,8 @@ RLoadXPM(RContext *context, char *file, int index) color_table[1][i] = green; color_table[2][i] = blue; color_table[3][i] = 255; - } else if (strncmp(&(line[j]), "None", 4)==0) { + } else if (strncmp(&(line[j]), "None", 4)==0 + || strncmp(&(line[j]), "none", 4)==0) { color_table[3][i] = 0; transp = 1; } else { diff --git a/wrlib/png.c b/wrlib/png.c index 0c666cdf..5aa057a3 100644 --- a/wrlib/png.c +++ b/wrlib/png.c @@ -155,8 +155,8 @@ RLoadPNG(RContext *context, char *file, int index) sgamma = 1; } else { /* no, this is correct. Old gimp versions are broken and save wrong - * data. Upgrade gimp */ - sgamma = 2.0; + * data. Upgrade gimp. wtf :/*/ + sgamma = 1.0; } if (png_get_gAMA(png, pinfo, &gamma))