aboutsummaryrefslogtreecommitdiff
path: root/generic/tkZinc.c
diff options
context:
space:
mode:
authorlecoanet2007-01-23 13:08:18 +0000
committerlecoanet2007-01-23 13:08:18 +0000
commit42f902be35e6349b7121542cd5133d24fa751078 (patch)
treed6d0b055d4b993fe5898b5c2a989e9d8097caa8e /generic/tkZinc.c
parentcb98dd20e9e0f92995a6fd1177ef1676a55e401b (diff)
downloadtkzinc-42f902be35e6349b7121542cd5133d24fa751078.zip
tkzinc-42f902be35e6349b7121542cd5133d24fa751078.tar.gz
tkzinc-42f902be35e6349b7121542cd5133d24fa751078.tar.bz2
tkzinc-42f902be35e6349b7121542cd5133d24fa751078.tar.xz
Integrated extension detection via glew
Added MouseWheel support Rotation patch
Diffstat (limited to 'generic/tkZinc.c')
-rw-r--r--generic/tkZinc.c542
1 files changed, 401 insertions, 141 deletions
diff --git a/generic/tkZinc.c b/generic/tkZinc.c
index 1a5784a..d737cfb 100644
--- a/generic/tkZinc.c
+++ b/generic/tkZinc.c
@@ -30,6 +30,9 @@ static const char compile_id[]="$Compile: " __FILE__ " " __DATE__ " " __TIME__ "
static const char * const zinc_version = "zinc-version-" PACKAGE_VERSION;
+#define GLEW_STATIC
+#include <GL/glew.h>
+
#include "Types.h"
#include "Geo.h"
#include "Item.h"
@@ -166,6 +169,9 @@ static int ZnGLAttribs[] = {
ZnTess ZnTesselator;
+#if defined(GL) && defined(ROTATION)
+static void TransformEvent _ANSI_ARGS_((ZnWInfo *wi, XEvent *event));
+#endif
static void PickCurrentItem _ANSI_ARGS_((ZnWInfo *wi, XEvent *event));
#ifdef PTK_800
static int ZnReliefParse _ANSI_ARGS_((ClientData client_data, Tcl_Interp *interp,
@@ -246,44 +252,54 @@ static Tk_ObjCustomOption gradientOption = {
#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
+#define BACK_COLOR_SPEC (BORDER_WIDTH_SPEC + 1)
+#define CONFINE_SPEC (BACK_COLOR_SPEC + 1)
+#define CURSOR_SPEC (CONFINE_SPEC + 1)
+#define FONT_SPEC (CURSOR_SPEC + 1)
+#define FORE_COLOR_SPEC (FONT_SPEC + 1)
+#define FULL_RESHAPE_SPEC (FORE_COLOR_SPEC + 1)
+#define HEIGHT_SPEC (FULL_RESHAPE_SPEC + 1)
+#define HIGHLIGHT_BACK_COLOR_SPEC (HEIGHT_SPEC + 1)
+#define HIGHLIGHT_COLOR_SPEC (HIGHLIGHT_BACK_COLOR_SPEC + 1)
+#define HIGHLIGHT_THICKNESS_SPEC (HIGHLIGHT_COLOR_SPEC + 1)
+#define INSERT_COLOR_SPEC (HIGHLIGHT_THICKNESS_SPEC + 1)
+#define INSERT_OFF_TIME_SPEC (INSERT_COLOR_SPEC + 1)
+#define INSERT_ON_TIME_SPEC (INSERT_OFF_TIME_SPEC + 1)
+#define INSERT_WIDTH_SPEC (INSERT_ON_TIME_SPEC + 1)
+#define PICK_APERTURE_SPEC (INSERT_WIDTH_SPEC + 1)
+#define RELIEF_SPEC (PICK_APERTURE_SPEC + 1)
+#define RENDER_SPEC (RELIEF_SPEC + 1)
+#define RESHAPE_SPEC (RENDER_SPEC + 1)
+#define SCROLL_REGION_SPEC (RESHAPE_SPEC + 1)
+#define SELECT_COLOR_SPEC (SCROLL_REGION_SPEC + 1)
+#define TAKE_FOCUS_SPEC (SELECT_COLOR_SPEC + 1)
+#define TILE_SPEC (TAKE_FOCUS_SPEC + 1)
+#define WIDTH_SPEC (TILE_SPEC + 1)
+#define X_SCROLL_CMD_SPEC (WIDTH_SPEC + 1)
+#define X_SCROLL_INCREMENT_SPEC (X_SCROLL_CMD_SPEC + 1)
+#define Y_SCROLL_CMD_SPEC (X_SCROLL_INCREMENT_SPEC + 1)
+#define Y_SCROLL_INCREMENT_SPEC (Y_SCROLL_CMD_SPEC + 1)
+#define BBOXES_SPEC (Y_SCROLL_INCREMENT_SPEC + 1)
+#define BBOXES_COLOR_SPEC (BBOXES_SPEC + 1)
+#define LIGHT_ANGLE_SPEC (BBOXES_COLOR_SPEC + 1)
+#define FOLLOW_POINTER_SPEC (LIGHT_ANGLE_SPEC + 1)
+#ifdef ATC
+#define MAP_DISTANCE_SYMBOL_SPEC (FOLLOW_POINTER_SPEC + 1)
+#define MAP_TEXT_FONT_SPEC (MAP_DISTANCE_SYMBOL_SPEC + 1)
+#define OVERLAP_MANAGER_SPEC (MAP_TEXT_FONT_SPEC + 1)
+#define SPEED_VECTOR_LENGTH_SPEC (OVERLAP_MANAGER_SPEC + 1)
+#define VISIBLE_HISTORY_SIZE_SPEC (SPEED_VECTOR_LENGTH_SPEC + 1)
+#define MANAGED_HISTORY_SIZE_SPEC (VISIBLE_HISTORY_SIZE_SPEC + 1)
+#define TRACK_SYMBOL_SPEC (MANAGED_HISTORY_SIZE_SPEC + 1)
+#endif
+#if defined(GL) && defined(ROTATION)
+#ifdef ATC
+#define SCREEN_ROTATION_SPEC (TRACK_SYMBOL_SPEC + 1)
+#else
+#define SCREEN_ROTATION_SPEC (FOLLOW_POINTER_SPEC + 1)
+#endif
+#define ENABLE_ROTATION_SPEC (SCREEN_ROTATION_SPEC + 1)
+#endif
#else
#define CONFIG_FONT 1<<0
#define CONFIG_MAP_FONT 1<<1
@@ -303,7 +319,11 @@ static Tk_ObjCustomOption gradientOption = {
#define CONFIG_MAP_SYMBOL 1<<15
#define CONFIG_TRACK_SYMBOL 1<<16
#define CONFIG_TILE 1<<17
-#define CONFIG_DEBUG 1<<18
+#define CONFIG_DEBUG 1<<18
+#if defined(GL) && defined(ROTATION)
+#define CONFIG_ROTATION 1<<19
+#define CONFIG_ENABLE_ROTATION 1<<20
+#endif
#endif
/*
@@ -342,16 +362,6 @@ static Tk_ConfigSpec config_specs[] = {
"600", Tk_Offset(ZnWInfo, insert_on_time), 0, NULL},
{TK_CONFIG_PIXELS, "-insertwidth", "insertWidth", "InsertWidth",
"2", Tk_Offset(ZnWInfo, text_info.insert_width), 0, NULL},
-#ifdef ATC
- {TK_CONFIG_CUSTOM, "-mapdistancesymbol", "mapDistanceSymbol", "MapDistanceSymbol",
- "AtcSymbol19", Tk_Offset(ZnWInfo, map_distance_symbol),
- TK_CONFIG_NULL_OK, &bitmapOption},
- {TK_CONFIG_FONT, "-maptextfont", "mapTextFont", "MapTextFont",
- "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*",
- Tk_Offset(ZnWInfo, map_text_font), 0, NULL},
- {TK_CONFIG_INT, "-overlapmanager", "overlapManager", "OverlapManager", "1",
- Tk_Offset(ZnWInfo, om_group_id), 0, NULL},
-#endif
{TK_CONFIG_INT, "-pickaperture", "pickAperture", "PickAperture",
"1", Tk_Offset(ZnWInfo, pick_aperture), 0, NULL},
{TK_CONFIG_CUSTOM, "-relief", "relief", "Relief",
@@ -364,22 +374,10 @@ static Tk_ConfigSpec config_specs[] = {
"", Tk_Offset(ZnWInfo, region), TK_CONFIG_NULL_OK, NULL},
{TK_CONFIG_CUSTOM, "-selectbackground", "selectBackground", "Foreground",
"#a0a0a0", Tk_Offset(ZnWInfo, text_info.sel_color), 0, &gradientOption},
-#ifdef ATC
- {TK_CONFIG_DOUBLE, "-speedvectorlength", "speedVectorLength",
- "SpeedVectorLength", "3", Tk_Offset(ZnWInfo, speed_vector_length), 0, NULL},
-#endif
{TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus",
NULL, Tk_Offset(ZnWInfo, take_focus), TK_CONFIG_NULL_OK, NULL},
{TK_CONFIG_CUSTOM, "-tile", "tile", "Tile",
"", Tk_Offset(ZnWInfo, tile), 0, &imageOption},
-#ifdef ATC
- {TK_CONFIG_INT, "-trackvisiblehistorysize", "trackVisibleHistorySize", "TrackVisibleHistorySize",
- "6", Tk_Offset(ZnWInfo, track_visible_history_size), 0, NULL},
- {TK_CONFIG_INT, "-trackmanagedhistorysize", "trackManagedHistorySize",
- "TrackManagedHistorySize", "6", Tk_Offset(ZnWInfo, track_managed_history_size), 0, NULL},
- {TK_CONFIG_CUSTOM, "-tracksymbol", "trackSymbol", "TrackSymbol",
- "AtcSymbol15", Tk_Offset(ZnWInfo, track_symbol), TK_CONFIG_NULL_OK, &bitmapOption},
-#endif
{TK_CONFIG_PIXELS, "-width", "width", "Width",
"10c", Tk_Offset(ZnWInfo, opt_width), 0, NULL},
{TK_CONFIG_CALLBACK, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
@@ -401,6 +399,30 @@ static Tk_ConfigSpec config_specs[] = {
"120", Tk_Offset(ZnWInfo, light_angle), 0, NULL},
{TK_CONFIG_BOOLEAN, "-followpointer", "followPointer",
"FollowPointer", "1", Tk_Offset(ZnWInfo, follow_pointer), 0, NULL},
+#ifdef ATC
+ {TK_CONFIG_CUSTOM, "-mapdistancesymbol", "mapDistanceSymbol", "MapDistanceSymbol",
+ "AtcSymbol19", Tk_Offset(ZnWInfo, map_distance_symbol),
+ TK_CONFIG_NULL_OK, &bitmapOption},
+ {TK_CONFIG_FONT, "-maptextfont", "mapTextFont", "MapTextFont",
+ "-adobe-helvetica-bold-r-normal--*-120-*-*-*-*-*-*",
+ Tk_Offset(ZnWInfo, map_text_font), 0, NULL},
+ {TK_CONFIG_INT, "-overlapmanager", "overlapManager", "OverlapManager", "1",
+ Tk_Offset(ZnWInfo, om_group_id), 0, NULL},
+ {TK_CONFIG_DOUBLE, "-speedvectorlength", "speedVectorLength",
+ "SpeedVectorLength", "3", Tk_Offset(ZnWInfo, speed_vector_length), 0, NULL},
+ {TK_CONFIG_INT, "-trackvisiblehistorysize", "trackVisibleHistorySize", "TrackVisibleHistorySize",
+ "6", Tk_Offset(ZnWInfo, track_visible_history_size), 0, NULL},
+ {TK_CONFIG_INT, "-trackmanagedhistorysize", "trackManagedHistorySize",
+ "TrackManagedHistorySize", "6", Tk_Offset(ZnWInfo, track_managed_history_size), 0, NULL},
+ {TK_CONFIG_CUSTOM, "-tracksymbol", "trackSymbol", "TrackSymbol",
+ "AtcSymbol15", Tk_Offset(ZnWInfo, track_symbol), TK_CONFIG_NULL_OK, &bitmapOption},
+#endif
+#if defined(GL) && defined(ROTATION)
+ {TK_CONFIG_BOOLEAN, "-enablerotation", "enableRotation", "EnableRotation",
+ "0", Tk_Offset(ZnWInfo, enable_rotation), 0, NULL},
+ {TK_CONFIG_DOUBLE, "-screenrotation", "screenRotation", "ScreenRotation",
+ "0", Tk_Offset(ZnWInfo, screen_rotation), 0, NULL},
+#endif
{TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};
@@ -441,16 +463,6 @@ static Tk_OptionSpec option_specs[] = {
"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},
-#ifdef ATC
- {TK_OPTION_STRING, "-mapdistancesymbol", "mapDistanceSymbol", "MapDistanceSymbol",
- "AtcSymbol19", Tk_Offset(ZnWInfo, map_symbol_obj), -1,
- TK_OPTION_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},
-#endif
{TK_OPTION_INT, "-pickaperture", "pickAperture", "PickAperture",
"1", -1, Tk_Offset(ZnWInfo, pick_aperture), 0, NULL, 0},
{TK_OPTION_CUSTOM, "-relief", "relief", "Relief",
@@ -464,25 +476,10 @@ static Tk_OptionSpec option_specs[] = {
TK_OPTION_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},
-#ifdef ATC
- {TK_OPTION_DOUBLE, "-speedvectorlength", "speedVectorLength",
- "SpeedVectorLength", "3", -1, Tk_Offset(ZnWInfo, speed_vector_length),
- 0, NULL, CONFIG_INVALIDATE_TRACKS},
-#endif
{TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
NULL, Tk_Offset(ZnWInfo, take_focus), -1, TK_OPTION_NULL_OK, NULL, 0},
{TK_OPTION_STRING, "-tile", "tile", "Tile",
"", Tk_Offset(ZnWInfo, tile_obj), -1, TK_OPTION_NULL_OK, NULL, CONFIG_TILE|CONFIG_DAMAGE_ALL},
-#ifdef ATC
- {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},
-#endif
{TK_OPTION_PIXELS, "-width", "width", "Width",
"10c", -1, Tk_Offset(ZnWInfo, opt_width), 0, NULL, CONFIG_DAMAGE_ALL|CONFIG_REQUEST_GEOM},
#ifdef PTK
@@ -514,6 +511,33 @@ static Tk_OptionSpec option_specs[] = {
"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},
+#ifdef ATC
+ {TK_OPTION_STRING, "-mapdistancesymbol", "mapDistanceSymbol", "MapDistanceSymbol",
+ "AtcSymbol19", Tk_Offset(ZnWInfo, map_symbol_obj), -1,
+ TK_OPTION_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_DOUBLE, "-speedvectorlength", "speedVectorLength",
+ "SpeedVectorLength", "3", -1, Tk_Offset(ZnWInfo, speed_vector_length),
+ 0, NULL, CONFIG_INVALIDATE_TRACKS},
+ {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},
+#endif
+#if defined(GL) && defined(ROTATION)
+ {TK_OPTION_BOOLEAN, "-enablerotation", "enableRotation", "EnableRotation",
+ "0", -1, Tk_Offset(ZnWInfo, enable_rotation), 0, NULL, CONFIG_ENABLE_ROTATION},
+ {TK_OPTION_DOUBLE, "-screenrotation", "screenRotation", "ScreenRotation",
+ "0", -1, Tk_Offset(ZnWInfo, screen_rotation), 0, NULL, CONFIG_ROTATION},
+#endif
{TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0}
};
@@ -1140,6 +1164,8 @@ static void
InitRendering2(ZnWInfo *wi,
Tk_Window top_level)
{
+ static int glew_inited = 0;
+ GLenum err;
ZnGLContextEntry *ce;
ZnGLContext gl_context;
GLfloat r[2]; /* Min, Max */
@@ -1278,6 +1304,14 @@ InitRendering2(ZnWInfo *wi,
fprintf(stderr, "Max texture size: %d\n",
ce->max_tex_size);
}
+
+ if (!glew_inited) {
+ glew_inited = 1;
+ err = glewInit();
+ if (err != GLEW_OK) {
+ fprintf(stderr, "GLEW: %s\n", glewGetErrorString(err));
+ }
+ }
#if defined(MAC_OSX_TK)
UpdateBufferRect(ce, wi->win);
@@ -1389,6 +1423,10 @@ ZincObjCmd(ClientData client_data, /* Main window associated with
wi->flags = 0;
wi->render = -1;
wi->real_top = None;
+#if defined(GL) && defined(ROTATION)
+ wi->screen_rotation = 0;
+ wi->enable_rotation = 0;
+#endif
ASSIGN(wi->flags, ZN_HAS_GL, has_gl);
#if defined(SHAPE)
@@ -1531,7 +1569,8 @@ ZincObjCmd(ClientData client_data, /* Main window associated with
Event, (ClientData) wi);
Tk_CreateEventHandler(tkwin, KeyPressMask|KeyReleaseMask|
ButtonPressMask|ButtonReleaseMask|EnterWindowMask|
- LeaveWindowMask|PointerMotionMask|VirtualEventMask,
+ LeaveWindowMask|PointerMotionMask|VirtualEventMask|
+ MouseWheelMask,
Bind, (ClientData) wi);
Tk_CreateSelHandler(tkwin, XA_PRIMARY, XA_STRING,
FetchSelection, (ClientData) wi, XA_STRING);
@@ -1562,11 +1601,16 @@ ZincObjCmd(ClientData client_data, /* Main window associated with
* Allocate double buffer pixmap/image.
*/
wi->draw_buffer = Tk_GetPixmap(wi->dpy, RootWindowOfScreen(wi->screen),
- wi->width, wi->height, Tk_Depth(wi->win));
+ wi->opt_width, wi->opt_height, Tk_Depth(wi->win));
}
-#ifdef GL
+
+#if defined(GL) && defined(ROTATION)
else {
InitRendering1(wi);
+ wi->canvastex = 0;
+ wi->fbo = 0;
+ wi->depthstencil = 0;
+ SET(wi->flags, ZN_UPDATE_CANVASTEX);
}
#endif
@@ -4559,12 +4603,13 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget.
ButtonPressMask | ButtonReleaseMask |
EnterWindowMask | LeaveWindowMask |
KeyPressMask | KeyReleaseMask |
- PointerMotionMask | VirtualEventMask)) {
+ PointerMotionMask | VirtualEventMask |
+ MouseWheelMask)) {
Tk_DeleteBinding(interp, wi->binding_table, elem, Tcl_GetString(args[3]));
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "requested illegal events; ",
"only key, button, motion, enter, leave ",
- "and virtual events may be used", NULL);
+ "mousewheel and virtual events may be used", NULL);
goto error;
}
}
@@ -6731,6 +6776,21 @@ Configure(Tcl_Interp *interp,/* Used for error reporting. */
#endif
#endif
+#if defined(GL) && defined(ROTATION)
+ //
+ // No rotation correction if no GL rendering
+ if (CONFIG_PROBE(SCREEN_ROTATION_SPEC) || CONFIG_PROBE(ENABLE_ROTATION_SPEC)) {
+ if (!wi->render) {
+ wi->screen_rotation = 0;
+ wi->enable_rotation = 0;
+ }
+ else {
+ SET(wi->flags, ZN_UPDATE_CANVASTEX);
+ ZnNeedRedisplay(wi);
+ }
+ }
+#endif
+
/*
* Maintain the pick aperture within meaningful bounds.
*/
@@ -6967,6 +7027,19 @@ Configure(Tcl_Interp *interp,/* Used for error reporting. */
wi->render = 0;
}
+#if defined(GL) && defined(ROTATION)
+ if ((mask & CONFIG_ROTATION) || (mask & CONFIG_ENABLE_ROTATION) || init) {
+ if (!wi->render) {
+ wi->screen_rotation = 0;
+ wi->enable_rotation = 0;
+ }
+ else {
+ SET(wi->flags, ZN_UPDATE_CANVASTEX);
+ ZnNeedRedisplay(wi);
+ }
+ }
+#endif
+
if ((mask & CONFIG_SCROLL_REGION) || init) {
/*
* Compute the scroll region
@@ -7357,10 +7430,12 @@ Event(ClientData client_data, /* Information about widget. */
if (event->type == MapNotify) {
SET(wi->flags, ZN_CONFIGURE_EVENT);
FinishSetup(wi);
+ wi->width = wi->opt_width;
+ wi->height = wi->opt_height;
ZnNeedRedisplay(wi);
}
else if (event->type == Expose) {
- ZnDim width, height;
+ ZnDim width, height;
SET(wi->flags, ZN_CONFIGURE_EVENT);
FinishSetup(wi);
@@ -7376,8 +7451,8 @@ Event(ClientData client_data, /* Information about widget. */
height += bbox.orig.y;
bbox.orig.y = 0;
}
- bbox.corner.x = MIN(wi->width, bbox.orig.x + width);
- bbox.corner.y = MIN(wi->height, bbox.orig.y + height);
+ bbox.corner.x = MIN(wi->opt_width, bbox.orig.x + width);
+ bbox.corner.y = MIN(wi->opt_height, bbox.orig.y + height);
//printf("expose %d %d %d %d\n",
// ((XExposeEvent*) event)->x, ((XExposeEvent*) event)->y,
@@ -7408,10 +7483,10 @@ Event(ClientData client_data, /* Information about widget. */
int_width = Tk_Width(wi->win);
int_height = Tk_Height(wi->win);
- if ((wi->width != int_width) || (wi->height != int_height)) {
+ if ((wi->opt_width != int_width) || (wi->opt_height != int_height)) {
bbox.orig.x = bbox.orig.y = 0;
- bbox.corner.x = MAX(wi->width, int_width);
- bbox.corner.y = MAX(wi->height, int_height);
+ bbox.corner.x = MAX(wi->opt_width, int_width);
+ bbox.corner.y = MAX(wi->opt_height, int_height);
wi->opt_width = wi->width = int_width;
wi->opt_height = wi->height = int_height;
@@ -7440,14 +7515,16 @@ Event(ClientData client_data, /* Information about widget. */
int_width, int_height,
DefaultDepthOfScreen(wi->screen));
}
-#if defined(MAC_OSX_TK) && defined(GL)
else {
+#if defined(GL)
+#if defined(MAC_OSX_TK)
ZnGLContextEntry *ce = ZnGLMakeCurrent(wi->dpy, wi);
UpdateBufferRect(ce, wi->win);
aglUpdateContext(ce->context);
+#endif
+ SET(wi->flags, ZN_UPDATE_CANVASTEX);
+#endif
}
-#endif
-
}
else {
/*
@@ -7913,6 +7990,11 @@ Bind(ClientData client_data, /* Information about widget. */
if ((event->type == ButtonPress) || (event->type == ButtonRelease)) {
int mask;
+#if defined(GL) && defined(ROTATION)
+ if (wi->enable_rotation) {
+ TransformEvent(wi, event);
+ }
+#endif
switch (event->xbutton.button) {
case Button1:
mask = Button1Mask;
@@ -7971,12 +8053,22 @@ Bind(ClientData client_data, /* Information about widget. */
}
else if ((event->type == EnterNotify) || (event->type == LeaveNotify)) {
+#if defined(GL) && defined(ROTATION)
+ if (wi->enable_rotation) {
+ TransformEvent(wi, event);
+ }
+#endif
wi->state = event->xcrossing.state;
PickCurrentItem(wi, event);
goto done;
}
else if (event->type == MotionNotify) {
+#if defined(GL) && defined(ROTATION)
+ if (wi->enable_rotation) {
+ TransformEvent(wi, event);
+ }
+#endif
wi->state = event->xmotion.state;
if (wi->follow_pointer) {
PickCurrentItem(wi, event);
@@ -8322,6 +8414,14 @@ Destroy(ZnWInfo *wi)
wi->map_font_tfi = NULL;
}
#endif
+#ifdef ROTATION
+ if (wi->canvastex) {
+ glDeleteFramebuffersEXT(1, &wi->fbo);
+ glDeleteRenderbuffersEXT(1, &wi->depthstencil);
+ glDeleteTextures(1, &wi->canvastex);
+ wi->canvastex = 0;
+ }
+#endif
/*
* Remove the widget from the context list and
* free the context if no more widgets are active.
@@ -8513,6 +8613,154 @@ Update(ZnWInfo *wi)
}
}
+#if defined(GL) && defined(ROTATION)
+static void
+TransformEvent(ZnWInfo *wi,
+ XEvent *event)
+{
+ ZnPoint p, xp;
+
+ p.x = event->xmotion.x;
+ p.y = event->xmotion.y;
+ ZnTransformPoint(&wi->rotation_transfo, &p, &xp);
+ event->xmotion.x = ZnNearestInt(xp.x);
+ event->xmotion.y = ZnNearestInt(xp.y);
+}
+
+static void
+SetupRotationTexture(ZnWInfo *wi)
+{
+ ZnReal offsetX, offsetY;
+ ZnReal tex_width, tex_height;
+ int i;
+ GLenum status;
+
+ //
+ // Create the canvas buffer if needed (rotation)
+ if (ISSET(wi->flags, ZN_UPDATE_CANVASTEX)) {
+ CLEAR(wi->flags, ZN_UPDATE_CANVASTEX);
+ //
+ // Free the canvas texture it'll be recreated
+ // automatically with the correct size.
+ if (wi->canvastex) {
+ glDeleteTextures(1, &wi->canvastex);
+ wi->canvastex = 0;
+ }
+ if (wi->depthstencil) {
+ glDeleteRenderbuffersEXT(1, &wi->depthstencil);
+ wi->depthstencil = 0;
+ }
+ //
+ // Compute the intermediate canvas size
+ wi->width = wi->height = hypot(wi->opt_width, wi->opt_height);
+ tex_width = To2Power(wi->width);
+ tex_height = To2Power(wi->height);
+ //
+ // Transform the window rectangle around the origin and
+ // compute window coordinates in texture space (center of window
+ // on texture center)
+ ZnTransfoSetIdentity(&wi->rotation_transfo);
+ offsetX = ZnNearestInt(wi->opt_width/2.0);
+ offsetY = ZnNearestInt(wi->opt_height/2.0);
+ ZnTranslate(&wi->rotation_transfo, -offsetX, -offsetY, 0);
+ ZnRotateDeg(&wi->rotation_transfo, -wi->screen_rotation);
+ //printf("taille: %d %d, rotation: %d, centre: %g %g\n",
+ // wi->opt_width, wi->opt_height, wi->screen_rotation, offsetX, offsetY);
+ wi->texcoords[0].x = wi->texcoords[0].y = 0;
+ wi->texcoords[1].x = 0; wi->texcoords[1].y = wi->opt_height;
+ wi->texcoords[2].x = wi->opt_width; wi->texcoords[2].y = wi->opt_height;
+ wi->texcoords[3].x = wi->opt_width; wi->texcoords[3].y = 0;
+ ZnTranslate(&wi->rotation_transfo, wi->width / 2, wi->height / 2, 0);
+ ZnScale(&wi->rotation_transfo, 1.0/tex_width, 1.0/tex_height);
+ ZnTransformPoints(&wi->rotation_transfo, wi->texcoords, wi->texcoords, 4);
+ //
+ // Compute event transformation to map incoming mouse event.
+ ZnTransfoSetIdentity(&wi->rotation_transfo);
+ ZnTranslate(&wi->rotation_transfo, -offsetX, -offsetY, 0);
+ ZnRotateDeg(&wi->rotation_transfo, wi->screen_rotation);
+ ZnTranslate(&wi->rotation_transfo, wi->width / 2, wi->height / 2, 0);
+ //
+ // Create a FBO if needed.
+ if (wi->fbo == 0) {
+ glGenFramebuffersEXT(1, &wi->fbo);
+ }
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, wi->fbo);
+ //
+ // Create a depth/stencil buffer combo.
+ glGenRenderbuffersEXT(1, &wi->depthstencil);
+ glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, wi->depthstencil);
+ glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT,
+ tex_width, tex_height);
+ //
+ // Create a texture for rendering.
+ glGenTextures(1, &wi->canvastex);
+ glBindTexture(GL_TEXTURE_2D, wi->canvastex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glGetError();
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_width, tex_height,
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ if (glGetError() != GL_NO_ERROR) {
+ ZnWarning("Can't allocate a texture for the intermediate canvas\n");
+ }
+ //
+ // Attach a depth/stencil combo to the fbo.
+ glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
+ GL_RENDERBUFFER_EXT, wi->depthstencil);
+ glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
+ GL_RENDERBUFFER_EXT, wi->depthstencil);
+ //
+ // Attach the texture to the fbo.
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
+ GL_TEXTURE_2D, wi->canvastex, 0);
+ status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+ if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ ZnWarning("Frame buffer installation is not complete\n");
+ }
+ }
+ //
+ // Redirect all GL primitives to the FBO.
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, wi->fbo);
+}
+
+static void
+FinalizeRotation(ZnWInfo *wi)
+{
+ //
+ // Ok we have the intermediate texture ready we'll cast it
+ // to the window now. We use a quad the size of the window
+ //
+ // First stop redirecting primitives to the fbo.
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+
+ glViewport(0, 0, wi->opt_width, wi->opt_height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0.0, wi->opt_width, 0.0, wi->opt_height, -1.0, 1.0);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ //glDisable(GL_BLEND);
+ glColor4us(65535, 65535, 65535, 65535);
+
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, wi->canvastex);
+ glBegin(GL_QUADS);
+ glTexCoord2d(wi->texcoords[0].x, wi->texcoords[0].y);
+ glVertex2i(0, 0);
+ glTexCoord2d(wi->texcoords[1].x, wi->texcoords[1].y);
+ glVertex2i(0, wi->opt_height);
+ glTexCoord2d(wi->texcoords[2].x, wi->texcoords[2].y);
+ glVertex2i(wi->opt_width, wi->opt_height);
+ glTexCoord2d(wi->texcoords[3].x, wi->texcoords[3].y);
+ glVertex2i(wi->opt_width, 0);
+ glEnd();
+ glDisable(GL_TEXTURE_2D);
+}
+#endif
/*
**********************************************************************************
@@ -8542,8 +8790,6 @@ Repair(ZnWInfo *wi)
int darea_x1, darea_x2, darea_y1, darea_y2;
ZnGLContextEntry *ce;
#endif
- int int_width = Tk_Width(wi->win);
- int int_height = Tk_Height(wi->win);
//LARGE_INTEGER start, stop, sw_freq;
//QueryPerformanceFrequency(&sw_freq);
@@ -8572,6 +8818,16 @@ Repair(ZnWInfo *wi)
//printf("Repair, scissors: %d\n", ISCLEAR(wi->flags, ZN_CONFIGURE_EVENT));
ce = ZnGLMakeCurrent(wi->dpy, wi);
+ glDrawBuffer(GL_BACK);
+
+#if defined(GL) && defined(ROTATION)
+ //
+ // Setup for rotation and select the rendering fbo.
+ if (wi->enable_rotation) {
+ SetupRotationTexture(wi);
+ }
+#endif
+
glEnable(GL_POINT_SMOOTH);
glEnable(GL_LINE_SMOOTH);
#if 0
@@ -8586,7 +8842,6 @@ Repair(ZnWInfo *wi)
color = ZnGetGradientColor(wi->back_color, 0.0, NULL);
glClearColor((GLfloat) color->red/65536, (GLfloat) color->green/65536,
(GLfloat) color->blue/65536, 0.0);
- glDrawBuffer(GL_BACK);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
@@ -8607,26 +8862,25 @@ Repair(ZnWInfo *wi)
}
else {
darea_x1 = darea_y1 = wi->damaged_area.orig.x = wi->damaged_area.orig.y = 0;
- darea_x2 = wi->damaged_area.corner.x = int_width;
- darea_y2 = wi->damaged_area.corner.y = int_height;
+ darea_x2 = wi->damaged_area.corner.x = wi->width;
+ darea_y2 = wi->damaged_area.corner.y = wi->height;
}
#else
/*
* We do not use the damaged area set it to the whole area.
*/
darea_x1 = darea_y1 = wi->damaged_area.orig.x = wi->damaged_area.orig.y = 0;
- darea_x2 = wi->damaged_area.corner.x = int_width;
- darea_y2 = wi->damaged_area.corner.y = int_height;
+ darea_x2 = wi->damaged_area.corner.x = wi->width;
+ darea_y2 = wi->damaged_area.corner.y = wi->height;
#endif
//
// glViewport and glOrtho must always be used together with
// matching parameters to keep the mapping straight (no distorsion).
- glViewport(darea_x1, int_height - darea_y2, darea_x2 - darea_x1, darea_y2 - darea_y1);
+ glViewport(darea_x1, wi->height - darea_y2, darea_x2 - darea_x1, darea_y2 - darea_y1);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(darea_x1, darea_x2, darea_y2, darea_y1, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
-
/*
* Clear the GL buffers.
*/
@@ -8639,8 +8893,8 @@ Repair(ZnWInfo *wi)
ZnBBox bbox;
bbox.orig.x = bbox.orig.y = 0.0;
- bbox.corner.x = int_width;
- bbox.corner.y = int_height;
+ bbox.corner.x = wi->width;
+ bbox.corner.y = wi->height;
ZnRenderTile(wi, wi->tile, NULL, NULL, NULL, (ZnPoint *) &bbox);
}
else {
@@ -8656,14 +8910,20 @@ Repair(ZnWInfo *wi)
wi->top_group->class->Render(wi->top_group);
+#if defined(GL) && defined(ROTATION)
+ if (wi->enable_rotation) {
+ FinalizeRotation(wi);
+ }
+#endif
+
if ((wi->border_width > 0) || (wi->highlight_width > 0)) {
unsigned short alpha;
#ifdef GL_DAMAGE
- glViewport(0, 0, int_width, int_height);
+ glViewport(0, 0, wi->opt_width, wi->opt_height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
- glOrtho(0.0, int_width, int_height, 0.0, -1.0, 1.0);
+ glOrtho(0.0, wi->opt_width, wi->opt_height, 0.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
#endif
if (wi->highlight_width > 0) {
@@ -8675,12 +8935,12 @@ Repair(ZnWInfo *wi)
glBegin(GL_QUAD_STRIP);
glVertex2d(0.0, 0.0);
glVertex2i(wi->highlight_width, wi->highlight_width);
- glVertex2i(int_width, 0);
- glVertex2i(int_width - wi->highlight_width, wi->highlight_width);
- glVertex2i(int_width, int_height);
- glVertex2i(int_width - wi->highlight_width, int_height - wi->highlight_width);
- glVertex2i(0, int_height);
- glVertex2i(wi->highlight_width, int_height - wi->highlight_width);
+ glVertex2i(wi->opt_width, 0);
+ glVertex2i(wi->opt_width - wi->highlight_width, wi->highlight_width);
+ glVertex2i(wi->opt_width, wi->opt_height);
+ glVertex2i(wi->opt_width - wi->highlight_width, wi->opt_height - wi->highlight_width);
+ glVertex2i(0, wi->opt_height);
+ glVertex2i(wi->highlight_width, wi->opt_height - wi->highlight_width);
glVertex2i(0, 0);
glVertex2i(wi->highlight_width, wi->highlight_width);
glEnd();
@@ -8689,8 +8949,8 @@ Repair(ZnWInfo *wi)
if (wi->relief != ZN_RELIEF_FLAT) {
p[4].x = p[4].y = p[3].y = p[1].x = wi->highlight_width;
p[0] = p[4];
- p[3].x = p[2].x = int_width - wi->highlight_width;
- p[2].y = p[1].y = int_height - wi->highlight_width;
+ p[3].x = p[2].x = wi->opt_width - wi->highlight_width;
+ p[2].y = p[1].y = wi->opt_height - wi->highlight_width;
ZnRenderPolygonRelief(wi, wi->relief, wi->relief_grad,
False, p, 5, (ZnReal) wi->border_width);
}
@@ -8702,12 +8962,12 @@ Repair(ZnWInfo *wi)
glBegin(GL_QUAD_STRIP);
glVertex2d(0.0, 0.0);
glVertex2i(wi->highlight_width, wi->highlight_width);
- glVertex2i(int_width, 0);
- glVertex2i(int_width - wi->highlight_width, wi->highlight_width);
- glVertex2i(int_width, int_height);
- glVertex2i(int_width - wi->highlight_width, int_height - wi->highlight_width);
- glVertex2i(0, int_height);
- glVertex2i(wi->highlight_width, int_height - wi->highlight_width);
+ glVertex2i(wi->opt_width, 0);
+ glVertex2i(wi->opt_width - wi->highlight_width, wi->highlight_width);
+ glVertex2i(wi->opt_width, wi->opt_height);
+ glVertex2i(wi->opt_width - wi->highlight_width, wi->opt_height - wi->highlight_width);
+ glVertex2i(0, wi->opt_height);
+ glVertex2i(wi->highlight_width, wi->opt_height - wi->highlight_width);
glVertex2i(0, 0);
glVertex2i(wi->highlight_width, wi->highlight_width);
glEnd();
@@ -8794,8 +9054,8 @@ m * Merge the damaged area with the exposed area.
*/
merge.orig.x = MAX(merge.orig.x, wi->inset);
merge.orig.y = MAX(merge.orig.y, wi->inset);
- merge.corner.x = MIN(merge.corner.x, int_width-wi->inset);
- merge.corner.y = MIN(merge.corner.y, int_height-wi->inset);
+ merge.corner.x = MIN(merge.corner.x, wi->opt_width-wi->inset);
+ merge.corner.y = MIN(merge.corner.y, wi->opt_height-wi->inset);
ZnBBox2XRect(&merge, &r);
XCopyArea(wi->dpy,
wi->draw_buffer, Tk_WindowId(wi->win), wi->gc,
@@ -8812,8 +9072,8 @@ m * Merge the damaged area with the exposed area.
wi->draw_buffer = Tk_WindowId(wi->win);
if (wi->relief_grad != ZN_RELIEF_FLAT) {
r.x = r.y = wi->highlight_width;
- r.width = int_width - 2*wi->highlight_width;
- r.height = int_height - 2*wi->highlight_width;
+ r.width = wi->opt_width - 2*wi->highlight_width;
+ r.height = wi->opt_height - 2*wi->highlight_width;
ZnDrawRectangleRelief(wi, wi->relief, wi->relief_grad, &r,
(ZnDim) wi->border_width);
}
@@ -8821,14 +9081,14 @@ m * Merge the damaged area with the exposed area.
XSetForeground(wi->dpy, wi->gc, ZnGetGradientPixel(wi->back_color, 0.0));
XSetFillStyle(wi->dpy, wi->gc, FillSolid);
rs[0].x = rs[0].y = wi->highlight_width;
- rs[0].width = int_width - 2*wi->highlight_width;
+ rs[0].width = wi->opt_width - 2*wi->highlight_width;
rs[0].height = wi->border_width;
- rs[1].x = int_width - wi->highlight_width - wi->border_width;
+ rs[1].x = wi->opt_width - wi->highlight_width - wi->border_width;
rs[1].y = 0;
rs[1].width = wi->border_width;
- rs[1].height = int_height - 2*wi->highlight_width;
+ rs[1].height = wi->opt_height - 2*wi->highlight_width;
rs[2].x = 0;
- rs[2].y = int_height - wi->highlight_width - wi->border_width;
+ rs[2].y = wi->opt_height - wi->highlight_width - wi->border_width;
rs[2].width = rs[0].width;
rs[2].height = wi->border_width;
rs[3].x = rs[3].y = wi->highlight_width;
@@ -8844,19 +9104,19 @@ m * Merge the damaged area with the exposed area.
wi->highlight_bg_color, 0.0));
XSetFillStyle(wi->dpy, wi->gc, FillSolid);
rs[0].x = rs[0].y = 0;
- rs[0].width = int_width;
+ rs[0].width = wi->opt_width;
rs[0].height = wi->highlight_width;
- rs[1].x = int_width - wi->highlight_width;
+ rs[1].x = wi->opt_width - wi->highlight_width;
rs[1].y = 0;
rs[1].width = wi->highlight_width;
- rs[1].height = int_height;
+ rs[1].height = wi->opt_height;
rs[2].x = 0;
- rs[2].y = int_height - wi->highlight_width;
- rs[2].width = int_width;
+ rs[2].y = wi->opt_height - wi->highlight_width;
+ rs[2].width = wi->opt_width;
rs[2].height = wi->highlight_width;
rs[3].x = rs[3].y = 0;
rs[3].width = wi->highlight_width;
- rs[3].height = int_height;
+ rs[3].height = wi->opt_height;
XFillRectangles(wi->dpy, Tk_WindowId(wi->win), wi->gc, rs, 4);
}
//STOP_PRINT("Total GDI");