diff options
author | William Joye <wjoye@cfa.harvard.edu> | 2016-10-27 18:59:29 (GMT) |
---|---|---|
committer | William Joye <wjoye@cfa.harvard.edu> | 2016-10-27 18:59:29 (GMT) |
commit | d4d595fa7fb12903db9227d33d48b2b00120dbd1 (patch) | |
tree | 7d18365de0d6d1b29399b6a17c7eb01c2eb3ed49 /tksao/widget | |
parent | 949f96e29bfe0bd8710d775ce220e597064e2589 (diff) | |
download | blt-d4d595fa7fb12903db9227d33d48b2b00120dbd1.zip blt-d4d595fa7fb12903db9227d33d48b2b00120dbd1.tar.gz blt-d4d595fa7fb12903db9227d33d48b2b00120dbd1.tar.bz2 |
Initial commit
Diffstat (limited to 'tksao/widget')
-rw-r--r-- | tksao/widget/truecolor16.C | 148 | ||||
-rw-r--r-- | tksao/widget/truecolor16.h | 42 | ||||
-rw-r--r-- | tksao/widget/truecolor24.C | 292 | ||||
-rw-r--r-- | tksao/widget/truecolor24.h | 47 | ||||
-rw-r--r-- | tksao/widget/truecolor8.C | 71 | ||||
-rw-r--r-- | tksao/widget/truecolor8.h | 42 | ||||
-rw-r--r-- | tksao/widget/widget.C | 813 | ||||
-rw-r--r-- | tksao/widget/widget.h | 203 |
8 files changed, 1658 insertions, 0 deletions
diff --git a/tksao/widget/truecolor16.C b/tksao/widget/truecolor16.C new file mode 100644 index 0000000..ed0aa60 --- /dev/null +++ b/tksao/widget/truecolor16.C @@ -0,0 +1,148 @@ +// Copyright (C) 1999-2016 +// Smithsonian Astrophysical Observatory, Cambridge, MA, USA +// For conditions of distribution and use, see copyright notice in "copyright" + +#include "truecolor16.h" +#include "util.h" + +TrueColor16::TrueColor16(Visual* visual) +{ +#if !(_WIN32) + rx_ = visual->red_mask; + gx_ = visual->green_mask; + bx_ = visual->blue_mask; +#endif +#if _WIN32 + // windows masks are plain wrong + rx_ = 0x7C00; + gx_ = 0x03E0; + bx_ = 0x001F; +#endif + + rm_ = decodeMask((unsigned short)rx_, &rs_); + gm_ = decodeMask((unsigned short)gx_, &gs_); + bm_ = decodeMask((unsigned short)bx_, &bs_); +} + +unsigned short TrueColor16::decodeMask(unsigned short mask, int* s) +{ + // first calc ffs for mask + unsigned short m1 = mask; + int m1s; + for (m1s=0; m1s<16; m1s++) { + if (m1 & 0x1) + break; + m1 >>= 1; + } + + // then shift mask to mask a char + for (int i=0; i<16; i++) { + if (mask & 0x8000) + break; + mask <<= 1; + } + mask >>= 8; + + // now calc ffs for new mask + unsigned short m2 = mask; + int m2s; + for (m2s=0; m2s<16; m2s++) { + if (m2 & 0x1) + break; + m2 >>= 1; + } + + *s = m1s-m2s; + return mask; +} + +void TrueColor16::encodeTrueColor(XColor* src, char* dest, XImage* ximage) +{ + if (!ximage) + return; + + int msb = ximage->byte_order; + + unsigned short r = (unsigned char)src->red; + unsigned short g = (unsigned char)src->green; + unsigned short b = (unsigned char)src->blue; + unsigned short v = 0; + v |= rs_>0 ? ((r & rm_) << rs_) : ((r & rm_) >> -rs_); + v |= gs_>0 ? ((g & gm_) << gs_) : ((g & gm_) >> -gs_); + v |= bs_>0 ? ((b & bm_) << bs_) : ((b & bm_) >> -bs_); + + if ((!msb && lsb()) || (msb && !lsb())) + memcpy(dest, &v, 2); + else { + unsigned char* rr = (unsigned char*)(&v); + *(dest) = *(rr+1); + *(dest+1) = *(rr); + } +} + +void TrueColor16::decodeTrueColor(char* src, XColor* dest, XImage* ximage) +{ + if (!ximage) + return; + + int msb = ximage->byte_order; + unsigned short v = 0; + + if ((!msb && lsb()) || (msb && !lsb())) + memcpy(dest, &v, 2); + else { + unsigned char* rr = (unsigned char*)(&v); + *(rr+1) = *(src+0); + *(rr+0) = *(src+1); + } + + dest->red = (unsigned short)((v & rx_) >> rs_); + dest->green = (unsigned short)((v & gx_) >> gs_); + dest->blue = (unsigned short)((v & bx_) >> bs_); +} + +void TrueColor16::encodeTrueColor(unsigned char* src, XImage* ximage) +{ + int& width = ximage->width; + int& height = ximage->height; + char* data = ximage->data; + int msb = ximage->byte_order; + + const unsigned char* ptr = src; + if ((!msb && lsb()) || (msb && !lsb())) { + for (int jj=0; jj<height; jj++) { + char* dest = data + jj*ximage->bytes_per_line; // may be padded at the end + + for (int ii=0; ii<width; ii++, dest+=2, ptr+=3) { + unsigned short r = ptr[0]; + unsigned short g = ptr[1]; + unsigned short b = ptr[2]; + unsigned short v = 0; + v |= rs_>0 ? ((r & rm_) << rs_) : ((r & rm_) >> -rs_); + v |= gs_>0 ? ((g & gm_) << gs_) : ((g & gm_) >> -gs_); + v |= bs_>0 ? ((b & bm_) << bs_) : ((b & bm_) >> -bs_); + + memcpy(dest, &v, 2); + } + } + } + else { + for (int jj=0; jj<height; jj++) { + char* dest = data + jj*ximage->bytes_per_line; + + for (int ii=0; ii<width; ii++, dest+=2, ptr+=3) { + unsigned short r = ptr[0]; + unsigned short g = ptr[1]; + unsigned short b = ptr[2]; + unsigned short v = 0; + v |= rs_>0 ? ((r & rm_) << rs_) : ((r & rm_) >> -rs_); + v |= gs_>0 ? ((g & gm_) << gs_) : ((g & gm_) >> -gs_); + v |= bs_>0 ? ((b & bm_) << bs_) : ((b & bm_) >> -bs_); + + unsigned char* rr = (unsigned char*)(&v); + *(dest) = *(rr+1); + *(dest+1) = *(rr); + } + } + } +} diff --git a/tksao/widget/truecolor16.h b/tksao/widget/truecolor16.h new file mode 100644 index 0000000..ba60c35 --- /dev/null +++ b/tksao/widget/truecolor16.h @@ -0,0 +1,42 @@ +// Copyright (C) 1999-2016 +// Smithsonian Astrophysical Observatory, Cambridge, MA, USA +// For conditions of distribution and use, see copyright notice in "copyright" + +#ifndef __truecolor16_h__ +#define __truecolor16_h__ + +#include <string.h> + +#include <iostream> +#include <sstream> +#include <iomanip> +using namespace std; + +#include <tk.h> + +class TrueColor16 { + protected: + unsigned long rx_; + unsigned long gx_; + unsigned long bx_; + unsigned short rm_; + unsigned short gm_; + unsigned short bm_; + int rs_; + int gs_; + int bs_; + + private: + unsigned short decodeMask(unsigned short, int*); + + protected: + void decodeTrueColor(char*, XColor*, XImage*); + void encodeTrueColor(XColor*, char*, XImage*); + void encodeTrueColor(unsigned char*, XImage*); + + public: + TrueColor16(Visual*); +}; + +#endif + diff --git a/tksao/widget/truecolor24.C b/tksao/widget/truecolor24.C new file mode 100644 index 0000000..a1d0673 --- /dev/null +++ b/tksao/widget/truecolor24.C @@ -0,0 +1,292 @@ +// Copyright (C) 1999-2016 +// Smithsonian Astrophysical Observatory, Cambridge, MA, USA +// For conditions of distribution and use, see copyright notice in "copyright" + +#include "truecolor24.h" +#include "util.h" + +TrueColor24::TrueColor24(Visual* visual) +{ +#if !(_WIN32 || MAC_OSX_TK) + ax_ = 0; + rx_ = visual->red_mask; + gx_ = visual->green_mask; + bx_ = visual->blue_mask; +#endif +#if MAC_OSX_TK + ax_ = 0xFF000000; + rx_ = 0x00FF0000; + gx_ = 0x0000FF00; + bx_ = 0x000000FF; +#endif +#if _WIN32 + // windows masks are plain wrong + ax_ = 0; + rx_ = 0x00FF0000; + gx_ = 0x0000FF00; + bx_ = 0x000000FF; +#endif + + rs_ = decodeMask((unsigned long)rx_); + gs_ = decodeMask((unsigned long)gx_); + bs_ = decodeMask((unsigned long)bx_); + as_ = decodeMask((unsigned long)ax_); +} + +int TrueColor24::decodeMask(unsigned long mask) +{ + switch (mask) { + case 0: + return 0; + case 0xff: + return 0; + case 0xff00: + return 8; + case 0xff0000: + return 16; + case 0xff000000: + return 24; + } + return 0; +} + +void TrueColor24::encodeTrueColor(XColor* src, char* dest, XImage* ximage) +{ + if (!ximage) + return; + + switch (ximage->bits_per_pixel) { + case 24: + encodeTrueColor24(src, dest, ximage); + break; + case 32: + encodeTrueColor32(src, dest, ximage); + break; + } +} + +void TrueColor24::decodeTrueColor(char* src, XColor* dest, XImage* ximage) +{ + if (!ximage) + return; + + switch (ximage->bits_per_pixel) { + case 24: + decodeTrueColor24(src, dest, ximage); + break; + case 32: + decodeTrueColor32(src, dest, ximage); + break; + } +} + +void TrueColor24::encodeTrueColor24(XColor* src, char* dest, XImage* ximage) +{ + int msb = ximage->byte_order; + + unsigned int r = (unsigned char)src->red; + unsigned int g = (unsigned char)src->green; + unsigned int b = (unsigned char)src->blue; + unsigned int v = 0; + v |= r << rs_; + v |= g << gs_; + v |= b << bs_; + + if ((!msb && lsb()) || (msb && !lsb())) + memcpy(dest, &v, 3); + else { + unsigned char* rr = (unsigned char*)(&v); + *(dest+0) = *(rr+3); + *(dest+1) = *(rr+2); + *(dest+2) = *(rr+1); + } +} + +void TrueColor24::decodeTrueColor24(char* src, XColor* dest, XImage* ximage) +{ + int msb = ximage->byte_order; + unsigned int v = 0; + + if ((!msb && lsb()) || (msb && !lsb())) + memcpy(&v, src, 3); + else { + unsigned char* rr = (unsigned char*)(&v); + *(rr+3) = *(src+0); + *(rr+2) = *(src+1); + *(rr+1) = *(src+2); + } + + dest->red = (unsigned short)((v & rx_) >> rs_); + dest->green = (unsigned short)((v & gx_) >> gs_); + dest->blue = (unsigned short)((v & bx_) >> bs_); +} + +void TrueColor24::encodeTrueColor32(XColor* src, char* dest, XImage* ximage) +{ + int msb = ximage->byte_order; + + unsigned int r = (unsigned char)src->red; + unsigned int g = (unsigned char)src->green; + unsigned int b = (unsigned char)src->blue; + unsigned int v = 0; +#ifdef MAC_OSX_TK + unsigned int a = 0xff; + v |= a << as_; +#endif + v |= r << rs_; + v |= g << gs_; + v |= b << bs_; + + if ((!msb && lsb()) || (msb && !lsb())) + memcpy(dest, &v, 4); + else { + unsigned char* rr = (unsigned char*)(&v); + *(dest+0) = *(rr+3); + *(dest+1) = *(rr+2); + *(dest+2) = *(rr+1); + *(dest+3) = *(rr+0); + } +} + +void TrueColor24::decodeTrueColor32(char* src, XColor* dest, XImage* ximage) +{ + int msb = ximage->byte_order; + unsigned int v = 0; + + if ((!msb && lsb()) || (msb && !lsb())) + memcpy(dest, &v, 4); + else { + unsigned char* rr = (unsigned char*)(&v); + *(rr+3) = *(src); + *(rr+2) = *(src+1); + *(rr+1) = *(src+2); + *(rr+0) = *(src+3); + } + + dest->red = (unsigned short)((v & rx_) >> rs_); + dest->green = (unsigned short)((v & gx_) >> gs_); + dest->blue = (unsigned short)((v & bx_) >> bs_); +} +void TrueColor24::encodeTrueColor(unsigned char* src, XImage* ximage) +{ + if (!ximage) + return; + + switch (ximage->bits_per_pixel) { + case 24: + encodeTrueColor24(src, ximage); + break; + case 32: + encodeTrueColor32(src, ximage); + break; + } +} + +void TrueColor24::encodeTrueColor24(unsigned char* src, XImage* ximage) +{ + int& width = ximage->width; + int& height = ximage->height; + char* data = ximage->data; + int bytesPerPixel = ximage->bits_per_pixel/8; + int msb = ximage->byte_order; + + const unsigned char* ptr = src; + if ((!msb && lsb()) || (msb && !lsb())) { + for (int jj=0; jj<height; jj++) { + char* dest = data + jj*ximage->bytes_per_line; + + for (int ii=0; ii<width; ii++, dest+=bytesPerPixel, ptr+=3) { + unsigned int r = ptr[0]; + unsigned int g = ptr[1]; + unsigned int b = ptr[2]; + unsigned int v = 0; + v |= r << rs_; + v |= g << gs_; + v |= b << bs_; + + memcpy(dest, &v, 3); + } + } + } + else { + for (int jj=0; jj<height; jj++) { + char* dest = data + jj*ximage->bytes_per_line; + + for (int ii=0; ii<width; ii++, dest+=bytesPerPixel, ptr+=3) { + unsigned int r = ptr[0]; + unsigned int g = ptr[1]; + unsigned int b = ptr[2]; + unsigned int v = 0; + v |= r << rs_; + v |= g << gs_; + v |= b << bs_; + + unsigned char* rr = (unsigned char*)(&v); + *(dest) = *(rr+3); + *(dest+1) = *(rr+2); + *(dest+2) = *(rr+1); + } + } + } +} + +void TrueColor24::encodeTrueColor32(unsigned char* src, XImage* ximage) +{ + int& width = ximage->width; + int& height = ximage->height; + char* data = ximage->data; + int bytesPerPixel = ximage->bits_per_pixel/8; + int msb = ximage->byte_order; + + const unsigned char* ptr = src; + if ((!msb && lsb()) || (msb && !lsb())) { + for (int jj=0; jj<height; jj++) { + // the line may be padded at the end + char* dest = data + jj*ximage->bytes_per_line; + + for (int ii=0; ii<width; ii++, dest+=bytesPerPixel, ptr+=3) { + unsigned int r = ptr[0]; + unsigned int g = ptr[1]; + unsigned int b = ptr[2]; + unsigned int v = 0; +#ifdef MAC_OSX_TK + unsigned int a = 0xff; + v |= a << as_; +#endif + v |= r << rs_; + v |= g << gs_; + v |= b << bs_; + + memcpy(dest, &v, 4); + } + } + } + else { + for (int jj=0; jj<height; jj++) { + // the line may be padded at the end + char* dest = data + jj*ximage->bytes_per_line; + + for (int ii=0; ii<width; ii++, dest+=bytesPerPixel, ptr+=3) { + unsigned int r = ptr[0]; + unsigned int g = ptr[1]; + unsigned int b = ptr[2]; + unsigned int v = 0; +#ifdef MAC_OSX_TK + unsigned int a = 0xff; + v |= a << as_; +#endif + v |= r << rs_; + v |= g << gs_; + v |= b << bs_; + + unsigned char* rr = (unsigned char*)(&v); + *(dest) = *(rr+3); + *(dest+1) = *(rr+2); + *(dest+2) = *(rr+1); + *(dest+3) = *(rr); + } + } + } +} + + diff --git a/tksao/widget/truecolor24.h b/tksao/widget/truecolor24.h new file mode 100644 index 0000000..7d106bd --- /dev/null +++ b/tksao/widget/truecolor24.h @@ -0,0 +1,47 @@ +// Copyright (C) 1999-2016 +// Smithsonian Astrophysical Observatory, Cambridge, MA, USA +// For conditions of distribution and use, see copyright notice in "copyright" + +#ifndef __truecolor24_h__ +#define __truecolor24_h__ + +#include <string.h> + +#include <iostream> +#include <sstream> +#include <iomanip> +using namespace std; + +#include <tk.h> + +class TrueColor24 { + protected: + unsigned long rx_; + unsigned long gx_; + unsigned long bx_; + unsigned long ax_; + int rs_; + int gs_; + int bs_; + int as_; + + private: + int decodeMask(unsigned long); + void decodeTrueColor24(char*, XColor*, XImage*); + void decodeTrueColor32(char*, XColor*, XImage*); + void encodeTrueColor24(XColor*, char*, XImage*); + void encodeTrueColor24(unsigned char*, XImage*); + void encodeTrueColor32(XColor*, char*, XImage*); + void encodeTrueColor32(unsigned char*, XImage*); + + protected: + void decodeTrueColor(char*, XColor*, XImage*); + void encodeTrueColor(XColor*, char*, XImage*); + void encodeTrueColor(unsigned char*, XImage*); + + public: + TrueColor24(Visual*); +}; + +#endif + diff --git a/tksao/widget/truecolor8.C b/tksao/widget/truecolor8.C new file mode 100644 index 0000000..98ef6bf --- /dev/null +++ b/tksao/widget/truecolor8.C @@ -0,0 +1,71 @@ +// Copyright (C) 1999-2016 +// Smithsonian Astrophysical Observatory, Cambridge, MA, USA +// For conditions of distribution and use, see copyright notice in "copyright" + +#include "truecolor8.h" +#include "util.h" + +TrueColor8::TrueColor8(Visual* visual) +{ + +#if !(_WIN32) + rx_ = visual->red_mask; + gx_ = visual->green_mask; + bx_ = visual->blue_mask; +#endif +#if _WIN32 + // windows masks are plain wrong + rx_ = 0xE0; + gx_ = 0x18; + bx_ = 0x07; +#endif + + rm_ = decodeMask((unsigned char)rx_, &rs_); + gm_ = decodeMask((unsigned char)rx_, &gs_); + bm_ = decodeMask((unsigned char)rx_, &bs_); +} + +unsigned char TrueColor8::decodeMask(unsigned char mask, int* s) +{ + *s=0; + for (int i=0; i<8; i++, (*s)++) { + if (mask & 0x80) + break; + mask <<= 1; + } + return mask; +} + +void TrueColor8::encodeTrueColor(XColor* src, char* dest, XImage* ximage) +{ + *dest = + ((((unsigned char)src->blue) & bm_) >> bs_) | + ((((unsigned char)src->green) & gm_) >> gs_) | + ((((unsigned char)src->red) & rm_) >> rs_); +} + +void TrueColor8::decodeTrueColor(char* src, XColor* dest, XImage* ximage) +{ + dest->red = (unsigned short)((*src & rx_) >> rs_); + dest->green = (unsigned short)((*src & gx_) >> gs_); + dest->blue = (unsigned short)((*src & bx_) >> bs_); +} + +void TrueColor8::encodeTrueColor(unsigned char* src, XImage* ximage) +{ + int& width = ximage->width; + int& height = ximage->height; + char* data = ximage->data; + + const unsigned char* ptr = src; + for (int j=0; j<height; j++) { + char* dest = data + j*ximage->bytes_per_line; + + for (int i=0; i<width; i++, dest++, ptr+=3) + *dest = + ((ptr[0] & rm_) >> rs_) | + ((ptr[1] & gm_) >> gs_) | + ((ptr[2] & bm_) >> bs_); + } +} + diff --git a/tksao/widget/truecolor8.h b/tksao/widget/truecolor8.h new file mode 100644 index 0000000..55d0fdc --- /dev/null +++ b/tksao/widget/truecolor8.h @@ -0,0 +1,42 @@ +// Copyright (C) 1999-2016 +// Smithsonian Astrophysical Observatory, Cambridge, MA, USA +// For conditions of distribution and use, see copyright notice in "copyright" + +#ifndef __truecolor8_h__ +#define __truecolor8_h__ + +#include <string.h> + +#include <iostream> +#include <sstream> +#include <iomanip> +using namespace std; + +#include <tk.h> + +class TrueColor8 { + protected: + unsigned long rx_; + unsigned long gx_; + unsigned long bx_; + unsigned char rm_; + unsigned char gm_; + unsigned char bm_; + int rs_; + int gs_; + int bs_; + + private: + unsigned char decodeMask(unsigned char, int*); + + protected: + void decodeTrueColor(char*, XColor*, XImage*); + void encodeTrueColor(XColor*, char*, XImage*); + void encodeTrueColor(unsigned char*, XImage*); + + public: + TrueColor8(Visual*); +}; + +#endif + diff --git a/tksao/widget/widget.C b/tksao/widget/widget.C new file mode 100644 index 0000000..743ce7b --- /dev/null +++ b/tksao/widget/widget.C @@ -0,0 +1,813 @@ +// Copyright (C) 1999-2016 +// Smithsonian Astrophysical Observatory, Cambridge, MA, USA +// For conditions of distribution and use, see copyright notice in "copyright" + +#include <tkInt.h> + +#include "widget.h" +#include "util.h" + +// Tk Canvas Widget Functions Declaration + +int WidgetConfigProc(Tcl_Interp* interp, Tk_Canvas canvas, Tk_Item* item, + int argc, Tcl_Obj *const argv[], int flags) +{ + return WIDGET(item).configure(argc, (const char**)argv, flags); +} + +int WidgetCoordProc(Tcl_Interp* interp, Tk_Canvas canvas, Tk_Item* item, + int argc, Tcl_Obj *const argv[]) +{ + return WIDGET(item).coordProc(argc, (char**)argv); +} + +void WidgetDeleteProc(Tk_Canvas canvas, Tk_Item* item, Display* display) +{ + delete ((WidgetOptions*)item)->widget; +} + +void WidgetDisplayProc(Tk_Canvas canvas, Tk_Item* item, Display* display, + Drawable draw, int x, int y, int width, int height) +{ + WIDGET(item).displayProc(draw, x, y, width, height); +} + +double WidgetPointProc(Tk_Canvas canvas, Tk_Item* item, double* point) +{ + return WIDGET(item).pointProc(point); +} + +int WidgetAreaProc(Tk_Canvas canvas, Tk_Item* item, double* bbox) +{ + return WIDGET(item).areaProc(bbox); +} + +int WidgetPostscriptProc(Tcl_Interp* interp, Tk_Canvas canvas, + Tk_Item* item, int prepass) +{ + return WIDGET(item).postscriptProc(prepass); +} + +void WidgetScaleProc(Tk_Canvas canvas, Tk_Item* item, + double Ox, double Oy , double Sx, double Sy) +{ + WIDGET(item).scaleProc(Ox, Oy, Sx, Sy); +} + +void WidgetTranslateProc(Tk_Canvas canvas, Tk_Item* item, double x, double y) +{ + WIDGET(item).translateProc(x, y); +} + +int WidgetIndexProc(Tcl_Interp* interp, Tk_Canvas canvas, Tk_Item* item, + char indexString, int* indexPtr) +{ + WIDGET(item).indexProc(indexString, indexPtr); + return 1; +} + +void WidgetICursorProc(Tk_Canvas canvas, Tk_Item* item, int index) +{ + WIDGET(item).icursorProc(index); +} + +int WidgetSelectionProc(Tk_Canvas canvas, Tk_Item* item, + int offset, char* buffer, int maxBytes) +{ + WIDGET(item).selectionProc(offset, buffer, maxBytes); + return 1; +} + +void WidgetInsertProc(Tk_Canvas canvas, Tk_Item* item, int index, char* string) +{ + WIDGET(item).insertProc(index, string); +} + +void WidgetDCharsProc(Tk_Canvas canvas, Tk_Item* item, int first, int last) +{ + WIDGET(item).dcharsProc(first, last); +} + +int WidgetParse(ClientData widget, Tcl_Interp* interp, int argc, + const char** argv) +{ + int result; + Tcl_Preserve(widget); + + if (argc >= 2 && !strncmp(argv[1],"config",6)) + result = ((Widget*)widget)->configCmd(argc-2, argv+2); + + else { + istringstream istr(ios::in|ios::out); + ostream ostr(istr.rdbuf()); + + for (int i=1; i<argc; i++) + ostr << argv[i] << " "; + ostr << ends; + + result = ((Widget*)widget)->parse(istr); + } + + Tcl_Release(widget); + return result; +} + +// Member Functions + +Widget::Widget(Tcl_Interp* interp_, Tk_Canvas canvas_, Tk_Item* item) : + interp(interp_), canvas(canvas_) +{ + // initialize item ptr to this. This is the method the canvas widget procs + // know how to call member functions. + ((WidgetOptions*)item)->widget = this; + + // init members + options = (WidgetOptions*)item; + configSpecs = NULL; + tkwin = Tk_CanvasTkwin(canvas); + display = Tk_Display(tkwin); + screenNumber = Tk_ScreenNumber(tkwin); + visual = Tk_Visual(tkwin); + depth = Tk_Depth(tkwin); + + pixmap = 0; + widgetGC = NULL; + visible = True; + + originX = 0; + originY = 0; + + // this is needed because of a problem with Tk_ConfigureWidget + options->cmdName = NULL; + options->helvetica = NULL; + options->courier = NULL; + options->times = NULL; + + cmd = NULL; + result = TCL_OK; + + // postscript + psLevel = 2; + psResolution = 300; + psColorSpace = RGB; +} + +Widget::~Widget() +{ + // free the options + Tk_FreeOptions(configSpecs, (char*)this->options, display, 0); + + // clean up tcl command + if (cmd) { + Tcl_DeleteCommand(interp, cmd); + delete [] cmd; + } + + // clean up pixmap resources + if (pixmap) + Tk_FreePixmap(display, pixmap); + + if (widgetGC) + XFreeGC(display, widgetGC); +} + +void Widget::error(const char* m) +{ + Tcl_AppendResult(interp, m, NULL); + result = TCL_ERROR; +} + +void Widget::msg(const char* m) +{ + Tcl_AppendResult(interp, m, NULL); +} + +int Widget::configure(int argc, const char** argv, int flags) +{ + if (Tk_ConfigureWidget(interp, tkwin, configSpecs, argc, argv, + (char*)this->options, flags) != TCL_OK) + return TCL_ERROR; + + if (flags != TK_CONFIG_ARGV_ONLY) { + // create command + createCommand(); + updateBBox(); + invalidPixmap(); + } + else { + // configure command + if (configSpecs[CONFIGCOMMAND].specFlags & TK_CONFIG_OPTION_SPECIFIED) + createCommand(); + + if ((configSpecs[CONFIGX].specFlags & TK_CONFIG_OPTION_SPECIFIED) || + (configSpecs[CONFIGY].specFlags & TK_CONFIG_OPTION_SPECIFIED) || + (configSpecs[CONFIGWIDTH].specFlags & TK_CONFIG_OPTION_SPECIFIED) || + (configSpecs[CONFIGHEIGHT].specFlags & TK_CONFIG_OPTION_SPECIFIED) || + (configSpecs[CONFIGANCHOR].specFlags & TK_CONFIG_OPTION_SPECIFIED)) + updateBBox(); + + if ((configSpecs[CONFIGWIDTH].specFlags & TK_CONFIG_OPTION_SPECIFIED) || + (configSpecs[CONFIGHEIGHT].specFlags & TK_CONFIG_OPTION_SPECIFIED)) + invalidPixmap(); + + if ((configSpecs[CONFIGX].specFlags & TK_CONFIG_OPTION_SPECIFIED) || + (configSpecs[CONFIGY].specFlags & TK_CONFIG_OPTION_SPECIFIED) || + (configSpecs[CONFIGWIDTH].specFlags & TK_CONFIG_OPTION_SPECIFIED) || + (configSpecs[CONFIGHEIGHT].specFlags & TK_CONFIG_OPTION_SPECIFIED) || + (configSpecs[CONFIGANCHOR].specFlags & TK_CONFIG_OPTION_SPECIFIED)) + redraw(); + } + + return TCL_OK; +} + +// Required Canvas Functions + +int Widget::coordProc(int argc, char** argv) +{ + char xStr[TCL_DOUBLE_SPACE], yStr[TCL_DOUBLE_SPACE]; + + switch (argc) { + + // print the current values + case 0: + Tcl_PrintDouble(interp, options->x, xStr); + Tcl_PrintDouble(interp, options->y, yStr); + Tcl_AppendResult(interp, xStr, " ", yStr, NULL); + return TCL_OK; + + // set current x&y to new values + case 2: { + double x0, y0; + if ((Tk_CanvasGetCoord(interp, canvas, argv[0], &x0) != TCL_OK) || + (Tk_CanvasGetCoord(interp, canvas, argv[1], &y0) != TCL_OK)) + return TCL_ERROR; + options->x = (int)x0; + options->y = (int)y0; + updateBBox(); + return TCL_OK; + } + + // else, error message + default: + Tcl_AppendResult(interp, "wrong # coordinates: expected 0 or 2", NULL); + return TCL_ERROR; + } +} + +// Widget Display Procedure. It takes the contents of the pixmap and +// after clipping, copies it into the drawable. + +void Widget::displayProc(Drawable draw, int clipX, int clipY, + int clipWidth, int clipHeight) +{ + if (visible == False) + return; + + // create bbox + BBox bb(clipX, clipY, clipX+clipWidth, clipY+clipHeight); + + // update the pixmap from ximage/graphics + if (updatePixmap(bb) != TCL_OK) + return; // something is wrong, bail out + + // define pixmap clip region + // NOTE: it appears that the canvas coord system is 1 to n, width/height = n + // with the original of value 1,1 located at upper left corner + int pmX, pmY, pmWidth, pmHeight; + + if (clipX > options->item.x1) { + pmX = clipX - options->item.x1; + pmWidth = options->item.x2 - clipX; + } + else { + pmX = 0; + if ((clipX + clipWidth) < options->item.x2) + pmWidth = clipX + clipWidth - options->item.x1; + else + pmWidth = options->item.x2 - options->item.x1; + } + + if (clipY > options->item.y1) { + pmY = clipY - options->item.y1; + pmHeight = options->item.y2 - clipY; + } + else { + pmY = 0; + if ((clipY + clipHeight) < options->item.y2) + pmHeight = clipY + clipHeight - options->item.y1; + else + pmHeight = options->item.y2 - options->item.y1; + } + + // convert to canvas coords + short drawX, drawY; + Tk_CanvasDrawableCoords(canvas, (double)(options->item.x1 + pmX), + (double)(options->item.y1 + pmY), &drawX, &drawY); + + // just in case + if (!widgetGC) + widgetGC = XCreateGC(display, Tk_WindowId(tkwin), 0, NULL); + + // set the clip region and copy the pixmap into the drawable + XSetClipOrigin(display, widgetGC, drawX - pmX, drawY - pmY); + XCopyArea(display, pixmap, draw, widgetGC, pmX, pmY, (unsigned int) pmWidth, + (unsigned int) pmHeight, drawX, drawY); +} + +double Widget::pointProc(double* point) +{ + double xdiff, ydiff; + + if (point[0] < options->item.x1) + xdiff = options->item.x1 - point[0]; + else if (point[0] > options->item.x2) + xdiff = point[0] - options->item.x2; + else + xdiff = 0; + + if (point[1] < options->item.y1) + ydiff = options->item.y1 - point[1]; + else if (point[1] > options->item.y2) + ydiff = point[1] - options->item.y2; + else + ydiff = 0; + + return hypot(xdiff, ydiff); +} + +int Widget::areaProc(double* bbox) +{ + if ((bbox[2] <= options->item.x1) || (bbox[0] >= options->item.x2) || + (bbox[3] <= options->item.y1) || (bbox[1] >= options->item.y2)) + return -1; // item is outside bbox + + if ((bbox[0] <= options->item.x1) && (bbox[1] <= options->item.y1) && + (bbox[2] >= options->item.x2) && (bbox[3] >= options->item.y2)) + return 1; // item is inside bbox + + return 0; // item overlaps bbox +} + +int Widget::postscriptProc(int prepass) +{ + return TCL_OK; +} + +void Widget::scaleProc(double Ox, double Oy, double Sx, double Sy) +{ + // translate to (Ox,Oy), scale by (Sx,Sy), translate back from (Ox,Oy) + options->x = (int)(Ox + (Sx * (options->x - Ox))); + options->y = (int)(Oy + (Sy * (options->y - Oy))); + options->width = (int)(options->width * Sx); + options->height = (int)(options->height * Sy); + + updateBBox(); + invalidPixmap(); // width and height have changed +} + +void Widget::translateProc(double deltaX, double deltaY) +{ + options->x += (int)deltaX; + options->y += (int)deltaY; + + updateBBox(); +} + +// Subcommand Functions + +int Widget::configCmd(int argc, const char** argv) +{ + switch (argc) { + case 0: + return Tk_ConfigureInfo(interp, tkwin, configSpecs, (char*)this->options, NULL, 0); + case 1: + return Tk_ConfigureInfo(interp, tkwin, configSpecs, + (char*)this->options, argv[0],0); + default: + return configure(argc, argv, TK_CONFIG_ARGV_ONLY); + } +} + +void Widget::getHeightCmd() +{ + ostringstream str; + str << options->height << ends; + Tcl_AppendResult(interp, str.str().c_str(), NULL); +} + +void Widget::getWidthCmd() +{ + ostringstream str; + str << options->width << ends; + Tcl_AppendResult(interp, str.str().c_str(), NULL); +} + +void Widget::hideCmd() +{ + visible = False; + redraw(); +} + +void Widget::queryCursorCmd() +{ + Window root, child; + int rootx,rooty,winx,winy; + unsigned int msk; + XQueryPointer(display,Tk_WindowId(tkwin),&root,&child, + &rootx,&rooty,&winx,&winy,&msk); + +#ifdef MAC_OSX_TK + // XQueryPointer: Only a partial implementation + // only rootx,rooty are valid + int xx,yy; + Tk_GetRootCoords(tkwin,&xx,&yy); + winx = rootx-xx; + winy = rooty-yy; +#endif + +#ifdef _WIN32 + winx = rootx; + winy = rooty; +#endif + + ostringstream str; + str << winx << ' ' << winy << ends; + Tcl_AppendResult(interp, str.str().c_str(), NULL); +} + +void Widget::resetCmd() +{ + reset(); + invalidPixmap(); + redraw(); +} + +void Widget::showCmd() +{ + visible = True; + redraw(); +} + +// Private Member Functions + +void Widget::createCommand() +{ + if (cmd) { + Tcl_DeleteCommand(interp, cmd); + if (cmd) + delete [] cmd; + } + + cmd = new char[strlen(options->cmdName)+1]; + strcpy(cmd, options->cmdName); + Tcl_CreateCommand(interp, cmd, WidgetParse, (ClientData)this, NULL); +} + +int Widget::checkArgs(int should, int argc, char** argv) +{ + // if should is negative, don't check + if (should >= 0) { + if (should != argc) { + ostringstream str; + str << should << '\0'; + Tcl_AppendResult(interp, "wrong # args: requires ", str.str().c_str(), + " args.", NULL); + return TCL_ERROR; + } + else + return TCL_OK; + } + + return TCL_OK; +} + +double Widget::getDisplayRatio() +{ +#ifdef MAC_OSX_TK + return 1.416; +#else + return 25.4/72 * + DisplayWidth(display, screenNumber) / + DisplayWidthMM(display, screenNumber); +#endif +} + +void Widget::invalidPixmap() +{ + if (pixmap) + Tk_FreePixmap(display, pixmap); + pixmap = 0; +} + +void Widget::redraw() +{ + Tk_CanvasEventuallyRedraw(canvas, options->item.x1, options->item.y1, + options->item.x2, options->item.y2); +} + +void Widget::redraw(BBox bb) +{ + // bb in canvas coords + // we need to expand by 1, i don't know why + Tk_CanvasEventuallyRedraw(canvas, (int)bb.ll[0], (int)bb.ll[1], + (int)bb.ur[0]+1, (int)bb.ur[1]+1); +} + +void Widget::redrawNow() +{ + Tk_CanvasEventuallyRedraw(canvas, options->item.x1, options->item.y1, + options->item.x2, options->item.y2); + Tcl_DoOneEvent(TCL_IDLE_EVENTS); +} + +void Widget::redrawNow(BBox bb) +{ + // bb in canvas coords + // we need to expand by 1, i don't know why + Tk_CanvasEventuallyRedraw(canvas, (int)bb.ll[0], (int)bb.ll[1], + (int)bb.ur[0]+1, (int)bb.ur[1]+1); + Tcl_DoOneEvent(TCL_IDLE_EVENTS); +} + +void Widget::forceUpdate() +{ + Tcl_DoOneEvent(TCL_IDLE_EVENTS); +} + +// Update Bounding Box. For image at (n,n) with size (m,m), +// bbox is defined from (n,n) to (n+m,n+m) + +void Widget::updateBBox() +{ + originX = options->x; + originY = options->y; + + int& ww = options->width; + int& hh = options->height; + + // Modify position point using anchor information. + switch (options->anchor) { + case TK_ANCHOR_N: + originX -= ww/2; + break; + case TK_ANCHOR_NE: + originX -= ww; + break; + case TK_ANCHOR_E: + originX -= ww; + originY -= hh/2; + break; + case TK_ANCHOR_SE: + originX -= ww; + originY -= hh; + break; + case TK_ANCHOR_S: + originX -= ww/2; + originY -= hh; + break; + case TK_ANCHOR_SW: + originY -= hh; + break; + case TK_ANCHOR_W: + originY -= hh/2; + break; + case TK_ANCHOR_NW: + break; + case TK_ANCHOR_CENTER: + originX -= ww/2; + originY -= hh/2; + break; + } + + // Update item item + options->item.x1 = originX; + options->item.y1 = originY; + options->item.x2 = originX + options->width; + options->item.y2 = originY + options->height; +} + +int Widget::getColor(const char* str) +{ + XColor* cc= NULL; + // starting with tk8.6, colors are W3C based, not X11 + if (!strncmp(str,"green",5) || !strncmp(str,"GREEN",5)) + cc = Tk_GetColor(interp, tkwin, "lime"); + else + cc = Tk_GetColor(interp, tkwin, str); + + return cc ? cc->pixel : 0; +} + +XColor* Widget::getXColor(const char* str) +{ + // note: Tk_GetColor can return an XColor without valid red,green,blue + // if common colorname is used. (uses XAllocNamedColor). + // force an hash string instead (uses XAllocColor). + + XColor* cc=NULL; + if (!strncmp(str,"white",5)) + cc = Tk_GetColor(interp, tkwin, "#ffffff"); + else if (!strncmp(str,"black",5)) + cc = Tk_GetColor(interp, tkwin, "#000000"); + else if (!strncmp(str,"red",3)) + cc = Tk_GetColor(interp, tkwin, "#ff0000"); + else if (!strncmp(str,"green",5)) + cc = Tk_GetColor(interp, tkwin, "#00ff00"); + else if (!strncmp(str,"blue",4)) + cc = Tk_GetColor(interp, tkwin, "#0000ff"); + else if (!strncmp(str,"cyan",4)) + cc = Tk_GetColor(interp, tkwin, "#00ffff"); + else if (!strncmp(str,"magenta",7)) + cc = Tk_GetColor(interp, tkwin, "#ff00ff"); + else if (!strncmp(str,"yellow",6)) + cc = Tk_GetColor(interp, tkwin, "#ffff00"); + else + cc = Tk_GetColor(interp, tkwin, str); + + return cc ? cc : Tk_GetColor(interp, tkwin, "white"); +} + +void Widget::warp(Vector& vv) +{ +#if !(_WIN32 || MAC_OSX_TK) + XWarpPointer(display, None, None, 0, 0, 0, 0, vv[0], vv[1]); +#endif + +#ifdef MAC_OSX_TK + XXWarpPointer(display, None, None, 0, 0, 0, 0, vv[0], vv[1]); +#endif + +#ifdef _WIN32 + Window root, child; + int rootx,rooty,winx,winy; + unsigned int msk; + XQueryPointer(display,Tk_WindowId(tkwin),&root,&child, + &rootx,&rooty,&winx,&winy,&msk); + XWarpPointer(display, None, Tk_WindowId(tkwin), 0, 0, 0, 0, + winx+vv[0], winy+vv[1]); +#endif +} + +void Widget::warpTo(Vector& vv) +{ +#if !(MAC_OSX_TK) + XWarpPointer(display, None, Tk_WindowId(tkwin), 0, 0, 0, 0, vv[0], vv[1]); +#endif + +#ifdef MAC_OSX_TK + XXWarpPointer(display, None, Tk_WindowId(tkwin), 0, 0, 0, 0, vv[0], vv[1]); +#endif +} + +void Widget::psHead1(ostream& str, int width, int height) +{ + switch (psColorSpace) { + case BW: + case GRAY: + str << "/picstr " << dec << width << " string def" << endl + << width << ' ' << height << " 8 matrix" << endl + << "{currentfile picstr readhexstring pop}" << endl + << "image" << endl; + break; + case RGB: + case CMYK: + str << "/picstr " << dec << width*3 << " string def" << endl + << width << ' ' << height << " 8 matrix" << endl + << "{currentfile picstr readhexstring pop}" << endl + << "false 3 colorimage" << endl; + break; + } +} + +void Widget::psHead2(ostream& str, int width, int height, const char* compress, + const char* decode) +{ + switch (psColorSpace) { + case BW: + case GRAY: + str << "/DeviceGray setcolorspace" << endl; + break; + case RGB: + str << "/DeviceRGB setcolorspace" << endl; + break; + case CMYK: + str << "/DeviceCMYK setcolorspace" << endl; + break; + } + + str << "<<" << endl + << "/ImageType 1" << endl + << "/Width " << dec << width << endl + << "/Height " << dec << height << endl + << "/BitsPerComponent 8" << endl; + + switch (psColorSpace) { + case BW: + case GRAY: + str << "/Decode [0 1]" << endl; + break; + case RGB: + str << "/Decode [0 1 0 1 0 1]" << endl; + break; + case CMYK: + str << "/Decode [0 1 0 1 0 1 0 1]" << endl; + break; + } + + str << "/ImageMatrix matrix" << endl + << "/DataSource currentfile" << endl; + + if (decode) + str << "/" << decode << "Decode filter" << endl; + + if (compress) + str << "/" << compress << "Decode filter" << endl; + + str << ">>" << endl + << "image" << endl; +} + +// compute coordinates of lower-left corner of the image +// taking into account the anchor position for the image. +// this mapping is different than in widget.c, due to postscript origin +// (y is flipped) + +Vector Widget::psOrigin() +{ + double xx = options->x; + double yy = Tk_CanvasPsY(canvas, options->y); + + double ww = options->width; + double hh = options->height; + + switch (options->anchor) { + case TK_ANCHOR_N: + xx -= ww/2; + yy -= hh; + break; + case TK_ANCHOR_NE: + xx -= ww; + yy -= hh; + break; + case TK_ANCHOR_E: + xx -= ww; + yy -= hh/2; + break; + case TK_ANCHOR_SE: + xx -= ww; + break; + case TK_ANCHOR_S: + xx -= ww/2; + break; + case TK_ANCHOR_SW: + break; + case TK_ANCHOR_W: + yy -= hh/2; + break; + case TK_ANCHOR_NW: + yy -= hh; + break; + case TK_ANCHOR_CENTER: + xx -= ww/2; + yy -= hh/2; + break; + } + + return Vector(xx,yy); +} + +// this routine attemps a work around for a problems with level 2 postscript +// and other software such as dvips and assemble + +/* +void Widget::psFix(ostringstream& ostr) +{ + string str = ostr.str(); + const char* buf = str.c_str(); + int size = str.length(); + char* a = (char*)buf; + + while (*a && a<buf+size) { + // dvips version 5.55. Basically, we can't have %% at the start of a line + if (*a=='\n' && *(a+1)=='%' && *(a+2)=='%') { + // reverse the order so that we don't have a %% at the begining of a line + *a++ = '%'; + *a++ = '%'; + *a++ = '\n'; + } + + // no one uses this anymore + // assemble. Basically, we can't have % at the start of a line + else if (*a=='\n' && *(a+1)=='%') { + // reverse the order so that we don't have a % at the begining of a line + *a++ = '%'; + *a++ = '\n'; + } + + a++; + } + + ostr.str(str); +} +*/ diff --git a/tksao/widget/widget.h b/tksao/widget/widget.h new file mode 100644 index 0000000..af06e4b --- /dev/null +++ b/tksao/widget/widget.h @@ -0,0 +1,203 @@ +// Copyright (C) 1999-2016 +// Smithsonian Astrophysical Observatory, Cambridge, MA, USA +// For conditions of distribution and use, see copyright notice in "copyright" + +#ifndef __widget_h__ +#define __widget_h__ + +#include <string.h> +#include <stdlib.h> +#include <limits.h> +#include <float.h> +#include <math.h> + +#include <iostream> +#include <sstream> +#include <iomanip> +using namespace std; + +#include <tcl.h> +#include <tk.h> + +#include "vector.h" + +class Attribute; + +extern float psScale; + +// General Defines + +#define WIDGET(x) (*(((WidgetOptions*)(x))->widget)) + +// Widget ConfigSpecs Defines + +#define CONFIGX 1 +#define CONFIGY 2 +#define CONFIGWIDTH 3 +#define CONFIGHEIGHT 4 +#define CONFIGANCHOR 5 +#define CONFIGCOMMAND 6 +#define CONFIGHELVETICA 7 +#define CONFIGCOURIER 8 +#define CONFIGTIMES 9 + +// Tk Canvas Widget Function Declarations + +extern int WidgetConfigProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int, + Tcl_Obj *const [],int); +extern int WidgetCoordProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int, Tcl_Obj *const []); +extern void WidgetDeleteProc(Tk_Canvas, Tk_Item*, Display*); +extern void WidgetDisplayProc(Tk_Canvas, Tk_Item*, Display*, Drawable, + int, int, int, int); +extern double WidgetPointProc(Tk_Canvas, Tk_Item*, double*); +extern int WidgetAreaProc(Tk_Canvas, Tk_Item*, double*); +extern int WidgetPostscriptProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, int); +extern void WidgetScaleProc(Tk_Canvas, Tk_Item*, double, double, + double, double); +extern void WidgetTranslateProc(Tk_Canvas, Tk_Item*, double, double); +extern int WidgetIndexProc(Tcl_Interp*, Tk_Canvas, Tk_Item*, char, int*); +extern void WidgetICursorProc(Tk_Canvas, Tk_Item*, int); +extern int WidgetSelectionProc(Tk_Canvas, Tk_Item*, int, char*, int); +extern void WidgetInsertProc(Tk_Canvas, Tk_Item*, int, char*); +extern void WidgetDCharsProc(Tk_Canvas, Tk_Item*, int, int); + +extern int WidgetParse(ClientData, Tcl_Interp*, int, char**); + +class Widget; + +// this structure is returned by each Canvas Function Proc + +struct WidgetOptions { + Tk_Item item; // required by tk + int x, y; // Coordinates of positioning point on canvas + int width; // widget width + int height; // widget height + Tk_Anchor anchor; // Where to anchor widget relative to x,y + char* cmdName; // Suggested Tcl command name + + char* helvetica; // name of X11 font + char* courier; // name of X11 font + char* times; // name of X11 font + + Widget* widget; // pointer to widget class +}; + +// Widget Class + +class Widget { + friend class Attribute; + + public: + enum PSColorSpace {BW, GRAY, RGB, CMYK}; + Tcl_Interp* interp; // Tcl interp + + protected: + WidgetOptions* options; // Pointer to Tk Options + Tk_ConfigSpec* configSpecs; // configure specs + Tk_Canvas canvas; // handle to canvas + Tk_Window tkwin; // Tk window id + + Display* display; // display of canvas + Visual* visual; // visual of canvas + int depth; // depth of canvas + int screenNumber; // screen number of canvas + + Pixmap pixmap; // size of canvas item + GC widgetGC; // gc for pixmap XCopyArea + int visible; // redraw when true + + int originX; // widget upper left origin + int originY; // widget upper left origin + + char* cmd; // actual command name used + int result; // result of TCL command + + int psResolution; // postscript resolution + int psLevel; // postscript level + PSColorSpace psColorSpace; // postscript color space + + protected: + virtual int updatePixmap(const BBox&) =0; // render into pixmap + virtual void invalidPixmap(); // pixmap is invalid + virtual void reset() {}; // reset widget + + void createCommand(); // create tcl command + void updateBBox(); // update item bounding box + + int checkArgs(int, int, char**); // check args utility + + void psHead1(ostream&, int, int); + void psHead2(ostream&, int, int, const char*, const char*); + Vector psOrigin(); + // void psFix(ostringstream& ostr); + + public: + Widget(Tcl_Interp*, Tk_Canvas, Tk_Item*); + virtual ~Widget(); + + Tcl_Interp* getInterp() {return interp;} + + void redraw(); // ping tk to redraw this widget + void redraw(BBox); // ping tk to redraw this bbox + void redrawNow(); // force update now this widget + void redrawNow(BBox); // force update now this bbox + void forceUpdate(); // only force update + + virtual int parse(istringstream&) =0; // parse subcommands + + virtual int configure(int, const char**, int); // parse config options + void error(const char*); // parse error function + void msg(const char*); // parse msg function + + Tk_Window getTkwin() {return tkwin;} + Display* getDisplay() {return display;} + double getDisplayRatio(); + Visual* getVisual() {return visual;} + int getWidth() {return options->width;} + int getHeight() {return options->height;} + int getDepth() {return depth;} + int getScreenNumber() {return screenNumber;} + Tk_Canvas getCanvas() {return canvas;} + + int getColor(const char* str); + XColor* getXColor(const char*); + + void warp(Vector&); + void warpTo(Vector&); + + // Required Canvas Functions + int coordProc(int, char**); + void displayProc(Drawable, int, int, int, int); + double pointProc(double*); + int areaProc(double*); + virtual int postscriptProc(int); + void scaleProc(double, double, double, double); + void translateProc(double, double); + virtual int indexProc(char indexString, int* indexPtr) {return TCL_OK;} + virtual void icursorProc(int index) {} + virtual int selectionProc(int offset, char* buffer, int maxBytes) + {return maxBytes;} + virtual void insertProc(int index, char* string) {} + virtual void dcharsProc(int first, int last) {} + + // Subcommand Functions + int configCmd(int, const char**); // configure command + void getHeightCmd(); // return height of widget + void getWidthCmd(); // return width of widget + void hideCmd(); // hide item command + void queryCursorCmd(); // get cursor coords + void resetCmd(); // reset item command + void showCmd(); // show item command + + // Postscript Commands + void psLevelCmd(int l) {psLevel = l;} + void psResolutionCmd(int r) {psResolution = r;} + void psColorSpaceCmd(PSColorSpace c) {psColorSpace = c;} + +#ifdef MAC_OSX_TK + virtual void macsosxPrintCmd() {} +#endif +}; + +#endif + |