~ubuntu-branches/ubuntu/precise/nvidia-settings/precise

« back to all changes in this revision

Viewing changes to src/gtk+-2.x/ctkdisplayconfig-utils.c

  • Committer: Bazaar Package Importer
  • Author(s): Alberto Milone (tseliot)
  • Date: 2009-01-31 17:21:51 UTC
  • mfrom: (1.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20090131172151-j7hdq3osfau2y51n
Tags: 180.25-0ubuntu1
* New upstream release (LP: #315667)
* debian/patches/02_add_missing_serverlayout.dpatch: drop patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
239
239
 *   "mode_name"  dot_clock  timings  flags
240
240
 *
241
241
 **/
242
 
static nvModeLinePtr modeline_parse(const char *modeline_str,
 
242
static nvModeLinePtr modeline_parse(nvDisplayPtr display,
 
243
                                    const char *modeline_str,
243
244
                                    const int broken_doublescan_modelines)
244
245
{
245
246
    nvModeLinePtr modeline = NULL;
356
357
        free(tmp);
357
358
    }
358
359
 
359
 
 
360
 
    /*
361
 
     * Calculate the vertical refresh rate of the modeline in Hz;
362
 
     * divide by two for double scan modes (if the double scan
363
 
     * modeline isn't broken; i.e., already has a correct vtotal), and
364
 
     * multiply by two for interlaced modes (so that we report the
365
 
     * field rate, rather than the frame rate)
366
 
     */
367
 
 
368
 
    htotal = (double) modeline->data.htotal;
369
 
    vtotal = (double) modeline->data.vtotal;
370
 
 
371
 
    pclk = strtod(modeline->data.clock, &nptr);
372
 
 
373
 
    if ((pclk == 0.0) || !nptr || *nptr != '\0' || ((htotal * vtotal) == 0)) {
374
 
        nv_warning_msg("Failed to compute the refresh rate "
375
 
                       "for the modeline '%s'", str);
376
 
        goto fail;
377
 
    }
378
 
 
379
 
    modeline->refresh_rate = (pclk * 1000000.0) / (htotal * vtotal);
380
 
 
381
 
    factor = 1.0;
382
 
 
383
 
    if ((modeline->data.flags & V_DBLSCAN) && !broken_doublescan_modelines) {
384
 
        factor *= 0.5;
385
 
    }
386
 
 
387
 
    if (modeline->data.flags & V_INTERLACE) {
388
 
        factor *= 2.0;
389
 
    }
390
 
 
391
 
    modeline->refresh_rate *= factor;
 
360
    modeline->refresh_rate = 0;
 
361
    if (display->is_sdi && display->gpu->num_gvo_modes) {
 
362
        /* Fetch the SDI refresh rate of the mode from the gvo mode table */
 
363
        int i;
 
364
        for (i = 0; i < display->gpu->num_gvo_modes; i++) {
 
365
            if (display->gpu->gvo_mode_data[i].id &&
 
366
                display->gpu->gvo_mode_data[i].name &&
 
367
                !strcmp(display->gpu->gvo_mode_data[i].name,
 
368
                        modeline->data.identifier)) {
 
369
                modeline->refresh_rate = display->gpu->gvo_mode_data[i].rate;
 
370
                modeline->refresh_rate /= 1000.0;
 
371
                break;
 
372
            }
 
373
        }
 
374
    }
 
375
 
 
376
    if (modeline->refresh_rate == 0) {
 
377
        /*
 
378
         * Calculate the vertical refresh rate of the modeline in Hz;
 
379
         * divide by two for double scan modes (if the double scan
 
380
         * modeline isn't broken; i.e., already has a correct vtotal), and
 
381
         * multiply by two for interlaced modes (so that we report the
 
382
         * field rate, rather than the frame rate)
 
383
         */
 
384
 
 
385
        htotal = (double) modeline->data.htotal;
 
386
        vtotal = (double) modeline->data.vtotal;
 
387
 
 
388
        pclk = strtod(modeline->data.clock, &nptr);
 
389
 
 
390
        if ((pclk == 0.0) || !nptr || *nptr != '\0' || ((htotal * vtotal) == 0)) {
 
391
            nv_warning_msg("Failed to compute the refresh rate "
 
392
                           "for the modeline '%s'", str);
 
393
            goto fail;
 
394
        }
 
395
 
 
396
        modeline->refresh_rate = (pclk * 1000000.0) / (htotal * vtotal);
 
397
 
 
398
        factor = 1.0;
 
399
 
 
400
        if ((modeline->data.flags & V_DBLSCAN) && !broken_doublescan_modelines) {
 
401
            factor *= 0.5;
 
402
        }
 
403
 
 
404
        if (modeline->data.flags & V_INTERLACE) {
 
405
            factor *= 2.0;
 
406
        }
 
407
 
 
408
        modeline->refresh_rate *= factor;
 
409
    }
392
410
 
393
411
    /* Restore the locale */
394
412
    if (old_locale) {
921
939
    str = modeline_strs;
922
940
    while (strlen(str)) {
923
941
 
924
 
        modeline = modeline_parse(str, broken_doublescan_modelines);
 
942
        modeline = modeline_parse(display, str, broken_doublescan_modelines);
925
943
        if (!modeline) {
926
944
            *err_str = g_strdup_printf("Failed to parse the following "
927
945
                                       "modeline of display device\n"
937
955
        }
938
956
 
939
957
        /* Add the modeline at the end of the display's modeline list */
940
 
        display->modelines = (nvModeLinePtr)xconfigAddListItem
941
 
            ((GenericListPtr)display->modelines, (GenericListPtr)modeline);
 
958
        xconfigAddListItem((GenericListPtr *)(&display->modelines),
 
959
                           (GenericListPtr)modeline);
942
960
        display->num_modelines++;
943
961
 
944
962
        /* Get next modeline string */
1243
1261
 
1244
1262
 
1245
1263
    /* Add the metamode at the end of the screen's metamode list */
1246
 
    screen->metamodes =
1247
 
        (nvMetaModePtr)xconfigAddListItem((GenericListPtr)screen->metamodes,
1248
 
                                          (GenericListPtr)metamode);
 
1264
    xconfigAddListItem((GenericListPtr *)(&screen->metamodes),
 
1265
                       (GenericListPtr)metamode);
1249
1266
 
1250
1267
 
1251
1268
    /* Split up the metamode into separate modes */
1316
1333
        
1317
1334
 
1318
1335
        /* Add the mode at the end of the display's mode list */
1319
 
        display->modes =
1320
 
            (nvModePtr)xconfigAddListItem((GenericListPtr)display->modes,
1321
 
                                          (GenericListPtr)mode);
 
1336
        xconfigAddListItem((GenericListPtr *)(&display->modes),
 
1337
                           (GenericListPtr)mode);
1322
1338
        display->num_modes++;
1323
1339
        
1324
1340
    } /* Done parsing a single metamode */
1391
1407
            }
1392
1408
 
1393
1409
            /* Add the mode at the end of display's mode list */
1394
 
            display->modes =
1395
 
                (nvModePtr)xconfigAddListItem((GenericListPtr)display->modes,
1396
 
                                              (GenericListPtr)mode);
 
1410
            xconfigAddListItem((GenericListPtr *)(&display->modes),
 
1411
                               (GenericListPtr)mode);
1397
1412
            display->num_modes++;
1398
1413
 
1399
1414
            metamode = metamode->next;
1651
1666
        }
1652
1667
 
1653
1668
        /* Remove the display from the GPU */
1654
 
        gpu->displays =
1655
 
            (nvDisplayPtr)xconfigRemoveListItem((GenericListPtr)gpu->displays,
1656
 
                                                (GenericListPtr)display);
 
1669
        xconfigRemoveListItem((GenericListPtr *)(&gpu->displays),
 
1670
                              (GenericListPtr)display);
1657
1671
        gpu->connected_displays &= ~(display->device_mask);
1658
1672
        gpu->num_displays--;
1659
1673
    }
1688
1702
 
1689
1703
 
1690
1704
 
 
1705
/** gpu_query_gvo_mode_info() ****************************************
 
1706
 *
 
1707
 * Adds GVO mode information to the GPU's gvo mode data table at
 
1708
 * the given table index.
 
1709
 *
 
1710
 **/
 
1711
static Bool gpu_query_gvo_mode_info(nvGpuPtr gpu, int mode_id, int table_idx)
 
1712
{
 
1713
    ReturnStatus ret1, ret2;
 
1714
    GvoModeData *data;
 
1715
    int rate;
 
1716
    char *name;
 
1717
 
 
1718
 
 
1719
    if (!gpu || table_idx >= gpu->num_gvo_modes) {
 
1720
        return FALSE;
 
1721
    }
 
1722
 
 
1723
    data = &(gpu->gvo_mode_data[table_idx]);
 
1724
 
 
1725
    ret1 = NvCtrlGetDisplayAttribute(gpu->handle,
 
1726
                                     mode_id,
 
1727
                                     NV_CTRL_GVO_VIDEO_FORMAT_REFRESH_RATE,
 
1728
                                     &(rate));
 
1729
    
 
1730
    ret2 = NvCtrlGetStringDisplayAttribute(gpu->handle,
 
1731
                                           mode_id,
 
1732
                                           NV_CTRL_STRING_GVO_VIDEO_FORMAT_NAME,
 
1733
                                           &(name));
 
1734
 
 
1735
    if ((ret1 == NvCtrlSuccess) && (ret2 == NvCtrlSuccess)) {
 
1736
        data->id = mode_id;
 
1737
        data->rate = rate;
 
1738
        data->name = name;
 
1739
        return TRUE;
 
1740
    }
 
1741
 
 
1742
    XFree(name);
 
1743
    return FALSE;
 
1744
}
 
1745
 
 
1746
 
1691
1747
/** gpu_add_display_from_server() ************************************
1692
1748
 *
1693
1749
 *  Adds the display with the device mask given to the GPU structure.
1726
1782
    }
1727
1783
 
1728
1784
 
 
1785
    /* Query if this display is an SDI display */
 
1786
    ret = NvCtrlGetDisplayAttribute(gpu->handle, device_mask,
 
1787
                                    NV_CTRL_IS_GVO_DISPLAY,
 
1788
                                    &(display->is_sdi));
 
1789
    if (ret != NvCtrlSuccess) {
 
1790
        nv_warning_msg("Failed to query if display device\n"
 
1791
                       "0x%08x connected to GPU-%d '%s' is an\n"
 
1792
                       "SDI device.",
 
1793
                       device_mask, NvCtrlGetTargetId(gpu->handle),
 
1794
                       gpu->name);
 
1795
        display->is_sdi = FALSE;
 
1796
    }
 
1797
 
 
1798
 
 
1799
    /* Load the SDI mode table so we can report accurate refresh rates. */
 
1800
    if (display->is_sdi && !gpu->gvo_mode_data) {
 
1801
        unsigned int valid1 = 0;
 
1802
        unsigned int valid2 = 0;
 
1803
        NVCTRLAttributeValidValuesRec valid;
 
1804
 
 
1805
        ret = NvCtrlGetValidAttributeValues(gpu->handle,
 
1806
                                            NV_CTRL_GVO_OUTPUT_VIDEO_FORMAT,
 
1807
                                            &valid);
 
1808
        if ((ret != NvCtrlSuccess) ||
 
1809
            (valid.type != ATTRIBUTE_TYPE_INT_BITS)) {
 
1810
            valid1 = 0;
 
1811
        } else {
 
1812
            valid1 = valid.u.bits.ints;
 
1813
        }
 
1814
        
 
1815
        ret = NvCtrlGetValidAttributeValues(gpu->handle,
 
1816
                                            NV_CTRL_GVO_OUTPUT_VIDEO_FORMAT2,
 
1817
                                            &valid);
 
1818
        if ((ret != NvCtrlSuccess) ||
 
1819
            (valid.type != ATTRIBUTE_TYPE_INT_BITS)) {
 
1820
            valid2 = 0;
 
1821
        } else {
 
1822
            valid2 = valid.u.bits.ints;
 
1823
        }
 
1824
 
 
1825
        /* Count the number of valid modes there are */
 
1826
        gpu->num_gvo_modes = count_number_of_bits(valid1);
 
1827
        gpu->num_gvo_modes += count_number_of_bits(valid2);
 
1828
        if (gpu->num_gvo_modes > 0) {
 
1829
            gpu->gvo_mode_data = (GvoModeData *)calloc(gpu->num_gvo_modes,
 
1830
                                                       sizeof(GvoModeData));
 
1831
        }
 
1832
        if (!gpu->gvo_mode_data) {
 
1833
            gpu->num_gvo_modes = 0;
 
1834
        } else {
 
1835
            // Gather all the bits and dump them into the array
 
1836
            int idx = 0; // Index into gvo_mode_data.
 
1837
            int id = 0;  // Mode ID
 
1838
            while (valid1) {
 
1839
                if (valid1 & 1) {
 
1840
                    if (gpu_query_gvo_mode_info(gpu, id, idx)) {
 
1841
                        idx++;
 
1842
                    }
 
1843
                }
 
1844
                valid1 >>= 1;
 
1845
                id++;
 
1846
            }
 
1847
            while (valid2) {
 
1848
                if (valid2 & 1) {
 
1849
                    if (gpu_query_gvo_mode_info(gpu, id, idx)) {
 
1850
                        idx++;
 
1851
                    }
 
1852
                }
 
1853
                valid2 >>= 1;
 
1854
                id++;
 
1855
            }                
 
1856
        }
 
1857
    }
 
1858
 
 
1859
 
1729
1860
    /* Query the modelines for the display device */
1730
1861
    if (!display_add_modelines_from_server(display, err_str)) {
1731
1862
        nv_warning_msg("Failed to add modelines to display device 0x%08x "
1737
1868
 
1738
1869
 
1739
1870
    /* Add the display at the end of gpu's display list */
1740
 
    gpu->displays =
1741
 
        (nvDisplayPtr)xconfigAddListItem((GenericListPtr)gpu->displays,
1742
 
                                         (GenericListPtr)display);
 
1871
    xconfigAddListItem((GenericListPtr *)(&gpu->displays),
 
1872
                       (GenericListPtr)display);
1743
1873
    gpu->connected_displays |= device_mask;
1744
1874
    gpu->num_displays++;
1745
1875
    return display;
1811
1941
        /* Remove the screen from the GPU */
1812
1942
        gpu = screen->gpu;
1813
1943
        
1814
 
        gpu->screens =
1815
 
            (nvScreenPtr)xconfigRemoveListItem((GenericListPtr)gpu->screens,
1816
 
                                               (GenericListPtr)screen);
 
1944
        xconfigRemoveListItem((GenericListPtr *)(&gpu->screens),
 
1945
                              (GenericListPtr)screen);
1817
1946
        gpu->num_screens--;
1818
1947
        
1819
1948
        /* Make sure other screens in the layout aren't relative
1963
2092
        }
1964
2093
    }
1965
2094
    /* Add the screen at the end of the gpu's screen list */
1966
 
    gpu->screens =
1967
 
        (nvScreenPtr)xconfigAddListItem((GenericListPtr)gpu->screens,
1968
 
                                        (GenericListPtr)screen);
 
2095
    xconfigAddListItem((GenericListPtr *)(&gpu->screens),
 
2096
                       (GenericListPtr)screen);
1969
2097
    gpu->num_screens++;
1970
2098
    return TRUE;
1971
2099
 
2256
2384
 
2257
2385
 
2258
2386
    /* Add the GPU at the end of the layout's GPU list */
2259
 
    layout->gpus = (nvGpuPtr)xconfigAddListItem((GenericListPtr)layout->gpus,
2260
 
                                                (GenericListPtr)gpu);
 
2387
    xconfigAddListItem((GenericListPtr *)(&layout->gpus),
 
2388
                       (GenericListPtr)gpu);
2261
2389
    layout->num_gpus++;
2262
2390
    return TRUE;
2263
2391