64
81
node_class->render = drawable_node_render;
65
82
node_class->compute_extents = drawable_node_compute_extents;
83
node_class->get_covered_region = drawable_node_get_covered_region;
69
87
cm_drawable_node_init (CmDrawableNode *drawable_node)
75
cm_drawable_node_set_damage_func (CmDrawableNode *node,
76
DrawableDamageFunc damage_func,
79
node->damage_func = damage_func;
80
node->damage_data = data;
92
cm_grid_new (0, 0, 20, 20, 32, 32);
93
drawable_node->explosion =
94
cm_explosion_new (20, 20, 20, 20);
95
drawable_node->pix_texture =
96
cm_pix_texture_new (NULL,
97
CM_NODE (drawable_node->grid));
98
drawable_node->tex_env =
99
cm_tex_env_new (CM_NODE (drawable_node->pix_texture));
100
drawable_node->stacker = cm_stacker_new ();
101
drawable_node->shadow = cm_shadow_new (20, 20, 32, 32);
102
cm_stacker_add_child (drawable_node->stacker, CM_NODE (drawable_node->shadow));
103
cm_stacker_add_child (drawable_node->stacker, CM_NODE (drawable_node->tex_env));
105
cm_deform_new (CM_NODE (drawable_node->stacker), 0, 0, 32, 32);
106
cm_node_own_child (CM_NODE (drawable_node), &drawable_node->deform, deform);
107
g_object_unref (deform);
108
drawable_node->explosion_level = 0.0;
84
112
queue_paint (CmDrawableNode *node)
87
g_print ("calling into metacity\n");
90
if (node->damage_func)
91
node->damage_func (node, node->damage_data);
94
#define SHADOW_WIDTH 64
97
bind_shadow_texture(void)
99
static unsigned char texture[4 * SHADOW_WIDTH * SHADOW_WIDTH];
100
static gboolean initialized;
101
static GLuint texture_name;
104
const int xofs = 4, yofs = 4;
105
const int fuzz = 2 * SHADOW_WIDTH / 3;
110
glGenTextures (1, &texture_name);
111
for (i = 0; i < SHADOW_WIDTH * 2; i++)
113
for (j = 0; j < SHADOW_WIDTH * 2; j++)
115
if (i < (xofs + fuzz))
116
dx = (xofs + fuzz) - i;
117
else if (i < (xofs + 2 * SHADOW_WIDTH - fuzz))
120
dx = i - (xofs + 2 * SHADOW_WIDTH - fuzz + 1);
122
if (j < (yofs + fuzz))
123
dy = (yofs + fuzz) - j;
124
else if (j < (yofs + 2 * SHADOW_WIDTH - fuzz))
127
dy = j - (yofs + 2 * SHADOW_WIDTH - fuzz + 1);
129
d = sqrt(dx * dx + dy * dy);
130
alpha = pow(0.8, d * 0.7) * 90;
132
texture[i + j * SHADOW_WIDTH * 2] = alpha;
136
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture_name);
137
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_ALPHA,
138
SHADOW_WIDTH * 2, SHADOW_WIDTH * 2, 0,
139
GL_ALPHA, GL_BYTE, texture);
142
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture_name);
146
emit_quad(int u0, int v0, int u1, int v1,
147
int x0, int y0, int x1, int y1,
148
CmDrawableNode *node)
152
glTexCoord2i (u0, v0);
153
node->deform_func(x0, y0, node->real_x, node->real_y,
154
node->real_width, node->real_height,
155
&dx, &dy, node->deform_data);
156
glVertex3i (dx, dy, 0);
157
glTexCoord2i (u1, v0);
158
node->deform_func(x1, y0, node->real_x, node->real_y,
159
node->real_width, node->real_height,
160
&dx, &dy, node->deform_data);
161
glVertex3i (dx, dy, 0);
162
glTexCoord2i (u1, v1);
163
node->deform_func(x1, y1, node->real_x, node->real_y,
164
node->real_width, node->real_height,
165
&dx, &dy, node->deform_data);
166
glVertex3i (dx, dy, 0);
167
glTexCoord2i (u0, v1);
168
node->deform_func(x0, y1, node->real_x, node->real_y,
169
node->real_width, node->real_height,
170
&dx, &dy, node->deform_data);
171
glVertex3f (dx, dy, 0);
175
draw_window (CmDrawableNode *node)
177
const int tile_size = 32;
181
w = node->real_width;
182
h = node->real_height;
186
for (u0 = 0; u0 < w; u0 += tile_size)
188
for (v0 = 0; v0 < h; v0 += tile_size)
190
u1 = MIN(u0 + tile_size, w);
191
v1 = MIN(v0 + tile_size, h);
193
emit_quad(u0, v0, u1, v1, u0, v0, u1, v1, node);
199
glColor4f (0.0, 0.0, 0.0, node->alpha);
200
glEnable (GL_TEXTURE_RECTANGLE_ARB);
201
bind_shadow_texture();
202
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
207
emit_quad(0, 0, tile_size, tile_size,
208
-tile_size, -tile_size, 0, 0, node);
209
emit_quad(tile_size, 0, 2 * tile_size, tile_size,
210
0, -tile_size, tile_size, 0, node);
212
emit_quad(2 * tile_size, 0, 3 * tile_size, tile_size,
213
w - tile_size, -tile_size, w, 0, node);
214
emit_quad(3 * tile_size, 0, 4 * tile_size, tile_size,
215
w, -tile_size, w + tile_size, 0, node);
217
emit_quad(0, tile_size, tile_size, 2 * tile_size,
218
-tile_size, 0, 0, tile_size, node);
219
emit_quad(3 * tile_size, tile_size, 4 * tile_size, 2 * tile_size,
220
w, 0, w + tile_size, tile_size, node);
222
for (u0 = tile_size; u0 < w - tile_size; u0 += tile_size)
226
u1 = MIN(u0 + tile_size, w - tile_size);
228
emit_quad(2 * tile_size, 0, 2 * tile_size, tile_size,
229
u0, v0, u1, v1, node);
233
emit_quad(2 * tile_size, 3 * tile_size, 2 * tile_size, 4 * tile_size,
234
u0, v0, u1, v1, node);
238
for (v0 = tile_size; v0 < h - tile_size; v0 += tile_size)
242
v1 = MIN(v0 + tile_size, h - tile_size);
244
emit_quad(0, 2 * tile_size, tile_size, 2 * tile_size,
245
u0, v0, u1, v1, node);
250
emit_quad(3 * tile_size, 2 * tile_size, 4 * tile_size, 2 * tile_size,
251
u0, v0, u1, v1, node);
254
emit_quad(0, 2 * tile_size, tile_size, 3 * tile_size,
255
-tile_size, h - tile_size, 0, h, node);
256
emit_quad(3 * tile_size, 2 * tile_size, 4 * tile_size, 3 * tile_size,
257
w, h - tile_size, w + tile_size, h, node);
259
emit_quad(tile_size, 3 * tile_size, 2 * tile_size, 4 * tile_size,
260
0, h, tile_size, h + tile_size, node);
261
emit_quad(2 * tile_size, 3 * tile_size, 3 * tile_size, 4 * tile_size,
262
w - tile_size, h, w, h + tile_size, node);
264
emit_quad(0, 3 * tile_size, tile_size, 4 * tile_size,
265
-tile_size, h, 0, h + tile_size, node);
266
emit_quad(3 * tile_size, 3 * tile_size, 4 * tile_size, 4 * tile_size,
267
w, h, w + tile_size, h + tile_size, node);
114
cm_node_queue_repaint (CM_NODE (node));
310
162
print_matrix ("proj", proj);
311
163
g_print ("viewport: %d %d %d %d\n", view[0], view[1], view[2], view[3]);
313
printf ("projected: %d %d %d => %f %f %f\n", x, y, z, wx, wy, wz);
165
g_print ("projected: %d %d %d => %f %f %f\n", x, y, z, wx, wy, wz);
318
update_geometry (CmDrawableNode *node)
320
WsRectangle geometry;
322
if (!ws_drawable_query_geometry (WS_DRAWABLE (node->drawable), &geometry))
327
node->real_x = geometry.x;
328
node->real_y = geometry.y;
329
node->real_width = geometry.width;
330
node->real_height = geometry.height;
334
drawable_node_render (CmNode *node)
336
CmDrawableNode *drawable_node = CM_DRAWABLE_NODE (node);
170
drawable_node_vertex (gdouble *x,
178
CmDrawableNode *dnode = data;
181
cm_drawable_node_get_clipbox (dnode, &clipbox);
183
glTexCoord2f (u * clipbox.width,
188
get_shape (CmDrawableNode *dnode)
193
cm_drawable_node_get_clipbox (dnode, &clipbox);
197
reg = ws_region_copy (dnode->shape);
198
ws_region_offset (reg, clipbox.x, clipbox.y);
202
reg = ws_region_rectangle (&clipbox);
209
print_region (const char *header, WsRegion *region)
213
WsRectangle *rects = NULL;
215
ws_region_get_rectangles (region, &rects, &n_rects);
217
g_print ("%s: \n", header);
218
for (i = 0; i < n_rects; ++i)
220
WsRectangle *r = &(rects[i]);
222
g_print (" %d %d %d %d\n", r->x, r->y, r->width, r->height);
231
drawable_node_get_covered_region (CmNode *node)
233
CmDrawableNode *dnode = CM_DRAWABLE_NODE (node);
236
ws_display_begin_error_trap (WS_RESOURCE (dnode->drawable)->display);
238
if (ws_window_query_input_only (WS_WINDOW (dnode->drawable)))
243
else if (!dnode->viewable)
248
else if (dnode->alpha != 1.0)
253
else if (cm_pix_texture_has_alpha (dnode->pix_texture))
258
else if (dnode->explosion_level > DBL_EPSILON)
263
else if (dnode->deformed)
270
result = get_shape (dnode);
275
ws_display_end_error_trap (WS_RESOURCE (dnode->drawable)->display);
281
set_geometries (CmDrawableNode *dnode)
283
WsRegion *reg = NULL;
286
reg = get_shape (dnode);
288
ws_region_get_clipbox (reg, &clipbox);
290
cm_grid_set_region (dnode->grid, reg);
291
cm_explosion_set_region (dnode->explosion, reg);
293
cm_deform_set_geometry (dnode->deform,
298
cm_shadow_set_geometry (dnode->shadow,
304
ws_region_destroy (reg);
308
drawable_node_render (CmNode *node,
338
311
WsScreen *screen;
345
if (!drawable_node->viewable)
348
if (!drawable_node->pixmap)
351
screen = ws_drawable_query_screen (WS_DRAWABLE (drawable_node->pixmap));
352
texture = ws_pixmap_get_texture (drawable_node->pixmap);
354
if (drawable_node->real_width == -1)
355
update_geometry (drawable_node);
357
scr_w = ws_screen_get_width (screen);
358
scr_h = ws_screen_get_height (screen);
361
vw = drawable_node->width / scr_w;
362
vh = drawable_node->height / scr_h;
363
vx = drawable_node->x / scr_w;
364
vy = drawable_node->y / scr_h;
368
g_print ("binding texture: %d\n", texture);
371
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texture);
374
glEnable (GL_TEXTURE_RECTANGLE_ARB);
376
glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
382
glVertex3f (vx, 1 - vy, 0.0);
383
glTexCoord2f (drawable_node->width, 0);
384
glVertex3f (vx + vw, 1 - vy, 0.0);
385
glTexCoord2f (drawable_node->width, drawable_node->height);
386
glVertex3f (vx + vw, 1 - (vy + vh), 0.0);
387
glTexCoord2f (0, drawable_node->height);
388
glVertex3f (vx, 1 - (vy + vh), 0.0);
392
glMatrixMode (GL_PROJECTION);
395
gluOrtho2D (0, scr_w, scr_h, 0);
397
glDisable (GL_TEXTURE_RECTANGLE_ARB);
398
glColor4f (0.0, 0.0, 0.1, 0.3);
400
glMatrixMode (GL_MODELVIEW);
403
/* Emperically determined constant that gets rid of some fuzzyness
312
CmDrawableNode *dnode = CM_DRAWABLE_NODE (node);
315
g_print ("are we going to render %lx (%p)?\n",
316
WS_RESOURCE_XID (dnode->drawable), dnode);
319
if (!dnode->viewable)
322
g_print ("not rendering %lx since it is not viewable\n",
323
WS_RESOURCE_XID (dnode->drawable));
328
if (!dnode->pix_texture)
331
g_print ("not rendering %lx since it doesn't have a pix_texture\n",
332
WS_RESOURCE_XID (dnode->drawable));
337
if (!dnode->pix_texture->pixmap)
340
g_print ("not rendering %lx since it doesn't have a pixmap\n",
341
WS_RESOURCE_XID (dnode->drawable));
347
g_print ("rendering %lx\n", WS_RESOURCE_XID (dnode->drawable));
350
WsPixmap *pixmap = dnode->pix_texture->pixmap;
351
WsDisplay *display = WS_RESOURCE (pixmap)->display;
353
ws_display_begin_error_trap (display);
355
if (ws_window_query_input_only (
356
WS_WINDOW (dnode->drawable)))
358
ws_display_end_error_trap (display);
362
screen = ws_drawable_query_screen (
363
WS_DRAWABLE (dnode->pix_texture->pixmap));
367
/* The pixmap was bad or something */
368
ws_display_end_error_trap (display);
372
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
376
cm_state_set_screen_coords (state);
379
ws_screen_get_width (screen),
380
ws_screen_get_height (screen), 0);
383
/* Empirically determined constant that gets rid of some fuzzyness
405
glTranslatef (-0.04, -0.04, 0);
407
glShadeModel (GL_SMOOTH);
409
glEnable (GL_LIGHTING);
413
glColor4f (1.0, 1.0, 1.0, drawable_node->alpha);
386
glTranslatef (-0.125, -0.125, 0);
390
g_print ("setting geometry: %d %d %d %d\n",
391
dnode->real_x, dnode->real_y,
392
dnode->real_width, dnode->real_height);
395
set_geometries (dnode);
398
glColor4f (1.0, 1.0, 1.0, dnode->alpha);
414
399
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
415
glEnable (GL_TEXTURE_RECTANGLE_ARB);
417
glColor4f (1.0, 0.9 + 0.1 * g_random_double(), 0.0, 1.0);
420
glBlendFunc (drawable_node->alpha < 0.99 ? GL_SRC_ALPHA : GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
421
glDisable (GL_LIGHTING);
423
draw_window(drawable_node);
430
g_print ("done painting\n");
401
glBlendFunc (dnode->alpha < 0.99 ? GL_SRC_ALPHA :
402
GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
406
cm_node_render (CM_NODE (dnode->pix_texture), state);
410
glTranslatef (20 * g_random_double(), 20 * g_random_double(), 0.0);
413
cm_node_render (CM_NODE (dnode->deform), state);
417
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, 0);
418
ws_display_end_error_trap (display);
461
445
WsWindow *window;
462
446
WsDisplay *display = WS_RESOURCE (node->drawable)->display;
463
WsRectangle geometry;
449
if (node->pix_texture->pixmap && !node->pix_texture->pixmap->do_updates)
466
g_print ("refreshing pixmap\n");
452
g_print ("not refreshing\n");
469
if (node->pixmap && !ws_pixmap_get_updates (node->pixmap))
472
457
window = WS_WINDOW (node->drawable);
477
g_print ("unreffing %p\n", node->pixmap);
479
g_object_unref (node->pixmap);
482
459
ws_display_begin_error_trap (display);
486
463
if (ws_window_query_mapped (window) &&
487
464
!ws_window_query_input_only (window))
489
node->pixmap = ws_window_name_pixmap (window);
466
pixmap = ws_window_name_pixmap (window);
468
g_print ("name pixmap on %lx %p\n", WS_RESOURCE_XID (window), pixmap);
492
472
if (ws_display_end_error_trap_with_return (display))
494
ws_display_begin_error_trap (display);
498
g_object_unref (node->pixmap);
503
ws_display_end_error_trap (display);
509
ws_drawable_query_geometry (WS_DRAWABLE (window), &geometry);
512
g_print ("naming pixmap %lx on window %lx (%d x %d)\n", WS_RESOURCE_XID (node->pixmap), WS_RESOURCE_XID (window), geometry.width, geometry.height);
515
ws_drawable_query_geometry (WS_DRAWABLE (node->pixmap), &geometry);
518
g_print ("pixmap size (%d x %d)\n", geometry.width, geometry.height);
520
ws_pixmap_set_damage_callback (node->pixmap, on_damage, node);
526
on_configure (WsWindow *window,
533
gboolean override_redirect,
536
CmDrawableNode *node = data;
538
if (node->pixmap && !ws_pixmap_get_updates (node->pixmap))
541
// g_print ("configure\n");
542
if (width != node->real_width ||
543
height != node->real_height)
545
refresh_pixmap (node);
550
node->real_width = width;
551
node->real_height = height;
476
ws_display_begin_error_trap (display);
478
g_object_unref (pixmap);
480
ws_display_end_error_trap (display);
486
ws_display_begin_error_trap (display);
488
cm_pix_texture_set_pixmap (node->pix_texture, pixmap);
492
g_signal_connect (pixmap, "damage_notify_event", G_CALLBACK (on_damage), node);
494
g_object_unref (pixmap);
497
ws_display_end_error_trap (display);
557
cm_drawable_node_new (WsDrawable *drawable)
501
cm_drawable_node_new (WsDrawable *drawable,
502
WsRectangle *geometry)
559
504
CmDrawableNode *node;
560
505
WsDisplay *display;
562
508
g_return_val_if_fail (drawable != NULL, NULL);
512
/* FIXME: possibly just assertion fail if this happens? */
564
521
display = WS_RESOURCE (drawable)->display;
566
523
node = g_object_new (CM_TYPE_DRAWABLE_NODE, NULL);
568
g_print ("creating drawable node %p containing %lx\n",
569
node, WS_RESOURCE_XID (drawable));
571
525
node->drawable = drawable;
573
ws_window_set_configure_callback (
574
WS_WINDOW (drawable), on_configure, node);
575
527
node->viewable = TRUE;
577
node->deform_func = cm_identity_deform;
578
node->deform_data = NULL;
580
node->damage_func = NULL;
581
node->damage_data = NULL;
583
529
node->timer = g_timer_new ();
587
node->real_width = -1;
588
node->real_height = -1;
531
node->geometry = *geometry;
590
534
ws_display_init_composite (ws_drawable_get_display (drawable));
591
535
ws_display_init_damage (ws_drawable_get_display (drawable));