~ubuntu-branches/ubuntu/saucy/nvidia-settings-updates/saucy

« back to all changes in this revision

Viewing changes to src/libXNVCtrlAttributes/NvCtrlAttributesXrandr.c

  • Committer: Package Import Robot
  • Author(s): Alberto Milone
  • Date: 2012-06-25 16:39:50 UTC
  • mfrom: (1.1.4)
  • Revision ID: package-import@ubuntu.com-20120625163950-qsci6udwk8mbyrdu
Tags: 302.17-0ubuntu1
* New upstream release.
* Refresh 04_nvidia-settings_natty_ftbs.patch.
* Drop 02_nvidia-settings-format-string.patch which
  is now upstream.
* debian/rules:
  - Make sure to install the new sources correctly.

Show diffs side-by-side

added added

removed removed

Lines of Context:
61
61
 
62
62
    void (* XRRSelectInput)
63
63
         (Display *dpy, Window window, int mask);
64
 
         
65
 
    XRRScreenConfiguration * (* XRRGetScreenInfo)
66
 
         (Display *dpy, Drawable draw);
67
 
         
68
 
    SizeID (* XRRConfigCurrentConfiguration)
69
 
         (XRRScreenConfiguration *config, Rotation *rotation);
70
 
 
71
 
    short (* XRRConfigCurrentRate)
72
 
         (XRRScreenConfiguration *config);    
73
 
         
74
 
    Rotation (* XRRConfigRotations)
75
 
         (XRRScreenConfiguration *config, Rotation *rotation);
76
 
     
77
 
    XRRScreenSize * (* XRRConfigSizes)
78
 
         (XRRScreenConfiguration *config, int *nsizes);
79
 
    
80
 
    short * (* XRRConfigRates)
81
 
         (XRRScreenConfiguration *config, int size_index, int *nrates);
82
 
 
83
 
    Status (* XRRSetScreenConfig)
84
 
         (Display *dpy, XRRScreenConfiguration *config, Drawable draw,
85
 
          int size_index, Rotation rotation, Time timestamp);
86
 
 
87
 
    Status (* XRRSetScreenConfigAndRate)
88
 
         (Display *dpy, XRRScreenConfiguration *config, Drawable draw,
89
 
          int size_index, Rotation rotation, short rate, Time timestamp);
90
 
 
91
 
    void (* XRRFreeScreenConfigInfo)
92
 
         (XRRScreenConfiguration *);
93
64
 
94
65
} __libXrandrInfo;
95
66
 
145
116
        NV_DLSYM(__libXrandr->handle, "XRRSelectInput");
146
117
    if ((error_str = dlerror()) != NULL) goto fail;
147
118
 
148
 
    __libXrandr->XRRGetScreenInfo =
149
 
        NV_DLSYM(__libXrandr->handle, "XRRGetScreenInfo");
150
 
    if ((error_str = dlerror()) != NULL) goto fail;
151
 
 
152
 
    __libXrandr->XRRConfigCurrentConfiguration =
153
 
        NV_DLSYM(__libXrandr->handle, "XRRConfigCurrentConfiguration");
154
 
    if ((error_str = dlerror()) != NULL) goto fail;
155
 
 
156
 
    __libXrandr->XRRConfigCurrentRate =
157
 
        NV_DLSYM(__libXrandr->handle, "XRRConfigCurrentRate");
158
 
    if ((error_str = dlerror()) != NULL) goto fail;
159
 
 
160
 
    __libXrandr->XRRConfigRotations =
161
 
        NV_DLSYM(__libXrandr->handle, "XRRConfigRotations");
162
 
    if ((error_str = dlerror()) != NULL) goto fail;
163
 
 
164
 
    __libXrandr->XRRConfigSizes =
165
 
        NV_DLSYM(__libXrandr->handle, "XRRConfigSizes");
166
 
    if ((error_str = dlerror()) != NULL) goto fail;
167
 
 
168
 
    __libXrandr->XRRConfigRates =
169
 
        NV_DLSYM(__libXrandr->handle, "XRRConfigRates");
