Esempio n. 1
0
static gboolean
effects_draw_box_animation_timeout (BoxAnimationContext *context)
{
  double elapsed;
  GTimeVal current_time;
  MetaRectangle draw_rect;
  double fraction;

  g_get_current_time (&current_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;
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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 (&current_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;
}
Esempio n. 4
0
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);
}