static gboolean effects_draw_box_animation_timeout (BoxAnimationContext *context) { double elapsed; GTimeVal current_time; MetaRectangle draw_rect; double fraction; g_get_current_time (¤t_time); /* We use milliseconds for all times */ elapsed = ((((double)current_time.tv_sec - context->start_time.tv_sec) * G_USEC_PER_SEC + (current_time.tv_usec - context->start_time.tv_usec))) / 1000.0; if (elapsed < 0) { /* Probably the system clock was set backwards? */ meta_warning ("System clock seemed to go backwards?\n"); elapsed = G_MAXDOUBLE; /* definitely done. */ } if (elapsed > context->millisecs_duration) { /* All done */ XDestroyWindow (context->screen->display->xdisplay, context->wireframe_xwindow); g_free (context); return FALSE; } g_assert (context->millisecs_duration > 0.0); fraction = elapsed / context->millisecs_duration; draw_rect = context->start_rect; /* Now add a delta proportional to elapsed time. */ draw_rect.x += (context->end_rect.x - context->start_rect.x) * fraction; draw_rect.y += (context->end_rect.y - context->start_rect.y) * fraction; draw_rect.width += (context->end_rect.width - context->start_rect.width) * fraction; draw_rect.height += (context->end_rect.height - context->start_rect.height) * fraction; /* don't confuse X or gdk-pixbuf with bogus rectangles */ if (draw_rect.width < 1) draw_rect.width = 1; if (draw_rect.height < 1) draw_rect.height = 1; update_wireframe_window (context->screen->display, context->wireframe_xwindow, &draw_rect); /* kick changes onto the server */ XFlush (context->screen->display->xdisplay); return TRUE; }
void draw_box_animation (MetaScreen *screen, MetaRectangle *initial_rect, MetaRectangle *destination_rect, double seconds_duration) { BoxAnimationContext *context; #ifdef HAVE_SHAPE XSetWindowAttributes attrs; #else XGCValues gc_values; #endif g_return_if_fail (seconds_duration > 0.0); if (g_getenv ("MARCO_DEBUG_EFFECTS")) seconds_duration *= 10; /* slow things down */ /* Create the animation context */ context = g_new0 (BoxAnimationContext, 1); context->screen = screen; context->millisecs_duration = seconds_duration * 1000.0; context->start_rect = *initial_rect; context->end_rect = *destination_rect; #ifdef HAVE_SHAPE attrs.override_redirect = True; attrs.background_pixel = BlackPixel (screen->display->xdisplay, screen->number); context->wireframe_xwindow = XCreateWindow (screen->display->xdisplay, screen->xroot, initial_rect->x, initial_rect->y, initial_rect->width, initial_rect->height, 0, CopyFromParent, CopyFromParent, (Visual *)CopyFromParent, CWOverrideRedirect | CWBackPixel, &attrs); update_wireframe_window (screen->display, context->wireframe_xwindow, initial_rect); XMapWindow (screen->display->xdisplay, context->wireframe_xwindow); #else /* !HAVE_SHAPE */ context->first_time = TRUE; gc_values.subwindow_mode = IncludeInferiors; gc_values.function = GXinvert; context->gc = XCreateGC (screen->display->xdisplay, screen->xroot, GCSubwindowMode | GCFunction, &gc_values); /* Grab the X server to avoid screen dirt */ meta_display_grab (context->screen->display); meta_ui_push_delay_exposes (context->screen->ui); #endif /* Do this only after we get the pixbuf from the server, * so that the animation doesn't get truncated. */ g_get_current_time (&context->start_time); /* Add the timeout - a short one, could even use an idle, * but this is maybe more CPU-friendly. */ g_timeout_add (15, (GSourceFunc)effects_draw_box_animation_timeout, context); /* kick changes onto the server */ XFlush (context->screen->display->xdisplay); }
static gboolean effects_draw_box_animation_timeout (BoxAnimationContext *context) { double elapsed; GTimeVal current_time; MetaRectangle draw_rect; double fraction; #ifndef HAVE_SHAPE if (!context->first_time) { /* Restore the previously drawn background */ XDrawRectangle (context->screen->display->xdisplay, context->screen->xroot, context->gc, context->last_rect.x, context->last_rect.y, context->last_rect.width, context->last_rect.height); } else context->first_time = FALSE; #endif /* !HAVE_SHAPE */ g_get_current_time (¤t_time); /* We use milliseconds for all times */ elapsed = ((((double)current_time.tv_sec - context->start_time.tv_sec) * G_USEC_PER_SEC + (current_time.tv_usec - context->start_time.tv_usec))) / 1000.0; if (elapsed < 0) { /* Probably the system clock was set backwards? */ meta_warning ("System clock seemed to go backwards?\n"); elapsed = G_MAXDOUBLE; /* definitely done. */ } if (elapsed > context->millisecs_duration) { /* All done */ #ifdef HAVE_SHAPE XDestroyWindow (context->screen->display->xdisplay, context->wireframe_xwindow); #else meta_display_ungrab (context->screen->display); meta_ui_pop_delay_exposes (context->screen->ui); XFreeGC (context->screen->display->xdisplay, context->gc); #endif /* !HAVE_SHAPE */ graphics_sync (context); g_free (context); return FALSE; } g_assert (context->millisecs_duration > 0.0); fraction = elapsed / context->millisecs_duration; draw_rect = context->start_rect; /* Now add a delta proportional to elapsed time. */ draw_rect.x += (context->end_rect.x - context->start_rect.x) * fraction; draw_rect.y += (context->end_rect.y - context->start_rect.y) * fraction; draw_rect.width += (context->end_rect.width - context->start_rect.width) * fraction; draw_rect.height += (context->end_rect.height - context->start_rect.height) * fraction; /* don't confuse X or gdk-pixbuf with bogus rectangles */ if (draw_rect.width < 1) draw_rect.width = 1; if (draw_rect.height < 1) draw_rect.height = 1; #ifdef HAVE_SHAPE update_wireframe_window (context->screen->display, context->wireframe_xwindow, &draw_rect); #else context->last_rect = draw_rect; /* Draw the rectangle */ XDrawRectangle (context->screen->display->xdisplay, context->screen->xroot, context->gc, draw_rect.x, draw_rect.y, draw_rect.width, draw_rect.height); #endif /* !HAVE_SHAPE */ /* kick changes onto the server */ graphics_sync (context); return TRUE; }
void draw_box_animation (MetaScreen *screen, MetaRectangle *initial_rect, MetaRectangle *destination_rect, double seconds_duration) { BoxAnimationContext *context; XSetWindowAttributes attrs; g_return_if_fail (seconds_duration > 0.0); if (g_getenv ("METACITY_DEBUG_EFFECTS")) seconds_duration *= 10; /* slow things down */ /* Create the animation context */ context = g_new0 (BoxAnimationContext, 1); context->screen = screen; context->millisecs_duration = seconds_duration * 1000.0; context->start_rect = *initial_rect; context->end_rect = *destination_rect; attrs.override_redirect = True; attrs.background_pixel = BlackPixel (screen->display->xdisplay, screen->number); context->wireframe_xwindow = XCreateWindow (screen->display->xdisplay, screen->xroot, initial_rect->x, initial_rect->y, initial_rect->width, initial_rect->height, 0, CopyFromParent, CopyFromParent, (Visual *)CopyFromParent, CWOverrideRedirect | CWBackPixel, &attrs); update_wireframe_window (screen->display, context->wireframe_xwindow, initial_rect); XMapWindow (screen->display->xdisplay, context->wireframe_xwindow); /* Do this only after we get the pixbuf from the server, * so that the animation doesn't get truncated. */ g_get_current_time (&context->start_time); /* Add the timeout - a short one, could even use an idle, * but this is maybe more CPU-friendly. */ g_timeout_add (15, (GSourceFunc)effects_draw_box_animation_timeout, context); /* kick changes onto the server */ XFlush (context->screen->display->xdisplay); }