#include "minitru-int.h" struct mt_mode * mt_modes_add(struct mt_mode *modes, struct mt_mode *new) { if (!modes) return new; if (new) { struct mt_mode *m = modes; while (m->next) m = m->next; m->next = new; } return modes; } hidden struct mt_mode * mt_mode_alloc(void) { return calloc(1, sizeof(struct mt_mode)); } struct mt_mode * mt_mode_copy(const struct mt_mode *mode) { struct mt_mode *ret = mt_mode_alloc(); memcpy(ret, mode, sizeof(*ret)); return ret; } float mt_mode_hsync(const struct mt_mode *mode) { return (float)mode->clock / (float)mode->htotal; } float mt_mode_vsync(const struct mt_mode *mode) { float refresh = mode->clock * 1000.0 / mode->htotal / mode->vtotal; if (mode->flags & MT_FLAG_INTERLACED) refresh *= 2; if (mode->flags & MT_FLAG_DBLSCAN) refresh /= 2; return refresh; } static int mode_refresh(const struct mt_mode *mode) { return (int)(mt_mode_vsync(mode) + 0.5); } /* XXX fix RB flags */ static const struct mt_mode dmt_modes[] = { { 0, 0, 31500, 640, 672, 736, 832, 0, 350, 382, 385, 445, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC }, /* 640x350@85Hz */ { 0, 0, 31500, 640, 672, 736, 832, 0, 400, 401, 404, 445, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 640x400@85Hz */ { 0, 0, 35500, 720, 756, 828, 936, 0, 400, 401, 404, 446, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 720x400@85Hz */ { 0, 0, 25175, 640, 656, 752, 800, 0, 480, 490, 492, 525, 0, MT_FLAG_NHSYNC | MT_FLAG_NVSYNC }, /* 640x480@60Hz */ { 0, 0, 31500, 640, 664, 704, 832, 0, 480, 489, 492, 520, 0, MT_FLAG_NHSYNC | MT_FLAG_NVSYNC }, /* 640x480@72Hz */ { 0, 0, 31500, 640, 656, 720, 840, 0, 480, 481, 484, 500, 0, MT_FLAG_NHSYNC | MT_FLAG_NVSYNC }, /* 640x480@75Hz */ { 0, 0, 36000, 640, 696, 752, 832, 0, 480, 481, 484, 509, 0, MT_FLAG_NHSYNC | MT_FLAG_NVSYNC }, /* 640x480@85Hz */ { 0, 0, 36000, 800, 824, 896, 1024, 0, 600, 601, 603, 625, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 800x600@56Hz */ { 0, 0, 40000, 800, 840, 968, 1056, 0, 600, 601, 605, 628, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 800x600@60Hz */ { 0, 0, 50000, 800, 856, 976, 1040, 0, 600, 637, 643, 666, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 800x600@72Hz */ { 0, 0, 49500, 800, 816, 896, 1056, 0, 600, 601, 604, 625, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 800x600@75Hz */ { 0, 0, 56250, 800, 832, 896, 1048, 0, 600, 601, 604, 631, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 800x600@85Hz */ { 0, 0, 73250, 800, 848, 880, 960, 0, 600, 603, 607, 636, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 800x600@120Hz RB */ { 0, 0, 33750, 848, 864, 976, 1088, 0, 480, 486, 494, 517, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 848x480@60Hz */ { 0, 0, 44900, 1024, 1032, 1208, 1264, 0, 768, 768, 772, 817, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC | MT_FLAG_INTERLACED }, /* 1024x768@43Hz (interlaced) */ { 0, 0, 65000, 1024, 1048, 1184, 1344, 0, 768, 771, 777, 806, 0, MT_FLAG_NHSYNC | MT_FLAG_NVSYNC }, /* 1024x768@60Hz */ { 0, 0, 75000, 1024, 1048, 1184, 1328, 0, 768, 771, 777, 806, 0, MT_FLAG_NHSYNC | MT_FLAG_NVSYNC }, /* 1024x768@70Hz */ { 0, 0, 78750, 1024, 1040, 1136, 1312, 0, 768, 769, 772, 800, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 1024x768@75Hz */ { 0, 0, 94500, 1024, 1072, 1168, 1376, 0, 768, 769, 772, 808, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 1024x768@85Hz */ { 0, 0, 115500, 1024, 1072, 1104, 1184, 0, 768, 771, 775, 813, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1024x768@120Hz RB */ { 0, 0, 108000, 1152, 1216, 1344, 1600, 0, 864, 865, 868, 900, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 1152x864@75Hz */ { 0, 0, 68250, 1280, 1328, 1360, 1440, 0, 768, 771, 778, 790, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1280x768@60Hz RB */ { 0, 0, 79500, 1280, 1344, 1472, 1664, 0, 768, 771, 778, 798, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1280x768@60Hz */ { 0, 0, 102250, 1280, 1360, 1488, 1696, 0, 768, 771, 778, 805, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1280x768@75Hz */ { 0, 0, 117500, 1280, 1360, 1496, 1712, 0, 768, 771, 778, 809, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1280x768@85Hz */ { 0, 0, 140250, 1280, 1328, 1360, 1440, 0, 768, 771, 778, 813, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1280x768@120Hz RB */ { 0, 0, 71000, 1280, 1328, 1360, 1440, 0, 800, 803, 809, 823, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1280x800@60Hz RB */ { 0, 0, 83500, 1280, 1352, 1480, 1680, 0, 800, 803, 809, 831, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1280x800@60Hz */ { 0, 0, 106500, 1280, 1360, 1488, 1696, 0, 800, 803, 809, 838, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1280x800@75Hz */ { 0, 0, 122500, 1280, 1360, 1496, 1712, 0, 800, 803, 809, 843, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1280x800@85Hz */ { 0, 0, 146250, 1280, 1328, 1360, 1440, 0, 800, 803, 809, 847, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1280x800@120Hz RB */ { 0, 0, 108000, 1280, 1376, 1488, 1800, 0, 960, 961, 964, 1000, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 1280x960@60Hz */ { 0, 0, 148500, 1280, 1344, 1504, 1728, 0, 960, 961, 964, 1011, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 1280x960@85Hz */ { 0, 0, 175500, 1280, 1328, 1360, 1440, 0, 960, 963, 967, 1017, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1280x960@120Hz RB */ { 0, 0, 108000, 1280, 1328, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 1280x1024@60Hz */ { 0, 0, 135000, 1280, 1296, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 1280x1024@75Hz */ { 0, 0, 157500, 1280, 1344, 1504, 1728, 0, 1024, 1025, 1028, 1072, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 1280x1024@85Hz */ { 0, 0, 187250, 1280, 1328, 1360, 1440, 0, 1024, 1027, 1034, 1084, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1280x1024@120Hz RB */ { 0, 0, 85500, 1360, 1424, 1536, 1792, 0, 768, 771, 777, 795, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 1360x768@60Hz */ { 0, 0, 148250, 1360, 1408, 1440, 1520, 0, 768, 771, 776, 813, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1360x768@120Hz RB */ { 0, 0, 101000, 1400, 1448, 1480, 1560, 0, 1050, 1053, 1057, 1080, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1400x1050@60Hz RB */ { 0, 0, 121750, 1400, 1488, 1632, 1864, 0, 1050, 1053, 1057, 1089, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1400x1050@60Hz */ { 0, 0, 156000, 1400, 1504, 1648, 1896, 0, 1050, 1053, 1057, 1099, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1400x1050@75Hz */ { 0, 0, 179500, 1400, 1504, 1656, 1912, 0, 1050, 1053, 1057, 1105, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1400x1050@85Hz */ { 0, 0, 208000, 1400, 1448, 1480, 1560, 0, 1050, 1053, 1057, 1112, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1400x1050@120Hz RB */ { 0, 0, 88750, 1440, 1488, 1520, 1600, 0, 900, 903, 909, 926, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1440x900@60Hz RB */ { 0, 0, 106500, 1440, 1520, 1672, 1904, 0, 900, 903, 909, 934, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1440x900@60Hz */ { 0, 0, 136750, 1440, 1536, 1688, 1936, 0, 900, 903, 909, 942, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1440x900@75Hz */ { 0, 0, 157000, 1440, 1544, 1696, 1952, 0, 900, 903, 909, 948, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1440x900@85Hz */ { 0, 0, 182750, 1440, 1488, 1520, 1600, 0, 900, 903, 909, 953, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1440x900@120Hz RB */ { 0, 0, 162000, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 1600x1200@60Hz */ { 0, 0, 175500, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 1600x1200@65Hz */ { 0, 0, 189000, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 1600x1200@70Hz */ { 0, 0, 202500, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 1600x1200@75Hz */ { 0, 0, 229500, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, MT_FLAG_PHSYNC | MT_FLAG_PVSYNC }, /* 1600x1200@85Hz */ { 0, 0, 268250, 1600, 1648, 1680, 1760, 0, 1200, 1203, 1207, 1271, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1600x1200@120Hz RB */ { 0, 0, 119000, 1680, 1728, 1760, 1840, 0, 1050, 1053, 1059, 1080, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1680x1050@60Hz RB */ { 0, 0, 146250, 1680, 1784, 1960, 2240, 0, 1050, 1053, 1059, 1089, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1680x1050@60Hz */ { 0, 0, 187000, 1680, 1800, 1976, 2272, 0, 1050, 1053, 1059, 1099, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1680x1050@75Hz */ { 0, 0, 214750, 1680, 1808, 1984, 2288, 0, 1050, 1053, 1059, 1105, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1680x1050@85Hz */ { 0, 0, 245500, 1680, 1728, 1760, 1840, 0, 1050, 1053, 1059, 1112, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1680x1050@120Hz RB */ { 0, 0, 204750, 1792, 1920, 2120, 2448, 0, 1344, 1345, 1348, 1394, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1792x1344@60Hz */ { 0, 0, 261000, 1792, 1888, 2104, 2456, 0, 1344, 1345, 1348, 1417, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1792x1344@75Hz */ { 0, 0, 333250, 1792, 1840, 1872, 1952, 0, 1344, 1347, 1351, 1423, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1792x1344@120Hz RB */ { 0, 0, 218250, 1856, 1952, 2176, 2528, 0, 1392, 1393, 1396, 1439, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1856x1392@60Hz */ { 0, 0, 288000, 1856, 1984, 2208, 2560, 0, 1392, 1393, 1396, 1500, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1856x1392@75Hz */ { 0, 0, 356500, 1856, 1904, 1936, 2016, 0, 1392, 1395, 1399, 1474, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1856x1392@120Hz RB */ { 0, 0, 154000, 1920, 1968, 2000, 2080, 0, 1200, 1203, 1209, 1235, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1920x1200@60Hz RB */ { 0, 0, 193250, 1920, 2056, 2256, 2592, 0, 1200, 1203, 1209, 1245, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1920x1200@60Hz */ { 0, 0, 245250, 1920, 2056, 2264, 2608, 0, 1200, 1203, 1209, 1255, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1920x1200@75Hz */ { 0, 0, 281250, 1920, 2064, 2272, 2624, 0, 1200, 1203, 1209, 1262, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1920x1200@85Hz */ { 0, 0, 317000, 1920, 1968, 2000, 2080, 0, 1200, 1203, 1209, 1271, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1920x1200@120Hz RB */ { 0, 0, 234000, 1920, 2048, 2256, 2600, 0, 1440, 1441, 1444, 1500, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1920x1440@60Hz */ { 0, 0, 297000, 1920, 2064, 2288, 2640, 0, 1440, 1441, 1444, 1500, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 1920x1440@75Hz */ { 0, 0, 380500, 1920, 1968, 2000, 2080, 0, 1440, 1443, 1447, 1525, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 1920x1440@120Hz RB */ { 0, 0, 268500, 2560, 2608, 2640, 2720, 0, 1600, 1603, 1609, 1646, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 2560x1600@60Hz RB */ { 0, 0, 348500, 2560, 2752, 3032, 3504, 0, 1600, 1603, 1609, 1658, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 2560x1600@60Hz */ { 0, 0, 443250, 2560, 2768, 3048, 3536, 0, 1600, 1603, 1609, 1672, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 2560x1600@75Hz */ { 0, 0, 505250, 2560, 2768, 3048, 3536, 0, 1600, 1603, 1609, 1682, 0, MT_FLAG_NHSYNC | MT_FLAG_PVSYNC }, /* 2560x1600@85Hz */ { 0, 0, 552750, 2560, 2608, 2640, 2720, 0, 1600, 1603, 1609, 1694, 0, MT_FLAG_PHSYNC | MT_FLAG_NVSYNC | MT_FLAG_REDUCED }, /* 2560x1600@120Hz RB */ }; static const int num_dmt_modes; hidden struct mt_mode * find_dmt_mode(uint32_t hsize, uint32_t vsize, uint32_t refresh, uint32_t rb) { const struct mt_mode *ret; int i; for (i = 0; i < num_dmt_modes; i++) { ret = dmt_modes + i; if (!rb && (ret->flags & MT_FLAG_REDUCED)) continue; if (ret->hdisplay == hsize && ret->vdisplay == vsize && refresh == mode_refresh(ret)) return mt_mode_copy(ret); } return NULL; } struct mt_mode *mt_dmt_mode_list(void) { int i; struct mt_mode *ret; for (i = 0; i < num_dmt_modes; i++) ret = mt_modes_add(ret, mt_mode_copy(dmt_modes + i)); return ret; }