~muktupavels/metacity/adwaita-icon-theme-lp-1414613

« back to all changes in this revision

Viewing changes to src/core/effects.c

  • Committer: Package Import Robot
  • Author(s): Dmitry Shachnev
  • Date: 2014-11-18 18:13:01 UTC
  • mto: (2.3.7 vivid-proposed)
  • mto: This revision was merged to the branch mainline in revision 135.
  • Revision ID: package-import@ubuntu.com-20141118181301-csmd2xaakfjv48r8
Tags: upstream-3.14.2
ImportĀ upstreamĀ versionĀ 3.14.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 
3
3
/**
4
4
 * \file effects.c "Special effects" other than compositor effects.
5
 
 * 
 
5
 *
6
6
 * Before we had a serious compositor, we supported swooping
7
7
 * rectangles for minimising and so on.  These are still supported
8
8
 * today, even when the compositor is enabled.  The file contains two
36
36
 * In svn r3769 this was made explicit.
37
37
 */
38
38
 
39
 
/* 
 
39
/*
40
40
 * Copyright (C) 2001 Anders Carlsson, Havoc Pennington
41
 
 * 
 
41
 *
42
42
 * This program is free software; you can redistribute it and/or
43
43
 * modify it under the terms of the GNU General Public License as
44
44
 * published by the Free Software Foundation; either version 2 of the
48
48
 * WITHOUT ANY WARRANTY; without even the implied warranty of
49
49
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
50
50
 * General Public License for more details.
51
 
 * 
 
51
 *
52
52
 * You should have received a copy of the GNU General Public License
53
53
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
54
54
 */
95
95
 
96
96
  MetaRectangle start_rect;
97
97
  MetaRectangle end_rect;
98
 
  
 
98
 
99
99
} BoxAnimationContext;
100
100
 
101
101
/**
129
129
    MetaMinimizeEffect      minimize;
130
130
    /* ... and theoretically anything else */
131
131
  } u;
132
 
  
 
132
 
133
133
  MetaEffectPriv *priv;
134
134
};
135
135
 
181
181
{
182
182
  if (effect->priv->finished)
183
183
    effect->priv->finished (effect->priv->finished_data);
184
 
    
 
184
 
185
185
  g_free (effect->priv);
186
186
  g_free (effect);
187
187
}
196
196
    g_return_if_fail (window != NULL);
197
197
 
198
198
    effect = create_effect (META_EFFECT_FOCUS, window, finished, data);
199
 
    
 
199
 
200
200
    run_handler (effect);
201
201
}
202
202
 
211
211
 
212
212
    g_return_if_fail (window != NULL);
213
213
    g_return_if_fail (icon_rect != NULL);
214
 
    
 
214
 
215
215
    effect = create_effect (META_EFFECT_MINIMIZE, window, finished, data);
216
216
 
217
217
    effect->u.minimize.window_rect = *window_rect;
231
231
 
232
232
    g_return_if_fail (window != NULL);
233
233
    g_return_if_fail (icon_rect != NULL);
234
 
    
 
234
 
235
235
    effect = create_effect (META_EFFECT_UNMINIMIZE, window, finished, data);
236
236
 
237
237
    effect->u.minimize.window_rect = *window_rect;
246
246
                       gpointer            data)
