#include #include #include #include "Xsowl.h" #include "Xsowldef.h" using namespace std; int argc; char **argv; unsigned long black, white, blue, red, green, cyan, magenta, orange, pink, brown, violet, greenyellow, gray, yellow, darkgray, lightgray; Font widgetfont, inputfont; TWindowListElement *windowlist = NULL; long mask ( int type ) { for (int i = 0; iAddWidget ( this ); } TButton::~TButton () { delete[] text; } void TButton::Init ( TWindow *parent ) { int direction, ascent, descent; XCharStruct overall; window = XCreateSimpleWindow ( display, parent->GetWindow (), x, y, width, height, 0, black, lightgray ); drawcontext = XCreateGC ( display, window, 0L, 0 ); XSetLineAttributes ( display, drawcontext, 2, LineSolid, CapRound, JoinRound ); XSetFont ( display, drawcontext, widgetfont ); XQueryTextExtents ( display, widgetfont, text, strlen ( text ), &direction, &ascent, &descent, &overall ); tx = ( width - overall.rbearing + overall.lbearing ) / 2 + overall.lbearing; ty = ( height - ascent - descent ) / 2 + ascent; XMapRaised ( display, window ); Draw (); XSelectInput ( display, window, ExposureMask | ButtonPressMask | KeyPressMask | EnterWindowMask | ButtonReleaseMask | KeyReleaseMask | LeaveWindowMask ); } void TButton::Remove () { XDestroyWindow ( display, window ); XFreeGC ( display, drawcontext ); } int TButton::Check ( XEvent* ev ) { XEvent ev2; switch ( ev->type ) { case Expose: Draw(); break; case ButtonPress: case KeyPress: XClearWindow ( display, window ); XSetForeground ( display, drawcontext, blue ); XDrawString ( display, window, drawcontext, tx + 2, ty + 2, text, strlen ( text ) ); XSetForeground ( display, drawcontext, gray ); XDrawRectangle ( display, window, drawcontext, 0, 0, width - 1, height - 1 ); XSelectInput ( display, window, ButtonReleaseMask | KeyReleaseMask | ButtonPressMask | KeyPressMask | LeaveWindowMask ); while ( true ) { XNextEvent ( display, &ev2 ); if ( ev2.type == ButtonRelease || ev2.type == KeyRelease || ev2.type == LeaveNotify ) { XSetForeground ( display, drawcontext, lightgray ); XDrawString ( display, window, drawcontext, tx + 2, ty + 2, text, strlen ( text ) ); Draw (); if ( ev2.type == LeaveNotify ) { XSelectInput ( display, window, ExposureMask | ButtonPressMask | KeyPressMask | EnterWindowMask | KeyReleaseMask | ButtonReleaseMask | LeaveWindowMask ); return 0; } else { XSetForeground ( display, drawcontext, blue ); XDrawString ( display, window, drawcontext, tx, ty, text, strlen ( text ) ); return ID; } } } case EnterNotify: XSetForeground ( display, drawcontext, blue ); XDrawString ( display, window, drawcontext, tx, ty, text, strlen ( text ) ); break; case LeaveNotify: XSetForeground ( display, drawcontext, black ); XDrawString ( display, window, drawcontext, tx, ty, text, strlen ( text ) ); break; } return 0; } void TButton::Draw () { XSetForeground ( display, drawcontext, black ); XDrawString ( display, window, drawcontext, tx, ty, text, strlen ( text ) ); XSetForeground ( display, drawcontext, white ); XDrawLine ( display, window, drawcontext, 0, 0, width, 0 ); XDrawLine ( display, window, drawcontext, 0, 0, 0, height ); XSetForeground ( display, drawcontext, darkgray ); XDrawLine ( display, window, drawcontext, 0, height - 1, width, height - 1 ); XDrawLine ( display, window, drawcontext, width - 1, 0, width - 1, height ); } TCheckBox::TCheckBox ( int _x, int _y, bool _checked, int _ID ) { x = _x; y = _y; ID = _ID; checked = _checked; } TCheckBox::TCheckBox ( int _x, int _y, bool _checked, int _ID, TWindow *parent ) { x = _x; y = _y; ID = _ID; checked = _checked; parent->AddWidget ( this ); } void TCheckBox::Init ( TWindow *parent ) { window = XCreateSimpleWindow ( display, parent->GetWindow (), x, y, checksymbol_width + 4, checksymbol_height + 4, 0, black, lightgray ); drawcontext = XCreateGC ( display, window, 0L, 0 ); checkboxsymbol = XCreatePixmapFromBitmapData ( display, window, checksymbol_bits, checksymbol_width, checksymbol_height, red, lightgray, DefaultDepth ( display, screen ) ); entercheckboxsymbol = XCreatePixmapFromBitmapData ( display, window, checksymbol_bits, checksymbol_width, checksymbol_height, blue, lightgray, DefaultDepth ( display, screen ) ); XSetLineAttributes ( display, drawcontext, 2, LineSolid, CapRound, JoinRound ); XMapRaised ( display, window ); Draw (); XSelectInput ( display, window, ExposureMask | ButtonPressMask | KeyPressMask | EnterWindowMask | LeaveWindowMask ); } void TCheckBox::Remove () { XDestroyWindow ( display, window ); XFreeGC ( display, drawcontext ); } int TCheckBox::Check ( XEvent *ev ) { switch ( ev->type ) { case Expose: Draw (); break; case EnterNotify: if ( checked ) XCopyArea ( display, entercheckboxsymbol, window, drawcontext, 0, 0, checksymbol_width, checksymbol_height, 2, 2 ); else { XSetForeground ( display, drawcontext, blue ); XDrawLine ( display, window, drawcontext, 5, checksymbol_height - 2, checksymbol_width - 3, checksymbol_height - 2 ); } break; case LeaveNotify: Draw (); break; case KeyPress: case ButtonPress: checked = !checked; Draw (); if ( checked ) XCopyArea ( display, entercheckboxsymbol, window, drawcontext, 0, 0, checksymbol_width, checksymbol_height, 2, 2 ); else { XSetForeground ( display, drawcontext, blue ); XDrawLine ( display, window, drawcontext, 5, checksymbol_height - 2, checksymbol_width - 3, checksymbol_height - 2 ); } return ID; } return 0; } void TCheckBox::Toggle () { checked = !checked; Draw (); } void TCheckBox::SetCheckState ( bool state ) { checked = state; Draw (); } void TCheckBox::Draw () { XClearWindow ( display, window ); XSetForeground ( display, drawcontext, white ); XDrawLine ( display, window, drawcontext, 0, 0, checksymbol_width + 4, 0 ); XDrawLine ( display, window, drawcontext, 0, 0, 0, checksymbol_height + 4); XSetForeground ( display, drawcontext, darkgray ); XDrawLine ( display, window, drawcontext, 0, checksymbol_height + 3, checksymbol_width + 3, checksymbol_height + 3 ); XDrawLine ( display, window, drawcontext, checksymbol_width + 3, 0, checksymbol_width + 3, checksymbol_height + 3 ); if ( checked ) XCopyArea ( display, checkboxsymbol, window, drawcontext, 0, 0, checksymbol_width, checksymbol_height, 2, 2 ); } TInputBox::TInputBox ( int _x, int _y, int _width, char *_text, int _n, int _ID ) { x = _x; y = _y; width = _width; n = _n; ID = _ID; cursorpos = showpos = 0; text = new char[n + 1]; strcpy ( _text, text ); } TInputBox::TInputBox ( int _x, int _y, int _width, char *_text, int _n, int _ID, TWindow *parent ) { x = _x; y = _y; width = _width; n = _n; ID = _ID; cursorpos = showpos = 0; text = new char[n + 1]; strcpy ( _text, text ); parent->AddWidget ( this ); } TInputBox::~TInputBox () { delete[] text; } void TInputBox::Init ( TWindow *parent ) { int direction, ascent, _descent; XCharStruct overall; XQueryTextExtents ( display, inputfont, "Mj", 2, &direction, &ascent, &_descent, &overall ); height = ascent + _descent + 4; descent = _descent; XQueryTextExtents ( display, inputfont, "M", 2, &direction, &ascent, &_descent, &overall ); letterwidth = overall.rbearing; window = XCreateSimpleWindow ( display, parent->GetWindow (), x, y, width, height, 0, black, white ); drawcontext = XCreateGC ( display, window, 0L, 0 ); XSetLineAttributes ( display, drawcontext, 2, LineSolid, CapNotLast, JoinRound ); XSetFont ( display, drawcontext, inputfont ); XSetBackground ( display, drawcontext, white ); XSetForeground ( display, drawcontext, black ); XMapRaised ( display, window ); Draw (); XSelectInput ( display, window, ExposureMask | ButtonPressMask | KeyPressMask | EnterWindowMask | LeaveWindowMask ); XDefineCursor ( display, window, XCreateFontCursor ( display, XC_xterm ) ); } void TInputBox::SetText ( char *_text ) { cursorpos = showpos = 0; strcpy ( _text, text ); Draw (); } void TInputBox::DrawText () { int length; if ( strlen ( text ) < ( width - 6 ) / letterwidth ) length = strlen ( text ); else length = ( width - 6 ) / letterwidth; XSetForeground ( display, drawcontext, black ); XDrawImageString ( display, window, drawcontext, 3, height - 2 - descent, & ( text[showpos] ), length ); } void TInputBox::Draw () { XClearWindow ( display, window ); XSetForeground ( display, drawcontext, darkgray ); XDrawLine ( display, window, drawcontext, 1, 1, width, 1 ); XDrawLine ( display, window, drawcontext, 1, 1, 1, height ); DrawText (); } void TInputBox::MoveCursor ( int _cursorpos ) { int cursorline; XSetForeground ( display, drawcontext, white ); cursorline = 3 + ( cursorpos - showpos ) * letterwidth; XDrawLine ( display, window, drawcontext, cursorline, 3, cursorline, height - 3 ); cursorpos = _cursorpos; if ( cursorpos < showpos ) { showpos = cursorpos; Draw (); } if ( cursorpos > showpos + ( width - 6 ) / letterwidth ) { showpos = cursorpos - ( width - 6 ) / letterwidth; Draw (); } cursorline = 3 + ( cursorpos - showpos ) * letterwidth; XSetForeground ( display, drawcontext, black ); XDrawLine ( display, window, drawcontext, cursorline, 3, cursorline, height - 3 ); } void TInputBox::InsertKey ( char key ) { char *textwalk = & ( text[cursorpos] ); char movechar = key, helpchar; while ( *textwalk ) { helpchar = *textwalk; *textwalk = movechar; movechar = helpchar; textwalk++; } *textwalk = movechar; textwalk++; *textwalk = '\0'; Draw (); MoveCursor ( ++cursorpos ); } void TInputBox::DeleteChar () { int cursorline; char *textwalk = & ( text[cursorpos] ), *forwardwalk = textwalk; forwardwalk++; while ( *textwalk ) { *textwalk = *forwardwalk; textwalk++; forwardwalk++; } Draw (); cursorline = 3 + ( cursorpos - showpos ) * letterwidth; XSetForeground ( display, drawcontext, black ); XDrawLine ( display, window, drawcontext, cursorline, 3, cursorline, height - 3 ); } int TInputBox::Check ( XEvent *ev ) { int cursorline, newpos, key, IDreturn = 0; switch ( ev->type ) { case Expose: Draw (); break; case EnterNotify: XSetForeground ( display, drawcontext, black ); cursorline = 3 + ( cursorpos - showpos ) * letterwidth; XDrawLine ( display, window, drawcontext, cursorline, 3, cursorline, height - 3 ); break; case LeaveNotify: XSetForeground ( display, drawcontext, white ); cursorline = 3 + ( cursorpos - showpos ) * letterwidth; XDrawLine ( display, window, drawcontext, cursorline, 3, cursorline, height - 3 ); break; case ButtonPress: newpos = ( ev->xkey.x - 3 ) / letterwidth + showpos; if ( newpos > strlen ( text ) ) newpos = strlen ( text ); MoveCursor ( newpos ); break; case KeyPress: key = XLookupKeysym ( & ( ev->xkey ), 0 ); switch ( key ) { case XK_Shift_L: case XK_Shift_R: break; case XK_Left: if ( cursorpos > 0 ) MoveCursor ( cursorpos - 1 ); break; case XK_Right: if ( cursorpos < strlen ( text ) ) MoveCursor ( cursorpos + 1 ); break; case XK_BackSpace: if ( cursorpos > 0 ) { MoveCursor ( cursorpos - 1 ); DeleteChar (); IDreturn = ID; } break; case XK_Delete: DeleteChar (); IDreturn = ID; break; case XK_Home: MoveCursor ( 0 ); break; case XK_End: MoveCursor ( strlen ( text ) ); break; default: if ( strlen ( text ) < n ) { if ( ev->xkey.state & ShiftMask ) InsertKey ( XLookupKeysym ( & (ev->xkey ), 1 ) ); else InsertKey ( key ); IDreturn = ID; break; } } } IDreturn++; IDreturn--; return 0; } void TInputBox::Remove () { XDestroyWindow ( display, window ); XFreeGC ( display, drawcontext ); } TMenuItemListElement::TMenuItemListElement ( char *_text, int _ID ) { next = NULL; ID = _ID; text = new char[strlen ( _text ) + 1]; strcpy ( _text, text ); } TMenuListElement::TMenuListElement ( char *_text ) { next = NULL; menu = NULL; text = new char[strlen ( _text ) + 1]; strcpy ( _text, text ); width = 0; n = 0; } TMenu::~TMenu () { if ( begin ) delete begin; } void TMenu::AddDropDownMenu ( char *name ) { TMenuListElement *walk = begin; int x1 = 10, direction, ascent, descent; XCharStruct overall; if ( begin ) { x1 = walk->x2 + 20; while ( walk->next ) { walk = walk->next; x1 = walk->x2 + 20; } walk->next = new TMenuListElement ( name ); walk = walk->next; } else walk = begin = new TMenuListElement ( name ); walk->x1 = x1; walk->width = 0; XQueryTextExtents ( display, widgetfont, name, strlen ( name ), &direction, &ascent, &descent, &overall ); walk->x2 = x1 + overall.rbearing; } void TMenu::AddMenuItem ( char *name, int ID, char *menuname ) { TMenuListElement *menuwalk = begin; TMenuItemListElement *itemwalk; int ascent, descent, direction; XCharStruct overall; while ( menuwalk && !strcmp ( menuname, menuwalk->text ) ) menuwalk = menuwalk->next; if ( menuwalk ) { if ( menuwalk->menu ) { itemwalk = menuwalk->menu; while ( itemwalk->next ) itemwalk = itemwalk->next; itemwalk->next = new TMenuItemListElement ( name, ID ); } else menuwalk->menu = new TMenuItemListElement ( name, ID ); XQueryTextExtents ( display, widgetfont, name, strlen ( name ), &direction, &ascent, &descent, &overall ); if ( overall.rbearing > menuwalk->width ) menuwalk->width = overall.rbearing; ( menuwalk->n )++; } } void TMenu::Init ( TWindow *parent ) { int direction; XCharStruct overall; actual = NULL; XQueryTextExtents ( display, widgetfont, "Mj", 2, &direction, &ascent, &descent, &overall ); width = parent->GetWidth (); window = XCreateSimpleWindow ( display, parent->GetWindow (), 0, 0, width, ascent + descent + 4, 0, black, lightgray ); drawcontext = XCreateGC ( display, window, 0L, 0 ); XSetLineAttributes ( display, drawcontext, 2, LineSolid, CapRound, JoinRound ); XSetFont ( display, drawcontext, widgetfont ); XMapRaised ( display, window ); Draw (); XSelectInput ( display, window, ExposureMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask ); } void TMenu::Draw () { TMenuListElement *walk = begin; XSetForeground ( display, drawcontext, black ); while ( walk ) { XDrawString ( display, window, drawcontext, walk->x1, ascent + 1, walk->text, strlen ( walk->text ) ); walk = walk->next; } XSetForeground ( display, drawcontext, darkgray ); XDrawLine ( display, window, drawcontext, 0, ascent + descent + 3, width, ascent + descent + 3 ); XSetForeground ( display, drawcontext, white ); XDrawLine ( display, window, drawcontext, 0, ascent + descent + 4, width, ascent + descent + 4 ); } void TMenu::MakeActive ( int x ) { TMenuListElement *walk = begin; actual = NULL; while ( walk && ( walk->x1 <= x ) && !actual) { if ( walk->x2 >= x ) actual = walk; walk = walk->next; } if ( actual ) { XSetForeground ( display, drawcontext, blue ); XDrawString ( display, window, drawcontext, actual->x1, ascent + 1, actual->text, strlen ( actual->text ) ); } } TMenuItemListElement* TMenu::MakeItemActive ( int y, int& n, Window popup ) { TMenuItemListElement *walk = actual->menu; int yw = 5 + ascent + descent; n = 0; while ( walk && ( y > yw ) ) { walk = walk->next; yw += ascent + descent + 4; n++; } if ( walk ) { XSetForeground ( display, drawcontext, blue ); XDrawString ( display, popup, drawcontext, 10, yw - descent, walk->text, strlen ( walk-> text ) ); } return walk; } void TMenu::DeactivateItem ( TMenuItemListElement* &item, int n, Window popup ) { if ( item ) { XSetForeground ( display, drawcontext, black ); XDrawString ( display, popup, drawcontext, 10, n * ( ascent + descent + 4 ) + 5 + ascent, item->text, strlen ( item->text ) ); item = NULL; } } void TMenu::Deactivate () { if ( actual ) { XSetForeground ( display, drawcontext, black ); XDrawString ( display, window, drawcontext, actual->x1, ascent + 1, actual->text, strlen ( actual->text ) ); actual = NULL; } } void TMenu::DrawPopup ( Window popup, int width, int height ) { TMenuItemListElement* walk = actual->menu; int y = 5 + ascent; XSetForeground ( display, drawcontext, white ); XDrawLine ( display, popup, drawcontext, 0, 0, width, 0 ); XDrawLine ( display, popup, drawcontext, 0, 0, 0, height ); XSetForeground ( display, drawcontext, darkgray ); XDrawLine ( display, popup, drawcontext, 0, height - 1, width, height - 1 ); XDrawLine ( display, popup, drawcontext, width - 1, 0, width - 1, height ); XSetForeground ( display, drawcontext, black ); while ( walk ) { XDrawString ( display, popup, drawcontext, 10, y, walk->text, strlen ( walk->text ) ); y += ascent + descent + 4; walk = walk->next; } } int TMenu::SelectFromMenu () { Window popupmenu, rw, cw; XSetWindowAttributes attr; XEvent ev; int rx, ry, wx, wy, itemn = 0; // 14.4.2008 added: initialization unsigned int d; TMenuItemListElement *item = NULL; bool inside = false; attr.background_pixel = lightgray; attr.save_under = false; attr.override_redirect = true; attr.event_mask = ButtonPressMask | ButtonReleaseMask | KeyPressMask | ButtonMotionMask | PointerMotionMask; XSetForeground ( display, drawcontext, lightgray ); XSetBackground ( display, drawcontext, blue ); XDrawImageString ( display, window, drawcontext, actual->x1, ascent + 1, actual->text, strlen ( actual->text ) ); XQueryPointer ( display, window, &rw, &cw, &rx, &ry, &wx, &wy, &d ); popupmenu = XCreateWindow ( display, root_window, rx - wx + actual->x1, ry - wy + ascent + descent + 4, actual->width + 20, actual->n * (ascent + descent + 4 ) + 10, 0, CopyFromParent, InputOutput, CopyFromParent, CWBackPixel | CWSaveUnder | CWOverrideRedirect | CWEventMask, &attr ); XMapRaised ( display, popupmenu ); XDefineCursor ( display, popupmenu, XCreateFontCursor ( display, XC_arrow ) ); DrawPopup ( popupmenu, actual->width + 20, actual->n * (ascent + descent + 4 ) + 10 ); XGrabPointer ( display, popupmenu, true, ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime ); do { XNextEvent ( display, &ev ); if ( ev.xany.window == popupmenu ) switch ( ev.type ) { case EnterNotify: item = MakeItemActive ( ev.xmotion.y, itemn, popupmenu ); inside = true; break; case LeaveNotify: DeactivateItem ( item, itemn, popupmenu ); inside = false; break; case MotionNotify: if ( item ) { if ( ( ev.xmotion.y - 5 ) / ( ascent + descent + 4 ) != itemn ) { DeactivateItem ( item, itemn, popupmenu ); item = MakeItemActive ( ev.xmotion.y, itemn, popupmenu ); } } else if ( inside ) item = MakeItemActive ( ev.xmotion.y, itemn, popupmenu ); break; } } while ( ! ( ( ev.type == ButtonPress && ev.xany.window !=popupmenu ) || ( ev.type == ButtonRelease && ev.xany.window == popupmenu ) ) ); XUngrabPointer ( display, CurrentTime ); XDestroyWindow ( display, popupmenu ); XSetForeground ( display, drawcontext, black ); XSetBackground ( display, drawcontext, lightgray ); XDrawImageString ( display, window, drawcontext, actual->x1, ascent + 1, actual->text, strlen ( actual->text ) ); if ( item ) return item->ID; else return 0; } int TMenu::Check ( XEvent *ev ) { int IDreturn = 0; switch ( ev->type ) { case Expose: Draw (); break; case EnterNotify: MakeActive ( ev->xcrossing.x ); break; case LeaveNotify: Deactivate (); break; case MotionNotify: if ( actual ) { if ( actual->x1 >= ev->xmotion.x || ev->xmotion.x >= actual->x2 ) { Deactivate (); MakeActive ( ev->xmotion.x ); } } else MakeActive ( ev->xmotion.x ); break; case ButtonRelease: case ButtonPress: if ( actual ) IDreturn = SelectFromMenu (); } return IDreturn; } void TMenu::Remove () { XDestroyWindow ( display, window ); XFreeGC ( display, drawcontext ); } TLabel::TLabel ( int _x, int _y, char *_text, unsigned long _background ) { x = _x; y = _y; text = new char[strlen ( _text ) + 1]; background = _background; strcpy ( _text, text ); } TLabel::TLabel ( int _x, int _y, char *_text, unsigned long _background, TWindow *parent ) { x = _x; y = _y; text = new char[strlen ( _text ) + 1]; strcpy ( _text, text ); background = _background; parent->AddWidget ( this ); } void TLabel::Init ( TWindow *parent ) { int direction, descent; XCharStruct overall; XQueryTextExtents ( display, widgetfont, text, strlen ( text ), &direction, &ascent, &descent, &overall ); window = XCreateSimpleWindow ( display, parent->GetWindow (), x, y, overall.rbearing, ascent + descent, 0, black, background ); drawcontext = XCreateGC ( display, window, 0L, 0 ); XSetFont ( display, drawcontext, widgetfont ); XSetForeground ( display, drawcontext, black ); XMapRaised ( display, window ); Draw (); XSelectInput ( display, window, ExposureMask ); } void TLabel::Draw () { XDrawString ( display, window, drawcontext, 0, ascent, text, strlen ( text) ); } int TLabel::Check ( XEvent *ev ) { Draw (); return 0; } void TLabel::Remove () { XDestroyWindow ( display, window ); XFreeGC ( display, drawcontext ); } void TLabel::SetTextColor ( long unsigned _foreground ) { XSetForeground ( display, drawcontext, _foreground ); Draw (); } void TLabel::SetText ( char *_text ) { int direction, descent; XCharStruct overall; delete text; text = new char[strlen ( _text ) + 1]; strcpy ( _text, text ); XQueryTextExtents ( display, widgetfont, text, strlen ( text ), &direction, &ascent, &descent, &overall ); XResizeWindow ( display, window, overall.rbearing, ascent + descent ); } void TWindowEventWidget::AddEvent ( int type, int ID ) { TWindowEventListItem *help = new TWindowEventListItem; help->event = type; listmask |= mask ( type ); help->ID = ID; help->next = root; root = help; } void TWindowEventWidget::RemoveEvent ( int type ) { TWindowEventListItem *help = root, *follow = NULL; while ( help && help->event != type ) { follow = help; help = help->next; } if ( help ) { if ( follow ) follow->next = help->next; else root = help->next; delete help; listmask &= mask ( type ) ^ -1; } } int TWindowEventWidget::Check ( XEvent *ev ) { TWindowEventListItem *help = root; while ( help ) { if ( help->event == ev->type ) return help->ID; help = help->next; } return 0; } TWidgetList::TWidgetList () { root = NULL; begin = new TWindowEventWidget; } TWidgetList::~TWidgetList () { TWidgetListElement *help; while ( root ) { help = root; root = root->next; delete help; } delete begin; } void TWidgetList::AddWidget ( TWidget *element ) { TWidgetListElement *help = new TWidgetListElement; help->next = root; help->widget = element; root = help; } void TWidgetList::RemoveWidget ( TWidget *element ) { TWidgetListElement *help = root, *follow = NULL; while ( help && help->widget != element ) { follow = help; help = help->next; } if ( help ) { if ( follow ) follow->next = help->next; else root = help->next; delete help; } } int TWidgetList::ExtractID ( XEvent *ev ) { TWidgetListElement *walker = root; int returnID = 0; while ( walker && !returnID ) { if ( ev->xany.window == walker->widget->window ) returnID = walker->widget->Check ( ev ); walker = walker->next; } return returnID; } void TWindow::Init ( unsigned int _width, unsigned int _height, unsigned long background, char *title, char *icontitle ) { XEvent ev; if ( windowlist == NULL ) windowlist = new TWindowListElement ( this, NULL ); else windowlist = new TWindowListElement ( this, windowlist ); window = XCreateSimpleWindow ( display, root_window, 0, 0, _width, _height, 2, black, background ); XStoreName ( display, window, title ); XSetIconName ( display, window, icontitle ); width = _width; height = _height; drawcontext = XCreateGC ( display, window, 0L, 0 ); XSetLineAttributes ( display, drawcontext, 1, LineSolid, CapRound, JoinRound ); SetDrawBackground ( background ); font = XLoadFont ( display, "9x15" ); fontinuse = font; fill = false; widgetlist = new TWidgetList; AddWidget ( widgetlist->begin ); XMapRaised ( display, window ); XSelectInput ( display, window, ExposureMask ); do XNextEvent ( display, &ev ); while ( ev.type != Expose ); } TWindow::TWindow ( unsigned int width, unsigned int height, unsigned long background, char *title, char *icontitle ) { Init ( width, height, background, title, icontitle ); } TWindow::TWindow ( unsigned int width, unsigned int height, unsigned long background, char *title ) { Init ( width, height, background, title, title ); } TWindow::TWindow ( unsigned int width, unsigned int height ) { Init ( width, height, white, argv[0], argv[0] ); } TWindow::~TWindow () { TWindowListElement *walk = windowlist, *follow = NULL; TWindow *temp; delete widgetlist; XDestroyWindow ( display, window ); while ( walk->window != this ) { follow = walk; walk = walk->next; } if ( follow ) follow->next = walk->next; else windowlist = walk->next; delete walk; CheckForGlobalEvent ( temp ); } void TWindow::DrawLine (int x1, int y1, int x2, int y2 ) { XDrawLine ( display, window, drawcontext, x1, y1, x2, y2 ); } void TWindow::DrawPoint ( int x, int y ) { XDrawPoint ( display, window, drawcontext, x, y ); } // teken een deel van een ellips die ligt in de rechthoek (x,y,x+width,y+height), // dat deel wordt getekend lopend van arc1 tot arc1+arc2. void TWindow::DrawArc (int x, int y, unsigned int width, unsigned int height, int arc1, int arc2 ) { if ( fill ) XFillArc ( display, window, drawcontext, x, y, width, height, arc1*64, arc2*64 ); else XDrawArc ( display, window, drawcontext, x, y, width, height, arc1*64, arc2*64 ); } void TWindow::DrawRectangle ( int x, int y, unsigned int width, unsigned int height ) { if ( fill ) XFillRectangle ( display, window, drawcontext, x, y, width, height ); else XDrawRectangle ( display, window, drawcontext, x, y, width, height ); } void TWindow::DrawString ( int x, int y, char* string ) { if ( fill ) XDrawImageString ( display, window, drawcontext, x, y, string, strlen ( string ) ); else XDrawString ( display, window, drawcontext, x, y, string, strlen ( string ) ); } int TWindow::GetStringWidth ( char *string ) { XCharStruct overall; int ascent, descent, direction; XQueryTextExtents ( display, fontinuse, string, strlen ( string ), &direction, &ascent, &descent, &overall ); return overall.rbearing; } int TWindow::GetStringAscent ( char *string ) { XCharStruct overall; int ascent, descent, direction; XQueryTextExtents ( display, fontinuse, string, strlen ( string ), &direction, &ascent, &descent, &overall ); return ascent; } int TWindow::GetStringDescent ( char *string ) { XCharStruct overall; int ascent, descent, direction; XQueryTextExtents ( display, fontinuse, string, strlen ( string ), &direction, &ascent, &descent, &overall ); return descent; } void TWindow::SetDrawForeground ( unsigned long color ) { XSetForeground ( display, drawcontext, color ); } void TWindow::SetDrawBackground ( unsigned long color ) { XSetBackground ( display, drawcontext, color ); } void TWindow::SetDrawFont ( char *name ) { XUnloadFont ( display, font ); font = XLoadFont ( display, name ); fontinuse = font; XSetFont ( display, drawcontext, font ); } void TWindow::SetDrawFont ( Font fontname ) { fontinuse = fontname; XSetFont ( display, drawcontext, fontname ); } void TWindow::SetDrawLineStyle ( LineStyle linestyle, unsigned int width) { switch ( linestyle ) { case LineStyleSolid: XSetLineAttributes ( display, drawcontext, width, LineSolid, CapRound, JoinRound ); break; case LineStyleOnOffDash: XSetLineAttributes ( display, drawcontext, width, LineOnOffDash, CapRound, JoinRound ); break; case LineStyleDoubleDash: XSetLineAttributes ( display, drawcontext, width, LineDoubleDash, CapRound, JoinRound ); } } void TWindow::SetDrawFillStyle ( FillStyle fillstyle ) { switch ( fillstyle ) { case FillStyleNone: fill = false; break; case FillStyleSolid: fill = true; } } void TWindow::SetDrawArcStyle ( ArcStyle arcstyle ) { switch ( arcstyle ) { case ArcStyleChord: XSetArcMode ( display, drawcontext, ArcChord ); break; case ArcStylePieSlice: XSetArcMode ( display, drawcontext, ArcPieSlice ); } } void TWindow::ClearWindow () { XClearWindow ( display, window ); } void TWindow::AddEvent ( int eventtype, int ID ) { widgetlist->begin->AddEvent ( eventtype, ID ); XSelectInput ( display, window, widgetlist->begin->ExtractMask () | ExposureMask | ResizeRedirectMask ); } void TWindow::RemoveEvent ( int eventtype ) { widgetlist->begin->RemoveEvent ( eventtype ); XSelectInput ( display, window, widgetlist->begin->ExtractMask () | ExposureMask | ResizeRedirectMask ); } void TWindow::AddWidget ( TWidget *widget ) { widgetlist->AddWidget ( widget ); widget->Init ( this ); } void TWindow::RemoveWidget ( TWidget *widget ) { widget->Remove (); widgetlist->RemoveWidget ( widget ); } int TWindow::CheckForEvent () { XEvent ev; if ( XEventsQueued ( display, QueuedAfterFlush ) ) { XNextEvent ( display, &ev ); return GetEvent ( ev ); } else return 0; } int TWindow::WaitForEvent () { int IDreturn; XEvent ev; do XNextEvent ( display, &ev ); while ( ! ( IDreturn = GetEvent ( ev ) ) ); return IDreturn; } int TWindow::GetEvent ( XEvent &ev ) { TWindowListElement *walk; int IDreturn = 0, ID; if ( ev.xany.window == window ) { switch ( ev.type ) { case MotionNotify: pointerx = ev.xmotion.x; pointery = ev.xmotion.y; buttonstatus = NoButtonAction; specialkeystatus = NoSpecialKeyPressed; if ( ev.xmotion.state & Button1Mask ) buttonstatus |= Button1Action; if ( ev.xmotion.state & Button2Mask ) buttonstatus |= Button2Action; if ( ev.xmotion.state & Button3Mask ) buttonstatus |= Button3Action; if ( ev.xmotion.state & ShiftMask ) specialkeystatus |= ShiftKeyPressed; if ( ev.xmotion.state & ControlMask ) specialkeystatus |= ControlKeyPressed; break; case ButtonPress: case ButtonRelease: pointerx = ev.xbutton.x; pointery = ev.xbutton.y; specialkeystatus = NoSpecialKeyPressed; switch ( ev.xbutton.button ) { case Button1: buttonstatus = Button1Action; break; case Button2: buttonstatus = Button2Action; break; case Button3: buttonstatus = Button3Action; break; default: buttonstatus = NoButtonAction; } if ( ev.xbutton.state & ShiftMask ) specialkeystatus |= ShiftKeyPressed; if ( ev.xbutton.state & ControlMask ) specialkeystatus |= ControlKeyPressed; break; case EnterNotify: case LeaveNotify: pointerx = ev.xcrossing.x; pointery = ev.xcrossing.y; break; case Expose: case FocusIn: case FocusOut: break; case KeyPress: case KeyRelease: pointerx = ev.xkey.x; pointery = ev.xkey.y; specialkeystatus = NoSpecialKeyPressed; if ( ev.xmotion.state & ShiftMask ) { specialkeystatus |= ShiftKeyPressed; keypressedcode = XLookupKeysym ( &(ev.xkey), 1 ); } else keypressedcode = XLookupKeysym ( &(ev.xkey), 0 ); if ( ev.xmotion.state & ControlMask ) specialkeystatus |= ControlKeyPressed; break; case ResizeRequest: width = ev.xresizerequest.width; height = ev.xresizerequest.height; break; } } if ( ev.type == Expose ) { walk = windowlist; while ( walk && !IDreturn ) { ID = walk->window->widgetlist->ExtractID ( &ev ); if ( ID && walk->window == this ) IDreturn = ID; walk = walk->next; } } else IDreturn = widgetlist->ExtractID ( &ev ); return IDreturn; } void SetWidgetFont ( char *name ) { XUnloadFont ( display, widgetfont ); widgetfont = XLoadFont ( display, name ); } void SetInputFont ( char *name ) { XUnloadFont ( display, inputfont ); inputfont = XLoadFont ( display, name ); } void initcolors () { XColor exact, Xblue, Xred, Xgreen, Xcyan, Xmagenta, Xorange, Xpink, Xbrown, Xviolet, Xgreenyellow, Xgray, Xyellow, Xdarkgray, Xlightgray; unsigned int depth; Colormap cmap; depth = DefaultDepth( display, screen ); cmap = DefaultColormap( display, screen ); black = BlackPixel( display, screen ); white = WhitePixel( display, screen ); if( depth == 1 ) Xblue.pixel = Xred.pixel = Xgreen.pixel = Xcyan.pixel = Xmagenta.pixel = Xorange.pixel = Xpink.pixel = Xbrown.pixel = Xviolet.pixel = Xgreenyellow.pixel = Xgray.pixel = Xyellow.pixel = Xdarkgray.pixel = Xlightgray.pixel = white; else if ( !XAllocNamedColor ( display, cmap, "yellow", &exact, &Xyellow ) || !XAllocNamedColor ( display, cmap, "blue", &exact, &Xblue ) || !XAllocNamedColor ( display, cmap, "red", &exact, &Xred ) || !XAllocNamedColor ( display, cmap, "green", &exact, &Xgreen ) || !XAllocNamedColor ( display, cmap, "cyan", &exact, &Xcyan ) || !XAllocNamedColor ( display, cmap, "magenta", &exact, &Xmagenta ) || !XAllocNamedColor ( display, cmap, "coral", &exact, &Xorange ) || !XAllocNamedColor ( display, cmap, "pink", &exact, &Xpink ) || !XAllocNamedColor ( display, cmap, "brown", &exact, &Xbrown ) || !XAllocNamedColor ( display, cmap, "violet", &exact, &Xviolet ) || !XAllocNamedColor ( display, cmap, "greenyellow", &exact, &Xgreenyellow ) || !XAllocNamedColor ( display, cmap, "gray", &exact, &Xgray ) || !XAllocNamedColor ( display, cmap, "darkgray", &exact, &Xdarkgray ) || !XAllocNamedColor ( display, cmap, "lightgray", &exact, &Xlightgray ) ) { cerr << "FOUT: kleurtoekenning onmogelijk." << endl; exit ( 1 ); } yellow = Xyellow.pixel; blue = Xblue.pixel; red = Xred.pixel; green = Xgreen.pixel; cyan = Xcyan.pixel; magenta = Xmagenta.pixel; orange = Xorange.pixel; pink = Xpink.pixel; brown = Xbrown.pixel; violet = Xviolet.pixel; greenyellow = Xgreenyellow.pixel; gray = Xgray.pixel; darkgray = Xdarkgray.pixel; lightgray = Xlightgray.pixel; } int GetGlobalEvent ( TWindow* &window, XEvent &ev ) { TWindowListElement *walk = windowlist; int ID; while ( walk ) { if ( ( ID = walk->window->GetEvent ( ev ) ) ) { window = walk->window; return ID; } walk = walk->next; } return 0; } int WaitForGlobalEvent ( TWindow* &window ) { XEvent ev; int IDreturn = 0; do XNextEvent ( display, &ev ); while ( ! ( IDreturn = GetGlobalEvent ( window, ev ) ) ); return IDreturn; } int CheckForGlobalEvent ( TWindow* &window ) { XEvent ev; if ( XEventsQueued ( display, QueuedAfterFlush ) ) { XNextEvent ( display, &ev ); return GetGlobalEvent ( window, ev ); } else return 0; } int main ( int Argc, char *Argv[] ) { int returnval; argc = Argc; argv = new char*[Argc]; for ( int i = 0; i