170
 
    if ((error_str = dlerror()) != NULL) goto fail;
171
 
 
172
 
    __libXrandr->XRRSetScreenConfig =
173
 
        NV_DLSYM(__libXrandr->handle, "XRRSetScreenConfig");
174
 
    if ((error_str = dlerror()) != NULL) goto fail;
175
 
 
176
 
    __libXrandr->XRRSetScreenConfigAndRate =
177
 
        NV_DLSYM(__libXrandr->handle, "XRRSetScreenConfigAndRate");
178
 
    if ((error_str = dlerror()) != NULL) goto fail;
179
 
 
180
 
    __libXrandr->XRRFreeScreenConfigInfo =
181
 
        NV_DLSYM(__libXrandr->handle, "XRRFreeScreenConfigInfo");
182
 
    if ((error_str = dlerror()) != NULL) goto fail;
183
 
 
184
119
 
185
120
    /* Up the ref count */
186
121
    __libXrandr->ref_count++;
234
169
 
235
170
/******************************************************************************
236
171
 *
237
 
 * Some XR&R functions fails on XFree86 4.3.0 with BadImplementation if the
238
 
 * screen resolution is not the one the server started with.  We work around
239
 
 * that by temporarily installing an error handler, trying the call, and then
240
 
 * disabling the rotation page if it fails.
241
 
 *
242
 
 ****/
243
 
 
244
 
static int errors = 0;
245
 
static int (*old_error_handler)(Display *, XErrorEvent *);
246
 
 
247
 
static int
248
 
error_handler (Display *dpy, XErrorEvent *err)
249
 
{
250
 
    errors++;
251
 
    return 0;
252
 
 
253
 
} /* error_handler() */
254
 
 
255
 
 
256
 
 
257
 
/******************************************************************************
258
 
 *
259
172
 * Initializes the NvCtrlXrandrAttributes Extension by linking the
260
173
 * libXrandr.so.2 library and resolving functions used.
261
174
 *
265
178
NvCtrlInitXrandrAttributes (NvCtrlAttributePrivateHandle *h)
266
179
{
267
180
    NvCtrlXrandrAttributes * xrandr = NULL;
268
 
    XRRScreenConfiguration *sc;
269
 
    Rotation rotation, rotations;
270
181
 
271
182
    /* Check parameters */
272
183
    if ( !h || !h->dpy || h->target_type != NV_CTRL_TARGET_TYPE_X_SCREEN ) {
289
200
    }
290
201
    
291
202
 
292
 
    XSync(h->dpy, False);
293
 
    errors = 0;
294
 
    old_error_handler = XSetErrorHandler(error_handler);
295
 
    
296
203
    /* Verify server support of XRandR extension */
297
204
    if ( !__libXrandr->XRRQueryExtension(h->dpy,
298
205
                                         &(xrandr->event_base),
299
206
                                         &(xrandr->error_base)) ) {
300
 
        XSync(h->dpy, False);
301
 
        XSetErrorHandler(old_error_handler);
302
207
        goto fail;
303
208
    }
304
209
 
307
212
         ((xrandr->major_version < MIN_RANDR_MAJOR) ||
308
213
          ((xrandr->major_version == MIN_RANDR_MAJOR) &&
309
214
           (xrandr->minor_version < MIN_RANDR_MINOR)))) {
310
 
        XSync(h->dpy, False);
311
 
        XSetErrorHandler(old_error_handler);
312
215
        goto fail;
313
216
    }
314
217
   
316
219
    __libXrandr->XRRSelectInput(h->dpy, RootWindow(h->dpy, h->target_id),
317
220
                                RRScreenChangeNotifyMask);
318
221
 
319
 
 
320
 
    /* Try calling a couple functions that are known to fail */
321
 
    sc = __libXrandr->XRRGetScreenInfo(h->dpy, RootWindow(h->dpy, h->target_id));
322
 
    if ( sc ) {
323
 
        rotations = __libXrandr->XRRConfigRotations(sc, &rotation);
324
 
        __libXrandr->XRRFreeScreenConfigInfo(sc);
325
 
    } else {
326
 
        errors++;
327
 
    }
