~townsend/compiz/fix-decoration-grab-0.9.10

« back to all changes in this revision

Viewing changes to libdecoration/decoration.c

  • Committer: David Reveman
  • Date: 2006-11-26 17:11:17 UTC
  • Revision ID: git-v1:a8d0c31f1aafcd6132864299dffd1d20428a9f36
Add libdecoration and move some initial code from gtk-window-decorator into it.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright © 2006 Novell, Inc.
 
3
 *
 
4
 * This library is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU Lesser General Public
 
6
 * License as published by the Free Software Foundation; either
 
7
 * version 2 of the License, or (at your option) any later version.
 
8
 *
 
9
 * This library is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
12
 * Lesser General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU Lesser General Public
 
15
 * License along with this library; if not, write to the
 
16
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
17
 * Boston, MA 02111-1307, USA.
 
18
 */
 
19
 
 
20
#ifdef HAVE_CONFIG_H
 
21
#include <config.h>
 
22
#endif
 
23
 
 
24
#include <decoration.h>
 
25
 
 
26
/*
 
27
  decoration property
 
28
  -------------------
 
29
 
 
30
  data[0] = version
 
31
 
 
32
  data[1] = pixmap
 
33
 
 
34
  data[2] = input left
 
35
  data[3] = input right
 
36
  data[4] = input top
 
37
  data[5] = input bottom
 
38
 
 
39
  data[6] = input left when maximized
 
40
  data[7] = input right when maximized
 
41
  data[8] = input top when maximized
 
42
  data[9] = input bottom when maximized
 
43
 
 
44
  data[10] = min width
 
45
  data[11] = min height
 
46
 
 
47
  flags
 
48
 
 
49
  1st to 4nd bit p1 gravity, 5rd to 8th bit p2 gravity,
 
50
  9rd and 10th bit alignment, 11rd and 12th bit clamp,
 
51
  13th bit XX, 14th bit XY, 15th bit YX, 16th bit YY.
 
52
 
 
53
  data[11 + n * 9 + 1] = flags
 
54
  data[11 + n * 9 + 2] = p1 x
 
55
  data[11 + n * 9 + 3] = p1 y
 
56
  data[11 + n * 9 + 4] = p2 x
 
57
  data[11 + n * 9 + 5] = p2 y
 
58
  data[11 + n * 9 + 6] = widthMax
 
59
  data[11 + n * 9 + 7] = heightMax
 
60
  data[11 + n * 9 + 8] = x0
 
61
  data[11 + n * 9 + 9] = y0
 
62
 */
 
63
void
 
64
decor_quads_to_property (long            *data,
 
65
                         Pixmap          pixmap,
 
66
                         decor_extents_t *input,
 
67
                         decor_extents_t *max_input,
 
68
                         int             min_width,
 
69
                         int             min_height,
 
70
                         decor_quad_t    *quad,
 
71
                         int             nQuad)
 
72
{
 
73
    *data++ = DECOR_INTERFACE_VERSION;
 
74
 
 
75
    memcpy (data++, &pixmap, sizeof (Pixmap));
 
76
 
 
77
    *data++ = input->left;
 
78
    *data++ = input->right;
 
79
    *data++ = input->top;
 
80
    *data++ = input->bottom;
 
81
 
 
82
    *data++ = max_input->left;
 
83
    *data++ = max_input->right;
 
84
    *data++ = max_input->top;
 
85
    *data++ = max_input->bottom;
 
86
 
 
87
    *data++ = min_width;
 
88
    *data++ = min_height;
 
89
 
 
90
    while (nQuad--)
 
91
    {
 
92
        *data++ =
 
93
            (quad->p1.gravity << 0)    |
 
94
            (quad->p2.gravity << 4)    |
 
95
            (quad->align      << 8)    |
 
96
            (quad->clamp      << 10)   |
 
97
            (quad->m.xx ? XX_MASK : 0) |
 
98
            (quad->m.xy ? XY_MASK : 0) |
 
99
            (quad->m.yx ? YX_MASK : 0) |
 
100
            (quad->m.yy ? YY_MASK : 0);
 
101
 
 
102
        *data++ = quad->p1.x;
 
103
        *data++ = quad->p1.y;
 
104
        *data++ = quad->p2.x;
 
105
        *data++ = quad->p2.y;
 
106
        *data++ = quad->max_width;
 
107
        *data++ = quad->max_height;
 
108
        *data++ = quad->m.x0;
 
109
        *data++ = quad->m.y0;
 
110
 
 
111
        quad++;
 
112
    }
 
113
}
 
