diff options
Diffstat (limited to 'sway/commands/output/mode.c')
-rw-r--r-- | sway/commands/output/mode.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/sway/commands/output/mode.c b/sway/commands/output/mode.c index 5b710713..019d625a 100644 --- a/sway/commands/output/mode.c +++ b/sway/commands/output/mode.c | |||
@@ -20,6 +20,9 @@ struct cmd_results *output_cmd_mode(int argc, char **argv) { | |||
20 | output->custom_mode = 0; | 20 | output->custom_mode = 0; |
21 | } | 21 | } |
22 | 22 | ||
23 | // Reset custom modeline, if any | ||
24 | output->drm_mode.type = 0; | ||
25 | |||
23 | char *end; | 26 | char *end; |
24 | output->width = strtol(*argv, &end, 10); | 27 | output->width = strtol(*argv, &end, 10); |
25 | if (*end) { | 28 | if (*end) { |
@@ -58,3 +61,58 @@ struct cmd_results *output_cmd_mode(int argc, char **argv) { | |||
58 | return NULL; | 61 | return NULL; |
59 | } | 62 | } |
60 | 63 | ||
64 | static bool parse_modeline(char **argv, drmModeModeInfo *mode) { | ||
65 | mode->type = DRM_MODE_TYPE_USERDEF; | ||
66 | mode->clock = strtof(argv[0], NULL) * 1000; | ||
67 | mode->hdisplay = strtol(argv[1], NULL, 10); | ||
68 | mode->hsync_start = strtol(argv[2], NULL, 10); | ||
69 | mode->hsync_end = strtol(argv[3], NULL, 10); | ||
70 | mode->htotal = strtol(argv[4], NULL, 10); | ||
71 | mode->vdisplay = strtol(argv[5], NULL, 10); | ||
72 | mode->vsync_start = strtol(argv[6], NULL, 10); | ||
73 | mode->vsync_end = strtol(argv[7], NULL, 10); | ||
74 | mode->vtotal = strtol(argv[8], NULL, 10); | ||
75 | |||
76 | mode->vrefresh = mode->clock * 1000.0 * 1000.0 | ||
77 | / mode->htotal / mode->vtotal; | ||
78 | if (strcasecmp(argv[9], "+hsync") == 0) { | ||
79 | mode->flags |= DRM_MODE_FLAG_PHSYNC; | ||
80 | } else if (strcasecmp(argv[9], "-hsync") == 0) { | ||
81 | mode->flags |= DRM_MODE_FLAG_NHSYNC; | ||
82 | } else { | ||
83 | return false; | ||
84 | } | ||
85 | |||
86 | if (strcasecmp(argv[10], "+vsync") == 0) { | ||
87 | mode->flags |= DRM_MODE_FLAG_PVSYNC; | ||
88 | } else if (strcasecmp(argv[10], "-vsync") == 0) { | ||
89 | mode->flags |= DRM_MODE_FLAG_NVSYNC; | ||
90 | } else { | ||
91 | return false; | ||
92 | } | ||
93 | |||
94 | snprintf(mode->name, sizeof(mode->name), "%dx%d@%d", | ||
95 | mode->hdisplay, mode->vdisplay, mode->vrefresh / 1000); | ||
96 | |||
97 | return true; | ||
98 | } | ||
99 | |||
100 | struct cmd_results *output_cmd_modeline(int argc, char **argv) { | ||
101 | if (!config->handler_context.output_config) { | ||
102 | return cmd_results_new(CMD_FAILURE, "Missing output config"); | ||
103 | } | ||
104 | if (!argc) { | ||
105 | return cmd_results_new(CMD_INVALID, "Missing modeline argument."); | ||
106 | } | ||
107 | |||
108 | struct output_config *output = config->handler_context.output_config; | ||
109 | |||
110 | if (argc != 11 || !parse_modeline(argv, &output->drm_mode)) { | ||
111 | return cmd_results_new(CMD_INVALID, "Invalid modeline"); | ||
112 | } | ||
113 | |||
114 | config->handler_context.leftovers.argc = argc - 12; | ||
115 | config->handler_context.leftovers.argv = argv + 12; | ||
116 | return NULL; | ||
117 | } | ||
118 | |||