diff options
Diffstat (limited to 'generic/tkZinc.c')
-rw-r--r-- | generic/tkZinc.c | 1661 |
1 files changed, 1203 insertions, 458 deletions
diff --git a/generic/tkZinc.c b/generic/tkZinc.c index 9200c6d..00b2e35 100644 --- a/generic/tkZinc.c +++ b/generic/tkZinc.c @@ -67,6 +67,9 @@ static const char * const zinc_version = "zinc-version-" VERSION; #include <string.h> #include <math.h> #include <X11/Xatom.h> +#if defined(_WIN32) && defined(PTK) && !defined(PTK_800) +#include <tkPlatDecls.m> +#endif typedef struct _TagSearchExpr { @@ -130,11 +133,40 @@ static Tk_Uid dot_uid; static Tk_Uid star_uid; #ifdef GL -static ZnGLContextEntry *gl_contexts = NULL; +static ZnGLContextEntry *gl_contexts = NULL; +#ifndef _WIN32 +static int ZnMajorGlx, ZnMinorGlx; +static int ZnGLAttribs[] = { + GLX_RGBA, + GLX_DOUBLEBUFFER, + GLX_BUFFER_SIZE, 24, + /*GLX_BUFFER_SIZE, 32,*/ + GLX_STENCIL_SIZE, 8, + /*GLX_ALPHA_SIZE, 8,*/ + None +}; +#endif +#endif + +#ifdef _WIN32 + char msg[256]; #endif +/* + * Temporary object lists + */ + ZnList ZnWorkPoints; + ZnList ZnWorkXPoints; + ZnList ZnWorkStrings; + +/* + * Tesselator + */ + ZnTess ZnTesselator; + static void PickCurrentItem _ANSI_ARGS_((ZnWInfo *wi, XEvent *event)); +#ifdef PTK_800 static int ZnReliefParse _ANSI_ARGS_((ClientData client_data, Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *ovalue, char *widget_rec, int offset)); @@ -176,10 +208,106 @@ static Tk_CustomOption bitmapOption = { (Tk_OptionPrintProc *) ZnImagePrint, NULL }; +#else +static int ZnSetReliefOpt _ANSI_ARGS_((ClientData client_data, Tcl_Interp *interp, + Tk_Window tkwin, Tcl_Obj **ovalue, + char *widget_rec, int offset, char *old_val_ptr, int flags)); +static Tcl_Obj *ZnGetReliefOpt _ANSI_ARGS_((ClientData client_data, Tk_Window tkwin, + char *widget_rec, int offset)); +static void ZnRestoreReliefOpt _ANSI_ARGS_((ClientData client_data, Tk_Window tkwin, + char *val_ptr, char *old_val_ptr)); +static int ZnSetGradientOpt _ANSI_ARGS_((ClientData client_data, Tcl_Interp *interp, + Tk_Window tkwin, Tcl_Obj **ovalue, + char *widget_rec, int offset, char *old_val_ptr, int flags)); +static Tcl_Obj *ZnGetGradientOpt _ANSI_ARGS_((ClientData client_data, Tk_Window tkwin, + char *widget_rec, int offset)); +static void ZnRestoreGradientOpt _ANSI_ARGS_((ClientData client_data, Tk_Window tkwin, + char *val_ptr, char *old_val_ptr)); +static void ZnFreeGradientOpt _ANSI_ARGS_((ClientData client_data, Tk_Window tkwin, char *val_ptr)); + +static Tk_ObjCustomOption reliefOption = { + "znrelief", + ZnSetReliefOpt, + ZnGetReliefOpt, + ZnRestoreReliefOpt, + NULL, + 0 +}; +static Tk_ObjCustomOption gradientOption = { + "zngradient", + ZnSetGradientOpt, + ZnGetGradientOpt, + ZnRestoreGradientOpt, + ZnFreeGradientOpt, + NULL +}; +#endif + +#ifdef PTK_800 +#define BORDER_WIDTH_SPEC 0 +#define BACK_COLOR_SPEC 1 +#define CONFINE_SPEC 2 +#define CURSOR_SPEC 3 +#define FONT_SPEC 4 +#define FORE_COLOR_SPEC 5 +#define FULL_RESHAPE_SPEC 6 +#define HEIGHT_SPEC 7 +#define HIGHLIGHT_BACK_COLOR_SPEC 8 +#define HIGHLIGHT_COLOR_SPEC 9 +#define HIGHLIGHT_THICKNESS_SPEC 10 +#define INSERT_COLOR_SPEC 11 +#define INSERT_OFF_TIME_SPEC 12 +#define INSERT_ON_TIME_SPEC 13 +#define INSERT_WIDTH_SPEC 14 +#define MAP_DISTANCE_SYMBOL_SPEC 15 +#define MAP_TEXT_FONT_SPEC 16 +#define OVERLAP_MANAGER_SPEC 17 +#define PICK_APERTURE_SPEC 18 +#define RELIEF_SPEC 19 +#define RENDER_SPEC 20 +#define RESHAPE_SPEC 21 +#define SCROLL_REGION_SPEC 22 +#define SELECT_COLOR_SPEC 23 +#define SPEED_VECTOR_LENGTH_SPEC 24 +#define TAKE_FOCUS_SPEC 25 +#define TILE_SPEC 26 +#define VISIBLE_HISTORY_SIZE_SPEC 27 +#define MANAGED_HISTORY_SIZE_SPEC 28 +#define TRACK_SYMBOL_SPEC 29 +#define WIDTH_SPEC 30 +#define X_SCROLL_CMD_SPEC 31 +#define X_SCROLL_INCREMENT_SPEC 32 +#define Y_SCROLL_CMD_SPEC 33 +#define Y_SCROLL_INCREMENT_SPEC 34 +#define BBOXES_SPEC 35 +#define BBOXES_COLOR_SPEC 36 +#define LIGHT_ANGLE_SPEC 37 +#define FOLLOW_POINTER_SPEC 38 +#else +#define CONFIG_FONT 1<<0 +#define CONFIG_MAP_FONT 1<<1 +#define CONFIG_BACK_COLOR 1<<2 +#define CONFIG_REDISPLAY 1<<3 +#define CONFIG_DAMAGE_ALL 1<<4 +#define CONFIG_INVALIDATE_TRACKS 1<<5 +#define CONFIG_INVALIDATE_WPS 1<<6 +#define CONFIG_INVALIDATE_MAPS 1<<7 +#define CONFIG_REQUEST_GEOM 1<<8 +#define CONFIG_OM 1<<9 +#define CONFIG_FOCUS 1<<10 +#define CONFIG_FOCUS_ITEM 1<<11 +#define CONFIG_SCROLL_REGION 1<<12 +#define CONFIG_SET_ORIGIN 1<<13 +#define CONFIG_FOLLOW_POINTER 1<<14 +#define CONFIG_MAP_SYMBOL 1<<15 +#define CONFIG_TRACK_SYMBOL 1<<16 +#define CONFIG_TILE 1<<17 +#endif /* * Information used for argv parsing. */ +#ifdef PTK_800 static Tk_ConfigSpec config_specs[] = { {TK_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", "2", Tk_Offset(ZnWInfo, border_width), 0, NULL}, @@ -228,13 +356,8 @@ static Tk_ConfigSpec config_specs[] = { "0", Tk_Offset(ZnWInfo, render), 0, NULL}, {TK_CONFIG_BOOLEAN, "-reshape", "reshape", "Reshape", "1", Tk_Offset(ZnWInfo, reshape), 0, NULL}, -#ifdef PTK {TK_CONFIG_LANGARG, "-scrollregion", "scrollRegion", "ScrollRegion", "", Tk_Offset(ZnWInfo, region), TK_CONFIG_NULL_OK, NULL}, -#else - {TK_CONFIG_STRING, "-scrollregion", "scrollRegion", "ScrollRegion", - "", Tk_Offset(ZnWInfo, region), TK_CONFIG_NULL_OK, NULL}, -#endif {TK_CONFIG_CUSTOM, "-selectbackground", "selectBackground", "Foreground", "#a0a0a0", Tk_Offset(ZnWInfo, text_info.sel_color), 0, &gradientOption}, {TK_CONFIG_DOUBLE, "-speedvectorlength", "speedVectorLength", @@ -251,22 +374,12 @@ static Tk_ConfigSpec config_specs[] = { "AtcSymbol15", Tk_Offset(ZnWInfo, track_symbol), TK_CONFIG_NULL_OK, &bitmapOption}, {TK_CONFIG_PIXELS, "-width", "width", "Width", "10c", Tk_Offset(ZnWInfo, opt_width), 0, NULL}, -#ifdef PTK {TK_CONFIG_CALLBACK, "-xscrollcommand", "xScrollCommand", "ScrollCommand", "", Tk_Offset(ZnWInfo, x_scroll_cmd), TK_CONFIG_NULL_OK, NULL}, -#else - {TK_CONFIG_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand", - "", Tk_Offset(ZnWInfo, x_scroll_cmd), TK_CONFIG_NULL_OK, NULL}, -#endif {TK_CONFIG_PIXELS, "-xscrollincrement", "xScrollIncrement", "ScrollIncrement", "0", Tk_Offset(ZnWInfo, x_scroll_incr), 0, NULL}, -#ifdef PTK {TK_CONFIG_CALLBACK, "-yscrollcommand", "yScrollCommand", "ScrollCommand", "", Tk_Offset(ZnWInfo, y_scroll_cmd), TK_CONFIG_NULL_OK, NULL}, -#else - {TK_CONFIG_STRING, "-yscrollcommand", "yScrollCommand", "ScrollCommand", - "", Tk_Offset(ZnWInfo, y_scroll_cmd), TK_CONFIG_NULL_OK, NULL}, -#endif {TK_CONFIG_PIXELS, "-yscrollincrement", "yScrollIncrement", "ScrollIncrement", "0", Tk_Offset(ZnWInfo, y_scroll_incr), 0, NULL}, /* @@ -283,50 +396,112 @@ static Tk_ConfigSpec config_specs[] = { {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL} }; - -/* - * These defines must be kept in sync with the config_specs array. - */ -#define BORDER_WIDTH_SPEC 0 -#define BACK_COLOR_SPEC 1 -#define CONFINE_SPEC 2 -#define CURSOR_SPEC 3 -#define FONT_SPEC 4 -#define FORE_COLOR_SPEC 5 -#define FULL_RESHAPE_SPEC 6 -#define HEIGHT_SPEC 7 -#define HIGHLIGHT_BACK_COLOR_SPEC 8 -#define HIGHLIGHT_COLOR_SPEC 9 -#define HIGHLIGHT_THICKNESS_SPEC 10 -#define INSERT_COLOR_SPEC 11 -#define INSERT_OFF_TIME_SPEC 12 -#define INSERT_ON_TIME_SPEC 13 -#define INSERT_WIDTH_SPEC 14 -#define MAP_DISTANCE_SYMBOL_SPEC 15 -#define MAP_TEXT_FONT_SPEC 16 -#define OVERLAP_MANAGER_SPEC 17 -#define PICK_APERTURE_SPEC 18 -#define RELIEF_SPEC 19 -#define RENDER_SPEC 20 -#define RESHAPE_SPEC 21 -#define SCROLL_REGION_SPEC 22 -#define SELECT_COLOR_SPEC 23 -#define SPEED_VECTOR_LENGTH_SPEC 24 -#define TAKE_FOCUS_SPEC 25 -#define TILE_SPEC 26 -#define VISIBLE_HISTORY_SIZE_SPEC 27 -#define MANAGED_HISTORY_SIZE_SPEC 28 -#define TRACK_SYMBOL_SPEC 29 -#define WIDTH_SPEC 30 -#define X_SCROLL_CMD_SPEC 31 -#define X_SCROLL_INCREMENT_SPEC 32 -#define Y_SCROLL_CMD_SPEC 33 -#define Y_SCROLL_INCREMENT_SPEC 34 -#define BBOXES_SPEC 35 -#define BBOXES_COLOR_SPEC 36 -#define LIGHT_ANGLE_SPEC 37 -#define FOLLOW_POINTER_SPEC 38 - +#else +static Tk_OptionSpec option_specs[] = { + {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", + "2", -1, Tk_Offset(ZnWInfo, border_width), 0, NULL, CONFIG_DAMAGE_ALL|CONFIG_REQUEST_GEOM}, + {TK_OPTION_CUSTOM, "-backcolor", "backColor", "BackColor", + "#c3c3c3", -1, Tk_Offset(ZnWInfo, back_color), 0, &gradientOption, + CONFIG_BACK_COLOR|CONFIG_DAMAGE_ALL}, + {TK_OPTION_BOOLEAN, "-confine", "confine", "Confine", + "1", -1, Tk_Offset(ZnWInfo, confine), 0, NULL, CONFIG_SET_ORIGIN}, + {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", + "", -1, Tk_Offset(ZnWInfo, cursor), TK_CONFIG_NULL_OK, NULL, 0}, + {TK_OPTION_FONT, "-font", "font", "Font", + "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*", + -1, Tk_Offset(ZnWInfo, font), 0, NULL, CONFIG_FONT}, + {TK_OPTION_CUSTOM, "-forecolor", "foreColor", "Foreground", + "Black", -1, Tk_Offset(ZnWInfo, fore_color), 0, &gradientOption, 0}, + {TK_OPTION_BOOLEAN, "-fullreshape", "fullReshape", "FullReshape", + "1", -1, Tk_Offset(ZnWInfo, full_reshape), 0, NULL, 0}, + {TK_OPTION_PIXELS, "-height", "height", "Height", + "7c", -1, Tk_Offset(ZnWInfo, opt_height), 0, NULL, CONFIG_REQUEST_GEOM}, + {TK_OPTION_CUSTOM, "-highlightbackground", "highlightBackground", "HighlightBackground", + "#c3c3c3", -1, Tk_Offset(ZnWInfo, highlight_bg_color), 0, &gradientOption, + CONFIG_REDISPLAY}, + {TK_OPTION_CUSTOM, "-highlightcolor", "highlightColor", "HighlightColor", + "Black", -1, Tk_Offset(ZnWInfo, highlight_color), 0, &gradientOption, CONFIG_REDISPLAY}, + {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness", "HighlightThickness", + "2", -1, Tk_Offset(ZnWInfo, highlight_width), 0, NULL, CONFIG_REQUEST_GEOM|CONFIG_DAMAGE_ALL}, + {TK_OPTION_CUSTOM, "-insertbackground", "insertBackground", "Foreground", + "Black", -1, Tk_Offset(ZnWInfo, text_info.insert_color), 0, &gradientOption, 0}, + {TK_OPTION_INT, "-insertofftime", "insertOffTime", "OffTime", + "300", -1, Tk_Offset(ZnWInfo, insert_off_time), 0, NULL, CONFIG_FOCUS}, + {TK_OPTION_INT, "-insertontime", "insertOnTime", "OnTime", + "600", -1, Tk_Offset(ZnWInfo, insert_on_time), 0, NULL, CONFIG_FOCUS}, + {TK_OPTION_PIXELS, "-insertwidth", "insertWidth", "InsertWidth", + "2", -1, Tk_Offset(ZnWInfo, text_info.insert_width), 0, NULL, CONFIG_FOCUS_ITEM}, + {TK_OPTION_STRING, "-mapdistancesymbol", "mapDistanceSymbol", "MapDistanceSymbol", + "AtcSymbol19", Tk_Offset(ZnWInfo, map_symbol_obj), -1, + TK_CONFIG_NULL_OK, NULL, CONFIG_MAP_SYMBOL|CONFIG_INVALIDATE_MAPS}, + {TK_OPTION_FONT, "-maptextfont", "mapTextFont", "MapTextFont", + "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*", + -1, Tk_Offset(ZnWInfo, map_text_font), 0, NULL, CONFIG_MAP_FONT}, + {TK_OPTION_INT, "-overlapmanager", "overlapManager", "OverlapManager", "1", + -1, Tk_Offset(ZnWInfo, om_group_id), 0, NULL, CONFIG_OM}, + {TK_OPTION_INT, "-pickaperture", "pickAperture", "PickAperture", + "1", -1, Tk_Offset(ZnWInfo, pick_aperture), 0, NULL, 0}, + {TK_OPTION_CUSTOM, "-relief", "relief", "Relief", + "flat", -1, Tk_Offset(ZnWInfo, relief), 0, &reliefOption, CONFIG_REDISPLAY}, + {TK_OPTION_INT, "-render", "render", "Render", + "-1", -1, Tk_Offset(ZnWInfo, render), 0, NULL, 0}, + {TK_OPTION_BOOLEAN, "-reshape", "reshape", "Reshape", + "1", -1, Tk_Offset(ZnWInfo, reshape), 0, NULL, 0}, + {TK_OPTION_STRING, "-scrollregion", "scrollRegion", "ScrollRegion", + "", Tk_Offset(ZnWInfo, region), -1, + TK_CONFIG_NULL_OK, NULL, CONFIG_SET_ORIGIN|CONFIG_SCROLL_REGION}, + {TK_OPTION_CUSTOM, "-selectbackground", "selectBackground", "Foreground", + "#a0a0a0", -1, Tk_Offset(ZnWInfo, text_info.sel_color), 0, &gradientOption, 0}, + {TK_OPTION_DOUBLE, "-speedvectorlength", "speedVectorLength", + "SpeedVectorLength", "3", -1, Tk_Offset(ZnWInfo, speed_vector_length), + 0, NULL, CONFIG_INVALIDATE_TRACKS}, + {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", + NULL, Tk_Offset(ZnWInfo, take_focus), -1, TK_CONFIG_NULL_OK, NULL, 0}, + {TK_OPTION_STRING, "-tile", "tile", "Tile", + "", Tk_Offset(ZnWInfo, tile_obj), -1, TK_CONFIG_NULL_OK, NULL, CONFIG_TILE|CONFIG_DAMAGE_ALL}, + {TK_OPTION_INT, "-trackvisiblehistorysize", "trackVisibleHistorySize", "TrackVisibleHistorySize", + "6", -1, Tk_Offset(ZnWInfo, track_visible_history_size), 0, NULL, CONFIG_INVALIDATE_TRACKS}, + {TK_OPTION_INT, "-trackmanagedhistorysize", "trackManagedHistorySize", + "TrackManagedHistorySize", "6", -1, Tk_Offset(ZnWInfo, track_managed_history_size), + 0, NULL, CONFIG_INVALIDATE_TRACKS}, + {TK_OPTION_STRING, "-tracksymbol", "trackSymbol", "TrackSymbol", + "AtcSymbol15", Tk_Offset(ZnWInfo, track_symbol_obj), -1, + 0, NULL, CONFIG_TRACK_SYMBOL|CONFIG_INVALIDATE_TRACKS|CONFIG_INVALIDATE_WPS}, + {TK_OPTION_PIXELS, "-width", "width", "Width", + "10c", -1, Tk_Offset(ZnWInfo, opt_width), 0, NULL, CONFIG_DAMAGE_ALL|CONFIG_REQUEST_GEOM}, +#ifdef PTK + {TK_OPTION_CALLBACK, "-xscrollcommand", "xScrollCommand", "ScrollCommand", + "", -1, Tk_Offset(ZnWInfo, x_scroll_cmd), TK_CONFIG_NULL_OK, NULL, 0}, +#else + {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand", + "", Tk_Offset(ZnWInfo, x_scroll_cmd), -1, TK_CONFIG_NULL_OK, NULL, 0}, +#endif + {TK_OPTION_PIXELS, "-xscrollincrement", "xScrollIncrement", "ScrollIncrement", + "0", -1, Tk_Offset(ZnWInfo, x_scroll_incr), 0, NULL, 0}, +#ifdef PTK + {TK_OPTION_CALLBACK, "-yscrollcommand", "yScrollCommand", "ScrollCommand", + "", -1, Tk_Offset(ZnWInfo, y_scroll_cmd), TK_CONFIG_NULL_OK, NULL, 0}, +#else + {TK_OPTION_STRING, "-yscrollcommand", "yScrollCommand", "ScrollCommand", + "", Tk_Offset(ZnWInfo, y_scroll_cmd), -1, TK_CONFIG_NULL_OK, NULL, 0}, +#endif + {TK_OPTION_PIXELS, "-yscrollincrement", "yScrollIncrement", "ScrollIncrement", + "0", -1, Tk_Offset(ZnWInfo, y_scroll_incr), 0, NULL, 0}, + /* + * Debug options. + */ + {TK_OPTION_BOOLEAN, "-drawbboxes", "drawBBoxes", + "DrawBBoxes", "0", -1, Tk_Offset(ZnWInfo, draw_bboxes), 0, NULL, 0}, + {TK_OPTION_CUSTOM, "-bboxcolor", "bboxColor", "BBoxColor", + "Pink", -1, Tk_Offset(ZnWInfo, bbox_color), 0, &gradientOption, 0}, + {TK_OPTION_INT, "-lightangle", "lightAngle", "LightAngle", + "120", -1, Tk_Offset(ZnWInfo, light_angle), 0, NULL, CONFIG_DAMAGE_ALL}, + {TK_OPTION_BOOLEAN, "-followpointer", "followPointer", + "FollowPointer", "1", -1, Tk_Offset(ZnWInfo, follow_pointer), 0, NULL, CONFIG_FOLLOW_POINTER}, + + {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0} +}; +#endif static void CmdDeleted _ANSI_ARGS_((ClientData client_data)); static void Event _ANSI_ARGS_((ClientData client_data, XEvent *eventPtr)); @@ -336,8 +511,13 @@ static int FetchSelection _ANSI_ARGS_((ClientData clientData, int offset, static void SelectTo _ANSI_ARGS_((ZnItem item, int field, int index)); static int WidgetObjCmd _ANSI_ARGS_((ClientData client_data, Tcl_Interp *, int argc, Tcl_Obj *CONST args[])); +#ifdef PTK_800 static int Configure _ANSI_ARGS_((Tcl_Interp *interp, ZnWInfo *wi, int argc, Tcl_Obj *CONST args[], int flags)); +#else +static int Configure _ANSI_ARGS_((Tcl_Interp *interp, ZnWInfo *wi, + int argc, Tcl_Obj *CONST args[])); +#endif static void Redisplay _ANSI_ARGS_((ClientData client_data)); static void Destroy _ANSI_ARGS_((char *mem_ptr)); static void InitZinc _ANSI_ARGS_((Tcl_Interp *interp)); @@ -346,7 +526,7 @@ static void Update _ANSI_ARGS_((ZnWInfo *wi)); static void Repair _ANSI_ARGS_((ZnWInfo *wi)); - +#ifdef PTK_800 /* *---------------------------------------------------------------------- * @@ -366,11 +546,7 @@ ZnReliefParse(ClientData client_data __unused, { ZnReliefStyle *relief_ptr = (ZnReliefStyle *) (widget_rec + offset); ZnReliefStyle relief; -#ifdef PTK char *value = Tcl_GetString(ovalue); -#else - char *value = (char *) ovalue; -#endif int result = TCL_OK; if (value != NULL) { @@ -390,11 +566,7 @@ ZnReliefPrint(ClientData client_data __unused, Tcl_FreeProc **free_proc __unused) { ZnReliefStyle relief = *(ZnReliefStyle *) (widget_rec + offset); -#ifdef PTK return Tcl_NewStringObj(ZnNameOfRelief(relief), -1); -#else - return (Tcl_Obj *) ZnNameOfRelief(relief); -#endif } @@ -417,11 +589,7 @@ ZnGradientParse(ClientData client_data __unused, { ZnGradient **grad_ptr = (ZnGradient **) (widget_rec + offset); ZnGradient *grad, *prev_grad; -#ifdef PTK char *value = Tcl_GetString(ovalue); -#else - char *value = (char *) ovalue; -#endif prev_grad = *grad_ptr; if ((value != NULL) && (*value != '\0')) { @@ -445,11 +613,7 @@ ZnGradientPrint(ClientData client_data __unused, Tcl_FreeProc **free_proc __unused) { ZnGradient *gradient = *(ZnGradient **) (widget_rec + offset); -#ifdef PTK return Tcl_NewStringObj(ZnNameOfGradient(gradient), -1); -#else - return (Tcl_Obj *) ZnNameOfGradient(gradient); -#endif } @@ -473,11 +637,7 @@ ZnBitmapParse(ClientData client_data __unused, { ZnImage *image_ptr = (ZnImage *) (widget_rec + offset); ZnImage image, prev_image; -#ifdef PTK char *value = Tcl_GetString(ovalue); -#else - char *value = (char *) ovalue; -#endif ZnWInfo *wi = (ZnWInfo*) widget_rec; ZnBool is_bmap = True; @@ -522,11 +682,7 @@ ZnImageParse(ClientData client_data __unused, { ZnImage *image_ptr = (ZnImage *) (widget_rec + offset); ZnImage image, prev_image; -#ifdef PTK char *value = Tcl_GetString(ovalue); -#else - char *value = (char *) ovalue; -#endif ZnWInfo *wi = (ZnWInfo*) widget_rec; prev_image = *image_ptr; @@ -555,13 +711,137 @@ ZnImagePrint(ClientData client_data __unused, Tcl_FreeProc **free_proc __unused) { ZnImage image = *(ZnImage *) (widget_rec + offset); -#ifdef PTK return Tcl_NewStringObj(image?ZnNameOfImage(image):"", -1); +} #else - return (Tcl_Obj *) (image?ZnNameOfImage(image):""); -#endif +/* + *---------------------------------------------------------------------- + * + * ZnSetReliefOpt + * ZnGetReliefOpt + * ZnRestoreReliefOpt -- + * Converter for the -relief option. + * + *---------------------------------------------------------------------- + */ +static int +ZnSetReliefOpt(ClientData client_data __unused, + Tcl_Interp *interp __unused, + Tk_Window tkwin __unused, + Tcl_Obj **ovalue, + char *widget_rec, + int offset, + char *old_val_ptr, + int flags __unused) +{ + ZnReliefStyle *relief_ptr; + ZnReliefStyle relief; + char *value = Tcl_GetString(*ovalue); + + if (ZnGetRelief((ZnWInfo *) widget_rec, value, &relief) == TCL_ERROR) { + return TCL_ERROR; + } + if (offset >= 0) { + relief_ptr = (ZnReliefStyle *) (widget_rec + offset); + *((ZnReliefStyle *) old_val_ptr) = *relief_ptr; + *relief_ptr = relief; + } + return TCL_OK; } +static Tcl_Obj * +ZnGetReliefOpt(ClientData client_data __unused, + Tk_Window tkwin __unused, + char *widget_rec, + int offset) +{ + ZnReliefStyle relief = *(ZnReliefStyle *) (widget_rec + offset); + return Tcl_NewStringObj(ZnNameOfRelief(relief), -1); +} + +static void +ZnRestoreReliefOpt(ClientData client_data __unused, + Tk_Window tkwin __unused, + char *val_ptr, + char *old_val_ptr) +{ + *(ZnReliefStyle *) val_ptr = *(ZnReliefStyle *) old_val_ptr; +} + +/* + *---------------------------------------------------------------------- + * + * ZnSetGradientOpt + * ZnGetGradientOpt + * ZnRestoreGradientOpt -- + * Converter for the -*color* options. + * + *---------------------------------------------------------------------- + */ +static int +ZnSetGradientOpt(ClientData client_data __unused, + Tcl_Interp *interp, + Tk_Window tkwin, + Tcl_Obj **ovalue, + char *widget_rec, + int offset, + char *old_val_ptr, + int flags __unused) +{ + ZnGradient **grad_ptr; + ZnGradient *grad; + char *value = Tcl_GetString(*ovalue); + + if (offset >= 0) { + if (*value == '\0') { + grad = NULL; + } + else { + grad = ZnGetGradient(interp, tkwin, value); + if (grad == NULL) { + return TCL_ERROR; + } + } + grad_ptr = (ZnGradient **) (widget_rec + offset); + *(ZnGradient **) old_val_ptr = *grad_ptr; + *grad_ptr = grad; + } + return TCL_OK; +} + +static Tcl_Obj * +ZnGetGradientOpt(ClientData client_data __unused, + Tk_Window tkwin __unused, + char *widget_rec, + int offset) +{ + ZnGradient *gradient = *(ZnGradient **) (widget_rec + offset); + return Tcl_NewStringObj(ZnNameOfGradient(gradient), -1); +} + +static void +ZnRestoreGradientOpt(ClientData client_data __unused, + Tk_Window tkwin __unused, + char *val_ptr, + char *old_val_ptr) +{ + if (*(ZnGradient **) val_ptr != NULL) { + ZnFreeGradient(*(ZnGradient **) val_ptr); + } + *(ZnGradient **) val_ptr = *(ZnGradient **) old_val_ptr; +} + +static void +ZnFreeGradientOpt(ClientData client_data __unused, + Tk_Window tkwin __unused, + char *val_ptr) +{ + if (*(ZnGradient **) val_ptr != NULL) { + ZnFreeGradient(*(ZnGradient **) val_ptr); + } +} +#endif + /* *---------------------------------------------------------------------- @@ -633,33 +913,271 @@ ZnGetGLContext(Display *dpy) return context_entry; } -void +ZnGLContextEntry * ZnGLMakeCurrent(Display *dpy, Tk_Window win) { - ZnGLContextEntry *context_entry; + ZnGLContextEntry *ce; + + ce = ZnGetGLContext(dpy); +#ifdef _WIN32 + if (win) { + ce->hwnd = Tk_GetHWND(Tk_WindowId(win)); + } + ce->hdc = GetDC(ce->hwnd); + SetPixelFormat(ce->hdc, ce->ipixel, &ce->pfd); + + sprintf(msg, "hdc used: %d\n", ce->hdc); + OutputDebugString(msg); + if (wglMakeCurrent(ce->hdc, ce->context)) { + OutputDebugString("make current ok\n"); + } + else { + sprintf(msg, "erreur %d\n", GetLastError()); + OutputDebugString(msg); + } - context_entry = ZnGetGLContext(dpy); -#ifdef WIN - wglMakeCurrent(context_entry->hdc, context_entry->context); #else - glXMakeCurrent(dpy, win==NULL?DefaultRootWindow(dpy):Tk_WindowId(win), - context_entry->context); + glXMakeCurrent(dpy, win?Tk_WindowId(win):DefaultRootWindow(dpy), + ce->context); #endif + return ce; } +#ifdef _WIN32 void -ZnGLSwapBuffers(Display *dpy, - Tk_Window win) +ZnGLReleaseContext(ZnGLContextEntry *ce) { -#ifdef WIN - SwapBuffers(ZnGetGLContext(dpy)->hdc); + sprintf(msg, "Relasing hdc: %d\n", ce->hdc); + OutputDebugString(msg); + wglMakeCurrent(NULL, NULL); + ReleaseDC(ce->hwnd, ce->hdc); +} +#endif + +static void +ZnGLSwapBuffers(ZnGLContextEntry *ce, + Tk_Window win) +{ +#ifdef _WIN32 + sprintf(msg, "Swapping hdc: %d\n", ce->hdc); + OutputDebugString(msg); + SwapBuffers(ce->hdc); #else - glXSwapBuffers(dpy, Tk_WindowId(win)); + glXSwapBuffers(ce->dpy, Tk_WindowId(win)); #endif } #endif + +static void +InitRendering(ZnWInfo *wi) +{ + ZnGLContextEntry *ce; + /* + * Allocate double buffer pixmap/image. + */ + if (wi->render) { +#ifdef GL + ASSIGN(wi->flags, ZN_PRINT_CONFIG, (getenv("ZINC_GLX_INFO") != NULL)); + + if (ISSET(wi->flags, ZN_HAS_GL)) { + ZnGLContext gl_context; +# ifdef _WIN32 + /* + * Look for a matching context already available. + */ + Tk_MakeWindowExist(wi->win); + ce = ZnGetGLContext(wi->dpy); + if (ce) { + gl_context = ce->context; + ce->hwnd = Tk_GetHWND(Tk_WindowId(wi->win)); + ce->hdc = GetDC(ce->hwnd); + SetPixelFormat(ce->hdc, ce->ipixel, &ce->pfd); + } + else { + ce = ZnMalloc(sizeof(ZnGLContextEntry)); + ce->hwnd = Tk_GetHWND(Tk_WindowId(wi->win)); + ce->hdc = GetDC(ce->hwnd); + + memset(&ce->pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); + ce->pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); + ce->pfd.nVersion = 1; + ce->pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; + ce->pfd.iPixelType = PFD_TYPE_RGBA; + ce->pfd.cRedBits = 8; + ce->pfd.cGreenBits = 8; + ce->pfd.cBlueBits = 8; + ce->pfd.cAlphaBits = 8; + ce->pfd.cStencilBits = 8; + ce->pfd.iLayerType = PFD_MAIN_PLANE; + ce->ipixel = ChoosePixelFormat(ce->hdc, &ce->pfd); + sprintf(msg, "ipixel=%d dwFlags=0x%x req=0x%x iPixelType=%d hdc=%d\n", + ce->ipixel, + ce->pfd.dwFlags, + PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER, + ce->pfd.iPixelType==PFD_TYPE_RGBA, + ce->hdc); + OutputDebugString(msg); + if (!ce->ipixel) { + OutputDebugString("ChoosePixelFormat failed\n"); + } + wi->render = (SetPixelFormat(ce->hdc, ce->ipixel, &ce->pfd) == TRUE); + if (wi->render) { + gl_context = wglCreateContext(ce->hdc); + if (gl_context) { + ce->context = gl_context; + ce->dpy = wi->dpy; + ce->max_tex_size = 64; /* Minimum value is always valid */ + ce->max_line_width = 1; + ce->max_point_width = 1; + ce->next = gl_contexts; + gl_contexts = ce; + } + else { + OutputDebugString("wglCreateContext failed\n"); + ZnFree(ce); + } + } + else { + ZnFree(ce); + } + } + ReleaseDC(ce->hwnd, ce->hdc); + sprintf(msg, "render after: %d\n", wi->render); + OutputDebugString(msg); +# else /* _WIN32 */ + XVisualInfo *gl_visual = NULL; + Colormap colormap = 0; + + if (ISSET(wi->flags, ZN_PRINT_CONFIG)) { + fprintf(stderr, "GLX version %d.%d\n", ZnMajorGlx, ZnMinorGlx); + } + + /* + * Look for a matching context already available. + */ + ce = ZnGetGLContext(wi->dpy); + if (ce) { + gl_context = ce->context; + gl_visual = ce->visual; + colormap = ce->colormap; + } + else { + int val; + + gl_visual = glXChooseVisual(wi->dpy, + XScreenNumberOfScreen(wi->screen), + ZnGLAttribs); + if (!gl_visual) { + fprintf(stderr, "No glx visual\n"); + wi->render = 0; + } + else { + gl_context = glXCreateContext(wi->dpy, gl_visual, + NULL, wi->render==1); + if (!gl_context) { + fprintf(stderr, "No glx context\n"); + wi->render = 0; + } + else { + colormap = XCreateColormap(wi->dpy, RootWindowOfScreen(wi->screen), + gl_visual->visual, AllocNone); + ce = ZnMalloc(sizeof(ZnGLContextEntry)); + ce->context = gl_context; + ce->visual = gl_visual; + ce->colormap = colormap; + ce->dpy = wi->dpy; + ce->max_tex_size = 64; /* Minimum value is always valid */ + ce->max_line_width = 1; + ce->max_point_width = 1; + ce->next = gl_contexts; + gl_contexts = ce; + + if (ISSET(wi->flags, ZN_PRINT_CONFIG)) { + fprintf(stderr, " Visual : 0x%x, ", + (int) gl_visual->visualid); + glXGetConfig(wi->dpy, gl_visual, GLX_RGBA, &val); + fprintf(stderr, "RGBA : %d, ", val); + glXGetConfig(wi->dpy, gl_visual, GLX_DOUBLEBUFFER, &val); + fprintf(stderr, "Double Buffer : %d, ", val); + glXGetConfig(wi->dpy, gl_visual, GLX_STENCIL_SIZE, &val); + fprintf(stderr, "Stencil : %d, ", val); + glXGetConfig(wi->dpy, gl_visual, GLX_BUFFER_SIZE, &val); + fprintf(stderr, "depth : %d, ", val); + glXGetConfig(wi->dpy, gl_visual, GLX_RED_SIZE, &val); + fprintf(stderr, "red : %d, ", val); + glXGetConfig(wi->dpy, gl_visual, GLX_GREEN_SIZE, &val); + fprintf(stderr, "green : %d, ", val); + glXGetConfig(wi->dpy, gl_visual, GLX_BLUE_SIZE, &val); + fprintf(stderr, "blue : %d, ", val); + glXGetConfig(wi->dpy, gl_visual, GLX_ALPHA_SIZE, &val); + fprintf(stderr, "alpha : %d\n", val); + fprintf(stderr, " Direct Rendering: %d\n", + glXIsDirect(wi->dpy, gl_context)); + } + } + } + } + if (gl_visual && colormap) { + Tk_SetWindowVisual(wi->win, gl_visual->visual, 24, colormap); + } +# endif /* _WIN32 */ + } + else { + fprintf(stderr, "GL not available\n"); + wi->render = 0; + } +#else /* GL */ + wi->render = 0; +#endif /* GL */ + } + + if (!wi->render) { + wi->draw_buffer = Tk_GetPixmap(wi->dpy, RootWindowOfScreen(wi->screen), + wi->width, wi->height, Tk_Depth(wi->win)); + } + else { + GLfloat r[2]; /* Min, Max */ + GLint i[1]; + + ce = ZnGLMakeCurrent(wi->dpy, wi->win); + glGetFloatv(ZN_GL_LINE_WIDTH_RANGE, r); + ce->max_line_width = r[1]; + glGetFloatv(ZN_GL_POINT_SIZE_RANGE, r); + ce->max_point_width = r[1]; + glGetIntegerv(GL_MAX_TEXTURE_SIZE, i); + ce->max_tex_size = (unsigned int) i[0]; + + if (ISSET(wi->flags, ZN_PRINT_CONFIG)) { + fprintf(stderr, "OpenGL version %s\n", + (char *) glGetString(GL_VERSION)); + fprintf(stderr, " Rendering engine: %s, ", + (char *) glGetString(GL_RENDERER)); + fprintf(stderr, " Vendor: %s\n", + (char *) glGetString(GL_VENDOR)); + fprintf(stderr, " Available extensions: %s\n", + (char *) glGetString(GL_EXTENSIONS)); + fprintf(stderr, "Max antialiased line width: %g\n", + ce->max_line_width); + fprintf(stderr, "Max antialiased point size: %g\n", + ce->max_point_width); + fprintf(stderr, "Max texture size: %d\n", + ce->max_tex_size); + } + + if (!wi->font_tfi) { + wi->font_tfi = ZnGetTexFont(wi, wi->font); + } + if (!wi->map_font_tfi) { + wi->map_font_tfi = ZnGetTexFont(wi, wi->map_text_font); + } + + ZnGLReleaseContext(ce); + } +} + + /* *---------------------------------------------------------------------- * @@ -680,6 +1198,9 @@ ZincObjCmd(ClientData client_data, /* Main window associated with Tk_Window top_w = (Tk_Window) client_data; ZnWInfo *wi; Tk_Window tkwin; +#ifndef PTK_800 + Tk_OptionTable opt_table; +#endif unsigned int num; ZnBool has_gl = False; #ifndef _WIN32 @@ -687,18 +1208,8 @@ ZincObjCmd(ClientData client_data, /* Main window associated with int major_op, first_err, first_evt; # endif # ifdef GL - int major_glx, minor_glx; Display *dpy = Tk_Display(top_w); Screen *screen = Tk_Screen(top_w); - int attribs[] = { - GLX_RGBA, - GLX_DOUBLEBUFFER, - GLX_BUFFER_SIZE, 24, - /*GLX_BUFFER_SIZE, 32,*/ - GLX_STENCIL_SIZE, 8, - /*GLX_ALPHA_SIZE, 8,*/ - None - }; # endif #endif @@ -710,8 +1221,8 @@ ZincObjCmd(ClientData client_data, /* Main window associated with # else if (XQueryExtension(dpy, "GLX", &major_op, &first_evt, &first_err)) { if (glXQueryExtension(dpy, &first_err, &first_evt)) { - if (glXQueryVersion(dpy, &major_glx, &minor_glx)) { - if ((major_glx == 1) && (minor_glx >= 1)) { + if (glXQueryVersion(dpy, &ZnMajorGlx, &ZnMinorGlx)) { + if ((ZnMajorGlx == 1) && (ZnMinorGlx >= 1)) { has_gl = True; } } @@ -727,14 +1238,14 @@ ZincObjCmd(ClientData client_data, /* Main window associated with # ifdef _WIN32 Tcl_AppendResult(interp, " GL", NULL); # else - { + if (has_gl) { XVisualInfo *visual = glXChooseVisual(dpy, XScreenNumberOfScreen(screen), - attribs); - if (has_gl && visual) { + ZnGLAttribs); + if (visual) { Tcl_AppendResult(interp, " GL", NULL); + XFree(visual); } - XFree(visual); } # endif #endif @@ -745,6 +1256,11 @@ ZincObjCmd(ClientData client_data, /* Main window associated with if (tkwin == NULL) { return TCL_ERROR; } + +#ifndef PTK_800 + opt_table = Tk_CreateOptionTable(interp, option_specs); + #endif + Tk_SetClass(tkwin, "Zinc"); /* @@ -756,7 +1272,7 @@ ZincObjCmd(ClientData client_data, /* Main window associated with wi->dpy = Tk_Display(tkwin); wi->screen = Tk_Screen(tkwin); wi->flags = 0; - wi->render = 0; + wi->render = -1; wi->real_top = None; ASSIGN(wi->flags, ZN_HAS_GL, has_gl); @@ -780,7 +1296,10 @@ ZincObjCmd(ClientData client_data, /* Main window associated with #else wi->cmd = Tcl_CreateObjCommand(interp, Tk_PathName(tkwin), WidgetObjCmd, (ClientData) wi, CmdDeleted); -#endif +#endif +#ifndef PTK_800 + wi->opt_table = opt_table; +#endif wi->binding_table = 0; wi->fore_color = NULL; wi->back_color = NULL; @@ -801,13 +1320,18 @@ ZincObjCmd(ClientData client_data, /* Main window associated with #endif wi->map_distance_symbol = ZnUnspecifiedImage; wi->track_symbol = ZnUnspecifiedImage; + wi->tile = ZnUnspecifiedImage; +#ifndef PTK_800 + wi->map_symbol_obj = NULL; + wi->track_symbol_obj = NULL; + wi->tile_obj = NULL; +#endif wi->cursor = None; wi->hot_item = ZN_NO_ITEM; wi->hot_prev = ZN_NO_ITEM; wi->track_visible_history_size = 0; wi->track_managed_history_size = 0; wi->speed_vector_length = 0; - wi->tile = ZnUnspecifiedImage; wi->confine = 0; wi->origin.x = wi->origin.y = 0; wi->scroll_xo = wi->scroll_yo = 0; @@ -848,14 +1372,6 @@ ZincObjCmd(ClientData client_data, /* Main window associated with #endif wi->damaged_area_w = wi->damaged_area_h = 0; - wi->work_item_list = NULL; - wi->work_pts = ZnListNew(8, sizeof(ZnPoint)); -#ifdef GL - wi->work_doubles = ZnListNew(8, sizeof(double)); -#endif - wi->work_xpts = ZnListNew(8, sizeof(XPoint)); - wi->work_strs = ZnListNew(8, sizeof(char *)); - /* * Text management init. */ @@ -883,12 +1399,6 @@ ZincObjCmd(ClientData client_data, /* Main window associated with ZnInitClipStack(wi); ZnInitTransformStack(wi); - /* - * Allocate a GLU tesselator. - */ - wi->tess = gluNewTess(); - wi->tess_combine_list = NULL; - for (num = 0; num < ZN_NUM_ALPHA_STEPS; num++) { char name[TCL_INTEGER_SPACE+12]; @@ -906,180 +1416,27 @@ ZincObjCmd(ClientData client_data, /* Main window associated with Tk_CreateSelHandler(tkwin, XA_PRIMARY, XA_STRING, FetchSelection, (ClientData) wi, XA_STRING); +#ifdef PTK_800 if (Configure(interp, wi, argc-2, args+2, 0) != TCL_OK) { Tk_DestroyWindow(tkwin); return TCL_ERROR; } - +#else + if (Tk_InitOptions(interp, (char *) wi, opt_table, tkwin) != TCL_OK) { + Tk_DestroyWindow(tkwin); + return TCL_ERROR; + } + + if (Configure(interp, wi, argc-2, args+2) != TCL_OK) { + Tk_DestroyWindow(tkwin); + return TCL_ERROR; + } +#endif + wi->damaged_area.orig.x = wi->damaged_area.orig.y = 0; wi->damaged_area.corner.x = wi->width = wi->opt_width; wi->damaged_area.corner.y = wi->height = wi->opt_height; - /* - * Allocate double buffer pixmap/image. - */ - if (wi->render) { -#ifdef GL - ZnGLContextEntry *context_entry; - ZnGLContext gl_context; - - ASSIGN(wi->flags, ZN_PRINT_CONFIG, (getenv("ZINC_GLX_INFO") != NULL)); - - if (ISSET(wi->flags, ZN_HAS_GL)) { -# ifdef _WIN32 - PIXELFORMATDESCRIPTOR pfd = { - sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd - 1, // version number - PFD_DRAW_TO_WINDOW | - PFD_SUPPORT_OPENGL | // support OpenGL - PFD_DOUBLEBUFFER, // double buffered - PFD_TYPE_RGBA, // RGBA type - 0, // Color bits ignored - 8, 0, 8, 0, 8, 0, 8, 0, // R, G, B, A (color shifts ignored ) - 0, // accum bits ignored - 0, 0, 0, 0, // accum R, G, B, A ignored - 0, // no depth buffer - 8, // 8 bits stencil buffer - 0, // no auxiliary buffer - PFD_MAIN_PLANE, // main layer - 0, // reserved - 0, 0, 0 // layer masks ignored - }; - int ipixel; - HWND hwnd; - HDC hdc; - - Tk_MakeWindowExist(wi->win); - hwnd = Tk_GetHWND(Tk_WindowId(wi->win)); - hdc = GetDC(hwnd); - if (!hdc) { - OutputDebugString("Unable to get the hdc\n"); - } - /* - * Look for a matching context already available. - */ - context_entry = ZnGetGLContext(wi->dpy); - if (context_entry) { - gl_context = context_entry->context; - } - else { - ipixel = ChoosePixelFormat(hdc, &pfd); - /* sprintf(msg, "ipixel=%d dwFlags=0x%x req=0x%x iPixelType=%d\n", - ipixel, - pfd.dwFlags, - PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER, - pfd.iPixelType==PFD_TYPE_RGBA); - OutputDebugString(msg);*/ - if (!ipixel) { - OutputDebugString("ChoosePixelFormat failed\n"); - } - wi->render = (SetPixelFormat(hdc, ipixel, &pfd) == TRUE); - if (wi->render) { - gl_context = wglCreateContext(hdc); - if (!gl_context) { - OutputDebugString("wglCreateContext failed\n"); - } - else { - context_entry = ZnMalloc(sizeof(ZnGLContextEntry)); - context_entry->context = gl_context; - context_entry->hdc = hdc; - context_entry->next = gl_contexts; - gl_contexts = context_entry; - } - } - ZnGLRelease(wi); - } -# else /* _WIN32 */ - XVisualInfo *gl_visual = NULL; - Colormap colormap = 0; - - if (ISSET(wi->flags, ZN_PRINT_CONFIG)) { - fprintf(stderr, "GLX version %d.%d\n", major_glx, minor_glx); - } - - /* - * Look for a matching context already available. - */ - context_entry = ZnGetGLContext(wi->dpy); - if (context_entry) { - gl_context = context_entry->context; - gl_visual = context_entry->visual; - colormap = context_entry->colormap; - } - else { - int val; - - gl_visual = glXChooseVisual(wi->dpy, - XScreenNumberOfScreen(wi->screen), - attribs); - if (!gl_visual) { - fprintf(stderr, "No glx visual\n"); - wi->render = 0; - } - else { - gl_context = glXCreateContext(wi->dpy, gl_visual, - NULL, wi->render==1); - if (!gl_context) { - fprintf(stderr, "No glx context\n"); - wi->render = 0; - } - else { - colormap = XCreateColormap(wi->dpy, RootWindowOfScreen(wi->screen), - gl_visual->visual, AllocNone); - context_entry = ZnMalloc(sizeof(ZnGLContextEntry)); - context_entry->context = gl_context; - context_entry->visual = gl_visual; - context_entry->colormap = colormap; - context_entry->dpy = wi->dpy; - context_entry->max_tex_size = 64; /* Minimum value is always valid */ - context_entry->max_line_width = 1; - context_entry->max_point_width = 1; - context_entry->next = gl_contexts; - gl_contexts = context_entry; - - if (ISSET(wi->flags, ZN_PRINT_CONFIG)) { - fprintf(stderr, " Visual : 0x%x, ", - (int) gl_visual->visualid); - glXGetConfig(wi->dpy, gl_visual, GLX_RGBA, &val); - fprintf(stderr, "RGBA : %d, ", val); - glXGetConfig(wi->dpy, gl_visual, GLX_DOUBLEBUFFER, &val); - fprintf(stderr, "Double Buffer : %d, ", val); - glXGetConfig(wi->dpy, gl_visual, GLX_STENCIL_SIZE, &val); - fprintf(stderr, "Stencil : %d, ", val); - glXGetConfig(wi->dpy, gl_visual, GLX_BUFFER_SIZE, &val); - fprintf(stderr, "depth : %d, ", val); - glXGetConfig(wi->dpy, gl_visual, GLX_RED_SIZE, &val); - fprintf(stderr, "red : %d, ", val); - glXGetConfig(wi->dpy, gl_visual, GLX_GREEN_SIZE, &val); - fprintf(stderr, "green : %d, ", val); - glXGetConfig(wi->dpy, gl_visual, GLX_BLUE_SIZE, &val); - fprintf(stderr, "blue : %d, ", val); - glXGetConfig(wi->dpy, gl_visual, GLX_ALPHA_SIZE, &val); - fprintf(stderr, "alpha : %d\n", val); - fprintf(stderr, " Direct Rendering: %d\n", - glXIsDirect(wi->dpy, gl_context)); - } - } - } - } - if (gl_visual && colormap) { - Tk_SetWindowVisual(wi->win, gl_visual->visual, 24, colormap); - } -# endif /* _WIN32 */ - } - else { - fprintf(stderr, "GL not available\n"); - wi->render = 0; - } -#else /* GL */ - wi->render = 0; -#endif /* GL */ - } - if (!wi->render) { - wi->draw_buffer = Tk_GetPixmap(wi->dpy, RootWindowOfScreen(wi->screen), - wi->width, wi->height, Tk_Depth(wi->win)); - } - #ifdef PTK Tcl_SetObjResult(interp, LangWidgetObj(interp, tkwin)); #else @@ -1654,7 +2011,7 @@ ZnTagSearchScan(ZnWInfo *wi, unsigned int id; Tcl_HashEntry *entry; - ZnListEmpty(wi->work_strs); + ZnListEmpty(ZnWorkStrings); recursive = False; if ((*tag == '.') || (*tag == '*')) { recursive = (*tag == '*'); @@ -1693,22 +2050,22 @@ ZnTagSearchScan(ZnWInfo *wi, } } else { - ZnListAdd(wi->work_strs, + ZnListAdd(ZnWorkStrings, (void *) (recursive ? &star_uid : &dot_uid), ZnListTail); c = *next; *next = '\0'; path = Tk_GetUid(path); *next = c; - ZnListAdd(wi->work_strs, (void *) &path, ZnListTail); + ZnListAdd(ZnWorkStrings, (void *) &path, ZnListTail); } recursive = (*next == '*'); path = next+1; } group = LookupGroupFromPath(group, - ZnListArray(wi->work_strs), - ZnListSize(wi->work_strs)); + ZnListArray(ZnWorkStrings), + ZnListSize(ZnWorkStrings)); if (group == ZN_NO_ITEM) { Tcl_AppendResult(wi->interp, "path does not lead to a valid group\"", tag, "\"", NULL); @@ -2457,7 +2814,7 @@ UpdateScrollbars(ZnWInfo *wi) #ifdef PTK LangCallback *x_scroll_cmd, *y_scroll_cmd; #else - char *x_scroll_cmd, *y_scroll_cmd; + Tcl_Obj *x_scroll_cmd, *y_scroll_cmd; #endif Tcl_Obj *fractions; @@ -2491,9 +2848,9 @@ UpdateScrollbars(ZnWInfo *wi) result = LangDoCallback(interp, x_scroll_cmd, 0, 2, " %g %g", first, last); #else fractions = ScrollFractions(x_origin, x_origin + width, scroll_xo, scroll_xc); - result = Tcl_VarEval(interp, x_scroll_cmd, " ", Tcl_GetString(fractions), NULL); -#endif + result = Tcl_VarEval(interp, Tcl_GetString(x_scroll_cmd), " ", Tcl_GetString(fractions), NULL); Tcl_DecrRefCount(fractions); +#endif if (result != TCL_OK) { Tcl_BackgroundError(interp); } @@ -2505,12 +2862,12 @@ UpdateScrollbars(ZnWInfo *wi) #ifdef PTK ZnReal first, last; ScrollFractions(y_origin, y_origin + height, scroll_yo, scroll_yc, &first, &last); - result = LangDoCallback(interp, y_scroll_cmd, 0, 1, " %g %g", first, last); + result = LangDoCallback(interp, y_scroll_cmd, 0, 2, " %g %g", first, last); #else fractions = ScrollFractions(y_origin, y_origin + height, scroll_yo, scroll_yc); - result = Tcl_VarEval(interp, y_scroll_cmd, " ", Tcl_GetString(fractions), NULL); -#endif + result = Tcl_VarEval(interp, Tcl_GetString(y_scroll_cmd), " ", Tcl_GetString(fractions), NULL); Tcl_DecrRefCount(fractions); +#endif if (result != TCL_OK) { Tcl_BackgroundError(interp); } @@ -3045,8 +3402,8 @@ ZnParseCoordList(ZnWInfo *wi, if (old_style) { if ((num_elems%2) == 0) { *num_pts = num_elems/2; - ZnListAssertSize(wi->work_pts, *num_pts); - *pts = p = (ZnPoint *) ZnListArray(wi->work_pts); + ZnListAssertSize(ZnWorkPoints, *num_pts); + *pts = p = (ZnPoint *) ZnListArray(ZnWorkPoints); for (i = 0; i < num_elems; i += 2, p++) { if (Tcl_GetDoubleFromObj(wi->interp, elems[i], &d) == TCL_ERROR) { goto coord_error; @@ -3062,8 +3419,8 @@ ZnParseCoordList(ZnWInfo *wi, } else if (num_elems == 3) { *num_pts = 1; - ZnListAssertSize(wi->work_pts, *num_pts); - *pts = p = (ZnPoint *) ZnListArray(wi->work_pts); + ZnListAssertSize(ZnWorkPoints, *num_pts); + *pts = p = (ZnPoint *) ZnListArray(ZnWorkPoints); if (Tcl_GetDoubleFromObj(wi->interp, elems[0], &d) == TCL_ERROR) { goto coord_error; } @@ -3090,8 +3447,8 @@ ZnParseCoordList(ZnWInfo *wi, else { Tcl_ResetResult(wi->interp); *num_pts = num_elems; - ZnListAssertSize(wi->work_pts, *num_pts); - *pts = p = (ZnPoint *) ZnListArray(wi->work_pts); + ZnListAssertSize(ZnWorkPoints, *num_pts); + *pts = p = (ZnPoint *) ZnListArray(ZnWorkPoints); for (i = 0; i < num_elems; i++, p++) { result = Tcl_ListObjGetElements(wi->interp, elems[i], &num_selems, &selems); if ((result == TCL_ERROR) || (num_selems < 2) || (num_selems > 3)) { @@ -3431,7 +3788,6 @@ Coords(ZnWInfo *wi, int result, cmd = ZN_COORDS_READ; long index, contour = 0; char *str, *controls = NULL; - char c[2] = " "; Tcl_Obj *l, *entries[3]; result = ZnItemWithTagOrId(wi, args[2], &item, search_var); @@ -3440,6 +3796,11 @@ Coords(ZnWInfo *wi, Tcl_GetString(args[2]), "\"", NULL); return TCL_ERROR; } + if (!item->class->Coords) { + Tcl_AppendResult(wi->interp, " ", item->class->name, + " does not support the coords command", NULL); + return TCL_ERROR; + } num_points = 0; /*printf(" coords: argc=%d, item %d class: %s\n", argc, item->id, item->class->name);*/ @@ -3453,23 +3814,19 @@ Coords(ZnWInfo *wi, /*printf(" coords: read %d points, first is %g@%g\n", num_points, points->x, points->y);*/ l = Tcl_GetObjResult(wi->interp); - if (item->class->pos_offset >= 0) { - /* - * Special case for items with a -position. In this case - * we are guaranteed to return exactly one point, it is - * then more friendly to return it flat instead of as the - * only element of a list. - */ + if (ISSET(item->class->flags, ZN_CLASS_ONE_COORD)) { Tcl_ListObjAppendElement(wi->interp, l, Tcl_NewDoubleObj(points->x)); Tcl_ListObjAppendElement(wi->interp, l, Tcl_NewDoubleObj(points->y)); + if (controls && *controls) { + Tcl_ListObjAppendElement(wi->interp, l, Tcl_NewStringObj(controls, 1)); + } } else { for (i = 0; i < num_points; i++, points++) { entries[0] = Tcl_NewDoubleObj(points->x); entries[1] = Tcl_NewDoubleObj(points->y); if (controls && controls[i]) { - c[0] = controls[i]; - entries[2] = Tcl_NewStringObj(c, -1); + entries[2] = Tcl_NewStringObj(&controls[i], 1); Tcl_ListObjAppendElement(wi->interp, l, Tcl_NewListObj(3, entries)); } else { @@ -3610,9 +3967,8 @@ Coords(ZnWInfo *wi, l = Tcl_GetObjResult(wi->interp); Tcl_ListObjAppendElement(wi->interp, l, Tcl_NewDoubleObj(points->x)); Tcl_ListObjAppendElement(wi->interp, l, Tcl_NewDoubleObj(points->y)); - if (controls && controls[0]) { - c[0] = controls[0]; - Tcl_ListObjAppendElement(wi->interp, l, Tcl_NewStringObj(c, -1)); + if (controls && *controls) { + Tcl_ListObjAppendElement(wi->interp, l, Tcl_NewStringObj(controls, 1)); } } return TCL_OK; @@ -3829,7 +4185,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ } result = ZnItemWithTagOrId(wi, args[2], &item, &search_var); if ((result == TCL_ERROR) || (item == ZN_NO_ITEM) || - !item->class->has_anchors) { + ISCLEAR(item->class->flags, ZN_CLASS_HAS_ANCHORS)) { Tcl_AppendResult(interp, "unknown item or doesn't support anchors \"", Tcl_GetString(args[2]), NULL); goto error; @@ -4119,8 +4475,16 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ Tcl_WrongNumArgs(interp, 1, args, "cget option"); goto error; } +#ifdef PTK_800 result = Tk_ConfigureValue(interp, wi->win, config_specs, (char *) wi, Tcl_GetString(args[2]), 0); +#else + l = Tk_GetOptionValue(interp, (char *) wi, wi->opt_table, args[2], wi->win); + if (l == NULL) { + goto error; + } + Tcl_SetObjResult(interp, l); +#endif } break; /* @@ -4227,6 +4591,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ */ case ZN_W_CONFIGURE: { +#ifdef PTK_800 if (argc == 2) { result = Tk_ConfigureInfo(interp, wi->win, config_specs, (char *) wi, (char *) NULL, 0); @@ -4238,6 +4603,21 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ else { result = Configure(interp, wi, argc-2, args+2, TK_CONFIG_ARGV_ONLY); } +#else + if (argc == 2) { + l = Tk_GetOptionInfo(interp, (char *) wi, wi->opt_table, + (argc == 3) ? args[2] : NULL, wi->win); + if (l == NULL) { + goto error; + } + else { + Tcl_SetObjResult(interp, l); + } + } + else { + result = Configure(interp, wi, argc-2, args+2); + } +#endif } break; /* @@ -4650,7 +5030,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ if ((result == TCL_ERROR) || (item == ZN_NO_ITEM)) { goto error; } - l = Tcl_NewBooleanObj(item->class->has_anchors?1:0); + l = Tcl_NewBooleanObj(ISSET(item->class->flags, ZN_CLASS_HAS_ANCHORS) ? 1 : 0); Tcl_SetObjResult(interp, l); } break; @@ -4857,12 +5237,12 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ item != ZN_NO_ITEM; item = ZnTagSearchNext(search_var)) { if (argc < 2) { if (field == ZN_NO_PART) { - result = ZnAttributesInfo(wi, item, item->class->attr_desc, argc, args); + result = ZnAttributesInfo(wi->interp, item, item->class->attr_desc, argc, args); } else if (item->class->GetFieldSet) { ZnFieldSet fs = item->class->GetFieldSet(item); if (field < (int) ZnFIELD.NumFields(fs)) { - result = ZnAttributesInfo(wi, ZnFIELD.GetFieldStruct(fs, field), + result = ZnAttributesInfo(wi->interp, ZnFIELD.GetFieldStruct(fs, field), ZnFIELD.attr_desc, argc, args); } else { @@ -5007,9 +5387,11 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ */ case ZN_W_POSTSCRIPT: { +#if 0 if (ZnPostScriptCmd(wi, argc, args) != TCL_OK) { goto error; } +#endif } break; /* @@ -5878,7 +6260,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ if (Tcl_GetDoubleFromObj(interp, args[3+i], &d) == TCL_ERROR) { goto error; } - new._[i/2][i%2] = d; + new._[i/2][i%2] = (float) d; } entry = Tcl_FindHashEntry(wi->t_table, Tcl_GetString(args[2])); if (entry != NULL) { @@ -6049,21 +6431,12 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ done: ZnTagSearchDestroy(search_var); - if (wi->work_item_list) { - ZnListFree(wi->work_item_list); - wi->work_item_list = NULL; - } Tcl_Release((ClientData) wi); return result; error: - ZnTagSearchDestroy(search_var); - if (wi->work_item_list) { - ZnListFree(wi->work_item_list); - wi->work_item_list = NULL; - } - Tcl_Release((ClientData) wi); - return TCL_ERROR; + result = TCL_ERROR; + goto done; } @@ -6087,6 +6460,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */ * *---------------------------------------------------------------------- */ +#ifdef PTK_800 static int Configure(Tcl_Interp *interp,/* Used for error reporting. */ ZnWInfo *wi, /* Information about widget. */ @@ -6312,7 +6686,269 @@ Configure(Tcl_Interp *interp,/* Used for error reporting. */ return TCL_OK; } +#else +static void +TileUpdate(void *client_data) +{ + ZnWInfo *wi = (ZnWInfo*) client_data; + + ZnDamageAll(wi); +} + +static int +Configure(Tcl_Interp *interp,/* Used for error reporting. */ + ZnWInfo *wi, /* Information about widget. */ + int argc, /* Number of valid entries in args. */ + Tcl_Obj *CONST args[]) /* Arguments. */ +{ + ZnBool init; + int render, mask, error; + Tk_SavedOptions saved_options; + Tcl_Obj *error_result = NULL; + + render = wi->render; + init = render < 0; + for (error = 0; error <= 1; error++) { + if (!error) { + if (Tk_SetOptions(interp, (char *) wi, wi->opt_table, argc, args, + wi->win, &saved_options, &mask) != TCL_OK) { + continue; + } + } + else { + /* Save the error value for later report */ + error_result = Tcl_GetObjResult(interp); + Tcl_IncrRefCount(error_result); + Tk_RestoreSavedOptions(&saved_options); + } + + if (!init) { + if (render != wi->render) { + ZnWarning("It is not possible to change the -render option after widget creation.\n"); + wi->render = render; + } + } + else if (wi->render < 0) { + wi->render = 0; + } + + if ((mask & CONFIG_SCROLL_REGION) || init) { + /* + * Compute the scroll region + */ + wi->scroll_xo = wi->scroll_yo = 0; + wi->scroll_xc = wi->scroll_yc = 0; + if (wi->region != NULL) { + int argc2; + Tcl_Obj **args2; + + if (Tcl_ListObjGetElements(interp, wi->region, &argc2, &args2) != TCL_OK) { + badRegion: + Tcl_AppendResult(interp, "bad scrollRegion \"", + Tcl_GetString(wi->region), "\"", (char *) NULL); + continue; + } + if (argc2 != 4) { + goto badRegion; + } +#ifdef PTK_800 + if ((Tk_GetPixels(interp, wi->win, LangString(args2[0]), &wi->scroll_xo) != TCL_OK) || + (Tk_GetPixels(interp, wi->win, LangString(args2[1]), &wi->scroll_yo) != TCL_OK) || + (Tk_GetPixels(interp, wi->win, LangString(args2[2]), &wi->scroll_xc) != TCL_OK) || + (Tk_GetPixels(interp, wi->win, LangString(args2[3]), &wi->scroll_yc) != TCL_OK)) +#else + if ((Tk_GetPixelsFromObj(interp, wi->win, args2[0], &wi->scroll_xo) != TCL_OK) || + (Tk_GetPixelsFromObj(interp, wi->win, args2[1], &wi->scroll_yo) != TCL_OK) || + (Tk_GetPixelsFromObj(interp, wi->win, args2[2], &wi->scroll_xc) != TCL_OK) || + (Tk_GetPixelsFromObj(interp, wi->win, args2[3], &wi->scroll_yc) != TCL_OK)) +#endif + { + goto badRegion; + } + } + } + + if ((mask & CONFIG_SET_ORIGIN) || init) { + SetOrigin(wi, wi->origin.x, wi->origin.y); + SET(wi->flags, ZN_UPDATE_SCROLLBARS); + } + +#ifdef GL + if ((mask & CONFIG_FONT) || !wi->font_tfi) { + if (wi->font_tfi) { + ZnFreeTexFont(wi->font_tfi); + wi->font_tfi = NULL; + } + } + if ((mask & CONFIG_MAP_FONT) || !wi->map_font_tfi) { + if (wi->map_font_tfi) { + ZnFreeTexFont(wi->map_font_tfi); + wi->map_font_tfi = NULL; + } + } +#endif + + if ((mask & CONFIG_TILE) || init) { + char *tile_name; + if (wi->tile) { + ZnFreeImage(wi->tile, TileUpdate, wi); + } + if (!wi->tile_obj || !*(tile_name = Tcl_GetString(wi->tile_obj))) { + wi->tile = ZnUnspecifiedImage; + } + else { + wi->tile = ZnGetImage(wi, tile_name, TileUpdate, wi); + if (wi->tile == ZnUnspecifiedImage) { + Tcl_AppendResult(interp, "Incorrect tile \"", tile_name, "\"", (char *) NULL); + continue; + } + } + } + + if ((mask & CONFIG_MAP_SYMBOL) || init) { + if (wi->map_distance_symbol) { + ZnFreeImage(wi->map_distance_symbol, NULL, NULL); + } + wi->map_distance_symbol = ZnGetImage(wi, Tcl_GetString(wi->map_symbol_obj), NULL, NULL); + if ((wi->map_distance_symbol == ZnUnspecifiedImage) || + ! ZnImageIsBitmap(wi->map_distance_symbol)) { + Tcl_AppendResult(interp, "Incorrect bitmap \"", + Tcl_GetString(wi->map_symbol_obj), "\"", (char *) NULL); + continue; + } + } + + if ((mask & CONFIG_TRACK_SYMBOL) || init) { + if (wi->track_symbol) { + ZnFreeImage(wi->track_symbol, NULL, NULL); + } + wi->track_symbol = ZnGetImage(wi, Tcl_GetString(wi->track_symbol_obj), NULL, NULL); + if ((wi->track_symbol == ZnUnspecifiedImage) || + ! ZnImageIsBitmap(wi->track_symbol)) { + Tcl_AppendResult(interp, "Incorrect bitmap \"", + Tcl_GetString(wi->track_symbol_obj), "\"", (char *) NULL); + continue; + + } + } + + /* + * Maintain the pick aperture within meaningful bounds. + */ + if (wi->pick_aperture < 0) { + wi->pick_aperture = 0; + } + + if ((mask & CONFIG_BACK_COLOR) || !wi->relief_grad) { + XColor *color; + unsigned short alpha; + + Tk_SetWindowBackground(wi->win, ZnGetGradientPixel(wi->back_color, 0.0)); + if (wi->relief_grad) { + ZnFreeGradient(wi->relief_grad); + wi->relief_grad = NULL; + } + if (wi->relief != ZN_RELIEF_FLAT) { + color = ZnGetGradientColor(wi->back_color, 0.0, &alpha); + wi->relief_grad = ZnGetReliefGradient(interp, wi->win, + Tk_NameOfColor(color), alpha); + } + } + if (mask & CONFIG_DAMAGE_ALL) { + ZnDamageAll(wi); + } + if ((mask & CONFIG_REDISPLAY) || init) { + ZnNeedRedisplay(wi); + } + + wi->inset = wi->border_width + wi->highlight_width; + + if (mask & CONFIG_INVALIDATE_TRACKS) { + ZnITEM.InvalidateItems(wi->top_group, ZnTrack); + } + if (mask & CONFIG_INVALIDATE_MAPS) { + ZnITEM.InvalidateItems(wi->top_group, ZnMap); + } + if (mask & CONFIG_INVALIDATE_WPS) { + ZnITEM.InvalidateItems(wi->top_group, ZnWayPoint); + } + + /* + * Request the new geometry. + */ + if ((mask & CONFIG_REQUEST_GEOM) || init) { + Tk_GeometryRequest(wi->win, wi->opt_width, wi->opt_height); + } + + /* + * Update the registration with the overlap manager. + */ +#ifdef OM + if (mask & CONFIG_OM) { + Tcl_HashEntry *entry; + ZnItem grp; + + if (wi->om_group != ZN_NO_ITEM) { + OmUnregister((void *) wi); + wi->om_group = ZN_NO_ITEM; + } + if (wi->om_group_id != 0) { + entry = Tcl_FindHashEntry(wi->id_table, (char *) wi->om_group_id); + if (entry != NULL) { + grp = (ZnItem) Tcl_GetHashValue(entry); + if (grp->class == ZnGroup) { + OmRegister((void *) wi, ZnSendTrackToOm, + ZnSetLabelAngleFromOm, ZnQueryLabelPosition); + wi->om_group = grp; + } + } + } + } +#endif + + if ((mask & CONFIG_FOCUS_ITEM) && wi->focus_item) { + ZnITEM.Invalidate(wi->focus_item, ZN_COORDS_FLAG); + } + /* + * Update the blinking cursor timing if on/off time has changed. + */ + if (ISSET(wi->flags, ZN_GOT_FOCUS) && (mask & CONFIG_FOCUS)) { + Focus(wi, True); + } + + if (mask & CONFIG_FOLLOW_POINTER) { + if (wi->follow_pointer) { + /* Flag has just been turned on, process + * the last known positional event to update + * the item under pointer. + */ + if (wi->pick_event.type == ButtonPress || + wi->pick_event.type == ButtonRelease || + wi->pick_event.type == MotionNotify || + wi->pick_event.type == EnterNotify || + wi->pick_event.type == LeaveNotify) { + Tcl_Preserve((ClientData) wi); + CLEAR(wi->flags, ZN_INTERNAL_NEED_REPICK); + PickCurrentItem(wi, &wi->pick_event); + Tcl_Release((ClientData) wi); + } + } + } + break; + } + + if (error) { + Tcl_SetObjResult(interp, error_result); + Tcl_DecrRefCount(error_result); + return TCL_ERROR; + } + else { + Tk_FreeSavedOptions(&saved_options); + return TCL_OK; + } +} +#endif /* *---------------------------------------------------------------------- @@ -6381,11 +7017,6 @@ Focus(ZnWInfo *wi, if (wi->highlight_width > 0) { ZnNeedRedisplay(wi); } -#ifdef GL_DAMAGE - if (wi->render) { - /* ZnDamageAll(wi);*/ - } -#endif } @@ -6412,6 +7043,7 @@ Event(ClientData client_data, /* Information about widget. */ { ZnWInfo *wi = (ZnWInfo *) client_data; XGCValues values; + ZnBBox bbox; /*printf("=============== DEBUT %s %d EVENT ==================\n", event->type == MapNotify ? "MAP": @@ -6420,51 +7052,11 @@ Event(ClientData client_data, /* Information about widget. */ event->type == DestroyNotify ? "DESTROY" : "??", event->type);*/ if (event->type == MapNotify) { + SET(wi->flags, ZN_CONFIGURE_EVENT); if (!wi->gc) { SET(wi->flags, ZN_REALIZED); - - if (wi->render) { -#ifdef GL - GLfloat r[2]; /* Min, Max */ - GLint i[1]; - ZnGLContextEntry *ce; - - ce = ZnGetGLContext(wi->dpy); - ZnGLMakeCurrent(wi->dpy, 0); - glGetFloatv(ZN_GL_LINE_WIDTH_RANGE, r); - ce->max_line_width = r[1]; - glGetFloatv(ZN_GL_POINT_SIZE_RANGE, r); - ce->max_point_width = r[1]; - glGetIntegerv(GL_MAX_TEXTURE_SIZE, i); - ce->max_tex_size = (unsigned int) i[0]; - - if (!wi->font_tfi) { - wi->font_tfi = ZnGetTexFont(wi, wi->font); - } - if (!wi->map_font_tfi) { - wi->map_font_tfi = ZnGetTexFont(wi, wi->map_text_font); - } - - if (ISSET(wi->flags, ZN_PRINT_CONFIG)) { - fprintf(stderr, "OpenGL version %s\n", - (char *) glGetString(GL_VERSION)); - fprintf(stderr, " Rendering engine: %s, ", - (char *) glGetString(GL_RENDERER)); - fprintf(stderr, " Vendor: %s\n", - (char *) glGetString(GL_VENDOR)); - fprintf(stderr, " Available extensions: %s\n", - (char *) glGetString(GL_EXTENSIONS)); - fprintf(stderr, "Max antialiased line width: %g\n", - ce->max_line_width); - fprintf(stderr, "Max antialiased point size: %g\n", - ce->max_point_width); - fprintf(stderr, "Max texture size: %d\n", - ce->max_tex_size); - } - - /*ZnGLRelease(wi);*/ -#endif - } + /*OutputDebugString("MAP\n");*/ + InitRendering(wi); /* * Get the work GC and suppress GraphicExpose @@ -6498,13 +7090,14 @@ Event(ClientData client_data, /* Information about widget. */ XFree(children); } } - ZnNeedRedisplay(wi); } + ZnNeedRedisplay(wi); } else if (event->type == Expose) { - ZnBBox bbox; ZnDim width, height; + SET(wi->flags, ZN_CONFIGURE_EVENT); + bbox.orig.x = (((XExposeEvent*) event)->x); bbox.orig.y = (((XExposeEvent*) event)->y); width = ((XExposeEvent*) event)->width; @@ -6529,6 +7122,10 @@ Event(ClientData client_data, /* Information about widget. */ * if we are done adding exposed parts. */ ZnAddBBoxToBBox(&wi->exposed_area, &bbox); + /*sprintf(msg, "EXPOSE %g %g %g %g\n", + wi->exposed_area.orig.x, wi->exposed_area.orig.y, + wi->exposed_area.corner.x, wi->exposed_area.corner.y); + OutputDebugString(msg);*/ if (/*(((XExposeEvent*) event)->count == 0) &&*/ !ZnIsEmptyBBox(&wi->exposed_area)) { ZnNeedRedisplay(wi); @@ -6542,7 +7139,8 @@ Event(ClientData client_data, /* Information about widget. */ */ else if (event->type == ConfigureNotify) { int int_width, int_height; - ZnBBox bbox; + + SET(wi->flags, ZN_CONFIGURE_EVENT); int_width = Tk_Width(wi->win); int_height = Tk_Height(wi->win); @@ -6572,7 +7170,9 @@ Event(ClientData client_data, /* Information about widget. */ */ if (!wi->render) { /*printf("reallocating double buffer\n");*/ - Tk_FreePixmap(wi->dpy, wi->draw_buffer); + if (wi->draw_buffer) { + Tk_FreePixmap(wi->dpy, wi->draw_buffer); + } wi->draw_buffer = Tk_GetPixmap(wi->dpy, RootWindowOfScreen(wi->screen), int_width, int_height, DefaultDepthOfScreen(wi->screen)); @@ -7035,7 +7635,7 @@ Bind(ClientData client_data, /* Information about widget. */ XEvent *event) /* Information about event. */ { ZnWInfo *wi = (ZnWInfo *) client_data; - + Tcl_Preserve((ClientData) wi); /* @@ -7104,19 +7704,19 @@ Bind(ClientData client_data, /* Information about widget. */ } else if ((event->type == EnterNotify) || (event->type == LeaveNotify)) { -#ifdef GL_DAMAGE - /* - * Kludge to prevent incorrect redrawing after - * a move window when using GL. This code force - * a full window redraw on window enter/leaves - * hoping it will realign the back buffer soon - * enough to make the bug unnoticed. +#if defined(_WIN32) && defined(GL) + /* Only needed on Windows to help get the display right + * after a window move. It also helps with the first redraw + * after window creation. */ - if (wi->render) { - /* ZnDamageAll(wi);*/ - } + ZnBBox bbox; + + bbox.orig.x = bbox.orig.y = 0; + bbox.corner.x = Tk_Width(wi->win); + bbox.corner.y = Tk_Height(wi->win); + ZnDamage(wi, &bbox); #endif - + wi->state = event->xcrossing.state; PickCurrentItem(wi, event); goto done; @@ -7336,6 +7936,7 @@ Destroy(char *mem_ptr) /* Info about the widget. */ Tcl_HashEntry *entry; /*printf("Destroy begining\n");*/ + /*OutputDebugString("Destroy begining\n");*/ /* * This procedure could be invoked either because the window was * destroyed and the command was then deleted (in which case win @@ -7413,7 +8014,11 @@ Destroy(char *mem_ptr) /* Info about the widget. */ /* Free the tile */ if (wi->tile != ZnUnspecifiedImage) { +#ifdef PTK_800 ZnFreeImage(wi->tile, ZnImageUpdate, wi); +#else + ZnFreeImage(wi->tile, TileUpdate, wi); +#endif wi->tile = ZnUnspecifiedImage; } @@ -7433,6 +8038,7 @@ Destroy(char *mem_ptr) /* Info about the widget. */ wi->draw_buffer = 0; } +#ifdef PTK_800 if (wi->fore_color) { ZnFreeGradient(wi->fore_color); wi->fore_color = NULL; @@ -7441,6 +8047,7 @@ Destroy(char *mem_ptr) /* Info about the widget. */ ZnFreeGradient(wi->back_color); wi->back_color = NULL; } +#endif if (wi->relief_grad) { ZnFreeGradient(wi->relief_grad); wi->relief_grad = NULL; @@ -7451,8 +8058,12 @@ Destroy(char *mem_ptr) /* Info about the widget. */ } Tcl_DeleteTimerHandler(wi->blink_handler); - + +#ifdef PTK_800 Tk_FreeOptions(config_specs, (char *) wi, wi->dpy, 0); +#else + Tk_FreeConfigOptions((char *) wi, wi->opt_table, wi->win); +#endif /* * Should be empty by now. @@ -7460,24 +8071,14 @@ Destroy(char *mem_ptr) /* Info about the widget. */ ZnFreeTransformStack(wi); ZnFreeClipStack(wi); - ZnListFree(wi->work_pts); -#ifdef GL - ZnListFree(wi->work_doubles); -#endif - ZnListFree(wi->work_xpts); - ZnListFree(wi->work_strs); - #ifndef _WIN32 ZnFreeChrono(wi->total_draw_chrono); ZnFreeChrono(wi->this_draw_chrono); #endif - if (wi->tess) { - gluDeleteTess(wi->tess); - } - ZnFree(wi); /*printf("Destroy ending\n");*/ + /*OutputDebugString("Destroy ending\n");*/ } @@ -7586,11 +8187,12 @@ Update(ZnWInfo *wi) ZnGroupSetCallOm(wi->om_group, False); } #endif - + /*OutputDebugString("Update Begin\n");*/ if (ISSET(wi->top_group->inv_flags, ZN_COORDS_FLAG) || ISSET(wi->top_group->inv_flags, ZN_TRANSFO_FLAG)) { wi->top_group->class->ComputeCoordinates(wi->top_group, False); } + /*OutputDebugString("Update End\n");*/ } @@ -7612,21 +8214,27 @@ Repair(ZnWInfo *wi) #endif int int_width = Tk_Width(wi->win); int int_height = Tk_Height(wi->win); + ZnGLContextEntry *ce; if (wi->render) { + ZnGLWaitX(); #ifdef GL #ifdef GL_DAMAGE - ClampDamageArea(wi); - /* - * Merge the exposed area. - */ - ZnAddBBoxToBBox(&wi->damaged_area, &wi->exposed_area); - if (ZnIsEmptyBBox(&wi->damaged_area)) { - return; + if (ISCLEAR(wi->flags, ZN_CONFIGURE_EVENT)) { + ClampDamageArea(wi); + /* + * Merge the exposed area. + */ + ZnAddBBoxToBBox(&wi->damaged_area, &wi->exposed_area); + if (ZnIsEmptyBBox(&wi->damaged_area)) { + return; + } } #endif - ZnGLMakeCurrent(wi->dpy, wi->win); + /*sprintf(msg, "Repair, scissors: %d\n", ISCLEAR(wi->flags, ZN_CONFIGURE_EVENT)); + OutputDebugString(msg);*/ + ce = ZnGLMakeCurrent(wi->dpy, wi->win); glEnable(GL_POINT_SMOOTH); glEnable(GL_LINE_SMOOTH); #if 0 @@ -7656,32 +8264,35 @@ Repair(ZnWInfo *wi) glMatrixMode(GL_MODELVIEW); #ifdef GL_DAMAGE - glEnable(GL_SCISSOR_TEST); - - /* - * Set the damaged area as the scissor area. - */ - wi->damaged_area.orig.x = ZnNearestInt(wi->damaged_area.orig.x); - wi->damaged_area.orig.y = ZnNearestInt(wi->damaged_area.orig.y); - wi->damaged_area.corner.x = ZnNearestInt(wi->damaged_area.corner.x); - wi->damaged_area.corner.y = ZnNearestInt(wi->damaged_area.corner.y); - glScissor((int) wi->damaged_area.orig.x, - int_height - (int) wi->damaged_area.corner.y, - (int) (wi->damaged_area.corner.x - wi->damaged_area.orig.x), - (int) (wi->damaged_area.corner.y - wi->damaged_area.orig.y)); - /*printf("Repair : limiting to: %g %g %g %g\n", - wi->damaged_area.orig.x, wi->damaged_area.orig.y, - wi->damaged_area.corner.x, wi->damaged_area.corner.y);*/ + if (ISCLEAR(wi->flags, ZN_CONFIGURE_EVENT)) { + glEnable(GL_SCISSOR_TEST); + + /* + * Set the damaged area as the scissor area. + */ + wi->damaged_area.orig.x = ZnNearestInt(wi->damaged_area.orig.x); + wi->damaged_area.orig.y = ZnNearestInt(wi->damaged_area.orig.y); + wi->damaged_area.corner.x = ZnNearestInt(wi->damaged_area.corner.x); + wi->damaged_area.corner.y = ZnNearestInt(wi->damaged_area.corner.y); + glScissor((int) wi->damaged_area.orig.x, + int_height - (int) wi->damaged_area.corner.y, + (int) (wi->damaged_area.corner.x - wi->damaged_area.orig.x), + (int) (wi->damaged_area.corner.y - wi->damaged_area.orig.y)); + } + else { + wi->damaged_area.orig.x = wi->damaged_area.orig.y = wi->inset; + wi->damaged_area.corner.x = int_width-wi->inset; + wi->damaged_area.corner.y = int_height-wi->inset; + } #else /* - * We do not use the damaged area for GL rendering, - * set it to the whole area. + * We do not use the damaged area set it to the whole area. */ wi->damaged_area.orig.x = wi->damaged_area.orig.y = wi->inset; wi->damaged_area.corner.x = int_width-wi->inset; wi->damaged_area.corner.y = int_height-wi->inset; #endif - + /* * Clear the GL buffers. */ @@ -7706,7 +8317,9 @@ Repair(ZnWInfo *wi) unsigned short alpha; #ifdef GL_DAMAGE - glDisable(GL_SCISSOR_TEST); + if (ISCLEAR(wi->flags, ZN_CONFIGURE_EVENT)) { + glDisable(GL_SCISSOR_TEST); + } #endif if (wi->highlight_width > 0) { color = ZnGetGradientColor(ISSET(wi->flags, ZN_GOT_FOCUS)?wi->highlight_color: @@ -7755,15 +8368,12 @@ Repair(ZnWInfo *wi) glEnd(); } } -#ifdef GL_DAMAGE - glEnable(GL_SCISSOR_TEST); -#endif + + CLEAR(wi->flags, ZN_CONFIGURE_EVENT); } - glFlush(); /* Switch the GL buffers. */ - ZnGLSwapBuffers(wi->dpy, wi->win); - /*ZnGLRelease(wi);*/ + ZnGLSwapBuffers(ce, wi->win); /* * Wait the end of GL update if we need to synchronize @@ -7772,6 +8382,8 @@ Repair(ZnWInfo *wi) if (ISSET(wi->flags, ZN_MONITORING)) { ZnGLWaitGL(); } + + ZnGLReleaseContext(ce); #endif } else { @@ -7780,7 +8392,7 @@ Repair(ZnWInfo *wi) ClampDamageArea(wi); /* - * Merge the damaged area with the exposed area. +m * Merge the damaged area with the exposed area. */ ZnResetBBox(&merge); ZnCopyBBox(&wi->damaged_area, &merge); @@ -7816,7 +8428,6 @@ Repair(ZnWInfo *wi) XFillRectangle(wi->dpy, wi->draw_buffer, wi->gc, r.x, r.y, r.width, r.height); /* Draw the items */ - /*printf("Drawing\n");*/ wi->top_group->class->Draw(wi->top_group); ZnPopClip(wi, True); @@ -7994,6 +8605,116 @@ Redisplay(ClientData client_data) /* Information about the widget. */ } } +static void +ZnTessBegin(GLenum type, + void *data) +{ + ZnPoly *outlines = data; + ZnTriStrip *tristrips = data; + + ZnListEmpty(ZnWorkPoints); + ZnTesselator.type = type; + if (type == GL_LINE_LOOP) { + outlines->num_contours++; + outlines->contours = ZnRealloc(outlines->contours, + outlines->num_contours * sizeof(ZnContour)); + } + else { + tristrips->num_strips++; + tristrips->strips = ZnRealloc(tristrips->strips, + tristrips->num_strips * sizeof(ZnStrip)); + tristrips->strips[tristrips->num_strips-1].fan = (type==GL_TRIANGLE_FAN); + } + /*printf("Début de fragment de type: %s\n", + (type == GL_TRIANGLE_FAN) ? "FAN" : + (type == GL_TRIANGLE_STRIP) ? "STRIP" : + (type == GL_TRIANGLES) ? "TRIANGLES" : + (type == GL_LINE_LOOP) ? "LINE LOOP" : "");*/ +} + +static void +ZnTessVertex(void *vertex_data, + void *data) +{ + ZnTriStrip *tristrips = data; + ZnPoint p; + int size; + + p.x = ((GLdouble *) vertex_data)[0]; + p.y = ((GLdouble *) vertex_data)[1]; + /*printf("Sommet en %g %g\n", p.x, p.y);*/ + size = ZnListSize(ZnWorkPoints); + if ((ZnTesselator.type == GL_TRIANGLES) && (size == 3)) { + tristrips->strips[tristrips->num_strips-1].num_points = size; + tristrips->strips[tristrips->num_strips-1].points = ZnMalloc(size * sizeof(ZnPoint)); + memcpy(tristrips->strips[tristrips->num_strips-1].points, + ZnListArray(ZnWorkPoints), size * sizeof(ZnPoint)); + /*printf("Fin de fragment intermediaire %d, num points: %d\n", tristrips->num_strips-1, size);*/ + /* Allocate a new fragment */ + ZnListEmpty(ZnWorkPoints); + tristrips->num_strips++; + tristrips->strips = ZnRealloc(tristrips->strips, + tristrips->num_strips * sizeof(ZnStrip)); + tristrips->strips[tristrips->num_strips-1].fan = False; + } + ZnListAdd(ZnWorkPoints, &p, ZnListTail); +} + +static void +ZnTessEnd(void *data) +{ + ZnPoly *outlines = data; + ZnTriStrip *tristrips = data; + unsigned int size = ZnListSize(ZnWorkPoints); + unsigned int num; + + if (ZnTesselator.type == GL_LINE_LOOP) { + /* Add the last point to close the outline */ + size++; + num = outlines->num_contours; + outlines->contours[num-1].num_points = size; + outlines->contours[num-1].points = ZnMalloc(size * sizeof(ZnPoint)); + memcpy(outlines->contours[num-1].points, + ZnListArray(ZnWorkPoints), size * sizeof(ZnPoint)); + outlines->contours[num-1].points[size-1] = outlines->contours[num-1].points[0]; + outlines->contours[num-1].cw = !ZnTestCCW(outlines->contours[num-1].points, size); + } + else { + num = tristrips->num_strips; + tristrips->strips[num-1].num_points = size; + tristrips->strips[num-1].points = ZnMalloc(size * sizeof(ZnPoint)); + memcpy(tristrips->strips[num-1].points, + ZnListArray(ZnWorkPoints), size * sizeof(ZnPoint)); + } + /*printf("Fin de fragment %d, num points: %d\n", num, size);*/ +} + +static void +ZnTessCombine(GLdouble coords[3], + void *vertex_data[4] __unused, + GLfloat weight[4] __unused, + void **out_data, + void *data __unused) +{ + ZnCombineData *cdata; + + cdata = ZnMalloc(sizeof(ZnCombineData)); + cdata->v[0] = coords[0]; + cdata->v[1] = coords[1]; + cdata->next = ZnTesselator.combine_list; + ZnTesselator.combine_list = cdata; + *out_data = &cdata->v; + /*printf("Création d'un nouveau sommet en %g %g\n", + cdata->v[0], cdata->v[1]);*/ +} + +static void +ZnTessError(GLenum errno, + void *data __unused) +{ + fprintf(stderr, "Tesselation error in curve item: %d\n", errno); +} + static void InitZinc(Tcl_Interp *interp) { @@ -8050,8 +8771,32 @@ InitZinc(Tcl_Interp *interp) { sprintf(name, "AlphaStipple%d", i); Tk_DefineBitmap(interp, Tk_GetUid(name), (char *) bitmaps[i], 32, 32); } + + /* + * Initialize the temporary lists. + */ + ZnWorkPoints = ZnListNew(8, sizeof(ZnPoint)); + ZnWorkXPoints = ZnListNew(8, sizeof(XPoint)); + ZnWorkStrings = ZnListNew(8, sizeof(char *)); /* + * Allocate a GLU tesselator. + */ + ZnTesselator.tess = gluNewTess(); + ZnTesselator.combine_list = NULL; + gluTessCallback(ZnTesselator.tess, GLU_TESS_BEGIN_DATA, + (_GLUfuncptr) ZnTessBegin); + gluTessCallback(ZnTesselator.tess, GLU_TESS_VERTEX_DATA, + (_GLUfuncptr) ZnTessVertex); + gluTessCallback(ZnTesselator.tess, GLU_TESS_END_DATA, + (_GLUfuncptr) ZnTessEnd); + gluTessCallback(ZnTesselator.tess, GLU_TESS_COMBINE_DATA, + (_GLUfuncptr) ZnTessCombine); + gluTessCallback(ZnTesselator.tess, GLU_TESS_ERROR_DATA, + (_GLUfuncptr) ZnTessError); + gluTessNormal(ZnTesselator.tess, 0.0, 0.0, -1.0); + + /* * Initialize the item module. */ ZnItemInit(); |