114
 
 
115
int
 
116
decor_set_horz_quad_line (decor_quad_t *q,
 
117
                          int          left,
 
118
                          int          left_corner,
 
119
                          int          right,
 
120
                          int          right_corner,
 
121
                          int          top,
 
122
                          int          bottom,
 
123
                          int          gravity,
 
124
                          int          width,
 
125
                          double       x0,
 
126
                          double       y0)
 
127
{
 
128
    int dx, nQuad = 0;
 
129
 
 
130
    dx = (left_corner - right_corner) >> 1;
 
131
 
 
132
    q->p1.x       = -left;
 
133
    q->p1.y       = top;
 
134
    q->p1.gravity = gravity | GRAVITY_WEST;
 
135
    q->p2.x       = dx;
 
136
    q->p2.y       = bottom;
 
137
    q->p2.gravity = gravity;
 
138
    q->max_width  = left + left_corner;
 
139
    q->max_height = SHRT_MAX;
 
140
    q->align      = ALIGN_LEFT;
 
141
    q->clamp      = 0;
 
142
    q->m.xx       = 1.0;
 
143
    q->m.xy       = 0.0;
 
144
    q->m.yx       = 0.0;
 
145
    q->m.yy       = 1.0;
 
146
    q->m.x0       = x0;
 
147
    q->m.y0       = y0;
 
148
 
 
149
    q++; nQuad++;
 
150
 
 
151
    q->p1.x       = left_corner;
 
152
    q->p1.y       = top;
 
153
    q->p1.gravity = gravity | GRAVITY_WEST;
 
154
    q->p2.x       = -right_corner;
 
155
    q->p2.y       = bottom;
 
156
    q->p2.gravity = gravity | GRAVITY_EAST;
 
157
    q->max_width  = SHRT_MAX;
 
158
    q->max_height = SHRT_MAX;
 
159
    q->align      = 0;
 
160
    q->clamp      = 0;
 
161
    q->m.xx       = 0.0;
 
162
    q->m.xy       = 0.0;
 
163
    q->m.yx       = 0.0;
 
164
    q->m.yy       = 1.0;
 
165
    q->m.x0       = x0 + left + left_corner;
 
166
    q->m.y0       = y0;
 
167
 
 
168
    q++; nQuad++;
 
169
 
 
170
    q->p1.x       = dx;
 
171
    q->p1.y       = top;
 
172
    q->p1.gravity = gravity;
 
173
    q->p2.x       = right;
 
174
    q->p2.y       = bottom;
 
175
    q->p2.gravity = gravity | GRAVITY_EAST;
 
176
    q->max_width  = right_corner + right;
 
177
    q->max_height = SHRT_MAX;
 
178
    q->align      = ALIGN_RIGHT;
 
179
    q->clamp      = 0;
 
180
    q->m.xx       = 1.0;
 
181
    q->m.xy       = 0.0;
 
182
    q->m.yx       = 0.0;
 
183
    q->m.yy       = 1.0;
 
184
    q->m.x0       = x0 + width;
 
185
    q->m.y0       = y0;
 
186
 
 
187
    nQuad++;
 
188
 
 
189
    return nQuad;
 
190
}
 
191
 
 
192
int
 
193
decor_set_vert_quad_row (decor_quad_t *q,
 
194
                         int          top,
 
195
                         int          top_corner,
 
196
                         int          bottom,
 
197
                         int          bottom_corner,
 
198
                         int          left,
 
199
                         int          right,
 
200
                         int          gravity,
 
201
                         int          height,
 
202
                         double       x0,
 
203
                         double       y0)
 
