lib/igt_kms: Unify pipe name helpers
[platform/upstream/intel-gpu-tools.git] / tests / testdisplay_hotplug.c
1 /*
2  * Copyright 2010 Intel Corporation
3  *   Jesse Barnes <jesse.barnes@intel.com>
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23
24 #include <stdio.h>
25 #include <string.h>
26 #include <stdlib.h>
27
28 #include "testdisplay.h"
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include "igt_core.h"
34
35 #if HAVE_UDEV
36 #include <libudev.h>
37 static struct udev_monitor *uevent_monitor;
38 static struct udev *udev;
39 static GIOChannel *udevchannel;
40
41 static gboolean hotplug_event(GIOChannel *source, GIOCondition condition,
42                               gpointer data)
43 {
44         struct udev_device *dev;
45         dev_t udev_devnum;
46         struct stat s;
47         const char *hotplug;
48
49         dev = udev_monitor_receive_device(uevent_monitor);
50         if (!dev)
51                 goto out;
52
53         udev_devnum = udev_device_get_devnum(dev);
54         fstat(drm_fd, &s);
55
56         hotplug = udev_device_get_property_value(dev, "HOTPLUG");
57
58         if (memcmp(&s.st_rdev, &udev_devnum, sizeof(dev_t)) == 0 &&
59             hotplug && atoi(hotplug) == 1)
60                 update_display();
61
62         udev_device_unref(dev);
63 out:
64         return TRUE;
65 }
66
67
68 gboolean testdisplay_setup_hotplug(void)
69 {
70         int ret;
71
72         udev = udev_new();
73         if (!udev) {
74                 igt_warn("failed to create udev object\n");
75                 goto out;
76         }
77
78         uevent_monitor = udev_monitor_new_from_netlink(udev, "udev");
79         if (!uevent_monitor) {
80                 igt_warn("failed to create udev event monitor\n");
81                 goto out;
82         }
83
84         ret = udev_monitor_filter_add_match_subsystem_devtype(uevent_monitor,
85                                                               "drm",
86                                                               "drm_minor");
87         if (ret < 0) {
88                 igt_warn("failed to filter for drm events\n");
89                 goto out;
90         }
91
92         ret = udev_monitor_enable_receiving(uevent_monitor);
93         if (ret < 0) {
94                 igt_warn("failed to enable udev event reception\n");
95                 goto out;
96         }
97
98         udevchannel =
99                 g_io_channel_unix_new(udev_monitor_get_fd(uevent_monitor));
100         if (!udevchannel) {
101                 igt_warn("failed to create udev GIO channel\n");
102                 goto out;
103         }
104
105         ret = g_io_add_watch(udevchannel, G_IO_IN | G_IO_ERR, hotplug_event,
106                              udev);
107         if (ret < 0) {
108                 igt_warn("failed to add watch on udev GIO channel\n");
109                 goto out;
110         }
111
112         return TRUE;
113
114 out:
115         testdisplay_cleanup_hotplug();
116         return FALSE;
117 }
118
119 void testdisplay_cleanup_hotplug(void)
120 {
121         if (udevchannel)
122                 g_io_channel_shutdown(udevchannel, TRUE, NULL);
123         if (uevent_monitor)
124                 udev_monitor_unref(uevent_monitor);
125         if (udev)
126                 udev_unref(udev);
127 }
128 #else
129 gboolean testdisplay_setup_hotplug(void)
130 {
131         igt_warn("no hotplug support on this platform\n");
132         return TRUE;
133 }
134
135 void testdisplay_cleanup_hotplug(void)
136 {
137 }
138 #endif