1 /*
2 * Copyright (C) 2020 Red Hat
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17 * 02111-1307, USA.
18 */
19
20 #include "config.h"
21
22 #include "backends/native/meta-kms-mode-private.h"
23
24 #include "backends/native/meta-kms-impl-device.h"
25
26 struct _MetaKmsMode
27 {
28 MetaKmsImplDevice *impl_device;
29 MetaKmsModeFlag flags;
30 drmModeModeInfo drm_mode;
31 };
32
33 uint32_t
meta_kms_mode_create_blob_id(MetaKmsMode * mode,GError ** error)34 meta_kms_mode_create_blob_id (MetaKmsMode *mode,
35 GError **error)
36 {
37 int fd;
38 int ret;
39 uint32_t blob_id;
40
41 fd = meta_kms_impl_device_get_fd (mode->impl_device);
42
43 ret = drmModeCreatePropertyBlob (fd,
44 &mode->drm_mode,
45 sizeof (mode->drm_mode),
46 &blob_id);
47 if (ret < 0)
48 {
49 g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-ret),
50 "drmModeCreatePropertyBlob: %s",
51 g_strerror (-ret));
52 return 0;
53 }
54
55 return blob_id;
56 }
57
58 const char *
meta_kms_mode_get_name(MetaKmsMode * mode)59 meta_kms_mode_get_name (MetaKmsMode *mode)
60 {
61 return mode->drm_mode.name;
62 }
63
64 MetaKmsModeFlag
meta_kms_mode_get_flags(MetaKmsMode * mode)65 meta_kms_mode_get_flags (MetaKmsMode *mode)
66 {
67 return mode->flags;
68 }
69
70 const drmModeModeInfo *
meta_kms_mode_get_drm_mode(MetaKmsMode * mode)71 meta_kms_mode_get_drm_mode (MetaKmsMode *mode)
72 {
73 return &mode->drm_mode;
74 }
75
76 gboolean
meta_drm_mode_equal(const drmModeModeInfo * one,const drmModeModeInfo * two)77 meta_drm_mode_equal (const drmModeModeInfo *one,
78 const drmModeModeInfo *two)
79 {
80 return (one->clock == two->clock &&
81 one->hdisplay == two->hdisplay &&
82 one->hsync_start == two->hsync_start &&
83 one->hsync_end == two->hsync_end &&
84 one->htotal == two->htotal &&
85 one->hskew == two->hskew &&
86 one->vdisplay == two->vdisplay &&
87 one->vsync_start == two->vsync_start &&
88 one->vsync_end == two->vsync_end &&
89 one->vtotal == two->vtotal &&
90 one->vscan == two->vscan &&
91 one->vrefresh == two->vrefresh &&
92 one->flags == two->flags &&
93 one->type == two->type &&
94 strncmp (one->name, two->name, DRM_DISPLAY_MODE_LEN) == 0);
95 }
96
97 gboolean
meta_kms_mode_equal(MetaKmsMode * mode,MetaKmsMode * other_mode)98 meta_kms_mode_equal (MetaKmsMode *mode,
99 MetaKmsMode *other_mode)
100 {
101 return meta_drm_mode_equal (&mode->drm_mode, &other_mode->drm_mode);
102 }
103
104 unsigned int
meta_kms_mode_hash(MetaKmsMode * mode)105 meta_kms_mode_hash (MetaKmsMode *mode)
106 {
107 const drmModeModeInfo *drm_mode = &mode->drm_mode;
108 unsigned int hash = 0;
109
110 /*
111 * We don't include the name in the hash because it's generally
112 * derived from the other fields (hdisplay, vdisplay and flags)
113 */
114
115 hash ^= drm_mode->clock;
116 hash ^= drm_mode->hdisplay ^ drm_mode->hsync_start ^ drm_mode->hsync_end;
117 hash ^= drm_mode->vdisplay ^ drm_mode->vsync_start ^ drm_mode->vsync_end;
118 hash ^= drm_mode->vrefresh;
119 hash ^= drm_mode->flags ^ drm_mode->type;
120
121 return hash;
122 }
123
124 void
meta_kms_mode_free(MetaKmsMode * mode)125 meta_kms_mode_free (MetaKmsMode *mode)
126 {
127 g_free (mode);
128 }
129
130 MetaKmsMode *
meta_kms_mode_new(MetaKmsImplDevice * impl_device,const drmModeModeInfo * drm_mode,MetaKmsModeFlag flags)131 meta_kms_mode_new (MetaKmsImplDevice *impl_device,
132 const drmModeModeInfo *drm_mode,
133 MetaKmsModeFlag flags)
134 {
135 MetaKmsMode *mode;
136
137 mode = g_new0 (MetaKmsMode, 1);
138 mode->impl_device = impl_device;
139 mode->flags = flags;
140 mode->drm_mode = *drm_mode;
141
142 return mode;
143 }
144