aboutsummaryrefslogtreecommitdiff
path: root/generic
diff options
context:
space:
mode:
Diffstat (limited to 'generic')
-rw-r--r--generic/Item.c255
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);
+ }
}
}