204
{
 
205
    int dy, nQuad = 0;
 
206
 
 
207
    dy = (top_corner - bottom_corner) >> 1;
 
208
 
 
209
    q->p1.x       = left;
 
210
    q->p1.y       = -top;
 
211
    q->p1.gravity = gravity | GRAVITY_NORTH;
 
212
    q->p2.x       = right;
 
213
    q->p2.y       = dy;
 
214
    q->p2.gravity = gravity;
 
215
    q->max_width  = SHRT_MAX;
 
216
    q->max_height = top + top_corner;
 
217
    q->align      = ALIGN_TOP;
 
218
    q->clamp      = CLAMP_VERT;
 
219
    q->m.xx       = 1.0;
 
220
    q->m.xy       = 0.0;
 
221
    q->m.yx       = 0.0;
 
222
    q->m.yy       = 1.0;
 
223
    q->m.x0       = x0;
 
224
    q->m.y0       = y0;
 
225
 
 
226
    q++; nQuad++;
 
227
 
 
228
    q->p1.x       = left;
 
229
    q->p1.y       = top_corner;
 
230
    q->p1.gravity = gravity | GRAVITY_NORTH;
 
231
    q->p2.x       = right;
 
232
    q->p2.y       = -bottom_corner;
 
233
    q->p2.gravity = gravity | GRAVITY_SOUTH;
 
234
    q->max_width  = SHRT_MAX;
 
235
    q->max_height = SHRT_MAX;
 
236
    q->align      = 0;
 
237
    q->clamp      = CLAMP_VERT;
 
238
    q->m.xx       = 1.0;
 
239
    q->m.xy       = 0.0;
 
240
    q->m.yx       = 0.0;
 
241
    q->m.yy       = 0.0;
 
242
    q->m.x0       = x0;
 
243
    q->m.y0       = y0 + top + top_corner;
 
244
 
 
245
    q++; nQuad++;
 
246
 
 
247
    q->p1.x       = left;
 
248
    q->p1.y       = dy;
 
249
    q->p1.gravity = gravity;
 
250
    q->p2.x       = right;
 
251
    q->p2.y       = bottom;
 
252
    q->p2.gravity = gravity | GRAVITY_SOUTH;
 
253
    q->max_width  = SHRT_MAX;
 
254
    q->max_height = bottom_corner + bottom;
 
255
    q->align      = ALIGN_BOTTOM;
 
256
    q->clamp      = CLAMP_VERT;
 
257
    q->m.xx       = 1.0;
 
258
    q->m.xy       = 0.0;
 
259
    q->m.yx       = 0.0;
 
260
    q->m.yy       = 1.0;
 
261
    q->m.x0       = x0;
 
262
    q->m.y0       = y0 + height;
 
263
 
 
264
    nQuad++;
 
265
 
 
266
    return nQuad;
 
267
}
 
268
 
 
269
int
 
270
decor_set_common_window_quads (decor_context_t *c,
 
271
                               decor_quad_t    *q,
 
272
                               int             width,
 
273
                               int             height)
 
274
{
 
275
    int n, nQuad = 0;
 
276
 
 
277
    /* left quads */
 
278
    n = decor_set_vert_quad_row (q,
 
279
                                 0,
 
280
                                 c->top_corner_space,
 
281
                                 0,
 
282
                                 c->bottom_corner_space,
 
283
                                 -c->left_space,
 
284
                                 0,
 
285
                                 GRAVITY_WEST,
 
286
                                 height - c->top_space - c->titlebar_height -
 
287
                                 c->bottom_space,
 
288
                                 0.0,
 
289
                                 c->top_space + c->titlebar_height + 1.0);
 
290
 
 
291
    q += n; nQuad += n;
 
292
 
 
293
    /* right quads */
 
294
    n = decor_set_vert_quad_row (q,
 
295
                                 0,
 
296
                                 c->top_corner_space,
 
297
                                 0,
 
298
                                 c->bottom_corner_space,
 
299
                                 0,
 
300
                                 c->right_space,
 
301
                                 GRAVITY_EAST,
 
302
                                 height - c->top_space - c->titlebar_height -
 
303
                                 c->bottom_space,
 
304
                                 width - c->right_space,
 
305
                                 c->top_space + c->titlebar_height + 1.0);
 
306
 
 
307
    q += n; nQuad += n;
 
308
 
 
309
    /* bottom quads */
 
310
    n = decor_set_horz_quad_line (q,
 
311
                                  c->left_space,
 
312
                                  c->left_corner_space,
 
313
                                  c->right_space,
 
314
                                  c->right_corner_space,
 
315
                                  0,
 
316
                                  c->bottom_space,
 
317
                                  GRAVITY_SOUTH,
 
318
                                  width,
 
319
                                  0.0,
 
320
                                  c->top_space + c->titlebar_height +
 
321
                                  c->top_corner_space +
 
322
                                  c->bottom_corner_space + 2.0);
 
323
 
 
324
    nQuad += n;
 
325
 
 
326
    return nQuad;
 
327
}
 
