From bfcdb3b51ea88028b63f3f2d9577659e4119d20a Mon Sep 17 00:00:00 2001 From: lecoanet Date: Tue, 23 Mar 2004 14:53:46 +0000 Subject: Changes related to OpenGL context handling (only one context per display) and patches to avoid using widget structure in image cache */ --- generic/Arc.c | 6 +-- generic/Curve.c | 8 +-- generic/Draw.c | 6 ++- generic/Field.c | 6 +-- generic/Icon.c | 6 +-- generic/Image.c | 128 +++++++++++++++++++++++++---------------------- generic/Image.h | 2 +- generic/Map.c | 6 +-- generic/Rectangle.c | 6 +-- generic/Text.c | 2 +- generic/Track.c | 4 +- generic/Types.h | 20 -------- generic/WidgetInfo.h | 13 +---- generic/tkZinc.c | 138 ++++++++++++++++++++++++++++++++------------------- generic/tkZinc.h | 20 ++++++++ 15 files changed, 206 insertions(+), 165 deletions(-) diff --git a/generic/Arc.c b/generic/Arc.c index 13c4f39..be6508d 100644 --- a/generic/Arc.c +++ b/generic/Arc.c @@ -1005,7 +1005,7 @@ Draw(ZnItem item) if (arc->tile != ZnUnspecifiedImage) { if (!ZnImageIsBitmap(arc->tile)) { /* Fill tiled */ values.fill_style = FillTiled; - values.tile = ZnImagePixmap(arc->tile); + values.tile = ZnImagePixmap(arc->tile, wi->win); values.ts_x_origin = (int) item->item_bounding_box.orig.x; values.ts_y_origin = (int) item->item_bounding_box.orig.y; XChangeGC(wi->dpy, wi->gc, @@ -1014,7 +1014,7 @@ Draw(ZnItem item) } else { /* Fill stippled */ values.fill_style = FillStippled; - values.stipple = ZnImagePixmap(arc->tile); + values.stipple = ZnImagePixmap(arc->tile, wi->win); values.ts_x_origin = (int) item->item_bounding_box.orig.x; values.ts_y_origin = (int) item->item_bounding_box.orig.y; XChangeGC(wi->dpy, wi->gc, @@ -1060,7 +1060,7 @@ Draw(ZnItem item) } else { values.fill_style = FillStippled; - values.stipple = ZnImagePixmap(arc->line_pattern); + values.stipple = ZnImagePixmap(arc->line_pattern, wi->win); XChangeGC(wi->dpy, wi->gc, GCFillStyle|GCStipple|GCLineWidth|GCCapStyle|GCJoinStyle|GCForeground, &values); diff --git a/generic/Curve.c b/generic/Curve.c index 7798add..b896215 100644 --- a/generic/Curve.c +++ b/generic/Curve.c @@ -1211,14 +1211,14 @@ Draw(ZnItem item) if (cv->tile != ZnUnspecifiedImage) { if (!ZnImageIsBitmap(cv->tile)) { /* Fill tiled */ values.fill_style = FillTiled; - values.tile = ZnImagePixmap(cv->tile); + values.tile = ZnImagePixmap(cv->tile, wi->win); values.ts_x_origin = ZnNearestInt(item->item_bounding_box.orig.x); values.ts_y_origin = ZnNearestInt(item->item_bounding_box.orig.y); gc_mask |= GCTileStipXOrigin|GCTileStipYOrigin|GCTile; } else { /* Fill stippled */ values.fill_style = FillStippled; - values.stipple = ZnImagePixmap(cv->tile); + values.stipple = ZnImagePixmap(cv->tile, wi->win); values.ts_x_origin = ZnNearestInt(item->item_bounding_box.orig.x); values.ts_y_origin = ZnNearestInt(item->item_bounding_box.orig.y); gc_mask |= GCTileStipXOrigin|GCTileStipYOrigin|GCStipple|GCForeground; @@ -1298,7 +1298,7 @@ Draw(ZnItem item) } else { values.fill_style = FillStippled; - values.stipple = ZnImagePixmap(cv->line_pattern); + values.stipple = ZnImagePixmap(cv->line_pattern, wi->win); XChangeGC(wi->dpy, wi->gc, GCFillStyle|GCStipple|GCLineWidth|GCJoinStyle|GCCapStyle|GCForeground, &values); @@ -1350,7 +1350,7 @@ Draw(ZnItem item) h_width = (width+1)/2; h_height = (height+1)/2; values.fill_style = FillStippled; - values.stipple = ZnImagePixmap(cv->marker); + values.stipple = ZnImagePixmap(cv->marker, wi->win); values.foreground = ZnGetGradientPixel(cv->marker_color, 0.0); XChangeGC(wi->dpy, wi->gc, GCFillStyle|GCStipple|GCForeground, &values); for (j = 0; j < cv->outlines.num_contours; j++) { diff --git a/generic/Draw.c b/generic/Draw.c index 4375e13..ee37388 100644 --- a/generic/Draw.c +++ b/generic/Draw.c @@ -42,6 +42,7 @@ #include "List.h" #include "WidgetInfo.h" #include "Image.h" +#include "tkZinc.h" #include #include @@ -1157,6 +1158,7 @@ ZnRenderPolyline(ZnWInfo *wi, ZnPoint c1, c2; XColor *color; unsigned short alpha; + ZnGLContextEntry *ce = ZnGetGLContext(wi->dpy); /* * The code below draws curves thiner than the min @@ -1166,8 +1168,8 @@ ZnRenderPolyline(ZnWInfo *wi, * BUG: The joints are drawn only rounded. * The caps can be either round or butt (but not projecting). */ - thin = ((line_width <= wi->max_line_width) && - (line_width <= wi->max_point_width)); + thin = ((line_width <= ce->max_line_width) && + (line_width <= ce->max_point_width)); closed = (points->x == points[num_points-1].x) && (points->y == points[num_points-1].y); color = ZnGetGradientColor(gradient, 0.0, &alpha); alpha = ZnComposeAlpha(alpha, wi->alpha); diff --git a/generic/Field.c b/generic/Field.c index dd1d8b2..2f8b9b7 100644 --- a/generic/Field.c +++ b/generic/Field.c @@ -1793,7 +1793,7 @@ DrawField(ZnWInfo *wi, if (fptr->tile != ZnUnspecifiedImage) { if (!ZnImageIsBitmap(fptr->tile)) { /* Fill tiled */ values.fill_style = FillTiled; - values.tile = ZnImagePixmap(fptr->tile); + values.tile = ZnImagePixmap(fptr->tile, wi->win); values.ts_x_origin = (int) bbox->orig.x; values.ts_y_origin = (int) bbox->orig.y; XChangeGC(wi->dpy, wi->gc, @@ -1802,7 +1802,7 @@ DrawField(ZnWInfo *wi, } else { /* Fill stippled */ values.fill_style = FillStippled; - values.stipple = ZnImagePixmap(fptr->tile); + values.stipple = ZnImagePixmap(fptr->tile, wi->win); values.ts_x_origin = (int) bbox->orig.x; values.ts_y_origin = (int) bbox->orig.y; XChangeGC(wi->dpy, wi->gc, @@ -1833,7 +1833,7 @@ DrawField(ZnWInfo *wi, fw = ZnNearestInt(bbox->corner.x - bbox->orig.x); fh = ZnNearestInt(bbox->corner.y - bbox->orig.y); - pixmap = ZnImagePixmap(fptr->image); + pixmap = ZnImagePixmap(fptr->image, wi->win); photo_region = ZnImageRegion(fptr->image); ZnCurrentClip(wi, &clip_region, NULL, &simple); clip = TkCreateRegion(); diff --git a/generic/Icon.c b/generic/Icon.c index 81979a4..10dc1c6 100644 --- a/generic/Icon.c +++ b/generic/Icon.c @@ -368,7 +368,7 @@ Draw(ZnItem item) ZnIntersectBBox(&box, &wi->damaged_area, &inter); box = inter; ZnCurrentClip(wi, &clip_region, NULL, NULL); - pixmap = ZnImagePixmap(icon->image); + pixmap = ZnImagePixmap(icon->image, wi->win); photo_region = ZnImageRegion(icon->image); clip = TkCreateRegion(); /* @@ -440,7 +440,7 @@ Draw(ZnItem item) dest_im->data = ZnMalloc(dest_im->bytes_per_line * dest_im->height); memset(dest_im->data, 0, dest_im->bytes_per_line * dest_im->height); - pixmap = ZnImagePixmap(icon->image); + pixmap = ZnImagePixmap(icon->image, wi->win); photo_region = ZnImageRegion(icon->image); clip = TkCreateRegion(); /* @@ -517,7 +517,7 @@ Draw(ZnItem item) * one and use this last image as a mask to draw in the X * back buffer. */ - pixmap = ZnImagePixmap(icon->image); + pixmap = ZnImagePixmap(icon->image, wi->win); if (ZnTransfoIsTranslation(item->wi->current_transfo)) { ZnCurrentClip(wi, NULL, &clip_box, &simple); if (simple) { diff --git a/generic/Image.c b/generic/Image.c index 09ecdd3..fd0bb60 100644 --- a/generic/Image.c +++ b/generic/Image.c @@ -26,6 +26,7 @@ #include "Types.h" +#include "tkZinc.h" #include "Image.h" #include "WidgetInfo.h" #include "Geo.h" @@ -63,7 +64,8 @@ typedef struct _ImageStruct { GLuint texobj; #endif } i; - struct _ZnWInfo *wi; + Display *dpy; + Screen *screen; struct _ImageBits *bits; /* Bookkeeping */ @@ -89,13 +91,14 @@ typedef struct _ImageBits { #endif /* Bookeeping */ - struct _ZnWInfo *wi; /* The widget that created the tkimage below (the first - * to use this image). */ + Display *dpy; /* The tkimage below comes from this display. */ + Tcl_Interp *interp; /* The interp that created the tkimage below. */ Tk_Image tkimage; /* Keep this handle to be informed of changes */ Tk_PhotoHandle tkphoto; TkRegion valid_region; int width; int height; + int depth; Tcl_HashEntry *hash; /* From this it is easy to get the image/bitmap * name. */ Image images; /* Linked list of widget/display dependant @@ -171,7 +174,7 @@ InvalidateImage(ClientData client_data, * the same name as an old. The image is first deleted then re-instantiated. * As a side effect we also rely on it for telling if an image is a photo. */ - bits->tkphoto = Tk_FindPhoto(bits->wi->interp, image_name); + bits->tkphoto = Tk_FindPhoto(bits->interp, image_name); count = 0; this = bits->images; @@ -179,16 +182,16 @@ InvalidateImage(ClientData client_data, #ifdef GL if (this->for_gl) { if (this->i.texobj) { - ZnGLMakeCurrent(this->wi); + ZnGLMakeCurrent(this->dpy, 0); glDeleteTextures(1, &this->i.texobj); - ZnGLRelease(this->wi); + /*ZnGLRelease(this->wi);*/ this->i.texobj = 0; } } else { #endif if (this->i.pixmap != None) { - Tk_FreePixmap(this->wi->dpy, this->i.pixmap); + Tk_FreePixmap(this->dpy, this->i.pixmap); this->i.pixmap = None; } #ifdef GL @@ -241,7 +244,6 @@ ZnGetImage(ZnWInfo *wi, } bits = ZnMalloc(sizeof(ImageBits)); - bits->wi = wi; #ifdef GL bits->t_bits = NULL; #endif @@ -250,6 +252,8 @@ ZnGetImage(ZnWInfo *wi, bits->valid_region = NULL; bits->tkimage = NULL; bits->tkphoto = NULL; + bits->interp = wi->interp; + bits->dpy = wi->dpy; if (!Tk_GetImageMasterData(wi->interp, image_name, &type)) { /* @@ -270,6 +274,7 @@ ZnGetImage(ZnWInfo *wi, Tk_SizeOfBitmap(wi->dpy, pmap, &bits->width, &bits->height); mask = XGetImage(wi->dpy, pmap, 0, 0, (unsigned int) bits->width, (unsigned int) bits->height, 1L, XYPixmap); + bits->depth = 1; bits->rowstride = mask->bytes_per_line; bits->bpixels = ZnMalloc((unsigned int) (bits->height * bits->rowstride)); memset(bits->bpixels, 0, (unsigned int) (bits->height * bits->rowstride)); @@ -294,10 +299,12 @@ ZnGetImage(ZnWInfo *wi, ZnWarning("bogus photo image \""); goto im_error; } + bits->depth = Tk_Depth(wi->win); bits->tkimage = Tk_GetImage(wi->interp, wi->win, image_name, InvalidateImage, (ClientData) bits); } else { /* Other image types */ + bits->depth = Tk_Depth(wi->win); bits->tkimage = Tk_GetImage(wi->interp, wi->win, image_name, InvalidateImage, (ClientData) bits); Tk_SizeOfImage(bits->tkimage, &bits->width, &bits->height); @@ -323,8 +330,8 @@ ZnGetImage(ZnWInfo *wi, */ for (image = bits->images; image != NULL; image = image->next) { if (image->for_gl == for_gl) { - if ((for_gl && (image->wi->dpy == wi->dpy)) || - (!for_gl && (image->wi->screen == wi->screen))) { + if ((for_gl && (image->dpy == wi->dpy)) || + (!for_gl && (image->screen == wi->screen))) { if (!ZnImageIsBitmap(image)) { cs_ptr = ZnListArray(image->clients); num_cs = ZnListSize(image->clients); @@ -357,7 +364,8 @@ ZnGetImage(ZnWInfo *wi, image->bits = bits; image->refcount = 0; image->for_gl = for_gl; - image->wi = wi; + image->dpy = wi->dpy; + image->screen = wi->screen; if (!ZnImageIsBitmap(image)) { image->clients = ZnListNew(1, sizeof(ClientStruct)); @@ -503,14 +511,13 @@ ZnFreeImage(ZnImage image, } if (this->for_gl) { #ifdef GL - ZnWInfo *wi = this->wi; if (this->i.texobj) { - ZnGLMakeCurrent(wi); + ZnGLMakeCurrent(this->dpy, 0); /* printf("%d Libération de la texture %d pour l'image %s\n", wi, this->i.texobj, ZnNameOfImage(image));*/ glDeleteTextures(1, &this->i.texobj); this->i.texobj = 0; - ZnGLRelease(wi); + /*ZnGLRelease(wi);*/ } #endif } @@ -519,7 +526,7 @@ ZnFreeImage(ZnImage image, * This is an image, we need to free the instances. */ if (this->i.pixmap != None) { - Tk_FreePixmap(this->wi->dpy, this->i.pixmap); + Tk_FreePixmap(this->dpy, this->i.pixmap); } } else { @@ -527,7 +534,7 @@ ZnFreeImage(ZnImage image, * This is a bitmap ask Tk to free the resource. */ if (this->i.pixmap != None) { - Tk_FreeBitmap(this->wi->dpy, this->i.pixmap); + Tk_FreeBitmap(this->dpy, this->i.pixmap); } } ZnFree(this); @@ -598,11 +605,11 @@ ZnSizeOfImage(ZnImage image, ********************************************************************************** */ Pixmap -ZnImagePixmap(ZnImage image) +ZnImagePixmap(ZnImage image, + Tk_Window win) { Image this = (Image) image; ImageBits *bits = this->bits; - ZnWInfo *wi = bits->wi; /*printf("ZnImagePixmap: %s\n", ZnNameOfImage(image));*/ if (this->for_gl) { @@ -613,21 +620,27 @@ ZnImagePixmap(ZnImage image) if (this->i.pixmap == None) { if (ZnImageIsBitmap(image)) { - this->i.pixmap = Tk_GetBitmap(wi->interp, wi->win, Tk_GetUid(ZnNameOfImage(image))); + this->i.pixmap = Tk_GetBitmap(bits->interp, win, Tk_GetUid(ZnNameOfImage(image))); } else { Tk_Image tkimage; - if (bits->wi == wi) { + /* + * If the original image was created on the same display + * as the required display, we can get the pixmap from it. + * On the other hand we need first to obtain an image + * instance on the right display. + */ + if (bits->dpy == this->dpy) { tkimage = bits->tkimage; } else { /* Create a temporary tkimage to draw the pixmap. */ - tkimage = Tk_GetImage(wi->interp, wi->win, ZnNameOfImage(image), NULL, NULL); + tkimage = Tk_GetImage(bits->interp, win, ZnNameOfImage(image), NULL, NULL); } - this->i.pixmap = Tk_GetPixmap(wi->dpy, Tk_WindowId(wi->win), - bits->width, bits->height, Tk_Depth(wi->win)); + this->i.pixmap = Tk_GetPixmap(this->dpy, Tk_WindowId(win), + bits->width, bits->height, bits->depth); Tk_RedrawImage(tkimage, 0, 0, bits->width, bits->height, this->i.pixmap, 0, 0); if (tkimage != bits->tkimage) { @@ -678,9 +691,9 @@ ZnPointInImage(ZnImage image, ********************************************************************************** */ static void -BuildImageRegion(ImageBits *bits) +BuildImageRegion(Display *dpy, + ImageBits *bits) { - ZnWInfo *wi = bits->wi; Pixmap pmap; int x, y, end; GC gc; @@ -688,20 +701,19 @@ BuildImageRegion(ImageBits *bits) XRectangle rect; /*printf("BuildImageRegion: %s\n", ZnNameOfImage(bits->images));*/ - pmap = Tk_GetPixmap(wi->dpy, Tk_WindowId(wi->win), - bits->width, bits->height, Tk_Depth(wi->win)); - gc = XCreateGC(wi->dpy, pmap, 0, NULL); - XSetForeground(wi->dpy, gc, 0); - XFillRectangle(wi->dpy, pmap, gc, 0, 0, bits->width, bits->height); + pmap = Tk_GetPixmap(dpy, DefaultRootWindow(dpy), bits->width, bits->height, bits->depth); + gc = XCreateGC(dpy, pmap, 0, NULL); + XSetForeground(dpy, gc, 0); + XFillRectangle(dpy, pmap, gc, 0, 0, bits->width, bits->height); Tk_RedrawImage(bits->tkimage, 0, 0, bits->width, bits->height, pmap, 0, 0); - im1 = XGetImage(wi->dpy, pmap, 0, 0, bits->width, bits->height, ~0L, ZPixmap); + im1 = XGetImage(dpy, pmap, 0, 0, bits->width, bits->height, ~0L, ZPixmap); - XSetForeground(wi->dpy, gc, 1); - XFillRectangle(wi->dpy, pmap, gc, 0, 0, bits->width, bits->height); + XSetForeground(dpy, gc, 1); + XFillRectangle(dpy, pmap, gc, 0, 0, bits->width, bits->height); Tk_RedrawImage(bits->tkimage, 0, 0, bits->width, bits->height, pmap, 0, 0); - im2 = XGetImage(wi->dpy, pmap, 0, 0, bits->width, bits->height, ~0L, ZPixmap); - Tk_FreePixmap(wi->dpy, pmap); - XFreeGC(wi->dpy, gc); + im2 = XGetImage(dpy, pmap, 0, 0, bits->width, bits->height, ~0L, ZPixmap); + Tk_FreePixmap(dpy, pmap); + XFreeGC(dpy, gc); bits->valid_region = TkCreateRegion(); @@ -741,10 +753,11 @@ ZnImageRegion(ZnImage image) return NULL; } else { - ImageBits *bits = ((Image) image)->bits; + Image this = (Image) image; + ImageBits *bits = this->bits; #ifdef PTK if (!bits->valid_region) { - BuildImageRegion(bits); + BuildImageRegion(this->dpy, bits); } return bits->valid_region; #else @@ -753,7 +766,7 @@ ZnImageRegion(ZnImage image) } else { if (!bits->valid_region) { - BuildImageRegion(bits); + BuildImageRegion(this->dpy, bits); } return bits->valid_region; } @@ -894,32 +907,31 @@ From8r8g8b(unsigned char *data, } static void -GatherImageTexels(ImageBits *bits) +GatherImageTexels(Display *dpy, + ImageBits *bits) { Pixmap pmap; XImage *im; TkRegion valid_region; - int t_size, depth; - ZnWInfo *wi = bits->wi; + int t_size; /*printf("GatherImageTexels: %s\n", ZnNameOfImage(bits->images));*/ valid_region = ZnImageRegion(bits->images); t_size = bits->t_width * 4 * bits->t_height; bits->t_bits = ZnMalloc(t_size); - depth = Tk_Depth(wi->win); - pmap = Tk_GetPixmap(wi->dpy, Tk_WindowId(wi->win), - bits->width, bits->height, depth); + pmap = Tk_GetPixmap(dpy, DefaultRootWindow(dpy), + bits->width, bits->height, bits->depth); Tk_RedrawImage(bits->tkimage, 0, 0, bits->width, bits->height, pmap, 0, 0); - im = XGetImage(wi->dpy, pmap, 0, 0, bits->width, bits->height, ~0L, ZPixmap); - Tk_FreePixmap(wi->dpy, pmap); + im = XGetImage(dpy, pmap, 0, 0, bits->width, bits->height, ~0L, ZPixmap); + Tk_FreePixmap(dpy, pmap); - if (depth == 16) { + if (bits->depth == 16) { From5r6g5b(im->data, bits->width, bits->height, im->bytes_per_line, bits->t_bits, bits->t_width, bits->t_height, valid_region); } - else if ((depth == 24) || (depth == 32)) { + else if ((bits->depth == 24) || (bits->depth == 32)) { From8r8g8b(im->data, bits->width, bits->height, im->bytes_per_line, bits->t_bits, bits->t_width, bits->t_height, valid_region); } @@ -1030,7 +1042,7 @@ ZnImageTex(ZnImage image, * from a locally drawn pixmap. */ else { - GatherImageTexels(bits); + GatherImageTexels(bits->dpy, bits); } } @@ -1487,7 +1499,7 @@ ZnGetTexFont(ZnWInfo *wi, int width, height; unsigned int texw, texh; GLfloat xstep, ystep; - TkFont *tft = (TkFont *) font; + ZnGLContextEntry *ce = ZnGetGLContext(wi->dpy); if (!inited) { Tcl_InitHashTable(&font_textures, TCL_ONE_WORD_KEYS); @@ -1540,18 +1552,18 @@ ZnGetTexFont(ZnWInfo *wi, /* * Initial size of texture. */ - texw = wi->max_tex_size; + texw = ce->max_tex_size; texh = 64; while (texh < (unsigned int) (txf->ascent+txf->descent)) { texh *= 2; } - /*printf("Taille réelle de texture utilisée: %d\n", wi->max_tex_size);*/ + /*printf("Taille réelle de texture utilisée: %d\n", ce->max_tex_size);*/ /* * This is temporarily disabled until we find out * how to reliably get max_tex_size up front without * waiting for the window mapping. */ - if (texh > wi->max_tex_size) { + if (texh > ce->max_tex_size) { goto error; } xstep = 0/*0.5 / texw*/; @@ -1640,14 +1652,14 @@ ZnGetTexFont(ZnWInfo *wi, px = gap; maxheight = height; if ((unsigned int) (py + height + gap) >= texh) { - if (texh*2 < wi->max_tex_size) { + if (texh*2 < ce->max_tex_size) { texh *= 2; ZnFree(txf->teximage); txf->teximage = ZnMalloc(texw * texh * sizeof(unsigned char)); strcpy(glist, glist2); goto restart; } - else if (texw*2 < wi->max_tex_size) { + else if (texw*2 < ce->max_tex_size) { texw *= 2; ZnFree(txf->teximage); txf->teximage = ZnMalloc(texw * texh * sizeof(unsigned char)); @@ -1899,9 +1911,9 @@ ZnFreeTexFont(ZnTexFontInfo tfi) if (this->texobj) { /*printf("%d Libération de la texture %d pour la fonte %s\n", wi, this->texobj, ZnNameOfTexFont(tfi));*/ - ZnGLMakeCurrent(wi); + ZnGLMakeCurrent(wi->dpy, 0); glDeleteTextures(1, &this->texobj); - ZnGLRelease(wi); + /*ZnGLRelease(wi);*/ } /* diff --git a/generic/Image.h b/generic/Image.h index 91ce36d..87860cb 100644 --- a/generic/Image.h +++ b/generic/Image.h @@ -52,7 +52,7 @@ ZnNameOfImage(ZnImage image); void ZnSizeOfImage(ZnImage image, int *width, int *height); Pixmap -ZnImagePixmap(ZnImage image); +ZnImagePixmap(ZnImage image, Tk_Window win); ZnBool ZnImageIsBitmap(ZnImage image); TkRegion diff --git a/generic/Map.c b/generic/Map.c index 622668d..2db552b 100644 --- a/generic/Map.c +++ b/generic/Map.c @@ -1024,7 +1024,7 @@ Draw(ZnItem item) } else { /* Fill stippled */ values.fill_style = FillStippled; - values.stipple = ZnImagePixmap(map->fill_pattern); + values.stipple = ZnImagePixmap(map->fill_pattern, wi->win); XChangeGC(wi->dpy, wi->gc, GCFillStyle | GCStipple | GCForeground, &values); } @@ -1278,7 +1278,7 @@ Draw(ZnItem item) ZnSizeOfImage(sym, &w ,&h); ox = ((int) points[i].x) - w/2; oy = ((int) points[i].y) - h/2; - values.stipple = ZnImagePixmap(sym); + values.stipple = ZnImagePixmap(sym, wi->win); values.ts_x_origin = ox; values.ts_y_origin = oy; XChangeGC(wi->dpy, wi->gc, @@ -1292,7 +1292,7 @@ Draw(ZnItem item) ZnSizeOfImage(wi->map_distance_symbol, &w, &h); cnt = ZnListSize(map->marks); points = ZnListArray(map->marks); - values.stipple = ZnImagePixmap(wi->map_distance_symbol); + values.stipple = ZnImagePixmap(wi->map_distance_symbol, wi->win); XChangeGC(wi->dpy, wi->gc, GCStipple, &values); for (i = 0; i < cnt; i++) { ox = ((int) points[i].x) - w/2; diff --git a/generic/Rectangle.c b/generic/Rectangle.c index 51fe10d..500473c 100644 --- a/generic/Rectangle.c +++ b/generic/Rectangle.c @@ -504,7 +504,7 @@ Draw(ZnItem item) if (rect->tile != ZnUnspecifiedImage) { if (!ZnImageIsBitmap(rect->tile)) { /* Fill tiled */ values.fill_style = FillTiled; - values.tile = ZnImagePixmap(rect->tile); + values.tile = ZnImagePixmap(rect->tile, wi->win); if (ISSET(rect->flags, ALIGNED_BIT)) { values.ts_x_origin = (int) r.x; values.ts_y_origin = (int) r.y; @@ -518,7 +518,7 @@ Draw(ZnItem item) } else { values.fill_style = FillStippled; - values.stipple = ZnImagePixmap(rect->tile); + values.stipple = ZnImagePixmap(rect->tile, wi->win); if (ISSET(rect->flags, ALIGNED_BIT)) { values.ts_x_origin = (int) r.x; values.ts_y_origin = (int) r.y; @@ -579,7 +579,7 @@ Draw(ZnItem item) } else { values.fill_style = FillStippled; - values.stipple = ZnImagePixmap(rect->line_pattern); + values.stipple = ZnImagePixmap(rect->line_pattern, wi->win); gc_mask |= GCStipple; XChangeGC(wi->dpy, wi->gc, gc_mask, &values); } diff --git a/generic/Text.c b/generic/Text.c index b1725cc..b544149 100644 --- a/generic/Text.c +++ b/generic/Text.c @@ -993,7 +993,7 @@ Draw(ZnItem item) gc_mask = GCFont | GCForeground; if (text->fill_pattern != ZnUnspecifiedImage) { values.fill_style = FillStippled; - values.stipple = ZnImagePixmap(text->fill_pattern); + values.stipple = ZnImagePixmap(text->fill_pattern, wi->win); gc_mask |= GCFillStyle | GCStipple; } else { diff --git a/generic/Track.c b/generic/Track.c index 77366cf..7de1248 100644 --- a/generic/Track.c +++ b/generic/Track.c @@ -1106,7 +1106,7 @@ Draw(ZnItem item) else { /* Fill stippled */ values.fill_style = FillStippled; - values.stipple = ZnImagePixmap(track->marker_fill_pattern); + values.stipple = ZnImagePixmap(track->marker_fill_pattern, wi->win); XChangeGC(wi->dpy, wi->gc, GCFillStyle | GCStipple | GCLineWidth | GCForeground, &values); } @@ -1273,7 +1273,7 @@ Draw(ZnItem item) y = ((int) track->dev.y) - (height+1)/2; values.foreground = ZnGetGradientPixel(track->symbol_color, 0.0); values.fill_style = FillStippled; - values.stipple = ZnImagePixmap(track->symbol); + values.stipple = ZnImagePixmap(track->symbol, wi->win); values.ts_x_origin = x; values.ts_y_origin = y; XChangeGC(wi->dpy, wi->gc, diff --git a/generic/Types.h b/generic/Types.h index 68efcd9..b0784ea 100644 --- a/generic/Types.h +++ b/generic/Types.h @@ -174,17 +174,6 @@ EXTERN TkRegion ZnPolygonRegion(XPoint *points, int n, int fill_rule); # ifdef GL # define ZnGLContext HGLRC -# define ZnGLMakeCurrent(wi) \ -{ \ - wi->hdc = GetDC(wi->hwnd); \ - wglMakeCurrent(wi->hdc, wi->gl_context); \ -} -# define ZnGLRelease(wi) \ - ReleaseDC(wi->hwnd, wi->hdc); -# define ZnGLDestroyContext(wi) \ - wglDeleteContext(wi->gl_context) -# define ZnGLSwapBuffers(wi) \ - SwapBuffers(wi->hdc) # define ZnGLWaitGL() # define ZN_GL_LINE_WIDTH_RANGE GL_LINE_WIDTH_RANGE # define ZN_GL_POINT_SIZE_RANGE GL_POINT_SIZE_RANGE @@ -200,15 +189,6 @@ EXTERN TkRegion ZnPolygonRegion(XPoint *points, int n, XOffsetRegion((Region) reg, dx, dy) # ifdef GL # define ZnGLContext GLXContext -# define ZnGLMakeCurrent(wi) \ - glXMakeCurrent(wi->dpy, \ - wi->win ? Tk_WindowId(wi->win) : RootWindowOfScreen(wi->screen), \ - wi->gl_context) -# define ZnGLRelease(wi) -# define ZnGLDestroyContext(wi) \ - glXDestroyContext(wi->dpy, wi->gl_context); -# define ZnGLSwapBuffers(wi) \ - glXSwapBuffers(wi->dpy, Tk_WindowId(wi->win)) # define ZnGLWaitGL() \ glXWaitGL() # define ZN_GL_LINE_WIDTH_RANGE GL_SMOOTH_LINE_WIDTH_RANGE diff --git a/generic/WidgetInfo.h b/generic/WidgetInfo.h index 47c209d..926f475 100644 --- a/generic/WidgetInfo.h +++ b/generic/WidgetInfo.h @@ -201,18 +201,7 @@ typedef struct _ZnWInfo { Display *dpy; /* The display of the widget window. */ Screen *screen; Tk_Window win; /* The window of the widget. */ -#ifdef GL - ZnGLContext gl_context; -# ifdef _WIN32 - HDC hdc; - HWND hwnd; -# else - XVisualInfo *gl_visual; -# endif - ZnReal max_line_width; - ZnReal max_point_width; - unsigned int max_tex_size; -#endif /* GL */ + GLUtesselator *tess; ZnCombineData *tess_combine_list; int tess_type; diff --git a/generic/tkZinc.c b/generic/tkZinc.c index 8cd188d..4801b4d 100644 --- a/generic/tkZinc.c +++ b/generic/tkZinc.c @@ -130,17 +130,6 @@ 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 @@ -624,6 +613,52 @@ ZnNeedRedisplay(ZnWInfo *wi) } } +/* + *---------------------------------------------------------------------- + * + * ZnGetGlContext -- + * + *---------------------------------------------------------------------- + */ +#ifdef GL +ZnGLContextEntry * +ZnGetGLContext(Display *dpy) +{ + ZnGLContextEntry *context_entry; + + for (context_entry = gl_contexts; + context_entry && context_entry->dpy != dpy; + context_entry = context_entry->next); + + return context_entry; +} + +void +ZnGLMakeCurrent(Display *dpy, + Tk_Window win) +{ + ZnGLContextEntry *context_entry; + + 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); +#endif +} + +void +ZnGLSwapBuffers(Display *dpy, + Tk_Window win) +{ +#ifdef WIN + SwapBuffers(ZnGetGLContext(dpy)->hdc); +#else + glXSwapBuffers(dpy, Tk_WindowId(win)); +#endif +} +#endif /* *---------------------------------------------------------------------- @@ -763,7 +798,6 @@ ZincObjCmd(ClientData client_data, /* Main window associated with #ifdef GL wi->font_tfi = NULL; wi->map_font_tfi = NULL; - wi->max_tex_size = 64; /* Minimum value is always valid */ #endif wi->map_distance_symbol = ZnUnspecifiedImage; wi->track_symbol = ZnUnspecifiedImage; @@ -887,6 +921,7 @@ ZincObjCmd(ClientData client_data, /* Main window associated with if (wi->render) { #ifdef GL ZnGLContextEntry *context_entry; + ZnGLContext gl_context; ASSIGN(wi->flags, ZN_PRINT_CONFIG, (getenv("ZINC_GLX_INFO") != NULL)); @@ -910,25 +945,25 @@ ZincObjCmd(ClientData client_data, /* Main window associated with 0, // reserved 0, 0, 0 // layer masks ignored }; - int ipixel; + int ipixel; + HWND hwnd; + HDC hdc; Tk_MakeWindowExist(wi->win); - wi->hwnd = Tk_GetHWND(Tk_WindowId(wi->win)); - wi->hdc = GetDC(wi->hwnd); - if (!wi->hdc) { + 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. */ - for (context_entry = gl_contexts; - context_entry && context_entry->hdc != wi->hdc; - context_entry = context_entry->next); + context_entry = ZnGetGLContext(wi->dpy); if (context_entry) { - wi->gl_context = context_entry->context; + gl_context = context_entry->context; } else { - ipixel = ChoosePixelFormat(wi->hdc, &pfd); + ipixel = ChoosePixelFormat(hdc, &pfd); /* sprintf(msg, "ipixel=%d dwFlags=0x%x req=0x%x iPixelType=%d\n", ipixel, pfd.dwFlags, @@ -938,16 +973,16 @@ ZincObjCmd(ClientData client_data, /* Main window associated with if (!ipixel) { OutputDebugString("ChoosePixelFormat failed\n"); } - wi->render = (SetPixelFormat(wi->hdc, ipixel, &pfd) == TRUE); + wi->render = (SetPixelFormat(hdc, ipixel, &pfd) == TRUE); if (wi->render) { - wi->gl_context = wglCreateContext(wi->hdc); - if (!wi->gl_context) { + gl_context = wglCreateContext(hdc); + if (!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->context = gl_context; + context_entry->hdc = hdc; context_entry->next = gl_contexts; gl_contexts = context_entry; } @@ -965,12 +1000,9 @@ ZincObjCmd(ClientData client_data, /* Main window associated with /* * Look for a matching context already available. */ - for (context_entry = gl_contexts; - context_entry && context_entry->dpy != wi->dpy; - context_entry = context_entry->next); - + context_entry = ZnGetGLContext(wi->dpy); if (context_entry) { - wi->gl_context = context_entry->context; + gl_context = context_entry->context; gl_visual = context_entry->visual; colormap = context_entry->colormap; } @@ -985,9 +1017,9 @@ ZincObjCmd(ClientData client_data, /* Main window associated with wi->render = 0; } else { - wi->gl_context = glXCreateContext(wi->dpy, gl_visual, - NULL, wi->render==1); - if (!wi->gl_context) { + gl_context = glXCreateContext(wi->dpy, gl_visual, + NULL, wi->render==1); + if (!gl_context) { fprintf(stderr, "No glx context\n"); wi->render = 0; } @@ -995,10 +1027,13 @@ ZincObjCmd(ClientData client_data, /* Main window associated with colormap = XCreateColormap(wi->dpy, RootWindowOfScreen(wi->screen), gl_visual->visual, AllocNone); context_entry = ZnMalloc(sizeof(ZnGLContextEntry)); - context_entry->context = wi->gl_context; + 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; @@ -1022,7 +1057,7 @@ ZincObjCmd(ClientData client_data, /* Main window associated with 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)); + glXIsDirect(wi->dpy, gl_context)); } } } @@ -6275,18 +6310,21 @@ Event(ClientData client_data, /* Information about widget. */ if (event->type == MapNotify) { if (!wi->gc) { SET(wi->flags, ZN_REALIZED); + if (wi->render) { #ifdef GL - GLfloat r[2]; /* Min, Max */ - GLint i[1]; + GLfloat r[2]; /* Min, Max */ + GLint i[1]; + ZnGLContextEntry *ce; - ZnGLMakeCurrent(wi); + ce = ZnGetGLContext(wi->dpy); + ZnGLMakeCurrent(wi->dpy, 0); glGetFloatv(ZN_GL_LINE_WIDTH_RANGE, r); - wi->max_line_width = r[1]; + ce->max_line_width = r[1]; glGetFloatv(ZN_GL_POINT_SIZE_RANGE, r); - wi->max_point_width = r[1]; + ce->max_point_width = r[1]; glGetIntegerv(GL_MAX_TEXTURE_SIZE, i); - wi->max_tex_size = (unsigned int) i[0]; + ce->max_tex_size = (unsigned int) i[0]; if (!wi->font_tfi) { wi->font_tfi = ZnGetTexFont(wi, wi->font); @@ -6305,14 +6343,14 @@ Event(ClientData client_data, /* Information about widget. */ fprintf(stderr, " Available extensions: %s\n", (char *) glGetString(GL_EXTENSIONS)); fprintf(stderr, "Max antialiased line width: %g\n", - wi->max_line_width); + ce->max_line_width); fprintf(stderr, "Max antialiased point size: %g\n", - wi->max_point_width); + ce->max_point_width); fprintf(stderr, "Max texture size: %d\n", - wi->max_tex_size); + ce->max_tex_size); } - ZnGLRelease(wi); + /*ZnGLRelease(wi);*/ #endif } @@ -7476,7 +7514,7 @@ Repair(ZnWInfo *wi) } #endif - ZnGLMakeCurrent(wi); + ZnGLMakeCurrent(wi->dpy, wi->win); glEnable(GL_POINT_SMOOTH); glEnable(GL_LINE_SMOOTH); #if 0 @@ -7612,8 +7650,8 @@ Repair(ZnWInfo *wi) glFlush(); /* Switch the GL buffers. */ - ZnGLSwapBuffers(wi); - ZnGLRelease(wi); + ZnGLSwapBuffers(wi->dpy, wi->win); + /*ZnGLRelease(wi);*/ /* * Wait the end of GL update if we need to synchronize @@ -7657,7 +7695,7 @@ Repair(ZnWInfo *wi) } else { values.fill_style = FillTiled; - values.tile = ZnImagePixmap(wi->tile); + values.tile = ZnImagePixmap(wi->tile, wi->win); values.ts_x_origin = values.ts_y_origin = 0; XChangeGC(wi->dpy, wi->gc, GCFillStyle|GCTile|GCTileStipXOrigin|GCTileStipYOrigin, diff --git a/generic/tkZinc.h b/generic/tkZinc.h index 78b8556..361fdd2 100644 --- a/generic/tkZinc.h +++ b/generic/tkZinc.h @@ -60,6 +60,26 @@ typedef struct _ZnTagSearch { ZnList item_stack; } ZnTagSearch; +#ifdef GL +typedef struct _ZnGLContextEntry { + ZnGLContext context; + Display *dpy; + ZnReal max_line_width; + ZnReal max_point_width; + unsigned int max_tex_size; +#ifdef WIN + HDC hdc; +#else + XVisualInfo *visual; /* Should these two be managed by screen ? */ + Colormap colormap; +#endif + struct _ZnGLContextEntry *next; +} ZnGLContextEntry; + +ZnGLContextEntry *ZnGetGLContext(Display *dpy); +void ZnGLMakeCurrent(Display *dpy, Tk_Window win); +void ZnGLSwapBuffers(Display *dpy, Tk_Window win); +#endif int ZnParseCoordList(ZnWInfo *wi, Tcl_Obj *arg, ZnPoint **pts, char **controls, unsigned int *num_pts, ZnBool *old_format); -- cgit v1.1