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