328
 
 
329
int
 
330
decor_set_window_quads (decor_context_t *c,
 
331
                        decor_quad_t    *q,
 
332
                        int             width,
 
333
                        int             height,
 
334
                        int             button_width)
 
335
{
 
336
    int     n, nQuad = 0;
 
337
    int     top_left, top_right, y;
 
338
    double  y0;
 
339
 
 
340
    top_right = button_width;
 
341
    top_left  = width - c->left_space - c->right_space - top_right - 1;
 
342
 
 
343
    /* special case which can happen with large shadows */
 
344
    if (c->right_corner_space > top_right || c->left_corner_space > top_left)
 
345
    {
 
346
        y  = -c->titlebar_height;
 
347
        y0 = c->top_space;
 
348
 
 
349
        /* top quads */
 
350
        n = decor_set_horz_quad_line (q,
 
351
                                      c->left_space,
 
352
                                      c->left_corner_space,
 
353
                                      c->right_space,
 
354
                                      c->right_corner_space,
 
355
                                      -c->top_space - c->titlebar_height,
 
356
                                      y,
 
357
                                      GRAVITY_NORTH,
 
358
                                      width,
 
359
                                      0.0,
 
360
                                      0.0);
 
361
 
 
362
        q += n; nQuad += n;
 
363
    }
 
364
    else
 
365
    {
 
366
        y  = -c->top_space - c->titlebar_height;
 
367
        y0 = 0.0;
 
368
    }
 
369
 
 
370
    /* 3 top/titlebar quads */
 
371
    q->p1.x       = -c->left_space;
 
372
    q->p1.y       = y;
 
373
    q->p1.gravity = GRAVITY_NORTH | GRAVITY_WEST;
 
374
    q->p2.x       = -top_right;
 
375
    q->p2.y       = 0;
 
376
    q->p2.gravity = GRAVITY_NORTH | GRAVITY_EAST;
 
377
    q->max_width  = c->left_space + top_left;
 
378
    q->max_height = SHRT_MAX;
 
379
    q->align      = ALIGN_LEFT;
 
380
    q->clamp      = 0;
 
381
    q->m.xx       = 1.0;
 
382
    q->m.xy       = 0.0;
 
383
    q->m.yx       = 0.0;
 
384
    q->m.yy       = 1.0;
 
385
    q->m.x0       = 0.0;
 
386
    q->m.y0       = y0;
 
387
 
 
388
    q++; nQuad++;
 
389
 
 
390
    q->p1.x       = top_left;
 
391
    q->p1.y       = y;
 
392
    q->p1.gravity = GRAVITY_NORTH | GRAVITY_WEST;
 
393
    q->p2.x       = -top_right;
 
394
    q->p2.y       = 0;
 
395
    q->p2.gravity = GRAVITY_NORTH | GRAVITY_EAST;
 
396
    q->max_width  = SHRT_MAX;
 
397
    q->max_height = SHRT_MAX;
 
398
    q->align      = 0;
 
399
    q->clamp      = 0;
 
400
    q->m.xx       = 0.0;
 
401
    q->m.xy       = 0.0;
 
402
    q->m.yx       = 0.0;
 
403
    q->m.yy       = 1.0;
 
404
    q->m.x0       = c->left_space + top_left;
 
405
    q->m.y0       = y0;
 
406
 
 
407
    q++; nQuad++;
 
408
 
 
409
    q->p1.x       = 0;
 
410
    q->p1.y       = y;
 
411
    q->p1.gravity = GRAVITY_NORTH | GRAVITY_WEST;
 
412
    q->p2.x       = c->right_space;
 
413
    q->p2.y       = 0;
 
414
    q->p2.gravity = GRAVITY_NORTH | GRAVITY_EAST;
 
415
    q->max_width  = c->right_space + top_right;
 
416
    q->max_height = SHRT_MAX;
 
417
    q->align      = ALIGN_RIGHT;
 
418
    q->clamp      = 0;
 
419
    q->m.xx       = 1.0;
 
420
    q->m.xy       = 0.0;
 
421
    q->m.yx       = 0.0;
 
422
    q->m.yy       = 1.0;
 
423
    q->m.x0       = width;
 
424
    q->m.y0       = y0;
 
425
 
 
426
    q++; nQuad++;
 
427
 
 
428
    n = decor_set_common_window_quads (c, q, width, height);
 
429
 
 
430
    nQuad += n;
 
431
 
 
432
    return nQuad;
 
433
}
 