328
 
 
329
 
    XSync(h->dpy, False);
330
 
    XSetErrorHandler(old_error_handler);
331
 
    if ( errors > 0 ) {
332
 
        goto fail;
333
 
    }
334
 
 
335
222
    return xrandr;
336
223
 
337
224
 fail:
368
255
 
369
256
 
370
257
 
371
 
/******************************************************************************
372
 
 *
373
 
 * Retrieves XRandR integer attributes
374
 
 *
375
 
 ****/
376
 
 
377
 
ReturnStatus
378
 
NvCtrlXrandrGetAttribute (NvCtrlAttributePrivateHandle *h,
379
 
                          int attr, int *val)
380
 
{
381
 
    XRRScreenConfiguration *sc;
382
 
    Rotation rotation, rotations;
383
 
 
384
 
 
385
 
    /* Validate */
386
 
    if ( !h || !h->dpy || h->target_type != NV_CTRL_TARGET_TYPE_X_SCREEN ) {
387
 
        return NvCtrlBadHandle;
388
 
    }
389
 
    if ( !h->xrandr || !__libXrandr ) {
390
 
        return NvCtrlMissingExtension;
391
 
    }
392
 
    if ( !val ) {
393
 
        return NvCtrlBadArgument;
394
 
    }
395
 
 
396
 
 
397
 
    /* Get current screen configuration information */
398
 
    sc = __libXrandr->XRRGetScreenInfo(h->dpy, RootWindow(h->dpy,
399
 
                                                          h->target_id));
400
 
    if ( !sc ) {
401
 
        return NvCtrlError;
402
 
    }
403
 
    rotations = __libXrandr->XRRConfigRotations(sc, &rotation);
404
 
    __libXrandr->XRRFreeScreenConfigInfo(sc);
405
 
 
406
 
 
407
 
    /* Fetch right attribute */
408
 
    switch ( attr ) {
409
 
 
410
 
    case NV_CTRL_ATTR_XRANDR_ROTATION_SUPPORTED:
411
 
        /* For rotation to be supported, there must
412
 
         * be at least 2 orientations
413
 
         */
414
 
        *val = ( rotations != 1 && rotations != 2 &&
415
 
                 rotations != 4 && rotations != 8 ) ? 1 : 0;
416
 
        break;
417
 
 
418
 
    case NV_CTRL_ATTR_XRANDR_ROTATIONS:
419
 
        /* Return the available rotations */
420
 
        *val = rotations;
421
 
        break;
422
 
 
423
 
    case NV_CTRL_ATTR_XRANDR_ROTATION:
424
 
        /* Return the current rotation */
425
 
        *val = (int)rotation;
426
 
        break;
427
 
 
428
 
    default:
429
 
        return NvCtrlNoAttribute;
430
 
        break;
431
 
    } /* Done fetching attribute */
432
 
 
433
 
 
434
 
    return NvCtrlSuccess;
435
 
 
436
 
} /* NvCtrlXrandrGetAttribute */
437
 
 
438
 
 
439
 
 
440
 
/******************************************************************************
441
 
 *
442
 
 * Sets XRandR integer attributes
443
 
 *
444
 
 ****/
445
 
 
446
 
static ReturnStatus
447
 
set_rotation(NvCtrlAttributePrivateHandle *h, Rotation rotation)
448
 