247
247
{
248
248
    MetaEffect *effect;
249
 
    
 
249
 
250
250
    g_return_if_fail (window != NULL);
251
251
 
252
252
    effect = create_effect (META_EFFECT_CLOSE, window,
258
258
 
259
259
/* old ugly minimization effect */
260
260
 
261
 
#ifdef HAVE_SHAPE  
 
261
#ifdef HAVE_SHAPE
262
262
static void
263
263
update_wireframe_window (MetaDisplay         *display,
264
264
                         Window               xwindow,
270
270
                     rect->width, rect->height);
271
271
 
272
272
#define OUTLINE_WIDTH 3
273
 
  
 
273
 
274
274
  if (rect->width > OUTLINE_WIDTH * 2 &&
275
275
      rect->height > OUTLINE_WIDTH * 2)
276
276
    {
277
277
      XRectangle xrect;
278
278
      Region inner_xregion;
279
279
      Region outer_xregion;
280
 
      
 
280
 
281
281
      inner_xregion = XCreateRegion ();
282
282
      outer_xregion = XCreateRegion ();
283
283
 
285
285
      xrect.y = 0;
286
286
      xrect.width = rect->width;
287
287
      xrect.height = rect->height;
288
 
  
 
288
 
289
289
      XUnionRectWithRegion (&xrect, outer_xregion, outer_xregion);
290
 
  
 
290
 
291
291
      xrect.x += OUTLINE_WIDTH;
292
292
      xrect.y += OUTLINE_WIDTH;
293
293
      xrect.width -= OUTLINE_WIDTH * 2;
294
 
      xrect.height -= OUTLINE_WIDTH * 2;  
295
 
  
 
294
      xrect.height -= OUTLINE_WIDTH * 2;
 
295
 
296
296
      XUnionRectWithRegion (&xrect, inner_xregion, inner_xregion);
297
297
 
298
298
      XSubtractRegion (outer_xregion, inner_xregion, outer_xregion);
299
299
 
300
300
      XShapeCombineRegion (display->xdisplay, xwindow,
301
301
                           ShapeBounding, 0, 0, outer_xregion, ShapeSet);
302
 
  
 
302
 
303
303
      XDestroyRegion (outer_xregion);
304
304
      XDestroyRegion (inner_xregion);
305
305
    }
320
320
graphics_sync (BoxAnimationContext *context)
321
321
{
322
322
  XImage *image;
323
 
  
 
323
 
324
324
  image = XGetImage (context->screen->display->xdisplay,
325
325
                     context->screen->xroot,
326
326
                     0, 0, 1, 1,
336
336
  GTimeVal current_time;
337
337
  MetaRectangle draw_rect;
338
338
  double fraction;
339
 
  
 
339
 
340
340
#ifndef HAVE_SHAPE
341
341
  if (!context->first_time)
342
342
    {
353
353
#endif /* !HAVE_SHAPE */
354
354
 
355
355
  g_get_current_time (&current_time);
356
 
  
 
356
 
357
357
  /* We use milliseconds for all times */
358
358
  elapsed =
359
359
    ((((double)current_time.tv_sec - context->start_time.tv_sec) * G_USEC_PER_SEC +
360
360
      (current_time.tv_usec - context->start_time.tv_usec))) / 1000.0;
361
 
  
 
361
 
362
362
  if (elapsed < 0)
363
363
    {
364
364
      /* Probably the system clock was set backwards? */
380
380
#endif /* !HAVE_SHAPE */
381
381
 
382
382
      graphics_sync (context);
383
 
      
 
383
 
384
384
      g_free (context);
385
385
      return FALSE;
386
386
    }
387
387
 
388
388
  g_assert (context->millisecs_duration > 0.0);
389
389
  fraction = elapsed / context->millisecs_duration;
390
 
  
 
390
 
391
391
  draw_rect = context->start_rect;
392
 
  
 
392
 
393
393
  /* Now add a delta proportional to elapsed time. */
394
394
  draw_rect.x += (context->end_rect.x - context->start_rect.x) * fraction;
395
395
  draw_rect.y += (context->end_rect.y - context->start_rect.y) * fraction;
396
396
  draw_rect.width += (context->end_rect.width - context->start_rect.width) * fraction;
397
397
  draw_rect.height += (context->end_rect.height - context->start_rect.height) * fraction;
398
 
  
 
398
 
399
399
  /* don't confuse X or gdk-pixbuf with bogus rectangles */
400
400
  if (draw_rect.width < 1)
401
401
    draw_rect.width = 1;
415
415
                  context->gc,
416
416
                  draw_rect.x, draw_rect.y,
417
417
                  draw_rect.width, draw_rect.height);
418
 
    
 
418
 
419
419
#endif /* !HAVE_SHAPE */
420
420
 
421
421
  /* kick changes onto the server */
422
422
  graphics_sync (context);
423
 
  
 
423
 
424
424
  return TRUE;
425
425
}
426
 
 
 
426
 
427
427
void
428
428
draw_box_animation (MetaScreen     *screen,
429
429
                    MetaRectangle  *initial_rect,
437
437
#else
438
438
  XGCValues gc_values;
439
439
#endif
440
 
    
 
440
 
441
441
  g_return_if_fail (seconds_duration > 0.0);
442
442
 
443
443
  if (g_getenv ("METACITY_DEBUG_EFFECTS"))
444
444
    seconds_duration *= 10; /* slow things down */
445
 
  
 
445
 
446
446
  /* Create the animation context */
447
447
  context = g_new0 (BoxAnimationContext, 1);
448
448
 
489
489
                           screen->xroot,
490
490
                           GCSubwindowMode | GCFunction,
491
491
                           &gc_values);
492
 
      
 
492
 
493
493
  /* Grab the X server to avoid screen dirt */
494
494
  meta_display_grab (context->screen->display);
495
495
  meta_ui_push_delay_exposes (context->screen->ui);
499
499
   * so that the animation doesn't get truncated.
500
500
   */
501
501
  g_get_current_time (&context->start_time);
502
 
  
 
502
 
503
503
  /* Add the timeout - a short one, could even use an idle,
504
504
   * but this is maybe more CPU-friendly.
505
505
   */
508
508
                 context);
509
509
 
510
510
  /* kick changes onto the server */
511
 
  XFlush (context->screen->display->xdisplay);  
 
511
  XFlush (context->screen->display->xdisplay);
512
512
}
513
513
 
514
514
void
519
519
{
520
520
  /* Grab the X server to avoid screen dirt */
521
521
  meta_display_grab (screen->display);
522
 
  meta_ui_push_delay_exposes (screen->ui);  
 
522
  meta_ui_push_delay_exposes (screen->ui);
523
523
 
524
 
  meta_effects_update_wireframe (screen, 
 
524
  meta_effects_update_wireframe (screen,
525
525
                                 NULL, -1, -1,
526
526
                                 rect, width, height);
527
527
}
539
539
  XSegment segments[8];
540
540
  MetaRectangle shrunk_rect;
541
541
  int i;
542
 
  
 
542
 
543
543
#define LINE_WIDTH META_WIREFRAME_XOR_LINE_WIDTH
544
544
 
545
545
  /* We don't want the wireframe going outside the window area.
569
569
      XGCValues gc_values = { 0 };
570
570
 
571
571
      if (XGetGCValues (screen->display->xdisplay,
572
 
                        screen->root_xor_gc, 
 
572
                        screen->root_xor_gc,
573
573
                        GCFont, &gc_values))
574
574
        {
575
575
          char *text;
576
576
          int text_length;
577
577
 
578
578
          XFontStruct *font_struct;
579
 
          int text_width, text_height; 
 
579
          int text_width, text_height;
580
580
          int box_x, box_y;
581
581
          int box_width, box_height;
582
582
 
589
589
              text_length = strlen (text);
590
590
 
591
591
              text_width = text_length * font_struct->max_bounds.width;
592
 
              text_height = font_struct->max_bounds.descent + 
 
592
              text_height = font_struct->max_bounds.descent +
593
593
                            font_struct->max_bounds.ascent;
594
594
 
595
595
              box_width = text_width + 2 * LINE_WIDTH;
607
607
                                  screen->root_xor_gc,
608
608
                                  box_x, box_y,
609
609
                                  box_width, box_height);
610
 
                  XDrawString (screen->display->xdisplay, 
 
610
                  XDrawString (screen->display->xdisplay,
611
611
                               screen->xroot,
612
612
                               screen->root_xor_gc,
613
613
                               box_x + LINE_WIDTH,
632
632
  segments[0].x1 = shrunk_rect.x + shrunk_rect.width / 3;
633
633
  segments[0].y1 = shrunk_rect.y + LINE_WIDTH / 2 + LINE_WIDTH % 2;
634
634
  segments[0].x2 = segments[0].x1;
635
 
  segments[0].y2 = shrunk_rect.y + shrunk_rect.height - LINE_WIDTH / 2;  
 
635
  segments[0].y2 = shrunk_rect.y + shrunk_rect.height - LINE_WIDTH / 2;
636
636
 
637
637
  segments[1] = segments[0];
638
638
  segments[1].x1 = shrunk_rect.x + (shrunk_rect.width / 3) * 2;
650
650
  segments[3] = segments[2];
651
651
  segments[3].x1 = segments[2].x2 + LINE_WIDTH;
652
652
  segments[3].x2 = segments[1].x1 - LINE_WIDTH / 2;
653
 
  
 
653
 
654
654
  segments[4] = segments[3];
655
655
  segments[4].x1 = segments[3].x2 + LINE_WIDTH;
656
656
  segments[4].x2 = shrunk_rect.x + shrunk_rect.width - LINE_WIDTH / 2;
666
666
      segments[i].y2 = segments[i].y1;
667
667
      ++i;
668
668
    }
669
 
  
 
669
 
670
670
  XDrawSegments (screen->display->xdisplay,
671
671
                 screen->xroot,
672
672
                 screen->root_xor_gc,
685
685
{
686
686
  if (old_rect)
687
687
    draw_xor_rect (screen, old_rect, old_width, old_height);
688
 
    
 
688
 
689
689
  if (new_rect)
690
690
    draw_xor_rect (screen, new_rect, new_width, new_height);
691
 
    
 
691
 
692
692
  XFlush (screen->display->xdisplay);
693
693
}
694
694
 
698
698
                            int                  old_width,
699
699
                            int                  old_height)
700
700
{
701
 
  meta_effects_update_wireframe (screen, 
 
701
  meta_effects_update_wireframe (screen,
702
702
                                 old_rect, old_width, old_height,
703
703
                                 NULL, -1, -1);
704
 
  
 
704
 
705
705
  meta_display_ungrab (screen->display);
706
706
  meta_ui_pop_delay_exposes (screen->ui);
707
707
}