/**************************************************************************/ /* */ /* Copyright (c) 2001, 2011 NoMachine (http://www.nomachine.com) */ /* Copyright (c) 2008-2014 Oleksandr Shneyder */ /* Copyright (c) 2011-2016 Mike Gabriel */ /* Copyright (c) 2014-2016 Mihai Moldovan */ /* Copyright (c) 2014-2016 Ulrich Sibiller */ /* Copyright (c) 2015-2016 Qindel Group (http://www.qindel.com) */ /* */ /* NXAGENT, NX protocol compression and NX extensions to this software */ /* are copyright of the aforementioned persons and companies. */ /* */ /* Redistribution and use of the present software is allowed according */ /* to terms specified in the file LICENSE which comes in the source */ /* distribution. */ /* */ /* All rights reserved. */ /* */ /* NOTE: This software has received contributions from various other */ /* contributors, only the core maintainers and supporters are listed as */ /* copyright holders. Please contact us, if you feel you should be listed */ /* as copyright holder, as well. */ /* */ /**************************************************************************/ #include "windowstr.h" #include "scrnintstr.h" #ifdef _XSERVER64 #include "Agent.h" #define GC XlibGC #endif /* _XSERVER64 */ #include "Xlib.h" #include "Xutil.h" #include "Display.h" #include "Splash.h" #include "Screen.h" #include "Windows.h" #include "Atoms.h" #include "Trap.h" #include "Init.h" /* * Set here the required log level. */ #define PANIC #define WARNING #undef TEST #undef DEBUG /* * Colors used to paint the splash screen. */ #define nxagentLogoWhite 0xffffff #define nxagentLogoBlack 0x000000 #define nxagentLogoDarkGray 0x222222 #define nxagentLogoLightGray 0xbbbbbb Pixmap nxagentPixmapLogo; Window nxagentSplashWindow = None; Bool nxagentWMPassed = False; static void nxagentPaintLogo(Window win, GC gc, int scale, int width, int height); /* * From Screen.c. */ #ifdef NXAGENT_ONSTART extern Atom nxagentReadyAtom; #endif /* * From Clipboard.c. */ extern Atom serverCutProperty; void nxagentShowSplashWindow(Window parentWindow) { XWindowAttributes getAttributes; XWindowChanges values; XSetWindowAttributes attributes; GC gc; /* * Show splash window only when running as X2Go Agent */ if(!nxagentX2go) return; #ifdef TEST fprintf(stderr, "%s: Got called.\n", __func__); #endif #ifdef NXAGENT_TIMESTAMP { extern unsigned long startTime; fprintf(stderr, "%s: Initializing splash start at [%d] milliseconds.\n", __func__, GetTimeInMillis() - startTime); } #endif #ifdef NXAGENT_ONSTART XSetSelectionOwner(nxagentDisplay, nxagentReadyAtom, None, CurrentTime); #endif nxagentWMPassed = False; /* * This would cause a GetWindowAttributes and a * GetGeometry (asynchronous) reply. We use instead * the geometry requested by the user for the agent * window. * * XGetWindowAttributes(nxagentDisplay, parentWindow, &getAttributes); */ /* * During reconnection we draw the splash over * the default window and not over the root * window because it would be hidden by other * windows. */ if (nxagentReconnectTrap) { getAttributes.x = nxagentOption(RootX); getAttributes.y = nxagentOption(RootY); } else { getAttributes.x = 0; getAttributes.y = 0; } getAttributes.width = nxagentOption(RootWidth); getAttributes.height = nxagentOption(RootHeight); #ifdef TEST fprintf(stderr, "%s: Going to create new splash window.\n", __func__); #endif nxagentSplashWindow = XCreateSimpleWindow(nxagentDisplay, parentWindow, getAttributes.x, getAttributes.y, getAttributes.width, getAttributes.height, 0, WhitePixel (nxagentDisplay, 0), BlackPixel (nxagentDisplay, 0)); #ifdef TEST fprintf(stderr, "%s: Created new splash window with id [%ld].\n", __func__, nxagentSplashWindow); #endif gc = XCreateGC(nxagentDisplay, nxagentSplashWindow, 0, NULL); nxagentPaintLogo(nxagentSplashWindow, gc, 1, getAttributes.width, getAttributes.height); XMapRaised (nxagentDisplay, nxagentSplashWindow); values.stack_mode = Above; XConfigureWindow(nxagentDisplay, nxagentSplashWindow, CWStackMode, &values); attributes.override_redirect = True; XChangeWindowAttributes(nxagentDisplay, nxagentSplashWindow, CWOverrideRedirect, &attributes); XFreeGC(nxagentDisplay, gc); #ifdef NXAGENT_TIMESTAMP { extern unsigned long startTime; fprintf(stderr, "%s: Splash ends [%d] milliseconds.\n", __func__, GetTimeInMillis() - startTime); } #endif } void nxagentPaintLogo(Window win, GC gc, int scale, int width, int height) { int depth = DefaultDepth(nxagentDisplay, DefaultScreen(nxagentDisplay)); #ifdef DEBUG fprintf(stderr, "%s: Got called.\n", __func__); #endif #ifdef NXAGENT_LOGO_DEBUG fprintf(stderr, "%s: begin\n", __func__); fprintf(stderr, "%s: gen params are: w=%d h=%d d=%d w=%x b=%x g1=%x g2=%x \n", __func__, width, height, depth, nxagentLogoWhite, nxagentLogoBlack, nxagentLogoDarkGray, nxagentLogoLightGray); #endif int w = width/scale; int h = height/scale; int w2 = w/2; int h2 = h/2; int c; if (height > width) { c = w/30; } else { c = w/48; } XSetFunction(nxagentDisplay, gc, GXcopy); XSetFillStyle(nxagentDisplay, gc, FillSolid); nxagentPixmapLogo = XCreatePixmap(nxagentDisplay, win, width, height, depth); if (!nxagentPixmapLogo) { return; } if (blackRoot) { XSetForeground(nxagentDisplay, gc, nxagentLogoBlack); XSetBackground(nxagentDisplay, gc, nxagentLogoWhite); } else { XSetForeground(nxagentDisplay, gc, nxagentLogoWhite); XSetBackground(nxagentDisplay, gc, nxagentLogoBlack); } XPoint rect[4]; rect[0].x = 0; rect[0].y = 0; rect[1].x = 0; rect[1].y = h; rect[2].x = w; rect[2].y = h; rect[3].x = w; rect[3].y = 0; /* paint background */ XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin); #ifdef NXAGENT_LOGO_DEBUG fprintf(stderr, "%s: filled first poly\n", __func__); #endif /* * Draw X2GO Logo */ if (blackRoot) XSetForeground(nxagentDisplay, gc, nxagentLogoDarkGray); else XSetForeground(nxagentDisplay, gc, nxagentLogoLightGray); /* * Start 'X'. */ rect[0].x = w2-7*c; rect[0].y = h2-5*c; rect[1].x = w2-8*c; rect[1].y = h2-5*c; rect[2].x = w2-4*c; rect[2].y = h2+3*c; rect[3].x = w2-3*c; rect[3].y = h2+3*c; XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin); rect[0].x = w2-4*c; rect[0].y = h2-5*c; rect[1].x = w2-3*c; rect[1].y = h2-5*c; rect[2].x = w2-7*c; rect[2].y = h2+3*c; rect[3].x = w2-8*c; rect[3].y = h2+3*c; XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin); /* * End 'X'. */ /* * Start '2'. */ rect[0].x = w2-2*c; rect[0].y = h2-5*c; rect[1].x = w2-1*c; rect[1].y = h2-5*c; rect[2].x = w2-1*c; rect[2].y = h2-3*c; rect[3].x = w2-2*c; rect[3].y = h2-3*c; XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin); rect[0].x = w2-2*c; rect[0].y = h2-5*c; rect[1].x = w2+2*c; rect[1].y = h2-5*c; rect[2].x = w2+2*c; rect[2].y = h2-4*c; rect[3].x = w2-2*c; rect[3].y = h2-4*c; XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin); rect[0].x = w2+1*c; rect[0].y = h2-5*c; rect[1].x = w2+2*c; rect[1].y = h2-5*c; rect[2].x = w2+2*c; rect[2].y = h2-2*c; rect[3].x = w2+1*c; rect[3].y = h2-2*c; XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin); rect[0].x = w2+2*c; rect[0].y = h2-2*c; rect[1].x = w2+1*c; rect[1].y = h2-2*c; rect[2].x = w2-2*c; rect[2].y = h2+2*c; rect[3].x = w2-1*c; rect[3].y = h2+2*c; XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin); rect[0].x = w2-2*c; rect[0].y = h2+2*c; rect[1].x = w2+2*c; rect[1].y = h2+2*c; rect[2].x = w2+2*c; rect[2].y = h2+3*c; rect[3].x = w2-2*c; rect[3].y = h2+3*c; XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin); /* * End '2'. */ /* * Start 'G'. */ rect[0].x = w2+3*c; rect[0].y = h2-5*c; rect[1].x = w2+7*c; rect[1].y = h2-5*c; rect[2].x = w2+7*c; rect[2].y = h2-4*c; rect[3].x = w2+3*c; rect[3].y = h2-4*c; XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin); rect[0].x = w2+3*c; rect[0].y = h2-5*c; rect[1].x = w2+4*c; rect[1].y = h2-5*c; rect[2].x = w2+4*c; rect[2].y = h2+3*c; rect[3].x = w2+3*c; rect[3].y = h2+3*c; XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin); rect[0].x = w2+3*c; rect[0].y = h2+2*c; rect[1].x = w2+7*c; rect[1].y = h2+2*c; rect[2].x = w2+7*c; rect[2].y = h2+3*c; rect[3].x = w2+3*c; rect[3].y = h2+3*c; XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin); rect[0].x = w2+6*c; rect[0].y = h2-5*c; rect[1].x = w2+7*c; rect[1].y = h2-5*c; rect[2].x = w2+7*c; rect[2].y = h2-3*c; rect[3].x = w2+6*c; rect[3].y = h2-3*c; XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin); rect[0].x = w2+6*c; rect[0].y = h2-0*c; rect[1].x = w2+7*c; rect[1].y = h2-0*c; rect[2].x = w2+7*c; rect[2].y = h2+3*c; rect[3].x = w2+6*c; rect[3].y = h2+3*c; XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin); rect[0].x = w2+5*c; rect[0].y = h2-1*c; rect[1].x = w2+7*c; rect[1].y = h2-1*c; rect[2].x = w2+7*c; rect[2].y = h2+0*c; rect[3].x = w2+5*c; rect[3].y = h2+0*c; XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin); /* * End 'G'. */ /* * Start 'O'. */ rect[0].x = w2+8*c; rect[0].y = h2-5*c; rect[1].x = w2+12*c; rect[1].y = h2-5*c; rect[2].x = w2+12*c; rect[2].y = h2-4*c; rect[3].x = w2+8*c; rect[3].y = h2-4*c; XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin); rect[0].x = w2+8*c; rect[0].y = h2+3*c; rect[1].x = w2+12*c; rect[1].y = h2+3*c; rect[2].x = w2+12*c; rect[2].y = h2+2*c; rect[3].x = w2+8*c; rect[3].y = h2+2*c; XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin); rect[0].x = w2+8*c; rect[0].y = h2-5*c; rect[1].x = w2+9*c; rect[1].y = h2-5*c; rect[2].x = w2+9*c; rect[2].y = h2+3*c; rect[3].x = w2+8*c; rect[3].y = h2+3*c; XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin); rect[0].x = w2+11*c; rect[0].y = h2-5*c; rect[1].x = w2+12*c; rect[1].y = h2-5*c; rect[2].x = w2+12*c; rect[2].y = h2+3*c; rect[3].x = w2+11*c; rect[3].y = h2+3*c; XFillPolygon(nxagentDisplay, nxagentPixmapLogo, gc, rect, 4, Convex, CoordModeOrigin); /* * End 'O'. */ XSetWindowBackgroundPixmap(nxagentDisplay, win, nxagentPixmapLogo); #ifdef NXAGENT_LOGO_DEBUG fprintf(stderr, "%s: end\n", __func__); #endif } void nxagentRemoveSplashWindow(void) { if (nxagentWMPassed) return; if (nxagentReconnectTrap) return; #ifdef TEST fprintf(stderr, "%s: Destroying the splash window.\n", __func__); #endif if (!nxagentWMPassed) { #ifdef NXAGENT_ONSTART XSetSelectionOwner(nxagentDisplay, nxagentReadyAtom, nxagentDefaultWindows[0], CurrentTime); #endif nxagentWMPassed = True; } if (nxagentSplashWindow != None) { XDestroyWindow(nxagentDisplay, nxagentSplashWindow); nxagentSplashWindow = None; nxagentRefreshWindows(screenInfo.screens[0]->root); #ifdef TEST fprintf(stderr, "%s: setting the ownership of %s (%d) on window 0x%lx\n", __func__ "NX_CUT_BUFFER_SERVER", (int)serverCutProperty, nxagentWindow(screenInfo.screens[0]->root)); #endif XSetSelectionOwner(nxagentDisplay, serverCutProperty, nxagentWindow(screenInfo.screens[0]->root), CurrentTime); } if (nxagentPixmapLogo) { XFreePixmap(nxagentDisplay, nxagentPixmapLogo); nxagentPixmapLogo = (Pixmap) 0; } }