{
449
 
    XRRScreenConfiguration *sc;
450
 
    Rotation cur_rotation, rotations;
451
 
    SizeID cur_size;
452
 
    Status ret;
453
 
 
454
 
 
455
 
    assert(h->target_type == NV_CTRL_TARGET_TYPE_X_SCREEN);
456
 
 
457
 
    /* Get current screen configuration information */
458
 
    sc = __libXrandr->XRRGetScreenInfo(h->dpy, RootWindow(h->dpy,
459
 
                                                          h->target_id));
460
 
    if ( !sc ) {
461
 
        return NvCtrlError;
462
 
    }
463
 
    cur_size = __libXrandr->XRRConfigCurrentConfiguration(sc, &cur_rotation);
464
 
    rotations = __libXrandr->XRRConfigRotations(sc, &cur_rotation);
465
 
 
466
 
 
467
 
    /* Check orientation we want is supported */
468
 
    if ( !(rotations & rotation) ) {
469
 
        __libXrandr->XRRFreeScreenConfigInfo(sc);
470
 
        return NvCtrlBadArgument;
471
 
    }
472
 
 
473
 
 
474
 
    /* Set the orientation */
475
 
    ret = __libXrandr->XRRSetScreenConfig(h->dpy, sc,
476
 
                                          RootWindow(h->dpy, h->target_id),
477
 
                                          cur_size, rotation, CurrentTime);
478
 
    __libXrandr->XRRFreeScreenConfigInfo(sc);
479
 
    
480
 
    return ( ret == Success )?NvCtrlSuccess:NvCtrlError;
481
 
 
482
 
} /* set_rotation() */
483
 
 
484
 
 
485
 
ReturnStatus
486
 
NvCtrlXrandrSetAttribute (NvCtrlAttributePrivateHandle *h,
487
 
                          int attr, int val)
488
 
{
489
 
    /* Validate */
490
 
    if ( !h || !h->dpy || h->target_type != NV_CTRL_TARGET_TYPE_X_SCREEN ) {
491
 
        return NvCtrlBadHandle;
492
 
    }
493
 
    if ( !h->xrandr || !__libXrandr ) {
494
 
        return NvCtrlMissingExtension;
495
 
    }
496
 
 
497
 
 
498
 
    /* Set right attribute */
499
 
    switch ( attr ) {
500
 
 
501
 
    case NV_CTRL_ATTR_XRANDR_ROTATION_SUPPORTED:
502
 
        return NvCtrlReadOnlyAttribute;
503
 
        break;
504
 
 
505
 
    case NV_CTRL_ATTR_XRANDR_ROTATIONS:
506
 
        return NvCtrlReadOnlyAttribute;
507
 
        break;
508
 
 
509
 
    case NV_CTRL_ATTR_XRANDR_ROTATION:
510
 
        return set_rotation(h, (Rotation)val);
511
 
        break;
512
 
 
513
 
    default:
514
 
        return NvCtrlNoAttribute;
515
 
        break;
516
 
    }
517
 
 
518
 
    return NvCtrlSuccess;
519
 
 
520
 
} /* NvCtrlXrandrSetAttribute */
521
 
 
522
 
 
523
258
/*
524
259
 * Get Xrandr String Attribute Values
525
260
 */
549
284
    return NvCtrlNoAttribute;
550
285
 
551
286
} /* NvCtrlXrandrGetStringAttribute() */
552
 
 
553
 
 
554
 
/******************************************************************************
555
 
 *
556
 
 * Sets XRandR size and refresh rate.
557
 
 *
558
 
 ****/
559
 
 
560
 
ReturnStatus
561
 
NvCtrlXrandrSetScreenMagicMode (NvCtrlAttributePrivateHandle *h,
562
 
                                int width, int height, int magic_ref_rate)
563
 
