aboutsummaryrefslogtreecommitdiff
path: root/generic/tkZinc.c
diff options
context:
space:
mode:
authorlecoanet2004-05-07 09:50:32 +0000
committerlecoanet2004-05-07 09:50:32 +0000
commit1761ee2e8ad9f23ef9231ec9952c25ab2ac88439 (patch)
tree8b446a403332419d5597f4cbc0bc3b7248a1a5f6 /generic/tkZinc.c
parenta13c664aaf1672b668aec6ed7a6932896de40c57 (diff)
downloadtkzinc-1761ee2e8ad9f23ef9231ec9952c25ab2ac88439.zip
tkzinc-1761ee2e8ad9f23ef9231ec9952c25ab2ac88439.tar.gz
tkzinc-1761ee2e8ad9f23ef9231ec9952c25ab2ac88439.tar.bz2
tkzinc-1761ee2e8ad9f23ef9231ec9952c25ab2ac88439.tar.xz
Slightly rearranged the init sequence for openGL. This will
ensure that render will be reset has soon has possible if GL is not there. It will _stay_ set if we discover later that GL is not available. This will fix a rather bewildering situation when using images: The image is created for GL, then all of a sudden accessed in an X11 context. Fixed the event emitting code so that enter/leaves are not emitted (or omitted) out of sequence.
Diffstat (limited to 'generic/tkZinc.c')
-rw-r--r--generic/tkZinc.c362
1 files changed, 184 insertions, 178 deletions
diff --git a/generic/tkZinc.c b/generic/tkZinc.c
index 135ddb2..706c399 100644
--- a/generic/tkZinc.c
+++ b/generic/tkZinc.c
@@ -927,7 +927,7 @@ ZnGLMakeCurrent(Display *dpy,
ce->hdc = GetDC(ce->hwnd);
SetPixelFormat(ce->hdc, ce->ipixel, &ce->pfd);
- sprintf(msg, "hdc used: %d\n", ce->hdc);
+ /*sprintf(msg, "hdc used: %d\n", ce->hdc);
OutputDebugString(msg);
if (wglMakeCurrent(ce->hdc, ce->context)) {
OutputDebugString("make current ok\n");
@@ -935,8 +935,8 @@ ZnGLMakeCurrent(Display *dpy,
else {
sprintf(msg, "erreur %d\n", GetLastError());
OutputDebugString(msg);
- }
-
+ }*/
+ wglMakeCurrent(ce->hdc, ce->context);
#else
glXMakeCurrent(dpy, win?Tk_WindowId(win):DefaultRootWindow(dpy),
ce->context);
@@ -948,8 +948,6 @@ ZnGLMakeCurrent(Display *dpy,
void
ZnGLReleaseContext(ZnGLContextEntry *ce)
{
- sprintf(msg, "Relasing hdc: %d\n", ce->hdc);
- OutputDebugString(msg);
wglMakeCurrent(NULL, NULL);
ReleaseDC(ce->hwnd, ce->hdc);
}
@@ -960,8 +958,6 @@ ZnGLSwapBuffers(ZnGLContextEntry *ce,
Tk_Window win)
{
#ifdef _WIN32
- sprintf(msg, "Swapping hdc: %d\n", ce->hdc);
- OutputDebugString(msg);
SwapBuffers(ce->hdc);
#else
glXSwapBuffers(ce->dpy, Tk_WindowId(win));
@@ -974,172 +970,154 @@ 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));
+ ZnGLContext gl_context;
+ GLfloat r[2]; /* Min, Max */
+ GLint i[1];
- if (ISSET(wi->flags, ZN_HAS_GL)) {
- ZnGLContext gl_context;
+#ifdef GL
+ if (wi->render) {
# 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);
+ /*
+ * 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) {
+ fprintf(stderr, "ChoosePixelFormat failed\n");
+ OutputDebugString("ChoosePixelFormat failed\n");
}
- 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);
- }
+
+ if (SetPixelFormat(ce->hdc, ce->ipixel, &ce->pfd) == TRUE) {
+ 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 {
+ fprintf(stderr, "wglCreateContext failed\n");
+ OutputDebugString("wglCreateContext failed\n");
ZnFree(ce);
}
}
- ReleaseDC(ce->hwnd, ce->hdc);
- sprintf(msg, "render after: %d\n", wi->render);
- OutputDebugString(msg);
+ else {
+ ZnFree(ce);
+ }
+ }
+ ReleaseDC(ce->hwnd, ce->hdc);
+
# 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);
- }
+ XVisualInfo *gl_visual = NULL;
+ Colormap colormap = 0;
+
+ ASSIGN(wi->flags, ZN_PRINT_CONFIG, (getenv("ZINC_GLX_INFO") != NULL));
+
+ 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;
- /*
- * Look for a matching context already available.
- */
- ce = ZnGetGLContext(wi->dpy);
- if (ce) {
- gl_context = ce->context;
- gl_visual = ce->visual;
- colormap = ce->colormap;
+ gl_visual = glXChooseVisual(wi->dpy,
+ XScreenNumberOfScreen(wi->screen),
+ ZnGLAttribs);
+ if (!gl_visual) {
+ fprintf(stderr, "No glx visual\n");
}
else {
- int val;
-
- gl_visual = glXChooseVisual(wi->dpy,
- XScreenNumberOfScreen(wi->screen),
- ZnGLAttribs);
- if (!gl_visual) {
- fprintf(stderr, "No glx visual\n");
- wi->render = 0;
+ gl_context = glXCreateContext(wi->dpy, gl_visual,
+ NULL, wi->render==1);
+ if (!gl_context) {
+ fprintf(stderr, "No glx context\n");
}
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));
- }
+ 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;
+ if (gl_visual && colormap) {
+ Tk_SetWindowVisual(wi->win, gl_visual->visual, 24, colormap);
}
-#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];
+# endif /* _WIN32 */
ce = ZnGLMakeCurrent(wi->dpy, wi->win);
glGetFloatv(ZN_GL_LINE_WIDTH_RANGE, r);
@@ -1165,7 +1143,7 @@ InitRendering(ZnWInfo *wi)
fprintf(stderr, "Max texture size: %d\n",
ce->max_tex_size);
}
-
+
if (!wi->font_tfi) {
wi->font_tfi = ZnGetTexFont(wi, wi->font);
}
@@ -1175,6 +1153,7 @@ InitRendering(ZnWInfo *wi)
ZnGLReleaseContext(ce);
}
+#endif /* GL */
}
@@ -1246,6 +1225,9 @@ ZincObjCmd(ClientData client_data, /* Main window associated with
Tcl_AppendResult(interp, " GL", NULL);
XFree(visual);
}
+ else {
+ has_gl = False;
+ }
}
# endif
#endif
@@ -1437,6 +1419,22 @@ ZincObjCmd(ClientData client_data, /* Main window associated with
wi->damaged_area.corner.x = wi->width = wi->opt_width;
wi->damaged_area.corner.y = wi->height = wi->opt_height;
+ if (!has_gl) {
+ /* Do not allow GL rendering if not available. This should
+ * _not_ be changed later as images may have been created
+ * in the belief that GL will be available.
+ */
+ wi->render = 0;
+ }
+
+ if (!wi->render) {
+ /*
+ * Allocate double buffer pixmap/image.
+ */
+ 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
@@ -7402,8 +7400,7 @@ PickCurrentItem(ZnWInfo *wi,
XEvent *event)
{
int button_down;
- ZnItem item;
- ZnBool back_inside = False;
+ ZnBool enter_item;
ZnBool grab_release = False;
/*printf("PickCurrent current=%d, new=%d\n",
@@ -7418,6 +7415,7 @@ PickCurrentItem(ZnWInfo *wi,
button_down = wi->state
& (Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask);
if (!button_down) {
+ grab_release = ISSET(wi->flags, ZN_GRABBED_ITEM);
CLEAR(wi->flags, ZN_GRABBED_ITEM);
CLEAR(wi->flags, ZN_GRABBED_PART);
}
@@ -7473,7 +7471,6 @@ PickCurrentItem(ZnWInfo *wi,
* A LeaveNotify event automatically means that there's no current
* object, so the check for closest item can be skipped.
*/
- item = wi->new_item;
if (wi->pick_event.type != LeaveNotify) {
ZnPickStruct ps;
ZnReal dist;
@@ -7505,7 +7502,7 @@ PickCurrentItem(ZnWInfo *wi,
* This state is needed to do a valid detection
* of Enter during a grab.
*/
- back_inside = (wi->new_item != item);
+ enter_item = ((wi->new_item != wi->current_item) || ISSET(wi->flags, ZN_GRABBED_ITEM));
/*printf("------ PickCurrentItem current: %d %d, new %d %d\n",
wi->current_item==ZN_NO_ITEM?0:wi->current_item->id, wi->current_part,
@@ -7526,27 +7523,34 @@ PickCurrentItem(ZnWInfo *wi,
* Remove the "current" tag from the previous current item.
*/
if ((wi->current_item != ZN_NO_ITEM) &&
- (((wi->new_item != wi->current_item) && ISCLEAR(wi->flags, ZN_GRABBED_ITEM)) ||
- ((wi->new_part != wi->current_part) && ISCLEAR(wi->flags, ZN_GRABBED_PART)))) {
- XEvent event;
-
- item = wi->current_item;
- event = wi->pick_event;
- event.type = LeaveNotify;
-
- /*printf("== LEAVE %d %d ==\n", wi->current_item->id, wi->current_part);*/
+ (((wi->new_item != wi->current_item) || (wi->new_part != wi->current_part)) &&
+ ISCLEAR(wi->flags, ZN_GRABBED_ITEM))) {
+ ZnItem item = wi->current_item;
/*
- * If the event's detail happens to be NotifyInferior the
- * binding mechanism will discard the event. To be consistent,
- * always use NotifyAncestor.
+ * Actually emit the event only if not releasing a grab
+ * on button up.
*/
- event.xcrossing.detail = NotifyAncestor;
- SET(wi->flags, ZN_REPICK_IN_PROGRESS);
- DoEvent(wi, &event,
- wi->new_item != wi->current_item, ISCLEAR(wi->flags, ZN_GRABBED_PART));
- CLEAR(wi->flags, ZN_REPICK_IN_PROGRESS);
+ if (!grab_release) {
+ XEvent event;
+ event = wi->pick_event;
+ event.type = LeaveNotify;
+
+ /*printf("== LEAVE %d %d ==\n", wi->current_item->id, wi->current_part);*/
+ /*
+ * If the event's detail happens to be NotifyInferior the
+ * binding mechanism will discard the event. To be consistent,
+ * always use NotifyAncestor.
+ */
+ event.xcrossing.detail = NotifyAncestor;
+ SET(wi->flags, ZN_REPICK_IN_PROGRESS);
+ DoEvent(wi, &event,
+ wi->new_item != wi->current_item, ISCLEAR(wi->flags, ZN_GRABBED_PART));
+ CLEAR(wi->flags, ZN_REPICK_IN_PROGRESS);
+ }
/*
+ * In all cases, if a grab is not current, remove the current tag.
+ *
* The check on item below is needed because there could be an
* event handler for <LeaveNotify> that deletes the current item.
*/
@@ -7570,7 +7574,9 @@ PickCurrentItem(ZnWInfo *wi,
SET(wi->flags, ZN_GRABBED_ITEM);
}
else {
- grab_release = ISSET(wi->flags, ZN_GRABBED_ITEM);
+ if (button_down) {
+ grab_release = ISSET(wi->flags, ZN_GRABBED_ITEM);
+ }
CLEAR(wi->flags, ZN_GRABBED_ITEM);
wi->current_item = wi->new_item;
}
@@ -7602,7 +7608,7 @@ PickCurrentItem(ZnWInfo *wi,
event.type = EnterNotify;
event.xcrossing.detail = NotifyAncestor;
DoEvent(wi, &event,
- back_inside, !(grab_release && ISSET(wi->flags, ZN_GRABBED_PART)));
+ enter_item, !(grab_release && ISSET(wi->flags, ZN_GRABBED_PART)));
}
}
@@ -7678,7 +7684,7 @@ Bind(ClientData client_data, /* Information about widget. */
if (event->type == ButtonPress) {
/*
* On a button press, first repick the current item using
- * the button state before the event, the process the event.
+ * the button state before the event, then process the event.
*/
wi->state = event->xbutton.state;
PickCurrentItem(wi, event);