Ejemplo n.º 1
0
        private void runWindows(Control control)
        {
            this.mainControl = control;
            //
            stdInputHandle = Win32.GetStdHandle(StdHandleType.STD_INPUT_HANDLE);
            stdOutputHandle = Win32.GetStdHandle(StdHandleType.STD_OUTPUT_HANDLE);
            IntPtr[] handles = new[] {
                exitWaitHandle.SafeWaitHandle.DangerousGetHandle(),
                stdInputHandle,
                invokeWaitHandle.SafeWaitHandle.DangerousGetHandle(  )
            };

            // Set console mode to enable mouse and window resizing events
            const uint ENABLE_WINDOW_INPUT = 0x0008;
            const uint ENABLE_MOUSE_INPUT = 0x0010;
            uint consoleMode;
            Win32.GetConsoleMode( stdInputHandle, out consoleMode );
            Win32.SetConsoleMode(stdInputHandle, consoleMode | ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT);

            // Get console screen buffer size
            CONSOLE_SCREEN_BUFFER_INFO screenBufferInfo;
            Win32.GetConsoleScreenBufferInfo( stdOutputHandle, out screenBufferInfo );

            // Set Canvas size to current console window size (not to whole buffer size)
            savedWindowRect = new Rect( new Point( Console.WindowLeft, Console.WindowTop ),
                                        new Size( Console.WindowWidth, Console.WindowHeight ) );
            CanvasSize = new Size(savedWindowRect.Width, savedWindowRect.Height);

            canvas = userCanvasSize.IsEmpty
                ? new PhysicalCanvas( screenBufferInfo.dwSize.X, screenBufferInfo.dwSize.Y, stdOutputHandle )
                : new PhysicalCanvas( userCanvasSize.Width, userCanvasSize.Height, stdOutputHandle);
            renderer.Canvas = canvas;

            // Fill the canvas by default
            renderer.RootElementRect = userRootElementRect.IsEmpty
                ? new Rect( new Point(0, 0), canvas.Size ) : userRootElementRect;
            renderer.RootElement = mainControl;
            //
            mainControl.Invalidate();
            renderer.UpdateLayout();
            renderer.FinallyApplyChangesToCanvas(  );

            // Initially hide the console cursor
            HideCursor();

            this.running = true;
            this.mainThreadId = Thread.CurrentThread.ManagedThreadId;
            //
            while (true) {
                // 100 ms instead of Win32.INFINITE to check console window Zoomed and Iconic
                // state periodically (because if user presses Maximize/Restore button
                // there are no input event generated).
                uint waitResult = Win32.WaitForMultipleObjects(3, handles, false, 100);
                if (waitResult == 0) {
                    break;
                }
                if (waitResult == 1) {
                    processInput();
                }
                if ( waitResult == 2 ) {
                    // Do nothing special - because invokeActions will be invoked in loop anyway
                }

                // If we received WAIT_TIMEOUT - check window Zoomed and Iconic state
                // and correct buffer size and console window size
                if ( waitResult == 0x00000102 ) {
                    IntPtr consoleWindow = getConsoleWindowHwnd( );
                    bool isZoomed = Win32.IsZoomed(consoleWindow);
                    bool isIconic = Win32.IsIconic(consoleWindow);
                    if (maximized != isZoomed && !isIconic) {
                        if (isZoomed)
                            Maximize();
                        else
                            Restore();
                    }
                    if ( !maximized ) {
                        savedWindowRect = new Rect( new Point( Console.WindowLeft, Console.WindowTop ),
                                                    new Size( Console.WindowWidth, Console.WindowHeight ) );
                    }
                }
                // WAIT_FAILED
                if ( waitResult == 0xFFFFFFFF) {
                    throw new InvalidOperationException("Invalid wait result of WaitForMultipleObjects.");
                }

                while ( true ) {
                    bool anyInvokeActions = isAnyInvokeActions( );
                    bool anyRoutedEvent = !EventManager.IsQueueEmpty( );
                    bool anyLayoutToRevalidate = renderer.AnyControlInvalidated;

                    if (!anyInvokeActions && !anyRoutedEvent && !anyLayoutToRevalidate)
                        break;

                    EventManager.ProcessEvents();
                    processInvokeActions(  );
                    renderer.UpdateLayout(  );
                }

                renderer.FinallyApplyChangesToCanvas( );
            }

            // Restore cursor visibility before exit
            ShowCursor();

            // Restore console mode before exit
            Win32.SetConsoleMode( stdInputHandle, consoleMode );

            renderer.RootElement = null;

            // todo : restore attributes of console output
        }
