diff options
Diffstat (limited to 'generic')
-rw-r--r-- | generic/Item.c | 255 |
1 files changed, 193 insertions, 62 deletions
diff --git a/generic/Item.c b/generic/Item.c index 6e9cfbf..a2d159f 100644 --- a/generic/Item.c +++ b/generic/Item.c @@ -34,6 +34,7 @@ #include <stdio.h> #include <string.h> #ifdef GLX +#include <GL/glx.h> #include <GL/glu.h> #endif @@ -4742,7 +4743,6 @@ static void Repair(WidgetInfo *wi) { XGCValues values; - XRectangle r; ZnPoint pts[2]; ZnTriStrip tristrip; @@ -4750,9 +4750,99 @@ Repair(WidgetInfo *wi) #ifdef GLX ZnReal int_width, int_height; - int_width = Tk_Width(wi->win) - 2*wi->inset; - int_height = Tk_Height(wi->win) - 2*wi->inset; + glEnable(GL_POINT_SMOOTH); + glEnable(GL_LINE_SMOOTH); +#if 0 + glEnable(GL_POLYGON_SMOOTH); /* expensive ? */ +#endif + + glEnable(GL_BLEND); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glClearStencil(0); + glClearColor(wi->back_color->red/65536.0, wi->back_color->green/65536.0, + wi->back_color->blue/65536.0, 0.0); + + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + /* + * Init the composite group alpha. + */ + wi->alpha = 100; + int_width = Tk_Width(wi->win); + int_height = Tk_Height(wi->win); + + if ((wi->border_width > 0) || (wi->highlight_width > 0)) { +#ifdef GLX_DAMAGE + glDisable(GL_SCISSOR_TEST); +#endif + glViewport(0, 0, (GLsizei) int_width, int_height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(0.0, int_width, int_height, 0.0); + glMatrixMode(GL_MODELVIEW); + if (wi->highlight_width > 0) { + if (wi->text_info.got_focus) { + glColor4us(wi->highlight_color->red, wi->highlight_color->green, + wi->highlight_color->blue, 65535); + } + else { + glColor4us(wi->highlight_bg_color->red, wi->highlight_bg_color->green, + wi->highlight_bg_color->blue, 65535); + } + glBegin(GL_QUAD_STRIP); + glVertex2f(0.0, 0.0); + glVertex2f(wi->highlight_width, wi->highlight_width); + glVertex2f(Tk_Width(wi->win), 0); + glVertex2f(Tk_Width(wi->win) - wi->highlight_width, wi->highlight_width); + glVertex2f(Tk_Width(wi->win), Tk_Height(wi->win)); + glVertex2f(Tk_Width(wi->win) - wi->highlight_width, Tk_Height(wi->win) - wi->highlight_width); + glVertex2f(0, Tk_Height(wi->win)); + glVertex2f(wi->highlight_width, Tk_Height(wi->win) - wi->highlight_width); + glVertex2f(0, 0); + glVertex2f(wi->highlight_width, wi->highlight_width); + glEnd(); + } + if (wi->border_width > 0) { + ZnPoint p[5]; + + 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 = Tk_Width(wi->win) - wi->highlight_width; + p[2].y = p[1].y = Tk_Height(wi->win) - wi->highlight_width; + RenderPolygonRelief(wi, wi->relief, wi->relief_grad, + 65535, 0, p, 5, wi->border_width); + } + } + + int_width -= 2*wi->inset; + int_height -= 2*wi->inset; + /* + * Set the viewport and base coord system to the X device coord system. + */ + glViewport(wi->inset, wi->inset, (GLsizei) int_width, int_height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(0.0, int_width, int_height, 0.0); + glMatrixMode(GL_MODELVIEW); + +#ifdef GLX_DAMAGE + glEnable(GL_SCISSOR_TEST); + + /* + * Set the damaged area as the scissor area. + */ + wi->damaged_area.orig.x = REAL_TO_INT(wi->damaged_area.orig.x); + wi->damaged_area.orig.y = REAL_TO_INT(wi->damaged_area.orig.y); + wi->damaged_area.corner.x = REAL_TO_INT(wi->damaged_area.corner.x); + wi->damaged_area.corner.y = REAL_TO_INT(wi->damaged_area.corner.y); + glScissor(wi->inset+wi->damaged_area.orig.x, + wi->inset+int_height - wi->damaged_area.corner.y, + wi->damaged_area.corner.x - wi->damaged_area.orig.x, + wi->damaged_area.corner.y - wi->damaged_area.orig.y); +#else /* * We do not use the damaged area for GL rendering, * set it to the whole area. @@ -4760,23 +4850,12 @@ Repair(WidgetInfo *wi) wi->damaged_area.orig.x = wi->damaged_area.orig.y = 0.0; wi->damaged_area.corner.x = int_width; wi->damaged_area.corner.y = int_height; +#endif - /* Set the viewport (should be moved to the resize code) */ - /*glViewport(0, 0, (GLsizei) Tk_Width(wi->win), (GLsizei) Tk_Height(wi->win));*/ - glViewport(wi->inset, wi->inset, (GLsizei) int_width, (GLsizei) int_height); - /* Set the base coord system to the X device coord system. */ - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluOrtho2D(0.0, int_width, int_height, 0.0); - glMatrixMode(GL_MODELVIEW); - - /* Clear the GL buffers. */ - glClearColor(wi->back_color->red/65536.0, wi->back_color->green/65536.0, - wi->back_color->blue/65536.0, 0.0); - glClearStencil(0); + /* + * Clear the GL buffers. + */ glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - glEnable(GL_BLEND); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); /* * Setup the background tile if needed. @@ -4791,57 +4870,109 @@ Repair(WidgetInfo *wi) RenderTile(wi, GetImageTexture(wi->win, wi->tile_name, wi->tile), NULL, NULL, NULL, (ZnPoint *) &bbox); } - /* - * Init the composite group alpha. - */ - wi->alpha = 100; - - glEnable(GL_POINT_SMOOTH); - glEnable(GL_LINE_SMOOTH); -#if 0 - glEnable(GL_POLYGON_SMOOTH); /* expensive ? */ -#endif - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + wi->top_group->class->Render(wi->top_group); glFlush(); + + /* Switch the GL buffers. */ + glXSwapBuffers(wi->dpy, ZnWindowId(wi->win)); + /* + * Wait the end of GL update if we need to synchronize + * to monitor perfs. + */ + if (wi->monitoring) { + glXWaitGL(); + } #endif } else { - /* Set the whole damaged area as clip rect. */ - wi->damaged_area.orig.x = r.x = REAL_TO_INT(wi->damaged_area.orig.x); - wi->damaged_area.orig.y = r.y = REAL_TO_INT(wi->damaged_area.orig.y); - wi->damaged_area.corner.x = REAL_TO_INT(wi->damaged_area.corner.x); - wi->damaged_area.corner.y = REAL_TO_INT(wi->damaged_area.corner.y); - r.width = wi->damaged_area.corner.x - wi->damaged_area.orig.x; - r.height = wi->damaged_area.corner.y - wi->damaged_area.orig.y; - pts[0] = wi->damaged_area.orig; - pts[1] = wi->damaged_area.corner; - TRI_STRIP1(&tristrip, pts, 2); - PushClip(wi, &tristrip, True, True); - - /* Fill the background of the double buffer pixmap. */ - if (wi->tile == ZnUnspecifiedImage) { - values.foreground = ZnPixel(wi->back_color); - values.fill_style = FillSolid; - XChangeGC(wi->dpy, wi->gc, GCFillStyle|GCForeground, &values); - } - else { - values.fill_style = FillTiled; - values.tile = GetImagePixmap(wi->win, wi->tile_name, wi->tile, NULL); - values.ts_x_origin = values.ts_y_origin = 0; - XChangeGC(wi->dpy, wi->gc, - GCFillStyle|GCTile|GCTileStipXOrigin|GCTileStipYOrigin, - &values); + XRectangle r; + ZnBBox merge; + + /* + * Merge the repaired area with the exposed area. + */ + ResetBBox(&merge); + CopyBBox(&wi->damaged_area, &merge); + AddBBoxToBBox(&merge, &wi->exposed_area); + if (!IsEmptyBBox(&merge)) { + + /* Set the whole damaged area as clip rect. */ + wi->damaged_area.orig.x = r.x = REAL_TO_INT(wi->damaged_area.orig.x); + wi->damaged_area.orig.y = r.y = REAL_TO_INT(wi->damaged_area.orig.y); + wi->damaged_area.corner.x = REAL_TO_INT(wi->damaged_area.corner.x); + wi->damaged_area.corner.y = REAL_TO_INT(wi->damaged_area.corner.y); + r.width = wi->damaged_area.corner.x - wi->damaged_area.orig.x; + r.height = wi->damaged_area.corner.y - wi->damaged_area.orig.y; + pts[0] = wi->damaged_area.orig; + pts[1] = wi->damaged_area.corner; + TRI_STRIP1(&tristrip, pts, 2); + PushClip(wi, &tristrip, True, True); + + /* Fill the background of the double buffer pixmap. */ + if (wi->tile == ZnUnspecifiedImage) { + values.foreground = ZnPixel(wi->back_color); + values.fill_style = FillSolid; + XChangeGC(wi->dpy, wi->gc, GCFillStyle|GCForeground, &values); + } + else { + values.fill_style = FillTiled; + values.tile = GetImagePixmap(wi->win, wi->tile_name, wi->tile, NULL); + values.ts_x_origin = values.ts_y_origin = 0; + XChangeGC(wi->dpy, wi->gc, + GCFillStyle|GCTile|GCTileStipXOrigin|GCTileStipYOrigin, + &values); + } + /*printf("Repair : filling rectangle: %d %d %d %d\n", r.x, r.y, r.width, r.height);*/ + XFillRectangle(wi->dpy, wi->draw_buffer, wi->gc, r.x, r.y, r.width, r.height); + + /* Draw the items */ + /*printf("Drawing\n");*/ + wi->top_group->class->Draw(wi->top_group); + + PopClip(wi, True); + + /* + * Send the merged area back to screen. + */ + BBox2XRect(&merge, &r); + XCopyArea(wi->dpy, + wi->draw_buffer, ZnWindowId(wi->win), wi->gc, + r.x, r.y, r.width, r.height, r.x+wi->inset, r.y+wi->inset); } - /*printf("Repair : filling rectangle: %d %d %d %d\n", r.x, r.y, r.width, r.height);*/ - XFillRectangle(wi->dpy, wi->draw_buffer, wi->gc, r.x, r.y, r.width, r.height); - /* Draw the items */ - /*printf("Drawing\n");*/ - wi->top_group->class->Draw(wi->top_group); - - PopClip(wi, True); + /* + * Redraw the borders. + */ + if (wi->border_width > 0) { + Pixmap save; + XRectangle r; + + save = wi->draw_buffer; + wi->draw_buffer = ZnWindowId(wi->win); + r.x = r.y = wi->highlight_width; + r.width = Tk_Width(wi->win) - 2*wi->highlight_width; + r.height = Tk_Height(wi->win) - 2*wi->highlight_width; + DrawRectangleRelief(wi, wi->relief, wi->relief_grad, + &r, wi->border_width); + wi->draw_buffer = save; + } + if ((wi->highlight_width > 0) && !wi->render) { + XRectangle r[4]; + + XSetForeground(wi->dpy, wi->gc, + ZnPixel(wi->text_info.got_focus ? + wi->highlight_color : + wi->highlight_bg_color)); + r[0].x = r[0].y = r[1].x = r[2].x = 0; + r[0].width = Tk_Width(wi->win); + r[1].y = Tk_Height(wi->win) - wi->highlight_width; + r[1].width = Tk_Width(wi->win); + r[0].height = r[1].height = r[3].y = r[2].y = r[2].width = r[3].width = wi->highlight_width; + r[3].height = r[2].height = Tk_Height(wi->win) - 2*wi->highlight_width; + r[3].x = Tk_Width(wi->win) - wi->highlight_width; + XFillRectangles(wi->dpy, ZnWindowId(wi->win), wi->gc, r, 4); + } } } |