summaryrefslogtreecommitdiff
path: root/src/VBox/Additions/x11/VBoxClient/testcase/tstSeamlessX11.cpp
blob: dbbe7da0b66815919974dd3b425e6a9845982aec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/** @file
 * Linux seamless guest additions simulator in host.
 */

/*
 * Copyright (C) 2011 Oracle Corporation
 *
 * This file is part of VirtualBox Open Source Edition (OSE), as
 * available from http://www.virtualbox.org. This file is free software;
 * you can redistribute it and/or modify it under the terms of the GNU
 * General Public License (GPL) as published by the Free Software
 * Foundation, in version 2 as it comes in the "COPYING" file of the
 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
 */

#include <stdlib.h> /* exit() */

#include <iprt/initterm.h>
#include <iprt/semaphore.h>
#include <iprt/stream.h>
#include <VBox/VBoxGuestLib.h>

#include "../seamless.h"

static RTSEMEVENT eventSem;

int VbglR3SeamlessSendRects(uint32_t cRects, PRTRECT pRects)
{
    RTPrintf("Received rectangle update (%u rectangles):\n", cRects);
    for (unsigned i = 0; i < cRects; ++i)
    {
        RTPrintf("  xLeft: %d  yTop: %d  xRight: %d  yBottom: %d\n",
                 pRects[i].xLeft, pRects[i].yTop, pRects[i].xRight,
                 pRects[i].yBottom);
    }
    return true;
}

int VbglR3SeamlessSetCap(bool bState)
{
    RTPrintf("%s\n", bState ? "Seamless capability set"
                            : "Seamless capability unset");
    return true;
}

int VbglR3CtlFilterMask(uint32_t u32OrMask, uint32_t u32NotMask)
{
    RTPrintf("IRQ filter mask changed.  Or mask: 0x%x.  Not mask: 0x%x\n",
             u32OrMask, u32NotMask);
    return true;
}

int VbglR3SeamlessWaitEvent(VMMDevSeamlessMode *pMode)
{
    static bool active = false;

    int rc = VINF_SUCCESS;
    if (!active)
    {
        active = true;
        *pMode = VMMDev_Seamless_Visible_Region;
    }
    else
    {
        rc = RTSemEventWait(eventSem, RT_INDEFINITE_WAIT);
        if (RT_SUCCESS(rc))
        {
            rc = VERR_INTERRUPTED;
        }
    }
    return true;
}

int VbglR3InterruptEventWaits(void)
{
    return RTSemEventSignal(eventSem);
}

/**
 * Xlib error handler for certain errors that we can't avoid.
 */
int vboxClientXLibErrorHandler(Display *pDisplay, XErrorEvent *pError)
{
    char errorText[1024];

    if (pError->error_code == BadWindow)
    {
        /* This can be triggered if a guest application destroys a window before we notice. */
        RTPrintf("ignoring BadAtom error and returning\n");
        return 0;
    }
    XGetErrorText(pDisplay, pError->error_code, errorText, sizeof(errorText));
    RTPrintf("An X Window protocol error occurred: %s\n"
             "  Request code: %d\n"
             "  Minor code: %d\n"
             "  Serial number of the failed request: %d\n\n"
             "exiting.\n",
             errorText, (int)pError->request_code, (int)pError->minor_code,
             (int)pError->serial);
    exit(1);
}

int main( int argc, char **argv)
{
    int rc = VINF_SUCCESS;
    char ach[2];

    RTR3InitExe(argc, &argv, 0);
    RTPrintf("VirtualBox guest additions X11 seamless mode testcase\n");
    if (0 == XInitThreads())
    {
        RTPrintf("Failed to initialise X11 threading, exiting.\n");
        exit(1);
    }
    /* Set an X11 error handler, so that we don't die when we get unavoidable errors. */
    XSetErrorHandler(vboxClientXLibErrorHandler);
    RTPrintf("\nPress <Enter> to exit...\n");
    RTSemEventCreate(&eventSem);
    /** Our instance of the seamless class. */
    VBoxGuestSeamless seamless;
    LogRel(("Starting seamless Guest Additions...\n"));
    rc = seamless.init();
    if (rc != VINF_SUCCESS)
    {
        RTPrintf("Failed to initialise seamless Additions, rc = %d\n", rc);
    }
    RTStrmGetLine(g_pStdIn, ach, sizeof(ach));
    seamless.uninit();
    return rc;
}