{
564
 
    XRRScreenConfiguration *sc;
565
 
    Rotation cur_rotation;
566
 
    int nsizes;
567
 
    XRRScreenSize *sizes;
568
 
    int nrates;
569
 
    short *rates;
570
 
    Status ret;
571
 
 
572
 
 
573
 
    /* Validate */
574
 
    if ( !h || !h->dpy || h->target_type != NV_CTRL_TARGET_TYPE_X_SCREEN ) {
575
 
        return NvCtrlBadHandle;
576
 
    }
577
 
 
578
 
    if ( !h->xrandr || !__libXrandr ) {
579
 
        return NvCtrlMissingExtension;
580
 
    }
581
 
 
582
 
 
583
 
    /* Get current screen configuration information */
584
 
    sc = __libXrandr->XRRGetScreenInfo(h->dpy, RootWindow(h->dpy,
585
 
                                                          h->target_id));
586
 
    if ( !sc ) {
587
 
        return NvCtrlError;
588
 
    }
589
 
    __libXrandr->XRRConfigRotations(sc, &cur_rotation);
590
 
 
591
 
 
592
 
    /* Look for size that has matching refresh rate */
593
 
    sizes = __libXrandr->XRRConfigSizes(sc, &nsizes);
594
 
    while ( --nsizes >= 0 ) {
595
 
 
596
 
        /* Must match in size */
597
 
        if ( sizes[nsizes].width  != width ||
598
 
             sizes[nsizes].height != height ) {
599
 
            continue;
600
 
        }
601
 
 
602
 
        rates = __libXrandr->XRRConfigRates(sc, nsizes, &nrates);
603
 
        while ( --nrates >= 0 ) {
604
 
 
605
 
            /* Set the mode if we found the rate */
606
 
            if ( *rates == magic_ref_rate ) {
607
 
                ret = __libXrandr->XRRSetScreenConfigAndRate
608
 
                    (h->dpy, sc, RootWindow(h->dpy, h->target_id), nsizes,
609
 
                     cur_rotation, magic_ref_rate, CurrentTime);
610
 
                
611
 
                __libXrandr->XRRFreeScreenConfigInfo(sc);
612
 
                return (ret == Success)?NvCtrlSuccess:NvCtrlError;
613
 
            }
614
 
            rates++;
615
 
        }
616
 
    }
617
 
    
618
 
    /* If we are here, then we could not find the correct mode to set */
619
 
    __libXrandr->XRRFreeScreenConfigInfo(sc);
620
 
    return NvCtrlError;
621
 
 
622
 
} /* NvCtrlXrandrSetScreenMagicMode */
623
 
 
624
 
 
625
 
 
626
 
/******************************************************************************
627
 
 *
628
 
 * Gets XRandR size and refresh rate.
629
 
 *
630
 
 ****/
631
 
 
632
 
ReturnStatus
633
 
NvCtrlXrandrGetScreenMagicMode (NvCtrlAttributePrivateHandle *h,
634
 
                                int *width, int *height, int *magic_ref_rate)
635
 
{
636
 
    XRRScreenConfiguration *sc;
637
 
    Rotation cur_rotation;
638
 
    int nsizes;
639
 
    XRRScreenSize *sizes;
640
 
    int cur_size;
641
 
    short cur_rate;
642
 
 
643
 
 
644
 
    /* Validate */
645
 
    if ( !h || !h->dpy || h->target_type != NV_CTRL_TARGET_TYPE_X_SCREEN ) {
646
 
        return NvCtrlBadHandle;
647
 
    }
648
 
 
649
 
    if ( !h->xrandr || !__libXrandr ) {
650
 
        return NvCtrlMissingExtension;
651
 
    }
652
 
 
653
 
 
654
 
    /* Get current screen configuration information */
655
 
    sc = __libXrandr->XRRGetScreenInfo(h->dpy, RootWindow(h->dpy,
656
 
                                                          h->target_id));
657
 
    if ( !sc ) {
658
 
        return NvCtrlError;
659
 
    }
660
 
    cur_size = __libXrandr->XRRConfigCurrentConfiguration(sc, &cur_rotation);
661
 
    cur_rate = __libXrandr->XRRConfigCurrentRate(sc);
662
 
    sizes    = __libXrandr->XRRConfigSizes(sc, &nsizes);
663
 
    if (cur_size >= nsizes) {
664
 
        __libXrandr->XRRFreeScreenConfigInfo(sc);
665
 
        return NvCtrlError;
666
 
    }
667
 
 
668
 
 
669
 
    /* Get the width & height from the size information */
670
 
    *width = sizes[cur_size].width;
671
 
    *height = sizes[cur_size].height;
672
 
    *magic_ref_rate = (int)cur_rate;
673
 
    
674
 
    __libXrandr->XRRFreeScreenConfigInfo(sc);
675
 
    return NvCtrlSuccess;
676
 
 
677
 
} /* NvCtrlXrandrGetScreenMagicMode */