Ejemplo n.º 2
0
        public static void Main(string[] args)
        {
            #if !__MonoCS__
            handler = new ConsoleEventDelegate(ConsoleEventCallback);
            SetConsoleCtrlHandler(handler, true);
            #else
            // http://stackoverflow.com/questions/6546509/detect-when-console-application-is-closing-killed
            var signums = new Signum []
            {
                Signum.SIGABRT,
                Signum.SIGINT,
                Signum.SIGKILL,
                Signum.SIGQUIT,
                Signum.SIGTERM,
                Signum.SIGSTOP,
                Signum.SIGTSTP
            };

            List<UnixSignal> signals = new List<UnixSignal>();
            foreach (var signum in signums)
            {
                try
                {
                    signals.Add(new UnixSignal(signum));
                }
                catch(Exception) {}
            }

            new Thread (delegate ()
            {
                // Wait for a signal to be delivered
                UnixSignal.WaitAny(signals.ToArray(), -1);
                app.Shutdown("UnixSignal");
            }).Start();
            #endif

            if (string.IsNullOrWhiteSpace(Settings.Default.TempPath))
            {
                Settings.Default.TempPath = Settings.Default.GetAppDataPath() + "tmp";
            }
            if (!Settings.Default.TempPath.EndsWith("" + Path.DirectorySeparatorChar))
            {
                Settings.Default.TempPath += Path.DirectorySeparatorChar;
            }
            new DirectoryInfo(Settings.Default.TempPath).Create();

            if (string.IsNullOrWhiteSpace(Settings.Default.ReadyPath))
            {
                Settings.Default.ReadyPath = Settings.Default.GetAppDataPath() + "dl";
            }
            if (!Settings.Default.ReadyPath.EndsWith("" + Path.DirectorySeparatorChar))
            {
                Settings.Default.ReadyPath += Path.DirectorySeparatorChar;
            }
            new DirectoryInfo(Settings.Default.ReadyPath).Create();

            Settings.Default.Save();

            if (File.Exists(Settings.Default.GetAppDataPath() + "log4net.xml"))
            {
                // load settings from file
                XmlConfigurator.Configure(new FileInfo(Settings.Default.GetAppDataPath() + "log4net.xml"));
            }
            else
            {
                // build our own, who logs only fatals to console
                Logger root = ((Hierarchy)LogManager.GetRepository()).Root;

                var lAppender = new ConsoleAppender
                {
                    Name = "Console",
                    Layout = new PatternLayout("%date{dd-MM-yyyy HH:mm:ss,fff} %5level [%2thread] %line:%logger.%message%n"),
            #if DEBUG
                    Threshold = Level.Info
            #else
                    Threshold = Level.Fatal
            #endif
                };
                lAppender.ActivateOptions();

                root.AddAppender(lAppender);
                root.Repository.Configured = true;
            }

            #if __MonoCS__
            PlatformID id = Environment.OSVersion.Platform;
            // Don't allow running as root on Linux or Mac
            try
            {
                if ((id == PlatformID.Unix || id == PlatformID.MacOSX) && new UnixUserInfo(UnixEnvironment.UserName).UserId == 0)
                {
                    LogManager.GetLogger(typeof(Programm)).Fatal("Sorry, you can't run XG with these permissions. Safety first!");
                    Environment.Exit(-1);
                }
            }
            catch (ArgumentException)
            {
                // arch linux fix
                // https://github.com/lformella/xdcc-grabscher/issues/36
            }
            #endif

            app = new App();

            app.AddPlugin(new Plugin.Irc.Plugin());
            if (Settings.Default.UseJabberClient)
            {
                app.AddPlugin(new Plugin.Jabber.Plugin());
            }
            if (Settings.Default.UseElasticSearch)
            {
                app.AddPlugin(new Plugin.ElasticSearch.Plugin());
            }
            if (Settings.Default.UseWebserver)
            {
                var webServer = new Plugin.Webserver.Plugin { RrdDB = app.RrdDb };
                webServer.OnShutdown += delegate { app.Shutdown(webServer); };
                app.AddPlugin(webServer);
            }

            app.OnShutdownComplete += delegate { Environment.Exit(0); };
            app.Start(typeof(App).ToString());
        }

        #endregion Methods
    }