1 /*
2 * Xephyr - A kdrive X server thats runs in a host X window.
3 * Authored by Matthew Allum <mallum@o-hand.com>
4 *
5 * Copyright © 2004 Nokia
6 *
7 * Permission to use, copy, modify, distribute, and sell this software and its
8 * documentation for any purpose is hereby granted without fee, provided that
9 * the above copyright notice appear in all copies and that both that
10 * copyright notice and this permission notice appear in supporting
11 * documentation, and that the name of Nokia not be used in
12 * advertising or publicity pertaining to distribution of the software without
13 * specific, written prior permission. Nokia makes no
14 * representations about the suitability of this software for any purpose. It
15 * is provided "as is" without express or implied warranty.
16 *
17 * NOKIA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
19 * EVENT SHALL NOKIA BE LIABLE FOR ANY SPECIAL, INDIRECT OR
20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
22 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
23 * PERFORMANCE OF THIS SOFTWARE.
24 */
25
26 #ifdef HAVE_DIX_CONFIG_H
27 #include <dix-config.h>
28 #endif
29 #include "ephyr.h"
30 #include "ephyrlog.h"
31 #include "glx_extinit.h"
32
33 extern Window EphyrPreExistingHostWin;
34 extern Bool EphyrWantGrayScale;
35 extern Bool EphyrWantResize;
36 extern Bool EphyrWantNoHostGrab;
37 extern Bool kdHasPointer;
38 extern Bool kdHasKbd;
39 extern Bool ephyr_glamor, ephyr_glamor_gles2, ephyr_glamor_skip_present;
40
41 extern Bool ephyrNoXV;
42
43 void processScreenOrOutputArg(const char *screen_size, const char *output, char *parent_id);
44 void processOutputArg(const char *output, char *parent_id);
45 void processScreenArg(const char *screen_size, char *parent_id);
46
47 int
main(int argc,char * argv[],char * envp[])48 main(int argc, char *argv[], char *envp[])
49 {
50 hostx_use_resname(basename(argv[0]), 0);
51 return dix_main(argc, argv, envp);
52 }
53
54 void
InitCard(char * name)55 InitCard(char *name)
56 {
57 EPHYR_DBG("mark");
58 KdCardInfoAdd(&ephyrFuncs, 0);
59 }
60
61 void
InitOutput(ScreenInfo * pScreenInfo,int argc,char ** argv)62 InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv)
63 {
64 KdInitOutput(pScreenInfo, argc, argv);
65 }
66
67 void
InitInput(int argc,char ** argv)68 InitInput(int argc, char **argv)
69 {
70 KdKeyboardInfo *ki;
71 KdPointerInfo *pi;
72
73 if (!SeatId) {
74 KdAddKeyboardDriver(&EphyrKeyboardDriver);
75 KdAddPointerDriver(&EphyrMouseDriver);
76
77 if (!kdHasKbd) {
78 ki = KdNewKeyboard();
79 if (!ki)
80 FatalError("Couldn't create Xephyr keyboard\n");
81 ki->driver = &EphyrKeyboardDriver;
82 KdAddKeyboard(ki);
83 }
84
85 if (!kdHasPointer) {
86 pi = KdNewPointer();
87 if (!pi)
88 FatalError("Couldn't create Xephyr pointer\n");
89 pi->driver = &EphyrMouseDriver;
90 KdAddPointer(pi);
91 }
92 }
93
94 KdInitInput();
95 }
96
97 void
CloseInput(void)98 CloseInput(void)
99 {
100 KdCloseInput();
101 }
102
103 #if INPUTTHREAD
104 /** This function is called in Xserver/os/inputthread.c when starting
105 the input thread. */
106 void
ddxInputThreadInit(void)107 ddxInputThreadInit(void)
108 {
109 }
110 #endif
111
112 #ifdef DDXBEFORERESET
113 void
ddxBeforeReset(void)114 ddxBeforeReset(void)
115 {
116 }
117 #endif
118
119 void
ddxUseMsg(void)120 ddxUseMsg(void)
121 {
122 KdUseMsg();
123
124 ErrorF("\nXephyr Option Usage:\n");
125 ErrorF("-parent <XID> Use existing window as Xephyr root win\n");
126 ErrorF("-sw-cursor Render cursors in software in Xephyr\n");
127 ErrorF("-fullscreen Attempt to run Xephyr fullscreen\n");
128 ErrorF("-output <NAME> Attempt to run Xephyr fullscreen (restricted to given output geometry)\n");
129 ErrorF("-grayscale Simulate 8bit grayscale\n");
130 ErrorF("-resizeable Make Xephyr windows resizeable\n");
131 #ifdef GLAMOR
132 ErrorF("-glamor Enable 2D acceleration using glamor\n");
133 ErrorF("-glamor_gles2 Enable 2D acceleration using glamor (with GLES2 only)\n");
134 ErrorF("-glamor-skip-present Skip presenting the output when using glamor (for internal testing optimization)\n");
135 #endif
136 ErrorF
137 ("-fakexa Simulate acceleration using software rendering\n");
138 ErrorF("-verbosity <level> Set log verbosity level\n");
139 ErrorF("-noxv do not use XV\n");
140 ErrorF("-name [name] define the name in the WM_CLASS property\n");
141 ErrorF
142 ("-title [title] set the window title in the WM_NAME property\n");
143 ErrorF("-no-host-grab Disable grabbing the keyboard and mouse.\n");
144 ErrorF("\n");
145 }
146
147 void
processScreenOrOutputArg(const char * screen_size,const char * output,char * parent_id)148 processScreenOrOutputArg(const char *screen_size, const char *output, char *parent_id)
149 {
150 KdCardInfo *card;
151
152 InitCard(0); /*Put each screen on a separate card */
153 card = KdCardInfoLast();
154
155 if (card) {
156 KdScreenInfo *screen;
157 unsigned long p_id = 0;
158 Bool use_geometry;
159
160 screen = KdScreenInfoAdd(card);
161 KdParseScreen(screen, screen_size);
162 screen->driver = calloc(1, sizeof(EphyrScrPriv));
163 if (!screen->driver)
164 FatalError("Couldn't alloc screen private\n");
165
166 if (parent_id) {
167 p_id = strtol(parent_id, NULL, 0);
168 }
169
170 use_geometry = (strchr(screen_size, '+') != NULL);
171 EPHYR_DBG("screen number:%d\n", screen->mynum);
172 hostx_add_screen(screen, p_id, screen->mynum, use_geometry, output);
173 }
174 else {
175 ErrorF("No matching card found!\n");
176 }
177 }
178
179 void
processScreenArg(const char * screen_size,char * parent_id)180 processScreenArg(const char *screen_size, char *parent_id)
181 {
182 processScreenOrOutputArg(screen_size, NULL, parent_id);
183 }
184
185 void
processOutputArg(const char * output,char * parent_id)186 processOutputArg(const char *output, char *parent_id)
187 {
188 processScreenOrOutputArg("100x100+0+0", output, parent_id);
189 }
190
191 int
ddxProcessArgument(int argc,char ** argv,int i)192 ddxProcessArgument(int argc, char **argv, int i)
193 {
194 static char *parent = NULL;
195
196 EPHYR_DBG("mark argv[%d]='%s'", i, argv[i]);
197
198 if (!strcmp(argv[i], "-parent")) {
199 if (i + 1 < argc) {
200 int j;
201
202 /* If parent is specified and a screen argument follows, don't do
203 * anything, let the -screen handling init the rest */
204 for (j = i; j < argc; j++) {
205 if (!strcmp(argv[j], "-screen")) {
206 parent = argv[i + 1];
207 return 2;
208 }
209 }
210
211 processScreenArg("100x100", argv[i + 1]);
212 return 2;
213 }
214
215 UseMsg();
216 exit(1);
217 }
218 else if (!strcmp(argv[i], "-screen")) {
219 if ((i + 1) < argc) {
220 processScreenArg(argv[i + 1], parent);
221 parent = NULL;
222 return 2;
223 }
224
225 UseMsg();
226 exit(1);
227 }
228 else if (!strcmp(argv[i], "-output")) {
229 if (i + 1 < argc) {
230 processOutputArg(argv[i + 1], NULL);
231 return 2;
232 }
233
234 UseMsg();
235 exit(1);
236 }
237 else if (!strcmp(argv[i], "-sw-cursor")) {
238 hostx_use_sw_cursor();
239 return 1;
240 }
241 else if (!strcmp(argv[i], "-host-cursor")) {
242 /* Compatibility with the old command line argument, now the default. */
243 return 1;
244 }
245 else if (!strcmp(argv[i], "-fullscreen")) {
246 hostx_use_fullscreen();
247 return 1;
248 }
249 else if (!strcmp(argv[i], "-grayscale")) {
250 EphyrWantGrayScale = 1;
251 return 1;
252 }
253 else if (!strcmp(argv[i], "-resizeable")) {
254 EphyrWantResize = 1;
255 return 1;
256 }
257 #ifdef GLAMOR
258 else if (!strcmp (argv[i], "-glamor")) {
259 ephyr_glamor = TRUE;
260 ephyrFuncs.initAccel = ephyr_glamor_init;
261 ephyrFuncs.enableAccel = ephyr_glamor_enable;
262 ephyrFuncs.disableAccel = ephyr_glamor_disable;
263 ephyrFuncs.finiAccel = ephyr_glamor_fini;
264 return 1;
265 }
266 else if (!strcmp (argv[i], "-glamor_gles2")) {
267 ephyr_glamor = TRUE;
268 ephyr_glamor_gles2 = TRUE;
269 ephyrFuncs.initAccel = ephyr_glamor_init;
270 ephyrFuncs.enableAccel = ephyr_glamor_enable;
271 ephyrFuncs.disableAccel = ephyr_glamor_disable;
272 ephyrFuncs.finiAccel = ephyr_glamor_fini;
273 return 1;
274 }
275 else if (!strcmp (argv[i], "-glamor-skip-present")) {
276 ephyr_glamor_skip_present = TRUE;
277 return 1;
278 }
279 #endif
280 else if (!strcmp(argv[i], "-fakexa")) {
281 ephyrFuncs.initAccel = ephyrDrawInit;
282 ephyrFuncs.enableAccel = ephyrDrawEnable;
283 ephyrFuncs.disableAccel = ephyrDrawDisable;
284 ephyrFuncs.finiAccel = ephyrDrawFini;
285 return 1;
286 }
287 else if (!strcmp(argv[i], "-verbosity")) {
288 if (i + 1 < argc && argv[i + 1][0] != '-') {
289 int verbosity = atoi(argv[i + 1]);
290
291 LogSetParameter(XLOG_VERBOSITY, verbosity);
292 EPHYR_LOG("set verbosiry to %d\n", verbosity);
293 return 2;
294 }
295 else {
296 UseMsg();
297 exit(1);
298 }
299 }
300 else if (!strcmp(argv[i], "-noxv")) {
301 ephyrNoXV = TRUE;
302 EPHYR_LOG("no XVideo enabled\n");
303 return 1;
304 }
305 else if (!strcmp(argv[i], "-name")) {
306 if (i + 1 < argc && argv[i + 1][0] != '-') {
307 hostx_use_resname(argv[i + 1], 1);
308 return 2;
309 }
310 else {
311 UseMsg();
312 return 0;
313 }
314 }
315 else if (!strcmp(argv[i], "-title")) {
316 if (i + 1 < argc && argv[i + 1][0] != '-') {
317 hostx_set_title(argv[i + 1]);
318 return 2;
319 }
320 else {
321 UseMsg();
322 return 0;
323 }
324 }
325 else if (argv[i][0] == ':') {
326 hostx_set_display_name(argv[i]);
327 }
328 /* Xnest compatibility */
329 else if (!strcmp(argv[i], "-display")) {
330 hostx_set_display_name(argv[i + 1]);
331 return 2;
332 }
333 else if (!strcmp(argv[i], "-sync") ||
334 !strcmp(argv[i], "-full") ||
335 !strcmp(argv[i], "-sss") || !strcmp(argv[i], "-install")) {
336 return 1;
337 }
338 else if (!strcmp(argv[i], "-bw") ||
339 !strcmp(argv[i], "-class") ||
340 !strcmp(argv[i], "-geometry") || !strcmp(argv[i], "-scrns")) {
341 return 2;
342 }
343 /* end Xnest compat */
344 else if (!strcmp(argv[i], "-no-host-grab")) {
345 EphyrWantNoHostGrab = 1;
346 return 1;
347 }
348 else if (!strcmp(argv[i], "-sharevts") ||
349 !strcmp(argv[i], "-novtswitch")) {
350 return 1;
351 }
352 else if (!strcmp(argv[i], "-layout")) {
353 return 2;
354 }
355
356 return KdProcessArgument(argc, argv, i);
357 }
358
359 void
OsVendorInit(void)360 OsVendorInit(void)
361 {
362 EPHYR_DBG("mark");
363
364 if (SeatId)
365 hostx_use_sw_cursor();
366
367 if (hostx_want_host_cursor())
368 ephyrFuncs.initCursor = &ephyrCursorInit;
369
370 if (serverGeneration == 1) {
371 if (!KdCardInfoLast()) {
372 processScreenArg("640x480", NULL);
373 }
374 hostx_init();
375 }
376 }
377
378 KdCardFuncs ephyrFuncs = {
379 ephyrCardInit, /* cardinit */
380 ephyrScreenInitialize, /* scrinit */
381 ephyrInitScreen, /* initScreen */
382 ephyrFinishInitScreen, /* finishInitScreen */
383 ephyrCreateResources, /* createRes */
384 ephyrScreenFini, /* scrfini */
385 ephyrCardFini, /* cardfini */
386
387 0, /* initCursor */
388
389 0, /* initAccel */
390 0, /* enableAccel */
391 0, /* disableAccel */
392 0, /* finiAccel */
393
394 ephyrGetColors, /* getColors */
395 ephyrPutColors, /* putColors */
396
397 ephyrCloseScreen, /* closeScreen */
398 };
399