aboutsummaryrefslogtreecommitdiff
path: root/generic/tkZinc.c
diff options
context:
space:
mode:
authorlecoanet2004-03-04 08:39:00 +0000
committerlecoanet2004-03-04 08:39:00 +0000
commit34e9e2a7e4795e28f8189617f67adb32c0c91c2f (patch)
treec2fa588145de633ac31da1da5672da1cd8f0881f /generic/tkZinc.c
parent1b0ed7126d85ee2de0e7dba1f5a86044a69d8269 (diff)
downloadtkzinc-34e9e2a7e4795e28f8189617f67adb32c0c91c2f.zip
tkzinc-34e9e2a7e4795e28f8189617f67adb32c0c91c2f.tar.gz
tkzinc-34e9e2a7e4795e28f8189617f67adb32c0c91c2f.tar.bz2
tkzinc-34e9e2a7e4795e28f8189617f67adb32c0c91c2f.tar.xz
* OpenGL contexts are allocated by display instead of by widget.
* Colormaps are not allocated for each widget window but are cached by display (should be perhaps by screen) * Freed the visual info returned by each call to glXChooseVisual. This used to generate a memory leak for each widget instance. * Adapted for perl/Tk 804. * Some better init code to prevent valgrind from reporting use of unitialized memory (can be useful anyway). * Commented an OpenGL bug workaround dealing with bad partial redraw after moving the window. It seems to have disappeared (tested with NVIDIA 53.3). * Free the drawing GC as part of destroy cleanup.
Diffstat (limited to 'generic/tkZinc.c')
-rw-r--r--generic/tkZinc.c238
1 files changed, 155 insertions, 83 deletions
diff --git a/generic/tkZinc.c b/generic/tkZinc.c
index c6d924c..5782f6a 100644
--- a/generic/tkZinc.c
+++ b/generic/tkZinc.c
@@ -129,6 +129,22 @@ static Tk_Uid neg_tag_val_uid;
static Tk_Uid dot_uid;
static Tk_Uid star_uid;
+#ifdef GL
+typedef struct _ZnGLContextEntry {
+ ZnGLContext context;
+#ifdef WIN
+ HDC hdc;
+#else
+ Display *dpy;
+ XVisualInfo *visual; /* Should these two be managed by screen ? */
+ Colormap colormap;
+#endif
+ struct _ZnGLContextEntry *next;
+} ZnGLContextEntry;
+static ZnGLContextEntry *gl_contexts = NULL;
+#endif
+
+
static void PickCurrentItem _ANSI_ARGS_((ZnWInfo *wi, XEvent *event));
static int ZnReliefParse _ANSI_ARGS_((ClientData client_data, Tcl_Interp *interp,
Tk_Window tkwin, Tcl_Obj *ovalue,
@@ -676,10 +692,14 @@ ZincObjCmd(ClientData client_data, /* Main window associated with
# ifdef _WIN32
Tcl_AppendResult(interp, " GL", NULL);
# else
- if (has_gl && glXChooseVisual(dpy,
- XScreenNumberOfScreen(screen),
- attribs)) {
- Tcl_AppendResult(interp, " GL", NULL);
+ {
+ XVisualInfo *visual = glXChooseVisual(dpy,
+ XScreenNumberOfScreen(screen),
+ attribs);
+ if (has_gl && visual) {
+ Tcl_AppendResult(interp, " GL", NULL);
+ }
+ XFree(visual);
}
# endif
#endif
@@ -716,9 +736,12 @@ ZincObjCmd(ClientData client_data, /* Main window associated with
#endif
#ifdef PTK
+#ifdef PTK_800
wi->cmd = Lang_CreateWidget(interp, tkwin, (Tcl_CmdProc *) WidgetObjCmd,
(ClientData) wi, CmdDeleted);
-
+#else
+ wi->cmd = Lang_CreateWidget(interp, tkwin, WidgetObjCmd, (ClientData) wi, CmdDeleted);
+#endif
#else
wi->cmd = Tcl_CreateObjCommand(interp, Tk_PathName(tkwin), WidgetObjCmd,
(ClientData) wi, CmdDeleted);
@@ -740,11 +763,7 @@ ZincObjCmd(ClientData client_data, /* Main window associated with
#ifdef GL
wi->font_tfi = NULL;
wi->map_font_tfi = NULL;
- wi->gl_context = NULL;
wi->max_tex_size = 64; /* Minimum value is always valid */
-# ifndef _WIN32
- wi->gl_visual = NULL;
-# endif
#endif
wi->map_distance_symbol = ZnUnspecifiedImage;
wi->track_symbol = ZnUnspecifiedImage;
@@ -781,6 +800,8 @@ ZincObjCmd(ClientData client_data, /* Main window associated with
wi->gc = 0;
wi->draw_buffer = 0;
wi->pick_aperture = 0;
+ wi->state = 0;
+ memset(&wi->pick_event, 0, sizeof(XEvent));
wi->new_item = wi->current_item = ZN_NO_ITEM;
wi->new_part = wi->current_part = ZN_NO_PART;
wi->focus_item = ZN_NO_ITEM;
@@ -822,6 +843,8 @@ ZincObjCmd(ClientData client_data, /* Main window associated with
wi->highlight_width = 0;
wi->highlight_color = NULL;
wi->highlight_bg_color = NULL;
+ ZnResetBBox(&wi->exposed_area);
+ ZnResetBBox(&wi->damaged_area);
ZnInitClipStack(wi);
ZnInitTransformStack(wi);
@@ -854,7 +877,6 @@ ZincObjCmd(ClientData client_data, /* Main window associated with
return TCL_ERROR;
}
- ZnResetBBox(&wi->exposed_area);
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;
@@ -864,7 +886,8 @@ ZincObjCmd(ClientData client_data, /* Main window associated with
*/
if (wi->render) {
#ifdef GL
- wi->gl_context = 0;
+ ZnGLContextEntry *context_entry;
+
ASSIGN(wi->flags, ZN_PRINT_CONFIG, (getenv("ZINC_GLX_INFO") != NULL));
if (ISSET(wi->flags, ZN_HAS_GL)) {
@@ -895,74 +918,119 @@ ZincObjCmd(ClientData client_data, /* Main window associated with
if (!wi->hdc) {
OutputDebugString("Unable to get the hdc\n");
}
- ipixel = ChoosePixelFormat(wi->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(wi->hdc, ipixel, &pfd) == TRUE);
- if (wi->render) {
- wi->gl_context = wglCreateContext(wi->hdc);
- if (!wi->gl_context) {
- OutputDebugString("wglCreateContext failed\n");
- }
+ /*
+ * Look for a matching context already available.
+ */
+ for (context_entry = gl_contexts;
+ context_entry && context_entry->hdc != wi->hdc;
+ context_entry = context_entry->next);
+ if (context_entry) {
+ wi->gl_context = context_entry->context;
+ }
+ else {
+ ipixel = ChoosePixelFormat(wi->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(wi->hdc, ipixel, &pfd) == TRUE);
+ if (wi->render) {
+ wi->gl_context = wglCreateContext(wi->hdc);
+ if (!wi->gl_context) {
+ OutputDebugString("wglCreateContext failed\n");
+ }
+ else {
+ context_entry = ZnMalloc(sizeof(ZnGLContextEntry));
+ context_entry->context = wi->gl_context;
+ context_entry->hdc = wi->hdc;
+ context_entry->next = gl_contexts;
+ gl_contexts = context_entry;
+ }
+ }
+ ZnGLRelease(wi);
}
- ZnGLRelease(wi);
# else /* _WIN32 */
- int val;
+ 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.
+ */
+ for (context_entry = gl_contexts;
+ context_entry && context_entry->dpy != wi->dpy;
+ context_entry = context_entry->next);
- wi->gl_visual = glXChooseVisual(wi->dpy,
- XScreenNumberOfScreen(wi->screen),
- attribs);
- if (!wi->gl_visual) {
- fprintf(stderr, "No glx visual\n");
- wi->render = 0;
+ if (context_entry) {
+ wi->gl_context = context_entry->context;
+ gl_visual = context_entry->visual;
+ colormap = context_entry->colormap;
}
else {
- wi->gl_context = glXCreateContext(wi->dpy, wi->gl_visual,
- NULL, wi->render==1);
- if (!wi->gl_context) {
- fprintf(stderr, "No glx context\n");
+ int val;
+
+ gl_visual = glXChooseVisual(wi->dpy,
+ XScreenNumberOfScreen(wi->screen),
+ attribs);
+ if (!gl_visual) {
+ fprintf(stderr, "No glx visual\n");
wi->render = 0;
}
else {
- if (ISSET(wi->flags, ZN_PRINT_CONFIG)) {
- fprintf(stderr, " Visual : 0x%x, ",
- (int) wi->gl_visual->visualid);
- glXGetConfig(wi->dpy, wi->gl_visual, GLX_RGBA, &val);
- fprintf(stderr, "RGBA : %d, ", val);
- glXGetConfig(wi->dpy, wi->gl_visual, GLX_DOUBLEBUFFER, &val);
- fprintf(stderr, "Double Buffer : %d, ", val);
- glXGetConfig(wi->dpy, wi->gl_visual, GLX_STENCIL_SIZE, &val);
- fprintf(stderr, "Stencil : %d, ", val);
- glXGetConfig(wi->dpy, wi->gl_visual, GLX_BUFFER_SIZE, &val);
- fprintf(stderr, "depth : %d, ", val);
- glXGetConfig(wi->dpy, wi->gl_visual, GLX_RED_SIZE, &val);
- fprintf(stderr, "red : %d, ", val);
- glXGetConfig(wi->dpy, wi->gl_visual, GLX_GREEN_SIZE, &val);
- fprintf(stderr, "green : %d, ", val);
- glXGetConfig(wi->dpy, wi->gl_visual, GLX_BLUE_SIZE, &val);
- fprintf(stderr, "blue : %d, ", val);
- glXGetConfig(wi->dpy, wi->gl_visual, GLX_ALPHA_SIZE, &val);
- fprintf(stderr, "alpha : %d\n", val);
- fprintf(stderr, " Direct Rendering: %d\n",
- glXIsDirect(wi->dpy, wi->gl_context));
+ printf("creating context\n");
+ wi->gl_context = glXCreateContext(wi->dpy, gl_visual,
+ NULL, wi->render==1);
+ if (!wi->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 = wi->gl_context;
+ context_entry->visual = gl_visual;
+ context_entry->colormap = colormap;
+ context_entry->dpy = wi->dpy;
+ 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, wi->gl_context));
+ }
}
- Tk_SetWindowVisual(wi->win, wi->gl_visual->visual,
- 24,
- XCreateColormap(wi->dpy, RootWindowOfScreen(wi->screen),
- wi->gl_visual->visual, AllocNone));
}
}
+ if (gl_visual && colormap) {
+ Tk_SetWindowVisual(wi->win, gl_visual->visual, 24, colormap);
+ }
# endif /* _WIN32 */
}
else {
@@ -2104,7 +2172,7 @@ LayoutItems(ZnWInfo *wi,
{
int index/*, result*/;
/*ZnItem item;*/
-#ifdef PTK
+#ifdef PTK_800
static char *layout_cmd_strings[] =
#else
static CONST char *layout_cmd_strings[] =
@@ -2552,7 +2620,7 @@ FindItems(ZnWInfo *wi,
ZnItem item;
ZnPickStruct ps;
char *str;
-#ifdef PTK
+#ifdef PTK_800
static char *search_cmd_strings[] =
#else
static CONST char *search_cmd_strings[] =
@@ -3051,7 +3119,7 @@ Contour(ZnWInfo *wi,
ZnContour *contours;
/* Keep this array in sync with ZnContourCmd in Types.h */
-#ifdef PTK
+#ifdef PTK_800
static char *op_strings[] =
#else
static CONST char *op_strings[] =
@@ -3573,7 +3641,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
char c[] = "c";
double d;
-#ifdef PTK
+#ifdef PTK_800
static char *sub_cmd_strings[] =
#else
static CONST char *sub_cmd_strings[] =
@@ -3604,7 +3672,7 @@ WidgetObjCmd(ClientData client_data, /* Information about the widget. */
ZN_W_TRESET, ZN_W_TRESTORE, ZN_W_TSAVE, ZN_W_TSET, ZN_W_TYPE, ZN_W_VERTEX_AT,
ZN_W_XVIEW, ZN_W_YVIEW
};
-#ifdef PTK
+#ifdef PTK_800
static char *sel_cmd_strings[] =
#else
static CONST char *sel_cmd_strings[] =
@@ -6036,11 +6104,18 @@ Configure(Tcl_Interp *interp,/* Used for error reporting. */
return TCL_ERROR;
}
#ifdef PTK
+#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
+#else
if ((Tk_GetPixels(interp, wi->win, args2[0], &wi->scroll_xo) != TCL_OK) ||
(Tk_GetPixels(interp, wi->win, args2[1], &wi->scroll_yo) != TCL_OK) ||
(Tk_GetPixels(interp, wi->win, args2[2], &wi->scroll_xc) != TCL_OK) ||
@@ -6152,7 +6227,7 @@ Focus(ZnWInfo *wi,
}
#ifdef GL_DAMAGE
if (wi->render) {
- ZnDamageAll(wi);
+ /* ZnDamageAll(wi);*/
}
#endif
}
@@ -6879,7 +6954,7 @@ Bind(ClientData client_data, /* Information about widget. */
* enough to make the bug unnoticed.
*/
if (wi->render) {
- ZnDamageAll(wi);
+ /* ZnDamageAll(wi);*/
}
#endif
@@ -7196,18 +7271,26 @@ Destroy(char *mem_ptr) /* Info about the widget. */
/* Free the double buffer pixmap/image */
if (wi->draw_buffer) {
Tk_FreePixmap(wi->dpy, wi->draw_buffer);
+ wi->draw_buffer = 0;
}
if (wi->fore_color) {
ZnFreeGradient(wi->fore_color);
+ wi->fore_color = NULL;
}
if (wi->back_color) {
ZnFreeGradient(wi->back_color);
+ wi->back_color = NULL;
}
if (wi->relief_grad) {
ZnFreeGradient(wi->relief_grad);
+ wi->relief_grad = NULL;
}
-
+ if (wi->gc) {
+ XFreeGC(wi->dpy, wi->gc);
+ wi->gc = 0;
+ }
+
Tcl_DeleteTimerHandler(wi->blink_handler);
Tk_FreeOptions(config_specs, (char *) wi, wi->dpy, 0);
@@ -7230,17 +7313,6 @@ Destroy(char *mem_ptr) /* Info about the widget. */
ZnFreeChrono(wi->this_draw_chrono);
#endif
-#ifdef GL
- if (wi->gl_context) {
- ZnGLDestroyContext(wi);
- }
-# ifndef _WIN32
- if (wi->gl_visual) {
- XFree(wi->gl_visual);
- }
-# endif
-#endif
-
if (wi->tess) {
gluDeleteTess(wi->tess);
}