105b261ecSmrg/* 2ed6184dfSmrg * Xephyr - A kdrive X server that runs in a host X window. 305b261ecSmrg * Authored by Matthew Allum <mallum@o-hand.com> 435c4bbdfSmrg * 535c4bbdfSmrg * Copyright © 2004 Nokia 605b261ecSmrg * 705b261ecSmrg * Permission to use, copy, modify, distribute, and sell this software and its 805b261ecSmrg * documentation for any purpose is hereby granted without fee, provided that 905b261ecSmrg * the above copyright notice appear in all copies and that both that 1005b261ecSmrg * copyright notice and this permission notice appear in supporting 1105b261ecSmrg * documentation, and that the name of Nokia not be used in 1205b261ecSmrg * advertising or publicity pertaining to distribution of the software without 1305b261ecSmrg * specific, written prior permission. Nokia makes no 1405b261ecSmrg * representations about the suitability of this software for any purpose. It 1505b261ecSmrg * is provided "as is" without express or implied warranty. 1605b261ecSmrg * 1705b261ecSmrg * NOKIA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1805b261ecSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 1905b261ecSmrg * EVENT SHALL NOKIA BE LIABLE FOR ANY SPECIAL, INDIRECT OR 2005b261ecSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 2105b261ecSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 2205b261ecSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 2305b261ecSmrg * PERFORMANCE OF THIS SOFTWARE. 2405b261ecSmrg */ 2505b261ecSmrg 261b5d61b8Smrg#ifdef HAVE_DIX_CONFIG_H 271b5d61b8Smrg#include <dix-config.h> 2805b261ecSmrg#endif 2905b261ecSmrg#include "ephyr.h" 304642e01fSmrg#include "ephyrlog.h" 3135c4bbdfSmrg#include "glx_extinit.h" 3205b261ecSmrg 3305b261ecSmrgextern Window EphyrPreExistingHostWin; 3435c4bbdfSmrgextern Bool EphyrWantGrayScale; 3535c4bbdfSmrgextern Bool EphyrWantResize; 3635c4bbdfSmrgextern Bool EphyrWantNoHostGrab; 3735c4bbdfSmrgextern Bool kdHasPointer; 3835c4bbdfSmrgextern Bool kdHasKbd; 391b5d61b8Smrgextern Bool ephyr_glamor, ephyr_glamor_gles2, ephyr_glamor_skip_present; 4005b261ecSmrg 4135c4bbdfSmrgextern Bool ephyrNoXV; 424642e01fSmrg 4335c4bbdfSmrgvoid processScreenOrOutputArg(const char *screen_size, const char *output, char *parent_id); 4435c4bbdfSmrgvoid processOutputArg(const char *output, char *parent_id); 4535c4bbdfSmrgvoid processScreenArg(const char *screen_size, char *parent_id); 4635c4bbdfSmrg 4735c4bbdfSmrgint 4835c4bbdfSmrgmain(int argc, char *argv[], char *envp[]) 4935c4bbdfSmrg{ 5035c4bbdfSmrg hostx_use_resname(basename(argv[0]), 0); 5135c4bbdfSmrg return dix_main(argc, argv, envp); 5235c4bbdfSmrg} 534642e01fSmrg 5405b261ecSmrgvoid 5535c4bbdfSmrgInitCard(char *name) 5605b261ecSmrg{ 5705b261ecSmrg EPHYR_DBG("mark"); 5835c4bbdfSmrg KdCardInfoAdd(&ephyrFuncs, 0); 5935c4bbdfSmrg} 6035c4bbdfSmrg 6105b261ecSmrgvoid 6235c4bbdfSmrgInitOutput(ScreenInfo * pScreenInfo, int argc, char **argv) 6305b261ecSmrg{ 6435c4bbdfSmrg KdInitOutput(pScreenInfo, argc, argv); 6505b261ecSmrg} 6605b261ecSmrg 6705b261ecSmrgvoid 6835c4bbdfSmrgInitInput(int argc, char **argv) 6905b261ecSmrg{ 7035c4bbdfSmrg KdKeyboardInfo *ki; 7135c4bbdfSmrg KdPointerInfo *pi; 724642e01fSmrg 73d9252ffbSmrg KdAddKeyboardDriver(&EphyrKeyboardDriver); 74d9252ffbSmrg KdAddPointerDriver(&EphyrMouseDriver); 75d9252ffbSmrg 76d9252ffbSmrg if (!kdHasKbd) { 77d9252ffbSmrg ki = KdNewKeyboard(); 78d9252ffbSmrg if (!ki) 79d9252ffbSmrg FatalError("Couldn't create Xephyr keyboard\n"); 80d9252ffbSmrg ki->driver = &EphyrKeyboardDriver; 81d9252ffbSmrg KdAddKeyboard(ki); 82d9252ffbSmrg } 83d9252ffbSmrg 84d9252ffbSmrg if (!kdHasPointer) { 85d9252ffbSmrg pi = KdNewPointer(); 86d9252ffbSmrg if (!pi) 87d9252ffbSmrg FatalError("Couldn't create Xephyr pointer\n"); 88d9252ffbSmrg pi->driver = &EphyrMouseDriver; 89d9252ffbSmrg KdAddPointer(pi); 9035c4bbdfSmrg } 9135c4bbdfSmrg 9235c4bbdfSmrg KdInitInput(); 9305b261ecSmrg} 9405b261ecSmrg 956747b715Smrgvoid 9635c4bbdfSmrgCloseInput(void) 976747b715Smrg{ 9835c4bbdfSmrg KdCloseInput(); 996747b715Smrg} 1006747b715Smrg 1015a7dfde8Smrg#if INPUTTHREAD 1025a7dfde8Smrg/** This function is called in Xserver/os/inputthread.c when starting 1035a7dfde8Smrg the input thread. */ 1045a7dfde8Smrgvoid 1055a7dfde8SmrgddxInputThreadInit(void) 1065a7dfde8Smrg{ 1075a7dfde8Smrg} 1085a7dfde8Smrg#endif 1095a7dfde8Smrg 1106747b715Smrg#ifdef DDXBEFORERESET 1116747b715Smrgvoid 11235c4bbdfSmrgddxBeforeReset(void) 1136747b715Smrg{ 1146747b715Smrg} 1156747b715Smrg#endif 1166747b715Smrg 11705b261ecSmrgvoid 11835c4bbdfSmrgddxUseMsg(void) 11905b261ecSmrg{ 12035c4bbdfSmrg KdUseMsg(); 12135c4bbdfSmrg 12235c4bbdfSmrg ErrorF("\nXephyr Option Usage:\n"); 12335c4bbdfSmrg ErrorF("-parent <XID> Use existing window as Xephyr root win\n"); 12435c4bbdfSmrg ErrorF("-sw-cursor Render cursors in software in Xephyr\n"); 12535c4bbdfSmrg ErrorF("-fullscreen Attempt to run Xephyr fullscreen\n"); 12635c4bbdfSmrg ErrorF("-output <NAME> Attempt to run Xephyr fullscreen (restricted to given output geometry)\n"); 12735c4bbdfSmrg ErrorF("-grayscale Simulate 8bit grayscale\n"); 12835c4bbdfSmrg ErrorF("-resizeable Make Xephyr windows resizeable\n"); 12935c4bbdfSmrg#ifdef GLAMOR 13035c4bbdfSmrg ErrorF("-glamor Enable 2D acceleration using glamor\n"); 13135c4bbdfSmrg ErrorF("-glamor_gles2 Enable 2D acceleration using glamor (with GLES2 only)\n"); 1321b5d61b8Smrg ErrorF("-glamor-skip-present Skip presenting the output when using glamor (for internal testing optimization)\n"); 13335c4bbdfSmrg#endif 13435c4bbdfSmrg ErrorF 13535c4bbdfSmrg ("-fakexa Simulate acceleration using software rendering\n"); 13635c4bbdfSmrg ErrorF("-verbosity <level> Set log verbosity level\n"); 13735c4bbdfSmrg ErrorF("-noxv do not use XV\n"); 13835c4bbdfSmrg ErrorF("-name [name] define the name in the WM_CLASS property\n"); 13935c4bbdfSmrg ErrorF 14035c4bbdfSmrg ("-title [title] set the window title in the WM_NAME property\n"); 14135c4bbdfSmrg ErrorF("-no-host-grab Disable grabbing the keyboard and mouse.\n"); 14235c4bbdfSmrg ErrorF("\n"); 14305b261ecSmrg} 14405b261ecSmrg 1454642e01fSmrgvoid 14635c4bbdfSmrgprocessScreenOrOutputArg(const char *screen_size, const char *output, char *parent_id) 1474642e01fSmrg{ 14835c4bbdfSmrg KdCardInfo *card; 1494642e01fSmrg 15035c4bbdfSmrg InitCard(0); /*Put each screen on a separate card */ 15135c4bbdfSmrg card = KdCardInfoLast(); 1524642e01fSmrg 15335c4bbdfSmrg if (card) { 15435c4bbdfSmrg KdScreenInfo *screen; 15535c4bbdfSmrg unsigned long p_id = 0; 15635c4bbdfSmrg Bool use_geometry; 1574642e01fSmrg 15835c4bbdfSmrg screen = KdScreenInfoAdd(card); 15935c4bbdfSmrg KdParseScreen(screen, screen_size); 16035c4bbdfSmrg screen->driver = calloc(1, sizeof(EphyrScrPriv)); 16135c4bbdfSmrg if (!screen->driver) 16235c4bbdfSmrg FatalError("Couldn't alloc screen private\n"); 1634642e01fSmrg 16435c4bbdfSmrg if (parent_id) { 16535c4bbdfSmrg p_id = strtol(parent_id, NULL, 0); 1664642e01fSmrg } 16735c4bbdfSmrg 16835c4bbdfSmrg use_geometry = (strchr(screen_size, '+') != NULL); 16935c4bbdfSmrg EPHYR_DBG("screen number:%d\n", screen->mynum); 17035c4bbdfSmrg hostx_add_screen(screen, p_id, screen->mynum, use_geometry, output); 1714642e01fSmrg } 17235c4bbdfSmrg else { 17335c4bbdfSmrg ErrorF("No matching card found!\n"); 1744642e01fSmrg } 1754642e01fSmrg} 1764642e01fSmrg 17735c4bbdfSmrgvoid 17835c4bbdfSmrgprocessScreenArg(const char *screen_size, char *parent_id) 17935c4bbdfSmrg{ 18035c4bbdfSmrg processScreenOrOutputArg(screen_size, NULL, parent_id); 18135c4bbdfSmrg} 18235c4bbdfSmrg 18335c4bbdfSmrgvoid 18435c4bbdfSmrgprocessOutputArg(const char *output, char *parent_id) 18535c4bbdfSmrg{ 18635c4bbdfSmrg processScreenOrOutputArg("100x100+0+0", output, parent_id); 18735c4bbdfSmrg} 18835c4bbdfSmrg 18905b261ecSmrgint 19035c4bbdfSmrgddxProcessArgument(int argc, char **argv, int i) 19105b261ecSmrg{ 19235c4bbdfSmrg static char *parent = NULL; 19335c4bbdfSmrg 19435c4bbdfSmrg EPHYR_DBG("mark argv[%d]='%s'", i, argv[i]); 19535c4bbdfSmrg 19635c4bbdfSmrg if (!strcmp(argv[i], "-parent")) { 19735c4bbdfSmrg if (i + 1 < argc) { 19835c4bbdfSmrg int j; 1994642e01fSmrg 20035c4bbdfSmrg /* If parent is specified and a screen argument follows, don't do 20135c4bbdfSmrg * anything, let the -screen handling init the rest */ 20235c4bbdfSmrg for (j = i; j < argc; j++) { 20335c4bbdfSmrg if (!strcmp(argv[j], "-screen")) { 20435c4bbdfSmrg parent = argv[i + 1]; 20535c4bbdfSmrg return 2; 20635c4bbdfSmrg } 20735c4bbdfSmrg } 20835c4bbdfSmrg 20935c4bbdfSmrg processScreenArg("100x100", argv[i + 1]); 21035c4bbdfSmrg return 2; 21135c4bbdfSmrg } 21235c4bbdfSmrg 21335c4bbdfSmrg UseMsg(); 21435c4bbdfSmrg exit(1); 2154642e01fSmrg } 21635c4bbdfSmrg else if (!strcmp(argv[i], "-screen")) { 21735c4bbdfSmrg if ((i + 1) < argc) { 21835c4bbdfSmrg processScreenArg(argv[i + 1], parent); 21935c4bbdfSmrg parent = NULL; 22035c4bbdfSmrg return 2; 22135c4bbdfSmrg } 22205b261ecSmrg 22335c4bbdfSmrg UseMsg(); 22435c4bbdfSmrg exit(1); 2254642e01fSmrg } 22635c4bbdfSmrg else if (!strcmp(argv[i], "-output")) { 22735c4bbdfSmrg if (i + 1 < argc) { 22835c4bbdfSmrg processOutputArg(argv[i + 1], NULL); 22935c4bbdfSmrg return 2; 23035c4bbdfSmrg } 23135c4bbdfSmrg 23235c4bbdfSmrg UseMsg(); 23335c4bbdfSmrg exit(1); 23405b261ecSmrg } 23535c4bbdfSmrg else if (!strcmp(argv[i], "-sw-cursor")) { 23635c4bbdfSmrg hostx_use_sw_cursor(); 23735c4bbdfSmrg return 1; 23805b261ecSmrg } 23935c4bbdfSmrg else if (!strcmp(argv[i], "-host-cursor")) { 24035c4bbdfSmrg /* Compatibility with the old command line argument, now the default. */ 24135c4bbdfSmrg return 1; 24205b261ecSmrg } 24335c4bbdfSmrg else if (!strcmp(argv[i], "-fullscreen")) { 24435c4bbdfSmrg hostx_use_fullscreen(); 24535c4bbdfSmrg return 1; 24605b261ecSmrg } 24735c4bbdfSmrg else if (!strcmp(argv[i], "-grayscale")) { 24835c4bbdfSmrg EphyrWantGrayScale = 1; 24935c4bbdfSmrg return 1; 25005b261ecSmrg } 25135c4bbdfSmrg else if (!strcmp(argv[i], "-resizeable")) { 25235c4bbdfSmrg EphyrWantResize = 1; 25335c4bbdfSmrg return 1; 25435c4bbdfSmrg } 25535c4bbdfSmrg#ifdef GLAMOR 25635c4bbdfSmrg else if (!strcmp (argv[i], "-glamor")) { 25735c4bbdfSmrg ephyr_glamor = TRUE; 25835c4bbdfSmrg ephyrFuncs.initAccel = ephyr_glamor_init; 25935c4bbdfSmrg ephyrFuncs.enableAccel = ephyr_glamor_enable; 26035c4bbdfSmrg ephyrFuncs.disableAccel = ephyr_glamor_disable; 26135c4bbdfSmrg ephyrFuncs.finiAccel = ephyr_glamor_fini; 26235c4bbdfSmrg return 1; 26335c4bbdfSmrg } 26435c4bbdfSmrg else if (!strcmp (argv[i], "-glamor_gles2")) { 26535c4bbdfSmrg ephyr_glamor = TRUE; 26635c4bbdfSmrg ephyr_glamor_gles2 = TRUE; 26735c4bbdfSmrg ephyrFuncs.initAccel = ephyr_glamor_init; 26835c4bbdfSmrg ephyrFuncs.enableAccel = ephyr_glamor_enable; 26935c4bbdfSmrg ephyrFuncs.disableAccel = ephyr_glamor_disable; 27035c4bbdfSmrg ephyrFuncs.finiAccel = ephyr_glamor_fini; 27135c4bbdfSmrg return 1; 2724642e01fSmrg } 2731b5d61b8Smrg else if (!strcmp (argv[i], "-glamor-skip-present")) { 2741b5d61b8Smrg ephyr_glamor_skip_present = TRUE; 2751b5d61b8Smrg return 1; 2761b5d61b8Smrg } 2774642e01fSmrg#endif 27835c4bbdfSmrg else if (!strcmp(argv[i], "-fakexa")) { 27935c4bbdfSmrg ephyrFuncs.initAccel = ephyrDrawInit; 28035c4bbdfSmrg ephyrFuncs.enableAccel = ephyrDrawEnable; 28135c4bbdfSmrg ephyrFuncs.disableAccel = ephyrDrawDisable; 28235c4bbdfSmrg ephyrFuncs.finiAccel = ephyrDrawFini; 28335c4bbdfSmrg return 1; 28405b261ecSmrg } 28535c4bbdfSmrg else if (!strcmp(argv[i], "-verbosity")) { 28635c4bbdfSmrg if (i + 1 < argc && argv[i + 1][0] != '-') { 28735c4bbdfSmrg int verbosity = atoi(argv[i + 1]); 28805b261ecSmrg 28935c4bbdfSmrg LogSetParameter(XLOG_VERBOSITY, verbosity); 29035c4bbdfSmrg EPHYR_LOG("set verbosiry to %d\n", verbosity); 29135c4bbdfSmrg return 2; 29235c4bbdfSmrg } 29335c4bbdfSmrg else { 29435c4bbdfSmrg UseMsg(); 29535c4bbdfSmrg exit(1); 29635c4bbdfSmrg } 29735c4bbdfSmrg } 29835c4bbdfSmrg else if (!strcmp(argv[i], "-noxv")) { 29935c4bbdfSmrg ephyrNoXV = TRUE; 30035c4bbdfSmrg EPHYR_LOG("no XVideo enabled\n"); 30135c4bbdfSmrg return 1; 30235c4bbdfSmrg } 30335c4bbdfSmrg else if (!strcmp(argv[i], "-name")) { 30435c4bbdfSmrg if (i + 1 < argc && argv[i + 1][0] != '-') { 30535c4bbdfSmrg hostx_use_resname(argv[i + 1], 1); 30635c4bbdfSmrg return 2; 30735c4bbdfSmrg } 30835c4bbdfSmrg else { 30935c4bbdfSmrg UseMsg(); 31035c4bbdfSmrg return 0; 31135c4bbdfSmrg } 31235c4bbdfSmrg } 31335c4bbdfSmrg else if (!strcmp(argv[i], "-title")) { 31435c4bbdfSmrg if (i + 1 < argc && argv[i + 1][0] != '-') { 31535c4bbdfSmrg hostx_set_title(argv[i + 1]); 31635c4bbdfSmrg return 2; 31735c4bbdfSmrg } 31835c4bbdfSmrg else { 31935c4bbdfSmrg UseMsg(); 32035c4bbdfSmrg return 0; 32135c4bbdfSmrg } 32235c4bbdfSmrg } 32335c4bbdfSmrg else if (argv[i][0] == ':') { 32435c4bbdfSmrg hostx_set_display_name(argv[i]); 32535c4bbdfSmrg } 32635c4bbdfSmrg /* Xnest compatibility */ 32735c4bbdfSmrg else if (!strcmp(argv[i], "-display")) { 32835c4bbdfSmrg hostx_set_display_name(argv[i + 1]); 32935c4bbdfSmrg return 2; 33035c4bbdfSmrg } 33135c4bbdfSmrg else if (!strcmp(argv[i], "-sync") || 33235c4bbdfSmrg !strcmp(argv[i], "-full") || 33335c4bbdfSmrg !strcmp(argv[i], "-sss") || !strcmp(argv[i], "-install")) { 33435c4bbdfSmrg return 1; 33535c4bbdfSmrg } 33635c4bbdfSmrg else if (!strcmp(argv[i], "-bw") || 33735c4bbdfSmrg !strcmp(argv[i], "-class") || 33835c4bbdfSmrg !strcmp(argv[i], "-geometry") || !strcmp(argv[i], "-scrns")) { 33935c4bbdfSmrg return 2; 34035c4bbdfSmrg } 34135c4bbdfSmrg /* end Xnest compat */ 34235c4bbdfSmrg else if (!strcmp(argv[i], "-no-host-grab")) { 34335c4bbdfSmrg EphyrWantNoHostGrab = 1; 34435c4bbdfSmrg return 1; 34505b261ecSmrg } 3461b5d61b8Smrg else if (!strcmp(argv[i], "-sharevts") || 3471b5d61b8Smrg !strcmp(argv[i], "-novtswitch")) { 3481b5d61b8Smrg return 1; 3491b5d61b8Smrg } 3501b5d61b8Smrg else if (!strcmp(argv[i], "-layout")) { 3511b5d61b8Smrg return 2; 3521b5d61b8Smrg } 35305b261ecSmrg 35435c4bbdfSmrg return KdProcessArgument(argc, argv, i); 3554642e01fSmrg} 3564642e01fSmrg 35735c4bbdfSmrgvoid 35835c4bbdfSmrgOsVendorInit(void) 35905b261ecSmrg{ 36035c4bbdfSmrg EPHYR_DBG("mark"); 36105b261ecSmrg 3621b5d61b8Smrg if (SeatId) 3631b5d61b8Smrg hostx_use_sw_cursor(); 3641b5d61b8Smrg 36535c4bbdfSmrg if (hostx_want_host_cursor()) 36635c4bbdfSmrg ephyrFuncs.initCursor = &ephyrCursorInit; 36705b261ecSmrg 3681b5d61b8Smrg if (serverGeneration == 1) { 3691b5d61b8Smrg if (!KdCardInfoLast()) { 3701b5d61b8Smrg processScreenArg("640x480", NULL); 3711b5d61b8Smrg } 3721b5d61b8Smrg hostx_init(); 3731b5d61b8Smrg } 37405b261ecSmrg} 37505b261ecSmrg 37605b261ecSmrgKdCardFuncs ephyrFuncs = { 37735c4bbdfSmrg ephyrCardInit, /* cardinit */ 37835c4bbdfSmrg ephyrScreenInitialize, /* scrinit */ 37935c4bbdfSmrg ephyrInitScreen, /* initScreen */ 38035c4bbdfSmrg ephyrFinishInitScreen, /* finishInitScreen */ 38135c4bbdfSmrg ephyrCreateResources, /* createRes */ 38235c4bbdfSmrg ephyrScreenFini, /* scrfini */ 38335c4bbdfSmrg ephyrCardFini, /* cardfini */ 38435c4bbdfSmrg 38535c4bbdfSmrg 0, /* initCursor */ 38635c4bbdfSmrg 38735c4bbdfSmrg 0, /* initAccel */ 38835c4bbdfSmrg 0, /* enableAccel */ 38935c4bbdfSmrg 0, /* disableAccel */ 39035c4bbdfSmrg 0, /* finiAccel */ 39135c4bbdfSmrg 39235c4bbdfSmrg ephyrGetColors, /* getColors */ 39335c4bbdfSmrg ephyrPutColors, /* putColors */ 39435c4bbdfSmrg 39535c4bbdfSmrg ephyrCloseScreen, /* closeScreen */ 39605b261ecSmrg}; 397