434
 
 
435
int
 
436
decor_set_no_title_window_quads (decor_context_t *c,
 
437
                                 decor_quad_t    *q,
 
438
                                 int             width,
 
439
                                 int             height)
 
440
{
 
441
    int n, nQuad = 0;
 
442
 
 
443
    /* top quads */
 
444
    n = decor_set_horz_quad_line (q,
 
445
                                  c->left_space,
 
446
                                  c->left_corner_space,
 
447
                                  c->right_space,
 
448
                                  c->right_corner_space,
 
449
                                  -c->top_space - c->titlebar_height,
 
450
                                  0,
 
451
                                  GRAVITY_NORTH,
 
452
                                  width,
 
453
                                  0.0,
 
454
                                  0.0);
 
455
 
 
456
    q += n; nQuad += n;
 
457
 
 
458
    n = decor_set_common_window_quads (c, q, width, height);
 
459
 
 
460
    nQuad += n;
 
461
 
 
462
    return nQuad;
 
463
}
 
464
 
 
465
int
 
466
decor_set_shadow_quads (decor_context_t *c,
 
467
                        decor_quad_t    *q,
 
468
                        int             width,
 
469
                        int             height)
 
470
{
 
471
    int n, nQuad = 0;
 
472
 
 
473
    /* top quads */
 
474
    n = decor_set_horz_quad_line (q,
 
475
                                  c->left_space,
 
476
                                  c->left_corner_space,
 
477
                                  c->right_space,
 
478
                                  c->right_corner_space,
 
479
                                  -c->top_space,
 
480
                                  0,
 
481
                                  GRAVITY_NORTH,
 
482
                                  width,
 
483
                                  0.0,
 
484
                                  0.0);
 
485
 
 
486
    q += n; nQuad += n;
 
487
 
 
488
    /* left quads */
 
489
    n = decor_set_vert_quad_row (q,
 
490
                                 0,
 
491
                                 c->top_corner_space,
 
492
                                 0,
 
493
                                 c->bottom_corner_space,
 
494
                                 -c->left_space,
 
495
                                 0,
 
496
                                 GRAVITY_WEST,
 
497
                                 height - c->top_space - c->bottom_space,
 
498
                                 0.0,
 
499
                                 c->top_space);
 
500
 
 
501
    q += n; nQuad += n;
 
502
 
 
503
    /* right quads */
 
504
    n = decor_set_vert_quad_row (q,
 
505
                                 0,
 
506
                                 c->top_corner_space,
 
507
                                 0,
 
508
                                 c->bottom_corner_space,
 
509
                                 0,
 
510
                                 c->right_space,
 
511
                                 GRAVITY_EAST,
 
512
                                 height - c->top_space - c->bottom_space,
 
513
                                 width - c->right_space,
 
514
                                 c->top_space);
 
515
 
 
516
    q += n; nQuad += n;
 
517
 
 
518
    /* bottom quads */
 
519
    n = decor_set_horz_quad_line (q,
 
520
                                  c->left_space,
 
521
                                  c->left_corner_space,
 
522
                                  c->right_space,
 
523
                                  c->right_corner_space,
 
524
                                  0,
 
525
                                  c->bottom_space,
 
526
                                  GRAVITY_SOUTH,
 
527
                                  width,
 
528
                                  0.0,
 
529
                                  c->top_space + c->top_corner_space +
 
530
                                  c->bottom_corner_space + 1.0);
 
531
 
 
532
    nQuad += n;
 
533
 
 
534
    return nQuad;
 
535
}