~ubuntu-branches/ubuntu/trusty/compiz/trusty

« back to all changes in this revision

Viewing changes to plugins/ezoom/src/ezoom.cpp

  • Committer: Package Import Robot
  • Author(s): Ubuntu daily release
  • Date: 2013-08-22 06:58:07 UTC
  • mto: This revision was merged to the branch mainline in revision 3352.
  • Revision ID: package-import@ubuntu.com-20130822065807-17nlzez0d30y09so
Tags: upstream-0.9.10+13.10.20130822
ImportĀ upstreamĀ versionĀ 0.9.10+13.10.20130822

Show diffs side-by-side

added added

removed removed

Lines of Context:
79
79
 
80
80
/*
81
81
 * This toggles paint functions. We don't need to continually run code when we
82
 
 * are not doing anything
 
82
 * are not doing anything.
83
83
 */
84
84
static inline void
85
85
toggleFunctions (bool state)
102
102
        return false;
103
103
    else if ((unsigned int) out >= zs->zooms.size ())
104
104
        zs->zooms.resize (screen->outputDevs ().size ());
 
105
 
105
106
    return true;
106
107
}
107
108
 
113
114
 
114
115
    if (!outputIsZoomArea (out))
115
116
        return false;
 
117
 
116
118
    if (zs->grabbed & (1 << zs->zooms.at (out).output))
117
119
        return true;
 
120
 
118
121
    return false;
119
122
}
120
123
 
121
124
/* Check if we are zoomed out and not going anywhere
122
 
 * (similar to isActive but based on actual zoom, not grab)
 
125
 * (similar to isActive but based on actual zoom, not grab).
123
126
 */
124
127
static inline bool
125
128
isZoomed (int out)
129
132
    if (!outputIsZoomArea (out))
130
133
        return false;
131
134
 
132
 
    if (zs->zooms.at (out).currentZoom != 1.0f
133
 
        || zs->zooms.at (out).newZoom != 1.0f)
134
 
        return true;
135
 
 
136
 
    if (zs->zooms.at (out).zVelocity != 0.0f)
 
135
    if (zs->zooms.at (out).currentZoom != 1.0f  ||
 
136
        zs->zooms.at (out).newZoom     != 1.0f  ||
 
137
        zs->zooms.at (out).zVelocity   != 0.0f)
137
138
        return true;
138
139
 
139
140
    return false;
141
142
 
142
143
/* Returns the distance to the defined edge in zoomed pixels.  */
143
144
int
144
 
EZoomScreen::distanceToEdge (int out, EZoomScreen::ZoomEdge edge)
 
145
EZoomScreen::distanceToEdge (int                   out,
 
146
                             EZoomScreen::ZoomEdge edge)
145
147
{
146
 
    int        x1,y1,x2,y2;
147
148
    CompOutput *o = &screen->outputDevs ().at (out);
148
149
 
149
150
    if (!isActive (out))
150
151
        return 0;
 
152
 
 
153
    int x1, y1, x2, y2;
 
154
 
151
155
    convertToZoomedTarget (out, o->region ()->extents.x2,
152
156
                           o->region ()->extents.y2, &x2, &y2);
153
157
    convertToZoomedTarget (out, o->region ()->extents.x1,
154
158
                           o->region ()->extents.y1, &x1, &y1);
155
159
    switch (edge)
156
160
    {
 
161
        case WEST:  return o->region ()->extents.x1 - x1;
157
162
        case NORTH: return o->region ()->extents.y1 - y1;
 
163
        case EAST:  return x2 - o->region ()->extents.x2;
158
164
        case SOUTH: return y2 - o->region ()->extents.y2;
159
 
        case EAST: return x2 - o->region ()->extents.x2;
160
 
        case WEST: return o->region ()->extents.x1 - x1;
161
165
    }
 
166
 
162
167
    return 0; // Never reached.
163
168
}
164
169
 
165
 
/* Update/set translations based on zoom level and real translate.  */
 
170
/* Update/set translations based on zoom level and real translate. */
166
171
void
167
172
EZoomScreen::ZoomArea::updateActualTranslates ()
168
173
{
169
174
    xtrans = -realXTranslate * (1.0f - currentZoom);
170
 
    ytrans = realYTranslate * (1.0f - currentZoom);
 
175
    ytrans =  realYTranslate * (1.0f - currentZoom);
171
176
}
172
177
 
173
178
/* Returns true if the head in question is currently moving.
178
183
bool
179
184
EZoomScreen::isInMovement (int out)
180
185
{
181
 
    if (zooms.at (out).currentZoom == 1.0f &&
182
 
        zooms.at (out).newZoom == 1.0f &&
183
 
        zooms.at (out).zVelocity == 0.0f)
 
186
    if (zooms.at (out).currentZoom == 1.0f  &&
 
187
        zooms.at (out).newZoom     == 1.0f  &&
 
188
        zooms.at (out).zVelocity   == 0.0f)
184
189
        return false;
185
 
    if (zooms.at (out).currentZoom != zooms.at (out).newZoom ||
186
 
        zooms.at (out).xVelocity || zooms.at (out).yVelocity ||
187
 
        zooms.at (out).zVelocity)
188
 
        return true;
189
 
    if (zooms.at (out).xTranslate != zooms.at (out).realXTranslate ||
 
190
 
 
191
    if (zooms.at (out).currentZoom != zooms.at (out).newZoom        ||
 
192
        zooms.at (out).xVelocity                                    ||
 
193
        zooms.at (out).yVelocity                                    ||
 
194
        zooms.at (out).zVelocity                                    ||
 
195
        zooms.at (out).xTranslate != zooms.at (out).realXTranslate  ||
190
196
        zooms.at (out).yTranslate != zooms.at (out).realYTranslate)
191
197
        return true;
 
198
 
192
199
    return false;
193
200
}
194
201
 
205
212
    yTranslate (0.0f),
206
213
    realXTranslate (0.0f),
207
214
    realYTranslate (0.0f),
 
215
    xtrans (0.0f),
 
216
    ytrans (0.0f),
208
217
    locked (false)
209
218
{
210
219
    updateActualTranslates ();
222
231
    yTranslate (0.0f),
223
232
    realXTranslate (0.0f),
224
233
    realYTranslate (0.0f),
 
234
    xtrans (0.0f),
 
235
    ytrans (0.0f),
225
236
    locked (false)
226
237
{
227
238
}
228
 
/* Adjust the velocity in the z-direction.  */
 
239
 
 
240
/* Adjust the velocity in the z-direction. */
229
241
void
230
 
EZoomScreen::adjustZoomVelocity (int out, float chunk)
 
242
EZoomScreen::adjustZoomVelocity (int   out,
 
243
                                 float chunk)
231
244
{
232
 
    float d, adjust, amount;
233
 
 
234
 
    d = (zooms.at (out).newZoom - zooms.at (out).currentZoom) * 75.0f;
235
 
 
236
 
    adjust = d * 0.002f;
237
 
    amount = fabs (d);
 
245
    float d      = (zooms.at (out).newZoom - zooms.at (out).currentZoom) * 75.0f;
 
246
    float adjust = d * 0.002f;
 
247
    float amount = fabs (d);
 
248
 
238
249
    if (amount < 1.0f)
239
250
        amount = 1.0f;
240
251
    else if (amount > 5.0f)
241
252
        amount = 5.0f;
242
253
 
243
 
    zooms.at (out).zVelocity =
244
 
        (amount * zooms.at (out).zVelocity + adjust) / (amount + 1.0f);
 
254
    zooms.at (out).zVelocity = (amount * zooms.at (out).zVelocity + adjust) /
 
255
                               (amount + 1.0f);
245
256
 
246
257
    if (fabs (d) < 0.1f && fabs (zooms.at (out).zVelocity) < 0.005f)
247
258
    {
248
259
        zooms.at (out).currentZoom = zooms.at (out).newZoom;
249
 
        zooms.at (out).zVelocity = 0.0f;
 
260
        zooms.at (out).zVelocity   = 0.0f;
250
261
    }
251
262
    else
252
 
    {
253
263
        zooms.at (out).currentZoom += (zooms.at (out).zVelocity * chunk) /
254
 
            cScreen->redrawTime ();
255
 
    }
 
264
                                      cScreen->redrawTime ();
256
265
}
257
266
 
258
267
/* Adjust the X/Y velocity based on target translation and real
259
268
 * translation. */
260
269
void
261
 
EZoomScreen::adjustXYVelocity (int out, float chunk)
 
270
EZoomScreen::adjustXYVelocity (int   out,
 
271
                               float chunk)
262
272
{
263
 
    float xdiff, ydiff;
264
 
    float xadjust, yadjust;
265
 
    float xamount, yamount;
266
 
 
267
273
    zooms.at (out).xVelocity /= 1.25f;
268
274
    zooms.at (out).yVelocity /= 1.25f;
269
 
    xdiff =
270
 
        (zooms.at (out).xTranslate - zooms.at (out).realXTranslate) *
271
 
        75.0f;
272
 
    ydiff =
273
 
        (zooms.at (out).yTranslate - zooms.at (out).realYTranslate) *
274
 
        75.0f;
275
 
    xadjust = xdiff * 0.002f;
276
 
    yadjust = ydiff * 0.002f;
277
 
    xamount = fabs (xdiff);
278
 
    yamount = fabs (ydiff);
 
275
 
 
276
    float xdiff =
 
277
        (zooms.at (out).xTranslate - zooms.at (out).realXTranslate) * 75.0f;
 
278
    float ydiff =
 
279
        (zooms.at (out).yTranslate - zooms.at (out).realYTranslate) * 75.0f;
 
280
 
 
281
    float xadjust = xdiff * 0.002f;
 
282
    float yadjust = ydiff * 0.002f;
 
283
    float xamount = fabs (xdiff);
 
284
    float yamount = fabs (ydiff);
279
285
 
280
286
    if (xamount < 1.0f)
281
 
            xamount = 1.0f;
 
287
        xamount = 1.0f;
282
288
    else if (xamount > 5.0)
283
 
            xamount = 5.0f;
 
289
        xamount = 5.0f;
284
290
 
285
291
    if (yamount < 1.0f)
286
 
            yamount = 1.0f;
 
292
        yamount = 1.0f;
287
293
    else if (yamount > 5.0)
288
 
            yamount = 5.0f;
 
294
        yamount = 5.0f;
289
295
 
290
296
    zooms.at (out).xVelocity =
291
297
        (xamount * zooms.at (out).xVelocity + xadjust) / (xamount + 1.0f);
297
303
    {
298
304
        zooms.at (out).realXTranslate = zooms.at (out).xTranslate;
299
305
        zooms.at (out).realYTranslate = zooms.at (out).yTranslate;
300
 
        zooms.at (out).xVelocity = 0.0f;
301
 
        zooms.at (out).yVelocity = 0.0f;
 
306
        zooms.at (out).xVelocity      = 0.0f;
 
307
        zooms.at (out).yVelocity      = 0.0f;
302
308
        return;
303
309
    }
304
310
 
308
314
        (zooms.at (out).yVelocity * chunk) / cScreen->redrawTime ();
309
315
}
310
316
 
