1 /* vdagentd.c vdagentd xorg.conf writing code
3 Copyright 2011, 2012 Red Hat, Inc.
4 Copyright (c) 2014 Samsung Electronics Co., Ltd.
7 Hans de Goede <hdegoede@redhat.com>
9 This program is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 * Modifications by Samsung Electronics Co., Ltd.
23 1. modified xorg_conf path
30 #include <pciaccess.h>
37 #include "vdagentd-xorg-conf.h"
39 #define FPRINTF(...) \
41 r = fprintf(f, __VA_ARGS__); \
43 syslog(LOG_ERR, "Error writing to %s: %m", xorg_conf); \
45 pci_system_cleanup(); \
50 void vdagentd_write_xorg_conf(VDAgentMonitorsConfig *monitor_conf)
53 int i, r, count, min_x = INT_MAX, min_y = INT_MAX;
55 struct pci_device_iterator *it;
56 struct pci_device *dev;
57 const struct pci_id_match qxl_id_match = {
60 .subvendor_id = PCI_MATCH_ANY,
61 .subdevice_id = PCI_MATCH_ANY,
63 const char *xorg_conf = "/tmp/spice-vdagentd/xorg.conf.spice";
64 const char *xorg_conf_old = "/tmp/spice-vdagentd/xorg.conf.spice.old";
66 r = rename(xorg_conf, xorg_conf_old);
67 if (r && errno != ENOENT) {
69 "Error renaming %s to %s: %m, not generating xorg.conf",
70 xorg_conf, xorg_conf_old);
74 r = pci_system_init();
76 syslog(LOG_ERR, "Error initializing libpciaccess: %d, not generating xorg.conf", r);
80 it = pci_id_match_iterator_create(&qxl_id_match);
82 syslog(LOG_ERR, "Error could not create pci id iterator for QXL devices, not generating xorg.conf");
87 dev = pci_device_next(it);
89 syslog(LOG_ERR, "No QXL devices found, not generating xorg.conf");
94 f = fopen(xorg_conf, "w");
96 syslog(LOG_ERR, "Error opening %s for writing: %m", xorg_conf);
101 FPRINTF("# xorg.conf generated by spice-vdagentd\n");
102 FPRINTF("# generated from monitor info provided by the client\n\n");
104 if (monitor_conf->num_of_monitors == 1) {
105 FPRINTF("# Client has only 1 monitor\n");
106 FPRINTF("# This works best with no xorg.conf, leaving xorg.conf empty\n");
108 pci_system_cleanup();
112 FPRINTF("Section \"ServerFlags\"\n");
113 FPRINTF("\tOption\t\t\"Xinerama\"\t\"true\"\n");
114 FPRINTF("EndSection\n\n");
118 FPRINTF("Section \"Device\"\n");
119 FPRINTF("\tIdentifier\t\"qxl%d\"\n", i++);
120 FPRINTF("\tDriver\t\t\"qxl\"\n");
121 FPRINTF("\tBusID\t\t\"PCI:%02d:%02d:%d\"\n",
122 dev->bus, dev->dev, dev->func);
123 FPRINTF("\tOption\t\t\"NumHeads\"\t\"1\"\n");
124 FPRINTF("EndSection\n\n");
125 } while ((dev = pci_device_next(it)));
127 if (i < monitor_conf->num_of_monitors) {
128 FPRINTF("# Client has %d monitors, but only %d qxl devices found\n",
129 monitor_conf->num_of_monitors, i);
130 FPRINTF("# Only generation %d \"Screen\" sections\n\n", i);
133 count = monitor_conf->num_of_monitors;
136 for (i = 0; i < count; i++) {
137 FPRINTF("Section \"Screen\"\n");
138 FPRINTF("\tIdentifier\t\"Screen%d\"\n", i);
139 FPRINTF("\tDevice\t\t\"qxl%d\"\n", i);
140 FPRINTF("\tDefaultDepth\t24\n");
141 FPRINTF("\tSubSection \"Display\"\n");
142 FPRINTF("\t\tViewport\t0 0\n");
143 FPRINTF("\t\tDepth\t\t24\n");
144 FPRINTF("\t\tModes\t\t\"%dx%d\"\n", monitor_conf->monitors[i].width,
145 monitor_conf->monitors[i].height);
146 FPRINTF("\tEndSubSection\n");
147 FPRINTF("EndSection\n\n");
150 /* monitor_conf may contain negative values, convert these to 0 - # */
151 for (i = 0; i < count; i++) {
152 if (monitor_conf->monitors[i].x < min_x) {
153 min_x = monitor_conf->monitors[i].x;
155 if (monitor_conf->monitors[i].y < min_y) {
156 min_y = monitor_conf->monitors[i].y;
160 FPRINTF("Section \"ServerLayout\"\n");
161 FPRINTF("\tIdentifier\t\"layout\"\n");
162 for (i = 0; i < count; i++) {
163 FPRINTF("\tScreen\t\t\"Screen%d\" %d %d\n", i,
164 monitor_conf->monitors[i].x - min_x,
165 monitor_conf->monitors[i].y - min_y);
167 FPRINTF("EndSection\n");
170 pci_system_cleanup();