311
 
/* Animate the movement (if any) in preparation of a paint screen.  */
 
317
/* Animate the movement (if any) in preparation of a paint screen. */
312
318
void
313
 
EZoomScreen::preparePaint (int     msSinceLastPaint)
 
319
EZoomScreen::preparePaint (int msSinceLastPaint)
314
320
{
315
321
    if (grabbed)
316
322
    {
317
 
        int   steps;
318
 
        float amount, chunk;
 
323
        float amount = msSinceLastPaint * 0.05f * optionGetSpeed ();
 
324
        int   steps  = amount / (0.5f * optionGetTimestep ());
319
325
 
320
 
        amount = msSinceLastPaint * 0.05f * optionGetSpeed ();
321
 
        steps  = amount / (0.5f * optionGetTimestep ());
322
326
        if (!steps)
323
 
                steps = 1;
324
 
        chunk  = amount / (float) steps;
 
327
            steps = 1;
 
328
 
 
329
        float chunk  = amount / (float) steps;
 
330
 
325
331
        while (steps--)
326
332
        {
327
 
            unsigned int out;
328
 
            for (out = 0; out < zooms.size (); out++)
 
333
            for (unsigned int out = 0; out < zooms.size (); ++out)
329
334
            {
330
335
                if (!isInMovement (out) || !isActive (out))
331
336
                    continue;
333
338
                adjustXYVelocity (out, chunk);
334
339
                adjustZoomVelocity (out, chunk);
335
340
                zooms.at (out).updateActualTranslates ();
 
341
 
336
342
                if (!isZoomed (out))
337
343
                {
338
 
                    zooms.at (out).xVelocity = zooms.at (out).yVelocity =
339
 
                        0.0f;
 
344
                    zooms.at (out).xVelocity = zooms.at (out).yVelocity = 0.0f;
340
345
                    grabbed &= ~(1 << zooms.at (out).output);
 
346
 
341
347
                    if (!grabbed)
342
348
                    {
343
349
                        cScreen->damageScreen ();
346
352
                }
347
353
            }
348
354
        }
 
355
 
349
356
        if (optionGetZoomMode () == EzoomOptions::ZoomModeSyncMouse)
350
357
            syncCenterToMouse ();
351
358
    }
353
360
    cScreen->preparePaint (msSinceLastPaint);
354
361
}
355
362
 
356
 
/* Damage screen if we're still moving.  */
 
363
/* Damage screen if we're still moving. */
357
364
void
358
365
EZoomScreen::donePaint ()
359
366
{
360
367
    if (grabbed)
361
368
    {
362
 
        unsigned int out;
363
 
        for (out = 0; out < zooms.size (); out++)
 
369
        for (unsigned int out = 0; out < zooms.size (); ++out)
364
370
        {
365
371
            if (isInMovement (out) && isActive (out))
366
372
            {
372
378
    else if (grabIndex)
373
379
        cScreen->damageScreen ();
374
380
    else
375
 
        toggleFunctions (false);
 
381
        toggleFunctions (false);
376
382
 
377
383
    cScreen->donePaint ();
378
384
}
379
 
/* Draws a box from the screen coordinates inx1,iny1 to inx2,iny2 */
 
385
 
 
386
/* Draws a box from the screen coordinates inx1, iny1 to inx2, iny2. */
380
387
void
381
388
EZoomScreen::drawBox (const GLMatrix &transform,
382
 
                     CompOutput          *output,
383
 
                     CompRect             box)
 
389
                      CompOutput     *output,
 
390
                      CompRect       box)
384
391
{
385
 
    GLMatrix zTransform (transform);
386
 
    int           x1,x2,y1,y2;
387
 
    int           inx1, inx2, iny1, iny2;
388
 
    int           out = output->id ();
389
 
    GLushort colorData[4];
390
 
    GLfloat  vertexData[12];
 
392
    GLMatrix       zTransform (transform);
 
393
    int            inx1, inx2, iny1, iny2;
 
394
    int            out = output->id ();
 
395
    GLushort       colorData[4];
 
396
    GLfloat        vertexData[12];
391
397
    GLVertexBuffer *streamingBuffer = GLVertexBuffer::streamingBuffer ();
392
398
 
393
399
    zTransform.toScreenSpace (output, -DEFAULT_Z_CAMERA);
394
400
    convertToZoomed (out, box.x1 (), box.y1 (), &inx1, &iny1);
395
401
    convertToZoomed (out, box.x2 (), box.y2 (), &inx2, &iny2);
396
402
 
397
 
    x1 = MIN (inx1, inx2);
398
 
    y1 = MIN (iny1, iny2);
399
 
    x2 = MAX (inx1, inx2);
400
 
    y2 = MAX (iny1, iny2);
401
 
 
402
 
    streamingBuffer->begin (GL_TRIANGLE_STRIP);
403
 
 
404
 
    colorData[0] = 0x2fff;
405
 
    colorData[1] = 0x2fff;
406
 
    colorData[2] = 0x2fff;
407
 
    colorData[3] = 0x4fff;
408
 
 
409
 
    streamingBuffer->addColors (1, colorData);
 
403
    /* We can move in both directions from our starting point
 
404
     * so we need to calculate the right coordinates first. */
 
405
    int x1 = MIN (inx1, inx2);
 
406
    int y1 = MIN (iny1, iny2);
 
407
    int x2 = MAX (inx1, inx2);
 
408
    int y2 = MAX (iny1, iny2);
 
409
 
 
410
    const float MaxUShortFloat = std::numeric_limits <unsigned short>::max ();
 
411
 
 
412
    GLboolean glBlendEnabled = glIsEnabled (GL_BLEND);
 
413
 
 
414
    /* just enable blending if it is disabled */
 
415
    if (!glBlendEnabled)
 
416
        glEnable (GL_BLEND);
 
417
 
 
418
    /* Draw filled rectangle */
 
419
    float    alpha  = optionGetZoomBoxFillColorAlpha () / MaxUShortFloat;
 
420
    GLushort *color = optionGetZoomBoxFillColor ();
 
421
 
 
422
    colorData[0] = alpha * color[0];
 
423
    colorData[1] = alpha * color[1];
 
424
    colorData[2] = alpha * color[2];
 
425
    colorData[3] = alpha * MaxUShortFloat;
410
426
 
411
427
    vertexData[0]  = x1;
412
428
    vertexData[1]  = y1;
421
437
    vertexData[10] = y2;
422
438
    vertexData[11] = 0.0f;
423
439
 
 
440
    /* fill rectangle */
 
441
    streamingBuffer->begin (GL_TRIANGLE_STRIP);
 
442
 
 
443
    streamingBuffer->addColors (1, colorData);
424
444
    streamingBuffer->addVertices (4, vertexData);
425
445
 
426
446
    streamingBuffer->end ();
427
447
    streamingBuffer->render (zTransform);
428
448
 
429
 
 
430
 
    streamingBuffer->begin (GL_LINE_LOOP);
431
 
 
432
 
    colorData[0] = 0x2fff;
433
 
    colorData[1] = 0x2fff;
434
 
    colorData[2] = 0x4fff;
435
 
    colorData[3] = 0x9fff;
436
 
 
437
 
    streamingBuffer->addColors (1, colorData);
 
449
    /* draw rectangle outline */
 
450
    alpha = optionGetZoomBoxOutlineColorAlpha () / MaxUShortFloat;
 
451
    color = optionGetZoomBoxOutlineColor ();
 
452
 
 
453
    colorData[0] = alpha * color[0];
 
454
    colorData[1] = alpha * color[1];
 
455
    colorData[2] = alpha * color[2];
 
456
    colorData[3] = alpha * MaxUShortFloat;
438
457
 
439
458
    vertexData[0]  = x1;
440
459
    vertexData[1]  = y1;
449
468
    vertexData[10] = y2;
450
469
    vertexData[11] = 0.0f;
451
470
 
 
471
    glLineWidth (2.0);
 
472
 
 
473
    streamingBuffer->begin (GL_LINE_LOOP);
 
474
 
 
475
    streamingBuffer->addColors (1, colorData);
452
476
    streamingBuffer->addVertices (4, vertexData);
453
477
 
454
478
    streamingBuffer->end ();
455
479
    streamingBuffer->render (zTransform);
 
480
 
 
481
    /* just disable blending if it was disabled before */
 
482
    if (!glBlendEnabled)
 
483
        glDisable (GL_BLEND);
 
484
 
 
485
    /* Damage the zoom selection box region during draw. */
 
486
    cScreen->damageRegion (CompRegion (x1 - 1,
 
487
                                       y1 - 1,
 
488
                                       x2 - x1 + 1,
 
489
                                       y2 - y1 + 1));
456
490
}
 
491
 
457
492
/* Apply the zoom if we are grabbed.
458
493
 * Make sure to use the correct filter.
459
494
 */
460
495
bool
461
496
EZoomScreen::glPaintOutput (const GLScreenPaintAttrib &attrib,
462
 
                           const GLMatrix            &transform,
463
 
                           const CompRegion          &region,
464
 
                           CompOutput                *output,
465
 
                           unsigned int              mask)
 
497
                            const GLMatrix            &transform,
 
498
                            const CompRegion          &region,
 
499
                            CompOutput                *output,
 
500
                            unsigned int              mask)
466
501
{
467
502
    bool status;
468
 
    int  out = output->id ();
 
503
    int  out = output->id ();
469
504
 
470
505
    if (isActive (out))
471
506
    {
472
 
        GLScreenPaintAttrib sa = attrib;
 
507
        GLScreenPaintAttrib sa         = attrib;
473
508
        GLMatrix            zTransform = transform;
474
509
 
475
510
        mask &= ~PAINT_SCREEN_REGION_MASK;
476
511
        mask |= PAINT_SCREEN_CLEAR_MASK;
477
512
 
478
513
        zTransform.scale (1.0f / zooms.at (out).currentZoom,
479
 
                          1.0f / zooms.at (out).currentZoom,
480
 
                          1.0f);
 
514
                          1.0f / zooms.at (out).currentZoom,
 
515
                          1.0f);
481
516
        zTransform.translate (zooms.at (out).xtrans,
482
517
                              zooms.at (out).ytrans,
483
518
                              0);
487
522
        status = gScreen->glPaintOutput (sa, zTransform, region, output, mask);
488
523
 
489
524
        drawCursor (output, transform);
 
525
    }
 
526
    else
 
527
        status = gScreen->glPaintOutput (attrib, transform, region, output, mask);
490
528
 
491
 
    }
492
 
    else
493
 
    {
494
 
        status = gScreen->glPaintOutput (attrib, transform, region, output,
495
 
                                                                        mask);
496
 
    }
497
529
    if (grabIndex)
498
530
        drawBox (transform, output, box);
499
531
 
502
534
 
503
535
/* Makes sure we're not attempting to translate too far.
504
536
 * We are restricted to 0.5 to not go beyond the end
505
 
 * of the screen/head.  */
 
537
 * of the screen/head. */
506
538
static inline void
507
539
constrainZoomTranslate ()
508
540
{
509
 
    unsigned int out;
510
541
    ZOOM_SCREEN (screen);
511
542
 
512
 
    for (out = 0; out < zs->zooms.size (); out++)
 
543
    for (unsigned int out = 0; out < zs->zooms.size (); ++out)
513
544
    {
514
545
        if (zs->zooms.at (out).xTranslate > 0.5f)
515
546
            zs->zooms.at (out).xTranslate = 0.5f;
526
557
/* Functions for adjusting the zoomed area.
527
558
 * These are the core of the zoom plug-in; Anything wanting
528
559
 * to adjust the zoomed area must use setCenter or setZoomArea
529
 
 * and setScale or front ends to them.  */
 
560
 * and setScale or front ends to them. */
530
561
 
531
562
/* Sets the center of the zoom area to X,Y.
532
563
 * We have to be able to warp the pointer here: If we are moved by
538
569
 * that is, it's the point that's the same regardless of zoom level.
539
570
 */
540
571
void
541
 
EZoomScreen::setCenter (int x, int y, bool instant)
 
572
EZoomScreen::setCenter (int  x,
 
573
                        int  y,
 
574
                        bool instant)
542
575
{
543
576
    int         out = screen->outputDeviceForPoint (x, y);
544
 
    CompOutput  *o = &screen->outputDevs ().at (out);
 
577
    CompOutput  *o  = &screen->outputDevs ().at (out);
545
578
 
546
579
    if (zooms.at (out).locked)
547
580
        return;
567
600
/* Zooms the area described.
568
601
 * The math could probably be cleaned up, but should be correct now. */
569
602
void
570
 
EZoomScreen::setZoomArea (int        x,
571
 
                         int        y,
572
 
                         int        width,
573
 
                         int        height,
574
 
                         bool       instant)
 
603
EZoomScreen::setZoomArea (int  x,
 
604
                          int  y,
 
605
                          int  width,
 
606
                          int  height,
 
607
                          bool instant)
575
608
{
576
609
    CompWindow::Geometry outGeometry (x, y, width, height, 0);
577
 
    int         out = screen->outputDeviceForGeometry (outGeometry);
578
 
    CompOutput  *o = &screen->outputDevs ().at (out);
579
 
 
580
 
    if (zooms.at (out).newZoom == 1.0f)
581
 
        return;
582
 
 
583
 
    if (zooms.at (out).locked)
584
 
        return;
 
610
    int out = screen->outputDeviceForGeometry (outGeometry);
 
611
 
 
612
    if (zooms.at (out).newZoom == 1.0f ||
 
613
        zooms.at (out).locked)
 
614
        return;
 
615
 
 
616
    CompOutput *o = &screen->outputDevs ().at (out);
 
617
 
585
618
    zooms.at (out).xTranslate =
586
619
         (float) -((o->width () / 2) - (x + (width / 2) - o->x1 ()))
587
620
        / (o->width ());
607
640
void
608
641
EZoomScreen::areaToWindow (CompWindow *w)
609
642
{
610
 
    int left = w->serverX () - w->border ().left;
611
 
    int width = w->width () + w->border ().left + w->border ().right;
612
 
    int top = w->serverY () - w->border ().top;
613
 
    int height = w->height ()  + w->border ().top + w->border ().bottom;
 
643
    int left   = w->serverX () - w->border ().left;
 
644
    int top    = w->serverY () - w->border ().top;
 
645
    int width  = w->width ()   + w->border ().left + w->border ().right;
 
646
    int height = w->height ()  + w->border ().top  + w->border ().bottom;
614
647
 
615
648
    setZoomArea (left, top, width, height, false);
616
649
}
618
651
/* Pans the zoomed area vertically/horizontally by * value * zs->panFactor
619
652
 * TODO: Fix output. */
620
653
void
621
 
EZoomScreen::panZoom (int xvalue, int yvalue)
 
654
EZoomScreen::panZoom (int xvalue,
 
655
                      int yvalue)
622
656
{
623
 
    unsigned int out;
 
657
    float panFactor = optionGetPanFactor ();
624
658
 
625
 
    for (out = 0; out < zooms.size (); out++)
 
659
    for (unsigned int out = 0; out < zooms.size (); ++out)
626
660
    {
627
 
        zooms.at (out).xTranslate +=
628
 
            optionGetPanFactor () * xvalue *
629
 
            zooms.at (out).currentZoom;
630
 
        zooms.at (out).yTranslate +=
631
 
            optionGetPanFactor () * yvalue *
632
 
            zooms.at (out).currentZoom;
 
661
        zooms.at (out).xTranslate += panFactor * xvalue * zooms.at (out).currentZoom;
 
662
        zooms.at (out).yTranslate += panFactor * yvalue * zooms.at (out).currentZoom;
633
663
    }
634
664
 
635
665
    constrainZoomTranslate ();
643
673
{
644
674
    pollHandle.start ();
645
675
    lastChange = time(NULL);
646
 
    mouse = MousePoller::getCurrentPosition ();
 
676
    mouse      = MousePoller::getCurrentPosition ();
647
677
}
648
678
 
649
679
/* Sets the zoom (or scale) level.
650
680
 * Cleans up if we are suddenly zoomed out.
651
681
 */
652
682
void
653
 
EZoomScreen::setScale (int out, float value)
 
683
EZoomScreen::setScale (int   out,
 
684
                       float value)
654
685
{
655
686
    if (zooms.at (out).locked)
656
687
        return;
661
692
    {
662
693
        if (!pollHandle.active ())
663
694
            enableMousePolling ();
 
695
 
664
696
        grabbed |= (1 << zooms.at (out).output);
665
697
        cursorZoomActive (out);
666
698
    }
683
715
 * Convenience function for setting the scale factor for an area.
684
716
 */
685
717
static inline void
686
 
setScaleBigger (int out, float x, float y)
 
718
setScaleBigger (int   out,
 
719
                float x,
 
720
                float y)
687
721
{
688
722
    ZOOM_SCREEN (screen);
689
723
    zs->setScale (out, x > y ? x : y);
702
736
void
703
737
EZoomScreen::syncCenterToMouse ()
704
738
{
705
 
    int         x, y;
706
 
    int         out;
707
 
    CompOutput  *o;
708
 
 
709
 
    out = screen->outputDeviceForPoint (mouse.x (), mouse.y ());
710
 
    o = &screen->outputDevs ().at (out);
 
739
    int out = screen->outputDeviceForPoint (mouse.x (), mouse.y ());
711
740
 
712
741
    if (!isInMovement (out))
713
742
        return;
714
743
 
715
 
    x = (int) ((zooms.at (out).realXTranslate * o->width ()) +
716
 
               (o->width () / 2) + o->x1 ());
717
 
    y = (int) ((zooms.at (out).realYTranslate * o->height ()) +
718
 
               (o->height () / 2) + o->y1 ());
719
 
 
720
 
    if ((x != mouse.x () || y != mouse.y ())
721
 
        && grabbed && zooms.at (out).newZoom != 1.0f)
 
744
    CompOutput *o = &screen->outputDevs ().at (out);
 
745
 
 
746
    int x = (int) ((zooms.at (out).realXTranslate * o->width ()) +
 
747
                   (o->width () / 2) + o->x1 ());
 
748
    int y = (int) ((zooms.at (out).realYTranslate * o->height ()) +
 
749
                   (o->height () / 2) + o->y1 ());
 
750
 
 
751
    if ((x != mouse.x () || y != mouse.y ())    &&
 
752
        grabbed                                 &&
 
753
        zooms.at (out).newZoom != 1.0f)
722
754
    {
723
755
        screen->warpPointer (x - pointerX , y - pointerY );
724
756
        mouse.setX (x);
726
758
    }
727
759
}
728
760
 
729
 
/* Convert the point X,Y to where it would be when zoomed.  */
 
761
/* Convert the point X, Y to where it would be when zoomed. */
730
762
void
731
 
EZoomScreen::convertToZoomed (int        out,
732
 
                             int        x,
733
 
                             int        y,
734
 
                             int        *resultX,
735
 
                             int        *resultY)
 
763
EZoomScreen::convertToZoomed (int out,
 
764
                              int x,
 
765
                              int y,
 
766
                              int *resultX,
 
767
                              int *resultY)
736
768
{
737
 
    CompOutput *o;
738
 
 
739
769
    if (!outputIsZoomArea (out))
740
770
    {
741
771
        *resultX = x;
742
772
        *resultY = y;
743
773
    }
744
774
 
745
 
    o = &screen->outputDevs ()[out];
746
 
    ZoomArea    &za = zooms.at (out);
 
775
    CompOutput *o          = &screen->outputDevs ()[out];
 
776
    ZoomArea   &za         = zooms.at (out);
 
777
    int        oWidth      = o->width ();
 
778
    int        oHeight     = o->height ();
 
779
    int        halfOWidth  = oWidth  / 2;
 
780
    int        halfOHeight = oHeight / 2;
747
781
 
748
782
    x -= o->x1 ();
749
783
    y -= o->y1 ();
 
784
 
750
785
    *resultX = x - (za.realXTranslate *
751
 
                    (1.0f - za.currentZoom) * o->width ()) - o->width () / 2;
 
786
                    (1.0f - za.currentZoom) * oWidth) - halfOWidth;
752
787
    *resultX /= za.currentZoom;
753
 
    *resultX += o->width () / 2;
 
788
    *resultX += halfOWidth;
754
789
    *resultX += o->x1 ();
755
790
    *resultY = y - (za.realYTranslate *
756
 
                    (1.0f - za.currentZoom) * o->height ()) - o->height ()/ 2;
 
791
                    (1.0f - za.currentZoom) * oHeight) - halfOHeight;
757
792
    *resultY /= za.currentZoom;
758
 
    *resultY += o->height ()/ 2;
 
793
    *resultY += halfOHeight;
759
794
    *resultY += o->y1 ();
760
795
}
761
796
 
762
 
/* Same but use targeted translation, not real */
 
797
/* Same but use targeted translation, not real one. */
763
798
void
764
 
EZoomScreen::convertToZoomedTarget (int   out,
765
 
                                   int    x,
766
 
                                   int    y,
767
 
                                   int    *resultX,
768
 
                                   int    *resultY)
 
799
EZoomScreen::convertToZoomedTarget (int out,
 
800
                                    int x,
 
801
                                    int y,
 
802
                                    int *resultX,
 
803
                                    int *resultY)
769
804
{
770
 
    CompOutput *o = &screen->outputDevs ().at (out);
771
 
 
772
805
    if (!outputIsZoomArea (out))
773
806
    {
774
807
        *resultX = x;
775
808
        *resultY = y;
776
809
    }
777
810
 
778
 
    ZoomArea    &za = zooms.at (out);
 
811
    CompOutput *o          = &screen->outputDevs ().at (out);
 
812
    ZoomArea   &za         = zooms.at (out);
 
813
    int        oWidth      = o->width ();
 
814
    int        oHeight     = o->height ();
 
815
    int        halfOWidth  = oWidth  / 2;
 
816
    int        halfOHeight = oHeight / 2;
779
817
 
780
818
    x -= o->x1 ();
781
819
    y -= o->y1 ();
782
 
    *resultX = x - (za.xTranslate *
783
 
                    (1.0f - za.newZoom) * o->width ()) - o->width () / 2;
 
820
 
 
821
    *resultX = x - (za.xTranslate * (1.0f - za.newZoom) * oWidth)  - halfOWidth;
784
822
    *resultX /= za.newZoom;
785
 
    *resultX += o->width () / 2;
 
823
    *resultX += halfOWidth;
786
824
    *resultX += o->x1 ();
787
 
    *resultY = y - (za.yTranslate *
788
 
                    (1.0f - za.newZoom) * o->height ()) - o->height ()/2;
 
825
    *resultY = y - (za.yTranslate * (1.0f - za.newZoom) * oHeight) - halfOHeight;
789
826
    *resultY /= za.newZoom;
790
 
    *resultY += o->height () / 2;
 
827
    *resultY += halfOHeight;
791
828
    *resultY += o->y1 ();
792
829
}
793
830
 
796
833
 * Returns false if the point isn't on a actively zoomed head
797
834
 * or the area is locked. */
798
835
bool
799
 
EZoomScreen::ensureVisibility (int x, int y, int margin)
 
836
EZoomScreen::ensureVisibility (int x,
 
837
                               int y,
 
838
                               int margin)
800
839
{
801
 
    int         zoomX, zoomY;
802
 
    int         out;
803
 
    CompOutput  *o;
 
840
    int out = screen->outputDeviceForPoint (x, y);
804
841
 
805
 
    out = screen->outputDeviceForPoint (x, y);
806
842
    if (!isActive (out))
807
843
        return false;
808
844
 
809
 
    o = &screen->outputDevs ().at (out);
 
845
    int zoomX, zoomY;
810
846
    convertToZoomedTarget (out, x, y, &zoomX, &zoomY);
811
847
    ZoomArea &za = zooms.at (out);
 
848
 
812
849
    if (za.locked)
813
850
        return false;
814
851
 
 
852
    CompOutput *o = &screen->outputDevs ().at (out);
 
853
 
815
854
#define FACTOR (za.newZoom / (1.0f - za.newZoom))
816
855
    if (zoomX + margin > o->x2 ())
817
856
        za.xTranslate +=
846
885
 */
847
886
void
848
887
EZoomScreen::ensureVisibilityArea (int         x1,
849
 
                                  int         y1,
850
 
                                  int         x2,
851
 
                                  int         y2,
852
 
                                  int         margin,
853
 
                                  ZoomGravity gravity)
 
888
                                   int         y1,
 
889
                                   int         x2,
 
890
                                   int         y2,
 
891
                                   int         margin,
 
892
                                   ZoomGravity gravity)
854
893
{
855
 
    int        targetX, targetY, targetW, targetH;
856
 
    int        out;
857
 
    CompOutput *o;
858
 
 
859
 
    out = screen->outputDeviceForPoint (x1 + (x2-x1/2), y1 + (y2-y1/2));
860
 
    o = &screen->outputDevs ().at (out);
861
 
 
862
 
#define WIDTHOK (float)(x2-x1) / (float)o->width () < zooms.at (out).newZoom
863
 
#define HEIGHTOK (float)(y2-y1) / (float)o->height () < zooms.at (out).newZoom
864
 
 
865
 
    if (WIDTHOK &&
866
 
        HEIGHTOK) {
 
894
    int        out  = screen->outputDeviceForPoint (x1 + (x2 - x1 / 2), y1 + (y2 - y1 / 2));
 
895
    CompOutput *o   = &screen->outputDevs ().at (out);
 
896
 
 
897
    bool widthOkay  = (float)(x2-x1) / (float)o->width ()  < zooms.at (out).newZoom;
 
898
    bool heightOkay = (float)(y2-y1) / (float)o->height () < zooms.at (out).newZoom;
 
899
 
 
900
    if (widthOkay &&
 
901
        heightOkay)
 
902
    {
867
903
        ensureVisibility (x1, y1, margin);
868
904
        ensureVisibility (x2, y2, margin);
869
905
        return;
870
906
    }
871
907
 
 
908
    int targetX, targetY, targetW, targetH;
 
909
 
872
910
    switch (gravity)
873
911
    {
874
912
        case NORTHWEST:
875
913
            targetX = x1;
876
914
            targetY = y1;
877
 
            if (WIDTHOK)
 
915
 
 
916
            if (widthOkay)
878
917
                targetW = x2 - x1;
879
918
            else
880
919
                targetW = o->width () * zooms.at (out).newZoom;
881
 
            if (HEIGHTOK)
 
920
 
 
921
            if (heightOkay)
882
922
                targetH = y2 - y1;
883
923
            else
884
924
                targetH = o->height () * zooms.at (out).newZoom;
 
925
 
885
926
            break;
 
927
 
886
928
        case NORTHEAST:
887
929
            targetY = y1;
888
 
            if (WIDTHOK)
 
930
 
 
931
            if (widthOkay)
889
932
            {
890
933
                targetX = x1;
891
934
                targetW = x2-x1;
896
939
                targetW = o->width () * zooms.at (out).newZoom;
897
940
            }
898
941
 
899
 
            if (HEIGHTOK)
 
942
            if (heightOkay)
900
943
                targetH = y2-y1;
901
944
            else
902
945
                targetH = o->height () * zooms.at (out).newZoom;
 
946
 
903
947
            break;
 
948
 
904
949
        case SOUTHWEST:
905
950
            targetX = x1;
906
 
            if (WIDTHOK)
 
951
 
 
952
            if (widthOkay)
907
953
                targetW = x2-x1;
908
954
            else
909
955
                targetW = o->width () * zooms.at (out).newZoom;
910
 
            if (HEIGHTOK)
 
956
 
 
957
            if (heightOkay)
911
958
            {
912
959
                targetY = y1;
913
960
                targetH = y2-y1;
917
964
                targetY = y2 - (o->width () * zooms.at (out).newZoom);
918
965
                targetH = o->width () * zooms.at (out).newZoom;
919
966
            }
 
967
 
920
968
            break;
 
969
 
921
970
        case SOUTHEAST:
922
 
            if (WIDTHOK)
 
971
            if (widthOkay)
923
972
            {
924
973
                targetX = x1;
925
974
                targetW = x2-x1;
930
979
                targetX = x2 - targetW;
931
980
            }
932
981
 
933
 
            if (HEIGHTOK)
 
982
            if (heightOkay)
934
983
            {
935
984
                targetY = y1;
936
985
                targetH = y2 - y1;
940
989
                targetH = o->height () * zooms.at (out).newZoom;
941
990
                targetY = y2 - targetH;
942
991
            }
 
992
 
943
993
            break;
 
994
 
944
995
        case CENTER:
945
996
        default:
946
997
            setCenter (x1 + (x2 - x1 / 2), y1 + (y2 - y1 / 2), false);
947
998
            return;
 
999
 
948
1000
            break;
949
1001
    }
950
1002
 
951
1003
    setZoomArea (targetX, targetY, targetW, targetH, false);
 
1004
 
952
1005
    return ;
953
1006
}
954
1007
 
960
1013
void
961
1014
EZoomScreen::restrainCursor (int out)
962
1015
{
963
 
    int         x1, y1, x2, y2, margin;
 
1016
    int         x1, y1, x2, y2;
964
1017
    int         diffX = 0, diffY = 0;
965
 
    int         north, south, east, west;
966
 
    float       z;
967
1018
    CompOutput  *o = &screen->outputDevs ().at (out);
968
1019
 
969
 
    z = zooms.at (out).newZoom;
970
 
    margin = optionGetRestrainMargin ();
971
 
    north = distanceToEdge (out, NORTH);
972
 
    south = distanceToEdge (out, SOUTH);
973
 
    east = distanceToEdge (out, EAST);
974
 
    west = distanceToEdge (out, WEST);
 
1020
    float z      = zooms.at (out).newZoom;
 
1021
    int   margin = optionGetRestrainMargin ();
 
1022
    int   north  = distanceToEdge (out, NORTH);
 
1023
    int   south  = distanceToEdge (out, SOUTH);
 
1024
    int   east   = distanceToEdge (out, EAST);
 
1025
    int   west   = distanceToEdge (out, WEST);
975
1026
 
976
1027
    if (zooms.at (out).currentZoom == 1.0f)
977
1028
    {
990
1041
    if ((x2 - x1 > o->x2 () - o->x1 ()) ||
991
1042
       (y2 - y1 > o->y2 () - o->y1 ()))
992
1043
        return;
 
1044
 
993
1045
    if (x2 > o->x2 () - margin && east > 0)
994
1046
        diffX = x2 - o->x2 () + margin;
995
1047
    else if (x1 < o->x1 () + margin && west > 0)
1002
1054
 
1003
1055
    if (abs(diffX)*z > 0  || abs(diffY)*z > 0)
1004
1056
        screen->warpPointer ((int) (mouse.x () - pointerX) -
1005
 
                                                       (int) ((float)diffX * z),
1006
 
                             (int) (mouse.y () - pointerY) -
1007
 
                                                      (int) ((float)diffY * z));
 
1057
                                 (int) ((float)diffX * z),
 
1058
                             (int) (mouse.y () - pointerY) -
 
1059
                                 (int) ((float)diffY * z));
1008
1060
}
1009
1061
 
1010
1062
/* Check if the cursor is still visible.
1016
1068
void
1017
1069
EZoomScreen::cursorMoved ()
1018
1070
{
1019
 
    int         out;
 
1071
    int out = screen->outputDeviceForPoint (mouse.x (), mouse.y ());
1020
1072
 
1021
 
    out = screen->outputDeviceForPoint (mouse.x (), mouse.y ());
1022
1073
    if (isActive (out))
1023
1074
    {
1024
1075
        if (optionGetRestrainMouse ())
1025
1076
            restrainCursor (out);
1026
1077
 
1027
1078
        if (optionGetZoomMode () == EzoomOptions::ZoomModePanArea)
1028
 
        {
1029
1079
            ensureVisibilityArea (mouse.x () - cursor.hotX,
1030
1080
                                  mouse.y () - cursor.hotY,
1031
1081
                                  mouse.x () + cursor.width -
1034
1084
                                  cursor.hotY,
1035
1085
                                  optionGetRestrainMargin (),
1036
1086
                                  NORTHWEST);
1037
 
        }
1038
 
 
1039
1087
        cursorZoomActive (out);
1040
1088
    }
1041
1089
    else
1042
 
    {
1043
1090
        cursorZoomInactive ();
1044
 
    }
1045
1091
}
1046
1092
 
1047
1093
/* Update the mouse position.
1051
1097
void
1052
1098
EZoomScreen::updateMousePosition (const CompPoint &p)
1053
1099
{
1054
 
    int out;
1055
1100
    mouse.setX (p.x ());
1056
1101
    mouse.setY (p.y ());
1057
 
    out = screen->outputDeviceForPoint (mouse.x (), mouse.y ());
 
1102
 
 
1103
    int out = screen->outputDeviceForPoint (mouse.x (), mouse.y ());
1058
1104
    lastChange = time(NULL);
 
1105
 
1059
1106
    if (optionGetZoomMode () == EzoomOptions::ZoomModeSyncMouse &&
1060
 
        !isInMovement (out))
 
1107
        !isInMovement (out))
1061
1108
        setCenter (mouse.x (), mouse.y (), true);
 
1109
 
1062
1110
    cursorMoved ();
1063
1111
    cScreen->damageScreen ();
1064
1112
}
1073
1121
    if (!grabbed)
1074
1122
    {
1075
1123
        cursorMoved ();
 
1124
 
1076
1125
        if (pollHandle.active ())
1077
1126
            pollHandle.stop ();
1078
1127
    }
1080
1129
 
1081
1130
/* Free a cursor */
1082
1131
void
1083
 
EZoomScreen::freeCursor (CursorTexture * cursor)
 
1132
EZoomScreen::freeCursor (CursorTexture *cursor)
1084
1133
{
1085
1134
    if (!cursor->isSet)
1086
1135
        return;
1092
1141
 
1093
1142
/* Translate into place and draw the scaled cursor.  */
1094
1143
void
1095
 
EZoomScreen::drawCursor (CompOutput          *output,
1096
 
                        const GLMatrix      &transform)
 
1144
EZoomScreen::drawCursor (CompOutput    *output,
 
1145
                        const GLMatrix &transform)
1097
1146
{
1098
 
    int         out = output->id ();
 
1147
    int out = output->id ();
1099
1148
 
1100
1149
    if (cursor.isSet)
1101
1150
    {
1102
 
        GLMatrix      sTransform = transform;
1103
 
        float         scaleFactor;
1104
 
        int           ax, ay, x, y;
1105
 
        GLfloat         textureData[8];
1106
 
        GLfloat         vertexData[12];
1107
 
        GLVertexBuffer *streamingBuffer = GLVertexBuffer::streamingBuffer ();
1108
 
 
1109
1151
        /*
1110
1152
         * XXX: expo knows how to handle mouse when zoomed, so we back off
1111
1153
         * when expo is active.
1112
1154
         */
1113
 
        if (screen->grabExist ( "expo"))
 
1155
        if (screen->grabExist ("expo"))
1114
1156
        {
1115
1157
            cursorZoomInactive ();
1116
1158
            return;
1117
1159
        }
1118
1160
 
 
1161
        GLMatrix       sTransform = transform;
 
1162
        float          scaleFactor;
 
1163
        int            ax, ay;
 
1164
        GLfloat        textureData[8];
 
1165
        GLfloat        vertexData[12];
 
1166
        GLVertexBuffer *streamingBuffer = GLVertexBuffer::streamingBuffer ();
 
1167
 
1119
1168
        sTransform.toScreenSpace (output, -DEFAULT_Z_CAMERA);
1120
1169
        convertToZoomed (out, mouse.x (), mouse.y (), &ax, &ay);
1121
1170
        sTransform.translate ((float) ax, (float) ay, 0.0f);
1126
1175
            scaleFactor = 1.0f / optionGetScaleMouseStatic ();
1127
1176
 
1128
1177
        sTransform.scale (scaleFactor, scaleFactor, 1.0f);
1129
 
        x = -cursor.hotX;
1130
 
        y = -cursor.hotY;
1131
 
 
1132
 
        glEnable (GL_BLEND);
1133
 
        glEnable (GL_TEXTURE_2D);
 
1178
        int x = -cursor.hotX;
 
1179
        int y = -cursor.hotY;
 
1180
 
 
1181
        GLboolean glBlendEnabled = glIsEnabled (GL_BLEND);
 
1182
 
 
1183
        if (!glBlendEnabled)
 
1184
            glEnable (GL_BLEND);
 
1185
 
1134
1186
        glBindTexture (GL_TEXTURE_2D, cursor.texture);
1135
1187
 
1136
1188
        streamingBuffer->begin (GL_TRIANGLE_STRIP);
1165
1217
        streamingBuffer->render (sTransform);
1166
1218
 
1167
1219
        glBindTexture (GL_TEXTURE_2D, 0);
1168
 
        glDisable (GL_TEXTURE_2D);
1169
1220
        glDisable (GL_BLEND);
1170
1221
    }
1171
1222
}
1172
1223
 
1173
1224
/* Create (if necessary) a texture to store the cursor,
1174
 
 * fetch the cursor with XFixes. Store it.  */
 
1225
 * fetch the cursor with XFixes. Store it. */
1175
1226
void
1176
1227
EZoomScreen::updateCursor (CursorTexture * cursor)
1177
1228
{
1178
 
    unsigned char *pixels;
1179
 
    int           i;
1180
 
    Display       *dpy = screen->dpy ();
 
1229
    int     i;
 
1230
    Display *dpy = screen->dpy ();
1181
1231
 
1182
1232
    if (!cursor->isSet)
1183
1233
    {
1184
1234
        cursor->isSet = true;
1185
1235
        cursor->screen = screen;
1186
1236
 
1187
 
        glEnable (GL_TEXTURE_2D);
1188
1237
        glGenTextures (1, &cursor->texture);
1189
1238
        glBindTexture (GL_TEXTURE_2D, cursor->texture);
1190
1239
 
1191
1240
        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1192
1241
        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1193
1242
        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
1194
 
                         gScreen->textureFilter ());
1195
 
        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
1196
 
                         gScreen->textureFilter ());
1197
 
    }
1198
 
    else {
1199
 
        glEnable (GL_TEXTURE_2D);
 
1243
                         gScreen->textureFilter ());
 
1244
        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
 
1245
                         gScreen->textureFilter ());
1200
1246
    }
1201
1247
 
1202
1248
    XFixesCursorImage *ci = XFixesGetCursorImage (dpy);
 
1249
    unsigned char     *pixels;
 
1250
    unsigned long     pix;
1203
1251
 
1204
1252
    if (ci)
1205
1253
    {
1206
 
        cursor->width = ci->width;
 
1254
        cursor->width  = ci->width;
1207
1255
        cursor->height = ci->height;
1208
1256
        cursor->hotX = ci->xhot;
1209
1257
        cursor->hotY = ci->yhot;
1215
1263
            return;
1216
1264
        }
1217
1265
 
1218
 
        for (i = 0; i < ci->width * ci->height; i++)
 
1266
        for (i = 0; i < ci->width * ci->height; ++i)
1219
1267
        {
1220
 
            unsigned long pix = ci->pixels[i];
1221
 
            pixels[i * 4] = pix & 0xff;
 
1268
            pix                 = ci->pixels[i];
 
1269
            pixels[i * 4]       = pix & 0xff;
1222
1270
            pixels[(i * 4) + 1] = (pix >> 8) & 0xff;
1223
1271
            pixels[(i * 4) + 2] = (pix >> 16) & 0xff;
1224
1272
            pixels[(i * 4) + 3] = (pix >> 24) & 0xff;
1231
1279
        /* Fallback R: 255 G: 255 B: 255 A: 255
1232
1280
         * FIXME: Draw a cairo mouse cursor */
1233
1281
 
1234
 
        cursor->width = 1;
 
1282
        cursor->width  = 1;
1235
1283
        cursor->height = 1;
1236
 
        cursor->hotX = 0;
1237
 
        cursor->hotY = 0;
 
1284
        cursor->hotX   = 0;
 
1285
        cursor->hotY   = 0;
1238
1286
        pixels = (unsigned char *) malloc (cursor->width * cursor->height * 4);
1239
1287
 
1240
1288
        if (!pixels)
1241
1289
            return;
1242
1290
 
1243
 
        for (i = 0; i < cursor->width * cursor->height; i++)
 
1291
        for (i = 0; i < cursor->width * cursor->height; ++i)
1244
1292
        {
1245
 
            unsigned long pix = 0x00ffffff;
1246
 
            pixels[i * 4] = pix & 0xff;
 
1293
            pix                 = 0x00ffffff;
 
1294
            pixels[i * 4]       = pix & 0xff;
1247
1295
            pixels[(i * 4) + 1] = (pix >> 8) & 0xff;
1248
1296
            pixels[(i * 4) + 2] = (pix >> 16) & 0xff;
1249
1297
            pixels[(i * 4) + 3] = (pix >> 24) & 0xff;
1256
1304
    glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, cursor->width,
1257
1305
                  cursor->height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
1258
1306
    glBindTexture (GL_TEXTURE_2D, 0);
1259
 
    glDisable (GL_TEXTURE_2D);
1260
 
        
 
1307
 
1261
1308
    free (pixels);
1262
1309
}
1263
1310
 
1275
1322
    }
1276
1323
 
1277
1324
    if (cursor.isSet)
1278
 
    {
1279
1325
        freeCursor (&cursor);
1280
 
    }
1281
1326
 
1282
1327
    if (cursorHidden)
1283
1328
    {
1300
1345
    /* Force cursor hiding and mouse panning if this output is locked
1301
1346
     * and cursor hiding is not enabled and we are syncing the mouse
1302
1347
     */
1303
 
 
1304
 
    if (!optionGetScaleMouse () &&
1305
 
        (optionGetZoomMode () == EzoomOptions::ZoomModeSyncMouse &&
1306
 
         optionGetHideOriginalMouse () &&
1307
 
         !zooms.at (out).locked))
 
1348
    if (!optionGetScaleMouse ()                                 &&
 
1349
        optionGetZoomMode () == EzoomOptions::ZoomModeSyncMouse &&
 
1350
        optionGetHideOriginalMouse ()                           &&
 
1351
        !zooms.at (out).locked)
1308
1352
        return;
1309
1353
 
1310
1354
    if (!cursorInfoSelected)
1311
1355
    {
1312
1356
        cursorInfoSelected = true;
1313
 
        XFixesSelectCursorInput (screen->dpy (), screen->root (),
 
1357
        XFixesSelectCursorInput (screen->dpy (), screen->root (),
1314
1358
                                 XFixesDisplayCursorNotifyMask);
1315
1359
        updateCursor (&cursor);
1316
1360
    }
1317
 
    if (canHideCursor && !cursorHidden &&
1318
 
        (optionGetHideOriginalMouse () ||
1319
 
         zooms.at (out).locked))
 
1361
 
 
1362
    if (canHideCursor &&
 
1363
        !cursorHidden &&
 
1364
        (optionGetHideOriginalMouse () || zooms.at (out).locked))
1320
1365
    {
1321
1366
        cursorHidden = true;
1322
1367
        XFixesHideCursor (screen->dpy (), screen->root ());
1336
1381
 */
1337
1382
bool
1338
1383
EZoomScreen::setZoomAreaAction (CompAction         *action,
1339
 
                               CompAction::State  state,
1340
 
                               CompOption::Vector options)
 
1384
                                CompAction::State  state,
 
1385
                                CompOption::Vector options)
1341
1386
{
1342
 
    int        x1, y1, x2, y2, out;
1343
 
    bool       scale, restrain;
1344
 
    CompOutput *o;
1345
 
 
1346
 
    x1 = CompOption::getIntOptionNamed (options, "x1", -1);
1347
 
    y1 = CompOption::getIntOptionNamed (options, "y1", -1);
1348
 
    x2 = CompOption::getIntOptionNamed (options, "x2", -1);
1349
 
    y2 = CompOption::getIntOptionNamed (options, "y2", -1);
1350
 
    scale = CompOption::getBoolOptionNamed (options, "scale", false);
1351
 
    restrain = CompOption::getBoolOptionNamed (options, "restrain", false);
 
1387
    int x1 = CompOption::getIntOptionNamed (options, "x1", -1);
 
1388
    int y1 = CompOption::getIntOptionNamed (options, "y1", -1);
1352
1389
 
1353
1390
    if (x1 < 0 || y1 < 0)
1354
 
        return false;
 
1391
        return false;
 
1392
 
 
1393
    int x2 = CompOption::getIntOptionNamed (options, "x2", -1);
 
1394
    int y2 = CompOption::getIntOptionNamed (options, "y2", -1);
1355
1395
 
1356
1396
    if (x2 < 0)
1357
 
        x2 = x1 + 1;
 
1397
        x2 = x1 + 1;
1358
1398
 
1359
1399
    if (y2 < 0)
1360
 
        y2 = y1 + 1;
1361
 
 
1362
 
    out = screen->outputDeviceForPoint (x1, y1);
1363
 
#define WIDTH (x2 - x1)
1364
 
#define HEIGHT (y2 - y1)
1365
 
    setZoomArea (x1, y1, WIDTH, HEIGHT, false);
1366
 
    o = &screen->outputDevs (). at(out);
1367
 
    if (scale && WIDTH && HEIGHT)
1368
 
        setScaleBigger (out, (float) WIDTH / o->width (),
1369
 
                        (float) HEIGHT / o->height ());
1370
 
#undef WIDTH
1371
 
#undef HEIGHT
1372
 
        if (restrain)
1373
 
            restrainCursor (out);
 
1400
        y2 = y1 + 1;
 
1401
 
 
1402
    bool scale    = CompOption::getBoolOptionNamed (options, "scale", false);
 
1403
    bool restrain = CompOption::getBoolOptionNamed (options, "restrain", false);
 
1404
    int  out      = screen->outputDeviceForPoint (x1, y1);
 
1405
    int  width    = x2 - x1;
 
1406
    int  height   = y2 - y1;
 
1407
 
 
1408
    setZoomArea (x1, y1, width, height, false);
 
1409
    CompOutput *o = &screen->outputDevs (). at(out);
 
1410
 
 
1411
    if (scale && width && height)
 
1412
        setScaleBigger (out, width  / static_cast <float> (o->width ()),
 
1413
                             height / static_cast <float> (o->height ()));
 
1414
 
 
1415
    if (restrain)
 
1416
        restrainCursor (out);
1374
1417
 
1375
1418
    toggleFunctions (true);
1376
1419
 
1389
1432
 */
1390
1433
bool
1391
1434
EZoomScreen::ensureVisibilityAction (CompAction         *action,
1392
 
                                    CompAction::State  state,
1393
 
                                    CompOption::Vector options)
 
1435
                                     CompAction::State  state,
 
1436
                                     CompOption::Vector options)
1394
1437
{
1395
 
    int        x1, y1, x2, y2, margin, out;
1396
 
    bool       scale, restrain;
1397
 
    CompOutput *o;
 
1438
    int  x1       = CompOption::getIntOptionNamed (options, "x1", -1);
 
1439
    int  y1       = CompOption::getIntOptionNamed (options, "y1", -1);
1398
1440
 
1399
 
    x1 = CompOption::getIntOptionNamed (options, "x1", -1);
1400
 
    y1 = CompOption::getIntOptionNamed (options, "y1", -1);
1401
 
    x2 = CompOption::getIntOptionNamed (options, "x2", -1);
1402
 
    y2 = CompOption::getIntOptionNamed (options, "y2", -1);
1403
 
    margin = CompOption::getBoolOptionNamed (options, "margin", 0);
1404
 
    scale = CompOption::getBoolOptionNamed (options, "scale", false);
1405
 
    restrain = CompOption::getBoolOptionNamed (options, "restrain", false);
1406
1441
    if (x1 < 0 || y1 < 0)
1407
 
        return false;
 
1442
        return false;
 
1443
 
 
1444
    int  x2       = CompOption::getIntOptionNamed (options, "x2", -1);
 
1445
    int  y2       = CompOption::getIntOptionNamed (options, "y2", -1);
 
1446
    int  margin   = CompOption::getBoolOptionNamed (options, "margin", 0);
 
1447
    bool scale    = CompOption::getBoolOptionNamed (options, "scale", false);
 
1448
    bool restrain = CompOption::getBoolOptionNamed (options, "restrain", false);
 
1449
 
1408
1450
    if (x2 < 0)
1409
 
        y2 = y1 + 1;
1410
 
    out = screen->outputDeviceForPoint (x1, y1);
 
1451
        y2 = y1 + 1;
 
1452
 
 
1453
    int out = screen->outputDeviceForPoint (x1, y1);
1411
1454
    ensureVisibility (x1, y1, margin);
 
1455
 
1412
1456
    if (x2 >= 0 && y2 >= 0)
1413
 
        ensureVisibility (x2, y2, margin);
1414
 
    o = &screen->outputDevs (). at(out);
1415
 
#define WIDTH (x2 - x1)
1416
 
#define HEIGHT (y2 - y1)
1417
 
    if (scale && WIDTH && HEIGHT)
1418
 
        setScaleBigger (out, (float) WIDTH / o->width (),
1419
 
                        (float) HEIGHT / o->height ());
1420
 
#undef WIDTH
1421
 
#undef HEIGHT
 
1457
        ensureVisibility (x2, y2, margin);
 
1458
 
 
1459
    CompOutput *o = &screen->outputDevs (). at(out);
 
1460
 
 
1461
    int width  = x2 - x1;
 
1462
    int height = y2 - y1;
 
1463
 
 
1464
    if (scale && width && height)
 
1465
        setScaleBigger (out, width  / static_cast <float> (o->width ()),
 
1466
                             height / static_cast <float> (o->height ()));
 
1467
 
1422
1468
    if (restrain)
1423
1469
        restrainCursor (out);
1424
1470
 
1431
1477
 
1432
1478
bool
1433
1479
EZoomScreen::zoomBoxActivate (CompAction         *action,
1434
 
                             CompAction::State  state,
1435
 
                             CompOption::Vector options)
 
1480
                              CompAction::State  state,
 
1481
                              CompOption::Vector options)
1436
1482
{
1437
1483
    grabIndex = screen->pushGrab (None, "ezoom");
1438
1484
    clickPos.setX (pointerX);
1439
1485
    clickPos.setY (pointerY);
1440
1486
    box.setGeometry (pointerX, pointerY, 0, 0);
 
1487
 
1441
1488
    if (state & CompAction::StateInitButton)
1442
 
        action->setState (action->state () | CompAction::StateTermButton);
 
1489
        action->setState (action->state () | CompAction::StateTermButton);
1443
1490
 
1444
1491
    toggleFunctions (true);
1445
1492
 
1448
1495
 
1449
1496
bool
1450
1497
EZoomScreen::zoomBoxDeactivate (CompAction         *action,
1451
 
                               CompAction::State  state,
1452
 
                               CompOption::Vector options)
 
1498
                                CompAction::State  state,
 
1499
                                CompOption::Vector options)
1453
1500
{
1454
1501
    if (grabIndex)
1455
1502
    {
1456
 
        int        out;
1457
 
        int        x, y, width, height;
1458
 
        CompOutput *o;
1459
 
 
1460
 
        screen->removeGrab (grabIndex, NULL);
1461
 
        grabIndex = 0;
1462
 
 
1463
 
        if (pointerX < clickPos.x ())
1464
 
        {
 
1503
        screen->removeGrab (grabIndex, NULL);
 
1504
        grabIndex = 0;
 
1505
 
 
1506
        if (pointerX < clickPos.x ())
 
1507
        {
1465
1508
            box.setX (pointerX);
1466
1509
            box.setWidth (clickPos.x () - pointerX);
1467
 
        }
1468
 
        else
1469
 
        {
 
1510
        }
 
1511
        else
1470
1512
            box.setWidth (pointerX - clickPos.x ());
1471
 
        }
1472
1513
 
1473
 
        if (pointerY < clickPos.y ())
1474
 
        {
 
1514
        if (pointerY < clickPos.y ())
 
1515
        {
1475
1516
            box.setY (pointerY);
1476
1517
            box.setHeight (clickPos.y () - pointerY);
1477
 
        }
1478
 
        else
1479
 
        {
 
1518
        }
 
1519
        else
1480
1520
            box.setHeight (pointerY - clickPos.y ());
1481
 
        }
1482
 
 
1483
 
        x = MIN (box.x1 (), box.x2 ());
1484
 
        y = MIN (box.y1 (), box.y2 ());
1485
 
        width = MAX (box.x1 (), box.x2 ()) - x;
1486
 
        height = MAX (box.y1 (), box.y2 ()) - y;
1487
 
 
1488
 
        CompWindow::Geometry outGeometry (x, y, width, height, 0);
1489
 
 
1490
 
        out = screen->outputDeviceForGeometry (outGeometry);
1491
 
        o = &screen->outputDevs (). at (out);
1492
 
        setScaleBigger (out, (float) width/o->width (), (float)
1493
 
                        height/o->height ());
1494
 
        setZoomArea (x,y,width,height,false);
 
1521
 
 
1522
        int x      = MIN (box.x1 (), box.x2 ());
 
1523
        int y      = MIN (box.y1 (), box.y2 ());
 
1524
        int width  = MAX (box.x1 (), box.x2 ()) - x;
 
1525
        int height = MAX (box.y1 (), box.y2 ()) - y;
 
1526
 
 
1527
        CompWindow::Geometry outGeometry (x, y, width, height, 0);
 
1528
 
 
1529
        int        out = screen->outputDeviceForGeometry (outGeometry);
 
1530
        CompOutput *o  = &screen->outputDevs (). at (out);
 
1531
        setScaleBigger (out, width  / static_cast <float> (o->width ()),
 
1532
                             height / static_cast <float> (o->height ()));
 
1533
        setZoomArea (x, y, width, height, false);
1495
1534
    }
1496
1535
 
1497
1536
    toggleFunctions (true);
1503
1542
 */
1504
1543
bool
1505
1544
EZoomScreen::zoomIn (CompAction         *action,
1506
 
                    CompAction::State  state,
1507
 
                    CompOption::Vector options)
 
1545
                     CompAction::State  state,
 
1546
                     CompOption::Vector options)
1508
1547
{
1509
1548
    int out = screen->outputDeviceForPoint (pointerX, pointerY);
1510
1549
 
1511
1550
    if (optionGetZoomMode () == EzoomOptions::ZoomModeSyncMouse &&
1512
1551
        !isInMovement (out))
1513
 
        setCenter (pointerX, pointerY, true);
 
1552
        setCenter (pointerX, pointerY, true);
1514
1553
 
1515
 
    setScale (out,
1516
 
              zooms.at (out).newZoom /
1517
 
              optionGetZoomFactor ());
 
1554
    setScale (out, zooms.at (out).newZoom / optionGetZoomFactor ());
1518
1555
 
1519
1556
    toggleFunctions (true);
1520
1557
 
1525
1562
 */
1526
1563
bool
1527
1564
EZoomScreen::lockZoomAction (CompAction         *action,
1528
 
                            CompAction::State  state,
1529
 
                            CompOption::Vector options)
 
1565
                             CompAction::State  state,
 
1566
                             CompOption::Vector options)
1530
1567
{
1531
1568
    int out = screen->outputDeviceForPoint (pointerX, pointerY);
1532
1569
    zooms.at (out).locked = !zooms.at (out).locked;
1543
1580
 */
1544
1581
bool
1545
1582
EZoomScreen::zoomSpecific (CompAction         *action,
1546
 
                          CompAction::State  state,
1547
 
                          CompOption::Vector options,
1548
 
                          SpecificZoomTarget target)
 
1583
                           CompAction::State  state,
 
1584
                           CompOption::Vector options,
 
1585
                           SpecificZoomTarget target)
1549
1586
{
1550
 
    int          out = screen->outputDeviceForPoint (pointerX, pointerY);
1551
 
    float        zoom_level;
1552
 
    CompWindow   *w;
 
1587
    int   out = screen->outputDeviceForPoint (pointerX, pointerY);
 
1588
    float zoom_level;
1553
1589
 
1554
1590
    switch (target)
1555
1591
    {
1556
1592
        case ZoomTargetFirst:
1557
1593
            zoom_level = optionGetZoomSpec1 ();
1558
1594
            break;
 
1595
 
1559
1596
        case ZoomTargetSecond:
1560
1597
            zoom_level = optionGetZoomSpec2 ();
1561
1598
            break;
 
1599
 
1562
1600
        case ZoomTargetThird:
1563
1601
            zoom_level = optionGetZoomSpec3 ();
1564
1602
            break;
 
1603
 
1565
1604
        default:
1566
1605
            return false;
1567
1606
    }
1568
1607
 
1569
 
    if (zoom_level == 1.0f && zooms.at (out).newZoom == 1.0f)
1570
 
        return false;
1571
 
    if (screen->otherGrabExist (NULL))
1572
 
        return false;
 
1608
    if ((zoom_level == zooms.at (out).newZoom) ||
 
1609
        screen->otherGrabExist (NULL))
 
1610
        return false;
1573
1611
 
1574
1612
    setScale (out, zoom_level);
1575
1613
 
1576
 
    w = screen->findWindow (screen->activeWindow ());
1577
 
    if (optionGetSpecTargetFocus ()
1578
 
        && w)
1579
 
    {
1580
 
        areaToWindow (w);
1581
 
    }
 
1614
    CompWindow *w = screen->findWindow (screen->activeWindow ());
 
1615
 
 
1616
    if (optionGetSpecTargetFocus () && w)
 
1617
        areaToWindow (w);
1582
1618
    else
1583
1619
    {
1584
 
        int x = CompOption::getIntOptionNamed (options, "x", 0);
1585
 
        int y = CompOption::getIntOptionNamed (options, "y", 0);
1586
 
        setCenter (x, y, false);
 
1620
        int x = CompOption::getIntOptionNamed (options, "x", 0);
 
1621
        int y = CompOption::getIntOptionNamed (options, "y", 0);
 
1622
        setCenter (x, y, false);
1587
1623
    }
1588
1624
 
1589
1625
    toggleFunctions (true);
1598
1634
 */
1599
1635
bool
1600
1636
EZoomScreen::zoomToWindow (CompAction         *action,
1601
 
                          CompAction::State  state,
1602
 
                          CompOption::Vector options)
 
1637
                           CompAction::State  state,
 
1638
                           CompOption::Vector options)
1603
1639
{
1604
 
    int        width, height, out;
1605
 
    Window     xid;
1606
 
    CompWindow *w;
1607
 
    CompOutput *o;
 
1640
    Window     xid = CompOption::getIntOptionNamed (options, "window", 0);
 
1641
    CompWindow *w  = screen->findWindow (xid);
1608
1642
 
1609
 
    xid = CompOption::getIntOptionNamed (options, "window", 0);
1610
 
    w = screen->findWindow (xid);
1611
1643
    if (!w)
1612
1644
        return true;
1613
 
    width = w->width () + w->border ().left + w->border ().right;
1614
 
    height = w->height () + w->border ().top + w->border ().bottom;
1615
 
    out = screen->outputDeviceForGeometry (w->geometry ());
1616
 
    o = &screen->outputDevs ().at (out);
1617
 
    setScaleBigger (out, (float) width/o->width (),
1618
 
                    (float) height/o->height ());
 
1645
 
 
1646
    int        width  = w->width ()  + w->border ().left + w->border ().right;
 
1647
    int        height = w->height () + w->border ().top  + w->border ().bottom;
 
1648
    int        out    = screen->outputDeviceForGeometry (w->geometry ());
 
1649
    CompOutput *o     = &screen->outputDevs ().at (out);
 
1650
 
 
1651
    setScaleBigger (out, width  / static_cast <float> (o->width ()),
 
1652
                         height / static_cast <float> (o->height ()));
1619
1653
    areaToWindow (w);
1620
1654
    toggleFunctions (true);
1621
1655
 
1624
1658
 
1625
1659
bool
1626
1660
EZoomScreen::zoomPan (CompAction         *action,
1627
 
                     CompAction::State  state,
1628
 
                     CompOption::Vector options,
1629
 
                     float              horizAmount,
1630
 
                     float              vertAmount)
 
1661
                      CompAction::State  state,
 
1662
                      CompOption::Vector options,
 
1663
                      float              horizAmount,
 
1664
                      float              vertAmount)
1631
1665
{
1632
1666
    panZoom (horizAmount, vertAmount);
1633
1667
 
1638
1672
 */
1639
1673
bool
1640
1674
EZoomScreen::zoomCenterMouse (CompAction         *action,
1641
 
                             CompAction::State  state,
1642
 
                             CompOption::Vector options)
 
1675
                              CompAction::State  state,
 
1676
                              CompOption::Vector options)
1643
1677
{
1644
 
    int        out;
1645
 
 
1646
 
 
1647
 
    out = screen->outputDeviceForPoint (pointerX, pointerY);
1648
 
    screen->warpPointer ((int) (screen->outputDevs ().at (out).width ()/2 +
1649
 
                        screen->outputDevs ().at (out).x1 () - pointerX)
 
1678
    int out = screen->outputDeviceForPoint (pointerX, pointerY);
 
1679
 
 
1680
    screen->warpPointer ((int) (screen->outputDevs ().at (out).width () / 2 +
 
1681
                                screen->outputDevs ().at (out).x1 () - pointerX)
1650
1682
                         + ((float) screen->outputDevs ().at (out).width () *
1651
 
                                -zooms.at (out).xtrans),
1652
 
                         (int) (screen->outputDevs ().at (out).height ()/2 +
 
1683
                            -zooms.at (out).xtrans),
 
1684
                         (int) (screen->outputDevs ().at (out).height () / 2 +
1653
1685
                                screen->outputDevs ().at (out).y1 () - pointerY)
1654
1686
                         + ((float) screen->outputDevs ().at (out).height () *
1655
 
                                zooms.at (out).ytrans));
 
1687
                            zooms.at (out).ytrans));
1656
1688
    return true;
1657
1689
}
1658
1690
 
1663
1695
 */
1664
1696
bool
1665
1697
EZoomScreen::zoomFitWindowToZoom (CompAction         *action,
1666
 
                                 CompAction::State  state,
1667
 
                                 CompOption::Vector options)
 
1698
                                  CompAction::State  state,
 
1699
                                  CompOption::Vector options)
1668
1700
{
1669
 
    int            out;
 
1701
    CompWindow *w = screen->findWindow (CompOption::getIntOptionNamed (options,
 
1702
                                                                       "window", 0));
 
1703
    if (!w)
 
1704
        return true;
 
1705
 
1670
1706
    unsigned int   mask = CWWidth | CWHeight;
1671
1707
    XWindowChanges xwc;
1672
 
    CompWindow     *w;
1673
 
 
1674
 
    w = screen->findWindow (CompOption::getIntOptionNamed (
1675
 
                                                         options, "window", 0));
1676
 
    if (!w)
1677
 
        return true;
1678
 
 
1679
 
    out = screen->outputDeviceForGeometry (w->geometry ());
1680
 
    xwc.x = w->serverX ();
1681
 
    xwc.y = w->serverY ();
1682
 
    xwc.width = (int) (screen->outputDevs ().at (out).width () *
1683
 
                       zooms.at (out).currentZoom -
1684
 
                       (int) ((w->border ().left + w->border ().right)));
 
1708
 
 
1709
    int out = screen->outputDeviceForGeometry (w->geometry ());
 
1710
    xwc.x   = w->serverX ();
 
1711
    xwc.y   = w->serverY ();
 
1712
 
 
1713
    xwc.width  = (int) (screen->outputDevs ().at (out).width () *
 
1714
                        zooms.at (out).currentZoom -
 
1715
                        (int) ((w->border ().left + w->border ().right)));
1685
1716
    xwc.height = (int) (screen->outputDevs ().at (out).height () *
1686
1717
                        zooms.at (out).currentZoom -
1687
1718
                        (int) ((w->border ().top + w->border ().bottom)));
1691
1722
                               &xwc.width,
1692
1723
                               &xwc.height);
1693
1724
 
1694
 
 
1695
1725
    if (xwc.width == w->serverWidth ())
1696
1726
        mask &= ~CWWidth;
1697
1727
 
1710
1740
 
1711
1741
bool
1712
1742
EZoomScreen::initiate (CompAction         *action,
1713
 
                      CompAction::State  state,
1714
 
                      CompOption::Vector options)
 
1743
                       CompAction::State  state,
 
1744
                       CompOption::Vector options)
1715
1745
{
1716
1746
    zoomIn (action, state, options);
1717
1747
 
1728
1758
 
1729
1759
bool
1730
1760
EZoomScreen::zoomOut (CompAction         *action,
1731
 
                     CompAction::State  state,
1732
 
                     CompOption::Vector options)
 
1761
                      CompAction::State  state,
 
1762
                      CompOption::Vector options)
1733
1763
{
1734
1764
    int out = screen->outputDeviceForPoint (pointerX, pointerY);
1735
1765
 
1744
1774
 
1745
1775
bool
1746
1776
EZoomScreen::terminate (CompAction         *action,
1747
 
                       CompAction::State  state,
1748
 
                       CompOption::Vector options)
 
1777
                        CompAction::State  state,
 
1778
                        CompOption::Vector options)
1749
1779
{
1750
 
    int out;
1751
 
 
1752
 
    out = screen->outputDeviceForPoint (pointerX, pointerY);
 
1780
    int out = screen->outputDeviceForPoint (pointerX, pointerY);
1753
1781
 
1754
1782
    if (grabbed)
1755
1783
    {
1756
 
        zooms.at (out).newZoom = 1.0f;
1757
 
        cScreen->damageScreen ();
 
1784
        zooms.at (out).newZoom = 1.0f;
 
1785
        cScreen->damageScreen ();
1758
1786
    }
1759
1787
 
1760
1788
    toggleFunctions (true);
1761
1789
 
1762
1790
    action->setState (action->state () & ~(CompAction::StateTermKey |
1763
1791
                                           CompAction::StateTermButton));
 
1792
 
1764
1793
    return false;
1765
 
 
1766
1794
}
1767
1795
 
1768
1796
/* Focus-track related event handling.
1777
1805
void
1778
1806
EZoomScreen::focusTrack (XEvent *event)
1779
1807
{
1780
 
    int           out;
1781
1808
    static Window lastMapped = 0;
1782
1809
 
1783
 
    CompWindow    *w;
1784
 
 
1785
1810
    if (event->type == MapNotify)
1786
1811
    {
1787
1812
        lastMapped = event->xmap.window;
1790
1815
    else if (event->type != FocusIn)
1791
1816
        return;
1792
1817
 
1793
 
    if ((event->xfocus.mode != NotifyNormal)
1794
 
        && (lastMapped != event->xfocus.window))
 
1818
    if ((event->xfocus.mode != NotifyNormal) &&
 
1819
        (lastMapped != event->xfocus.window))
1795
1820
        return;
1796
1821
 
1797
1822
    lastMapped = 0;
1798
 
    w = screen->findWindow (event->xfocus.window);
1799
 
    if (w == NULL || w->id () == screen->activeWindow ())
1800
 
        return;
 
1823
    CompWindow *w = screen->findWindow (event->xfocus.window);
1801
1824
 
1802
 
    if (time(NULL) - lastChange < optionGetFollowFocusDelay () ||
 
1825
    if (w == NULL                                               ||
 
1826
        w->id () == screen->activeWindow ()                     ||
 
1827
        time(NULL) - lastChange < optionGetFollowFocusDelay ()  ||
1803
1828
        !optionGetFollowFocus ())
1804
1829
        return;
1805
1830
 
1806
 
    out = screen->outputDeviceForGeometry (w->geometry ());
 
1831
    int out = screen->outputDeviceForGeometry (w->geometry ());
 
1832
 
1807
1833
    if (!isActive (out) &&
1808
1834
        !optionGetAlwaysFocusFitWindow ())
1809
1835
        return;
 
1836
 
1810
1837
    if (optionGetFocusFitWindow ())
1811
1838
    {
1812
 
        int width = w->width () + w->border ().left + w->border ().right;
1813
 
        int height = w->height () + w->border ().top + w->border ().bottom;
1814
 
        float scale = MAX ((float) width/screen->outputDevs ().at(out).width (),
1815
 
                           (float) height/screen->outputDevs ().at (out).height ());
 
1839
        int width  = w->width ()  + w->border ().left + w->border ().right;
 
1840
        int height = w->height () + w->border ().top  + w->border ().bottom;
 
1841
        float scale = MAX (width  / static_cast <float> (screen->outputDevs ().at (out).width ()),
 
1842
                           height / static_cast <float> (screen->outputDevs ().at (out).height ()));
 
1843
 
1816
1844
        if (scale > optionGetAutoscaleMin ())
1817
 
                setScale (out, scale);
 
1845
            setScale (out, scale);
1818
1846
    }
1819
1847
 
1820
1848
    areaToWindow (w);
1822
1850
    toggleFunctions (true);
1823
1851
}
1824
1852
 
1825
 
 
1826
1853
/* Event handler. Pass focus-related events on and handle XFixes events. */
1827
1854
void
1828
1855
EZoomScreen::handleEvent (XEvent *event)
1829
1856
{
1830
 
    switch (event->type) {
 
1857
    switch (event->type)
 
1858
    {
1831
1859
        case MotionNotify:
1832
1860
            if (grabIndex)
1833
1861
            {
1834
 
                if (pointerX < clickPos.x ())
1835
 
                {
 
1862
                if (pointerX < clickPos.x ())
 
1863
                {
1836
1864
                    box.setX (pointerX);
1837
1865
                    box.setWidth (clickPos.x () - pointerX);
1838
 
                }
1839
 
                else
1840
 
                {
 
1866
                }
 
1867
                else
1841
1868
                    box.setWidth (pointerX - clickPos.x ());
1842
 
                }
1843
1869
 
1844
 
                if (pointerY < clickPos.y ())
1845
 
                {
 
1870
                if (pointerY < clickPos.y ())
 
1871
                {
1846
1872
                    box.setY (pointerY);
1847
1873
                    box.setHeight (clickPos.y () - pointerY);
1848
 
                }
1849
 
                else
1850
 
                {
 
1874
                }
 
1875
                else
1851
1876
                    box.setHeight (pointerY - clickPos.y ());
1852
 
                }
1853
 
                cScreen->damageScreen ();
 
1877
 
 
1878
                cScreen->damageScreen ();
1854
1879
            }
 
1880
 
1855
1881
            break;
1856
1882
 
1857
1883
        case FocusIn:
1858
1884
        case MapNotify:
1859
1885
            focusTrack (event);
1860
1886
            break;
 
1887
 
1861
1888
        default:
1862
1889
            if (event->type == fixesEventBase + XFixesCursorNotify)
1863
1890
            {
1864
1891
                //XFixesCursorNotifyEvent *cev = (XFixesCursorNotifyEvent *)
1865
 
                    //event;
1866
 
                    if (cursor.isSet)
1867
 
                        updateCursor (&cursor);
 
1892
                //event;
 
1893
                if (cursor.isSet)
 
1894
                    updateCursor (&cursor);
1868
1895
            }
 
1896
 
1869
1897
            break;
1870
1898
    }
1871
1899
 
1899
1927
    GLScreenInterface::setHandler (gScreen, false);
1900
1928
 
1901
1929
    int major, minor;
1902
 
    unsigned int n;
 
1930
 
1903
1931
    fixesSupported =
1904
1932
        XFixesQueryExtension(screen->dpy (),
1905
1933
                             &fixesEventBase,
1912
1940
    else
1913
1941
        canHideCursor = false;
1914
1942
 
1915
 
    n = screen->outputDevs ().size ();
 
1943
    unsigned int n = screen->outputDevs ().size ();
1916
1944
 
1917
 
    for (unsigned int i = 0; i < n; i++)
 
1945
    for (unsigned int i = 0; i < n; ++i)
1918
1946
    {
1919
1947
        /* zs->grabbed is a mask ... Thus this limit */
1920
1948
        if (i > sizeof (long int) * 8)
1921
1949
            break;
 
1950
 
1922
1951
        ZoomArea za (i);
1923
1952
        zooms.push_back (za);
1924
1953
    }
1962
1991
                                        &EZoomScreen::zoomFitWindowToZoom, this,
1963
1992
                                        _1, _2, _3));
1964
1993
 
1965
 
 
1966
1994
    optionSetLockZoomKeyInitiate (boost::bind (&EZoomScreen::lockZoomAction,
1967
1995
                                                this, _1, _2, _3));
1968
1996
    optionSetZoomBoxButtonInitiate (boost::bind (&EZoomScreen::zoomBoxActivate,
1976
2004
    optionSetEnsureVisibilityInitiate (boost::bind (
1977
2005
                                        &EZoomScreen::ensureVisibilityAction, this,
1978
2006
                                        _1, _2, _3));
1979
 
 
1980
2007
}
1981
2008
 
1982
2009
EZoomScreen::~EZoomScreen ()
1994
2021
bool
1995
2022
ZoomPluginVTable::init ()
1996
2023
{
1997
 
    if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION) ||
1998
 
        !CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI) ||
1999
 
        !CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI) ||
2000
 
        !CompPlugin::checkPluginABI ("mousepoll", COMPIZ_MOUSEPOLL_ABI))
2001
 
        return false;
 
2024
    if (CompPlugin::checkPluginABI ("core", CORE_ABIVERSION)            &&
 
2025
        CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI)  &&
 
2026
        CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI)        &&
 
2027
        CompPlugin::checkPluginABI ("mousepoll", COMPIZ_MOUSEPOLL_ABI))
 
2028
        return true;
2002
2029
 
2003
 
    return true;
 
2030
    return false;
2004
2031
}