Better CEC architecture.
authorStephaneLenclud
Sat, 26 Sep 2015 16:35:27 +0200
changeset 167d2295c186ce1
parent 166 22b327842add
child 168 2568261f74fb
Better CEC architecture.
Server/CecClient.cs
Server/CecSharpClient.cs
Server/ConsumerElectronicControl.cs
Server/MainForm.Hid.cs
Server/MainForm.cs
Server/SharpDisplayManager.csproj
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/Server/CecClient.cs	Sat Sep 26 16:35:27 2015 +0200
     1.3 @@ -0,0 +1,385 @@
     1.4 +/*
     1.5 + * This file is part of the libCEC(R) library.
     1.6 + *
     1.7 + * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited.    All rights reserved.
     1.8 + * libCEC(R) is an original work, containing original code.
     1.9 + *
    1.10 + * libCEC(R) is a trademark of Pulse-Eight Limited.
    1.11 + *
    1.12 + * This program is dual-licensed; you can redistribute it and/or modify
    1.13 + * it under the terms of the GNU General Public License as published by
    1.14 + * the Free Software Foundation; either version 2 of the License, or
    1.15 + * (at your option) any later version.
    1.16 + *
    1.17 + * This program is distributed in the hope that it will be useful,
    1.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
    1.20 + * GNU General Public License for more details.
    1.21 + *
    1.22 + * You should have received a copy of the GNU General Public License
    1.23 + * along with this program; if not, write to the Free Software
    1.24 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    1.25 + *
    1.26 + *
    1.27 + * Alternatively, you can license this library under a commercial license,
    1.28 + * please contact Pulse-Eight Licensing for more information.
    1.29 + *
    1.30 + * For more information contact:
    1.31 + * Pulse-Eight Licensing             <license@pulse-eight.com>
    1.32 + *         http://www.pulse-eight.com/
    1.33 + *         http://www.pulse-eight.net/
    1.34 + */
    1.35 +
    1.36 +using System;
    1.37 +using System.Text;
    1.38 +using CecSharp;
    1.39 +
    1.40 +namespace Cec
    1.41 +{
    1.42 +    class Client : CecCallbackMethods
    1.43 +    {
    1.44 +        /// <summary>
    1.45 +        /// 
    1.46 +        /// </summary>
    1.47 +        /// <param name="aDeviceName"></param>
    1.48 +        /// <param name="aHdmiPort"></param>
    1.49 +        public Client(string aDeviceName, byte aHdmiPort)
    1.50 +        {
    1.51 +            Config = new LibCECConfiguration();
    1.52 +            Config.DeviceTypes.Types[0] = CecDeviceType.Tv;
    1.53 +            Config.DeviceName = aDeviceName;
    1.54 +            Config.HDMIPort = aHdmiPort;
    1.55 +            //Config.ClientVersion = LibCECConfiguration.CurrentVersion;
    1.56 +            Config.SetCallbacks(this);
    1.57 +            LogLevel = (int)CecLogLevel.All;
    1.58 +
    1.59 +            iLib = new LibCecSharp(Config);
    1.60 +            iLib.InitVideoStandalone();
    1.61 +
    1.62 +            //Console.WriteLine("CEC Parser created - libCEC version " + Lib.VersionToString(Config.ServerVersion));
    1.63 +            Console.WriteLine("CEC Parser created - libCEC version " + Config.ServerVersion);
    1.64 +        }
    1.65 +
    1.66 +        public override int ReceiveCommand(CecCommand command)
    1.67 +        {
    1.68 +            return 1;
    1.69 +        }
    1.70 +
    1.71 +        public override int ReceiveKeypress(CecKeypress key)
    1.72 +        {
    1.73 +            return 1;
    1.74 +        }
    1.75 +
    1.76 +        public override int ReceiveLogMessage(CecLogMessage message)
    1.77 +        {
    1.78 +            if (((int)message.Level & LogLevel) == (int)message.Level)
    1.79 +            {
    1.80 +                string strLevel = "";
    1.81 +                switch (message.Level)
    1.82 +                {
    1.83 +                    case CecLogLevel.Error:
    1.84 +                        strLevel = "ERROR:     ";
    1.85 +                        break;
    1.86 +                    case CecLogLevel.Warning:
    1.87 +                        strLevel = "WARNING: ";
    1.88 +                        break;
    1.89 +                    case CecLogLevel.Notice:
    1.90 +                        strLevel = "NOTICE:    ";
    1.91 +                        break;
    1.92 +                    case CecLogLevel.Traffic:
    1.93 +                        strLevel = "TRAFFIC: ";
    1.94 +                        break;
    1.95 +                    case CecLogLevel.Debug:
    1.96 +                        strLevel = "DEBUG:     ";
    1.97 +                        break;
    1.98 +                    default:
    1.99 +                        break;
   1.100 +                }
   1.101 +                string strLog = string.Format("{0} {1,16} {2}", strLevel, message.Time, message.Message);
   1.102 +                Console.WriteLine(strLog);
   1.103 +            }
   1.104 +            return 1;
   1.105 +        }
   1.106 +
   1.107 +        /// <summary>
   1.108 +        /// 
   1.109 +        /// </summary>
   1.110 +        /// <param name="timeout"></param>
   1.111 +        /// <returns></returns>
   1.112 +        public bool Connect(int timeout)
   1.113 +        {
   1.114 +            CecAdapter[] adapters = iLib.FindAdapters(string.Empty);
   1.115 +            if (adapters.Length > 0)
   1.116 +                return Connect(adapters[0].ComPort, timeout);
   1.117 +            else
   1.118 +            {
   1.119 +                Console.WriteLine("Did not find any CEC adapters");
   1.120 +                return false;
   1.121 +            }
   1.122 +        }
   1.123 +
   1.124 +        public bool Connect(string port, int timeout)
   1.125 +        {
   1.126 +            return iLib.Open(port, timeout);
   1.127 +        }
   1.128 +
   1.129 +        public void Close()
   1.130 +        {
   1.131 +            iLib.Close();
   1.132 +        }
   1.133 +
   1.134 +        public void ListDevices()
   1.135 +        {
   1.136 +            int iAdapter = 0;
   1.137 +            foreach (CecAdapter adapter in iLib.FindAdapters(string.Empty))
   1.138 +            {
   1.139 +                Console.WriteLine("Adapter:    " + iAdapter++);
   1.140 +                Console.WriteLine("Path:         " + adapter.Path);
   1.141 +                Console.WriteLine("Com port: " + adapter.ComPort);
   1.142 +            }
   1.143 +        }
   1.144 +
   1.145 +        void ShowConsoleHelp()
   1.146 +        {
   1.147 +            Console.WriteLine(
   1.148 +                "================================================================================" + Environment.NewLine +
   1.149 +                "Available commands:" + Environment.NewLine +
   1.150 +                Environment.NewLine +
   1.151 +                "[tx] {bytes}                            transfer bytes over the CEC line." + Environment.NewLine +
   1.152 +                "[txn] {bytes}                         transfer bytes but don't wait for transmission ACK." + Environment.NewLine +
   1.153 +                "[on] {address}                        power on the device with the given logical address." + Environment.NewLine +
   1.154 +                "[standby] {address}             put the device with the given address in standby mode." + Environment.NewLine +
   1.155 +                "[la] {logical_address}        change the logical address of the CEC adapter." + Environment.NewLine +
   1.156 +                "[pa] {physical_address}     change the physical address of the CEC adapter." + Environment.NewLine +
   1.157 +                "[osd] {addr} {string}         set OSD message on the specified device." + Environment.NewLine +
   1.158 +                "[ver] {addr}                            get the CEC version of the specified device." + Environment.NewLine +
   1.159 +                "[ven] {addr}                            get the vendor ID of the specified device." + Environment.NewLine +
   1.160 +                "[lang] {addr}                         get the menu language of the specified device." + Environment.NewLine +
   1.161 +                "[pow] {addr}                            get the power status of the specified device." + Environment.NewLine +
   1.162 +                "[poll] {addr}                         poll the specified device." + Environment.NewLine +
   1.163 +                "[scan]                                        scan the CEC bus and display device info" + Environment.NewLine +
   1.164 +                "[mon] {1|0}                             enable or disable CEC bus monitoring." + Environment.NewLine +
   1.165 +                "[log] {1 - 31}                        change the log level. see cectypes.h for values." + Environment.NewLine +
   1.166 +                "[ping]                                        send a ping command to the CEC adapter." + Environment.NewLine +
   1.167 +                "[bl]                                            to let the adapter enter the bootloader, to upgrade" + Environment.NewLine +
   1.168 +                "                                                    the flash rom." + Environment.NewLine +
   1.169 +                "[r]                                             reconnect to the CEC adapter." + Environment.NewLine +
   1.170 +                "[h] or [help]                         show this help." + Environment.NewLine +
   1.171 +                "[q] or [quit]                         to quit the CEC test client and switch off all" + Environment.NewLine +
   1.172 +                "                                                    connected CEC devices." + Environment.NewLine +
   1.173 +                "================================================================================");
   1.174 +        }
   1.175 +
   1.176 +        public void MainLoop()
   1.177 +        {
   1.178 +            bool bContinue = true;
   1.179 +            string command;
   1.180 +            while (bContinue)
   1.181 +            {
   1.182 +                Console.WriteLine("waiting for input");
   1.183 +
   1.184 +                command = Console.ReadLine();
   1.185 +                if (command != null && command.Length == 0)
   1.186 +                    continue;
   1.187 +                string[] splitCommand = command.Split(' ');
   1.188 +                if (splitCommand[0] == "tx" || splitCommand[0] == "txn")
   1.189 +                {
   1.190 +                    CecCommand bytes = new CecCommand();
   1.191 +                    for (int iPtr = 1; iPtr < splitCommand.Length; iPtr++)
   1.192 +                    {
   1.193 +                        bytes.PushBack(byte.Parse(splitCommand[iPtr], System.Globalization.NumberStyles.HexNumber));
   1.194 +                    }
   1.195 +
   1.196 +                    if (command == "txn")
   1.197 +                        bytes.TransmitTimeout = 0;
   1.198 +
   1.199 +                    iLib.Transmit(bytes);
   1.200 +                }
   1.201 +                else if (splitCommand[0] == "on")
   1.202 +                {
   1.203 +                    if (splitCommand.Length > 1)
   1.204 +                        iLib.PowerOnDevices((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
   1.205 +                    else
   1.206 +                        iLib.PowerOnDevices(CecLogicalAddress.Broadcast);
   1.207 +                }
   1.208 +                else if (splitCommand[0] == "standby")
   1.209 +                {
   1.210 +                    if (splitCommand.Length > 1)
   1.211 +                        iLib.StandbyDevices((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
   1.212 +                    else
   1.213 +                        iLib.StandbyDevices(CecLogicalAddress.Broadcast);
   1.214 +                }
   1.215 +                else if (splitCommand[0] == "poll")
   1.216 +                {
   1.217 +                    bool bSent = false;
   1.218 +                    if (splitCommand.Length > 1)
   1.219 +                        bSent = iLib.PollDevice((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
   1.220 +                    else
   1.221 +                        bSent = iLib.PollDevice(CecLogicalAddress.Broadcast);
   1.222 +                    if (bSent)
   1.223 +                        Console.WriteLine("POLL message sent");
   1.224 +                    else
   1.225 +                        Console.WriteLine("POLL message not sent");
   1.226 +                }
   1.227 +                else if (splitCommand[0] == "la")
   1.228 +                {
   1.229 +                    if (splitCommand.Length > 1)
   1.230 +                        iLib.SetLogicalAddress((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
   1.231 +                }
   1.232 +                else if (splitCommand[0] == "pa")
   1.233 +                {
   1.234 +                    if (splitCommand.Length > 1)
   1.235 +                        iLib.SetPhysicalAddress(ushort.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
   1.236 +                }
   1.237 +                else if (splitCommand[0] == "osd")
   1.238 +                {
   1.239 +                    if (splitCommand.Length > 2)
   1.240 +                    {
   1.241 +                        StringBuilder osdString = new StringBuilder();
   1.242 +                        for (int iPtr = 1; iPtr < splitCommand.Length; iPtr++)
   1.243 +                        {
   1.244 +                            osdString.Append(splitCommand[iPtr]);
   1.245 +                            if (iPtr != splitCommand.Length - 1)
   1.246 +                                osdString.Append(" ");
   1.247 +                        }
   1.248 +                        iLib.SetOSDString((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber), CecDisplayControl.DisplayForDefaultTime, osdString.ToString());
   1.249 +                    }
   1.250 +                }
   1.251 +                else if (splitCommand[0] == "ping")
   1.252 +                {
   1.253 +                    iLib.PingAdapter();
   1.254 +                }
   1.255 +                else if (splitCommand[0] == "mon")
   1.256 +                {
   1.257 +                    bool enable = splitCommand.Length > 1 ? splitCommand[1] == "1" : false;
   1.258 +                    iLib.SwitchMonitoring(enable);
   1.259 +                }
   1.260 +                else if (splitCommand[0] == "bl")
   1.261 +                {
   1.262 +                    iLib.StartBootloader();
   1.263 +                }
   1.264 +                else if (splitCommand[0] == "lang")
   1.265 +                {
   1.266 +                    if (splitCommand.Length > 1)
   1.267 +                    {
   1.268 +                        string language = iLib.GetDeviceMenuLanguage((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
   1.269 +                        Console.WriteLine("Menu language: " + language);
   1.270 +                    }
   1.271 +                }
   1.272 +                else if (splitCommand[0] == "ven")
   1.273 +                {
   1.274 +                    if (splitCommand.Length > 1)
   1.275 +                    {
   1.276 +                        CecVendorId vendor = iLib.GetDeviceVendorId((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
   1.277 +                        Console.WriteLine("Vendor ID: " + iLib.ToString(vendor));
   1.278 +                    }
   1.279 +                }
   1.280 +                else if (splitCommand[0] == "ver")
   1.281 +                {
   1.282 +                    if (splitCommand.Length > 1)
   1.283 +                    {
   1.284 +                        CecVersion version = iLib.GetDeviceCecVersion((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
   1.285 +                        Console.WriteLine("CEC version: " + iLib.ToString(version));
   1.286 +                    }
   1.287 +                }
   1.288 +                else if (splitCommand[0] == "pow")
   1.289 +                {
   1.290 +                    if (splitCommand.Length > 1)
   1.291 +                    {
   1.292 +                        CecPowerStatus power = iLib.GetDevicePowerStatus((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
   1.293 +                        Console.WriteLine("power status: " + iLib.ToString(power));
   1.294 +                    }
   1.295 +                }
   1.296 +                else if (splitCommand[0] == "r")
   1.297 +                {
   1.298 +                    Console.WriteLine("closing the connection");
   1.299 +                    iLib.Close();
   1.300 +
   1.301 +                    Console.WriteLine("opening a new connection");
   1.302 +                    Connect(10000);
   1.303 +
   1.304 +                    Console.WriteLine("setting active source");
   1.305 +                    iLib.SetActiveSource(CecDeviceType.PlaybackDevice);
   1.306 +                }
   1.307 +                else if (splitCommand[0] == "scan")
   1.308 +                {
   1.309 +                    StringBuilder output = new StringBuilder();
   1.310 +                    output.AppendLine("CEC bus information");
   1.311 +                    output.AppendLine("===================");
   1.312 +                    CecLogicalAddresses addresses = iLib.GetActiveDevices();
   1.313 +                    for (int iPtr = 0; iPtr < addresses.Addresses.Length; iPtr++)
   1.314 +                    {
   1.315 +                        CecLogicalAddress address = (CecLogicalAddress)iPtr;
   1.316 +                        if (!addresses.IsSet(address))
   1.317 +                            continue;
   1.318 +
   1.319 +                        CecVendorId iVendorId = iLib.GetDeviceVendorId(address);
   1.320 +                        bool bActive = iLib.IsActiveDevice(address);
   1.321 +                        ushort iPhysicalAddress = iLib.GetDevicePhysicalAddress(address);
   1.322 +                        string strAddr = "todo: fixme"; //Lib.PhysicalAddressToString(iPhysicalAddress);
   1.323 +                        CecVersion iCecVersion = iLib.GetDeviceCecVersion(address);
   1.324 +                        CecPowerStatus power = iLib.GetDevicePowerStatus(address);
   1.325 +                        string osdName = iLib.GetDeviceOSDName(address);
   1.326 +                        string lang = iLib.GetDeviceMenuLanguage(address);
   1.327 +
   1.328 +                        output.AppendLine("device #" + iPtr + ": " + iLib.ToString(address));
   1.329 +                        output.AppendLine("address:             " + strAddr);
   1.330 +                        output.AppendLine("active source: " + (bActive ? "yes" : "no"));
   1.331 +                        output.AppendLine("vendor:                " + iLib.ToString(iVendorId));
   1.332 +                        output.AppendLine("osd string:        " + osdName);
   1.333 +                        output.AppendLine("CEC version:     " + iLib.ToString(iCecVersion));
   1.334 +                        output.AppendLine("power status:    " + iLib.ToString(power));
   1.335 +                        if (!string.IsNullOrEmpty(lang))
   1.336 +                            output.AppendLine("language:            " + lang);
   1.337 +                        output.AppendLine("");
   1.338 +                    }
   1.339 +                    Console.WriteLine(output.ToString());
   1.340 +                }
   1.341 +                else if (splitCommand[0] == "h" || splitCommand[0] == "help")
   1.342 +                    ShowConsoleHelp();
   1.343 +                else if (splitCommand[0] == "q" || splitCommand[0] == "quit")
   1.344 +                    bContinue = false;
   1.345 +                else if (splitCommand[0] == "log" && splitCommand.Length > 1)
   1.346 +                    LogLevel = int.Parse(splitCommand[1]);                
   1.347 +            }
   1.348 +        }
   1.349 +
   1.350 +        /// TODO: remove that
   1.351 +        static void Main(string[] args)
   1.352 +        {
   1.353 +            Client p = new Client("CEC",2);
   1.354 +            if (p.Connect(10000))
   1.355 +            {
   1.356 +                p.MainLoop();
   1.357 +            }
   1.358 +            else
   1.359 +            {
   1.360 +                Console.WriteLine("Could not open a connection to the CEC adapter");
   1.361 +            }
   1.362 +        }
   1.363 +
   1.364 +        /// <summary>
   1.365 +        /// Provide direct access to CEC library
   1.366 +        /// </summary>
   1.367 +        public LibCecSharp Lib
   1.368 +        {
   1.369 +            get
   1.370 +            {
   1.371 +                return iLib;
   1.372 +            }
   1.373 +        }
   1.374 +
   1.375 +        /// <summary>
   1.376 +        /// 
   1.377 +        /// </summary>
   1.378 +        private int LogLevel;
   1.379 +        /// <summary>
   1.380 +        /// 
   1.381 +        /// </summary>
   1.382 +        private LibCecSharp iLib;
   1.383 +        /// <summary>
   1.384 +        /// 
   1.385 +        /// </summary>
   1.386 +        private LibCECConfiguration Config;
   1.387 +    }
   1.388 +}
     2.1 --- a/Server/CecSharpClient.cs	Sat Sep 26 11:56:49 2015 +0200
     2.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.3 @@ -1,376 +0,0 @@
     2.4 -/*
     2.5 - * This file is part of the libCEC(R) library.
     2.6 - *
     2.7 - * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited.    All rights reserved.
     2.8 - * libCEC(R) is an original work, containing original code.
     2.9 - *
    2.10 - * libCEC(R) is a trademark of Pulse-Eight Limited.
    2.11 - *
    2.12 - * This program is dual-licensed; you can redistribute it and/or modify
    2.13 - * it under the terms of the GNU General Public License as published by
    2.14 - * the Free Software Foundation; either version 2 of the License, or
    2.15 - * (at your option) any later version.
    2.16 - *
    2.17 - * This program is distributed in the hope that it will be useful,
    2.18 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
    2.19 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
    2.20 - * GNU General Public License for more details.
    2.21 - *
    2.22 - * You should have received a copy of the GNU General Public License
    2.23 - * along with this program; if not, write to the Free Software
    2.24 - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    2.25 - *
    2.26 - *
    2.27 - * Alternatively, you can license this library under a commercial license,
    2.28 - * please contact Pulse-Eight Licensing for more information.
    2.29 - *
    2.30 - * For more information contact:
    2.31 - * Pulse-Eight Licensing             <license@pulse-eight.com>
    2.32 - *         http://www.pulse-eight.com/
    2.33 - *         http://www.pulse-eight.net/
    2.34 - */
    2.35 -
    2.36 -using System;
    2.37 -using System.Text;
    2.38 -using CecSharp;
    2.39 -
    2.40 -namespace Cec
    2.41 -{
    2.42 -    class Client : CecCallbackMethods
    2.43 -    {
    2.44 -        public Client()
    2.45 -        {
    2.46 -            Config = new LibCECConfiguration();
    2.47 -            Config.DeviceTypes.Types[0] = CecDeviceType.Tv;
    2.48 -            Config.DeviceName = "CEC";
    2.49 -            Config.HDMIPort = 2;
    2.50 -            //Config.ClientVersion = LibCECConfiguration.CurrentVersion;
    2.51 -            Config.SetCallbacks(this);
    2.52 -            LogLevel = (int)CecLogLevel.All;
    2.53 -
    2.54 -            Lib = new LibCecSharp(Config);
    2.55 -            Lib.InitVideoStandalone();
    2.56 -
    2.57 -            //Console.WriteLine("CEC Parser created - libCEC version " + Lib.VersionToString(Config.ServerVersion));
    2.58 -            Console.WriteLine("CEC Parser created - libCEC version " + Config.ServerVersion);
    2.59 -        }
    2.60 -
    2.61 -        public override int ReceiveCommand(CecCommand command)
    2.62 -        {
    2.63 -            return 1;
    2.64 -        }
    2.65 -
    2.66 -        public override int ReceiveKeypress(CecKeypress key)
    2.67 -        {
    2.68 -            return 1;
    2.69 -        }
    2.70 -
    2.71 -        public override int ReceiveLogMessage(CecLogMessage message)
    2.72 -        {
    2.73 -            if (((int)message.Level & LogLevel) == (int)message.Level)
    2.74 -            {
    2.75 -                string strLevel = "";
    2.76 -                switch (message.Level)
    2.77 -                {
    2.78 -                    case CecLogLevel.Error:
    2.79 -                        strLevel = "ERROR:     ";
    2.80 -                        break;
    2.81 -                    case CecLogLevel.Warning:
    2.82 -                        strLevel = "WARNING: ";
    2.83 -                        break;
    2.84 -                    case CecLogLevel.Notice:
    2.85 -                        strLevel = "NOTICE:    ";
    2.86 -                        break;
    2.87 -                    case CecLogLevel.Traffic:
    2.88 -                        strLevel = "TRAFFIC: ";
    2.89 -                        break;
    2.90 -                    case CecLogLevel.Debug:
    2.91 -                        strLevel = "DEBUG:     ";
    2.92 -                        break;
    2.93 -                    default:
    2.94 -                        break;
    2.95 -                }
    2.96 -                string strLog = string.Format("{0} {1,16} {2}", strLevel, message.Time, message.Message);
    2.97 -                Console.WriteLine(strLog);
    2.98 -            }
    2.99 -            return 1;
   2.100 -        }
   2.101 -
   2.102 -        /// <summary>
   2.103 -        /// 
   2.104 -        /// </summary>
   2.105 -        /// <param name="timeout"></param>
   2.106 -        /// <returns></returns>
   2.107 -        public bool Connect(int timeout)
   2.108 -        {
   2.109 -            CecAdapter[] adapters = Lib.FindAdapters(string.Empty);
   2.110 -            if (adapters.Length > 0)
   2.111 -                return Connect(adapters[0].ComPort, timeout);
   2.112 -            else
   2.113 -            {
   2.114 -                Console.WriteLine("Did not find any CEC adapters");
   2.115 -                return false;
   2.116 -            }
   2.117 -        }
   2.118 -
   2.119 -        public bool Connect(string port, int timeout)
   2.120 -        {
   2.121 -            return Lib.Open(port, timeout);
   2.122 -        }
   2.123 -
   2.124 -        public void Close()
   2.125 -        {
   2.126 -            Lib.Close();
   2.127 -        }
   2.128 -
   2.129 -        public void ListDevices()
   2.130 -        {
   2.131 -            int iAdapter = 0;
   2.132 -            foreach (CecAdapter adapter in Lib.FindAdapters(string.Empty))
   2.133 -            {
   2.134 -                Console.WriteLine("Adapter:    " + iAdapter++);
   2.135 -                Console.WriteLine("Path:         " + adapter.Path);
   2.136 -                Console.WriteLine("Com port: " + adapter.ComPort);
   2.137 -            }
   2.138 -        }
   2.139 -
   2.140 -        void ShowConsoleHelp()
   2.141 -        {
   2.142 -            Console.WriteLine(
   2.143 -                "================================================================================" + Environment.NewLine +
   2.144 -                "Available commands:" + Environment.NewLine +
   2.145 -                Environment.NewLine +
   2.146 -                "[tx] {bytes}                            transfer bytes over the CEC line." + Environment.NewLine +
   2.147 -                "[txn] {bytes}                         transfer bytes but don't wait for transmission ACK." + Environment.NewLine +
   2.148 -                "[on] {address}                        power on the device with the given logical address." + Environment.NewLine +
   2.149 -                "[standby] {address}             put the device with the given address in standby mode." + Environment.NewLine +
   2.150 -                "[la] {logical_address}        change the logical address of the CEC adapter." + Environment.NewLine +
   2.151 -                "[pa] {physical_address}     change the physical address of the CEC adapter." + Environment.NewLine +
   2.152 -                "[osd] {addr} {string}         set OSD message on the specified device." + Environment.NewLine +
   2.153 -                "[ver] {addr}                            get the CEC version of the specified device." + Environment.NewLine +
   2.154 -                "[ven] {addr}                            get the vendor ID of the specified device." + Environment.NewLine +
   2.155 -                "[lang] {addr}                         get the menu language of the specified device." + Environment.NewLine +
   2.156 -                "[pow] {addr}                            get the power status of the specified device." + Environment.NewLine +
   2.157 -                "[poll] {addr}                         poll the specified device." + Environment.NewLine +
   2.158 -                "[scan]                                        scan the CEC bus and display device info" + Environment.NewLine +
   2.159 -                "[mon] {1|0}                             enable or disable CEC bus monitoring." + Environment.NewLine +
   2.160 -                "[log] {1 - 31}                        change the log level. see cectypes.h for values." + Environment.NewLine +
   2.161 -                "[ping]                                        send a ping command to the CEC adapter." + Environment.NewLine +
   2.162 -                "[bl]                                            to let the adapter enter the bootloader, to upgrade" + Environment.NewLine +
   2.163 -                "                                                    the flash rom." + Environment.NewLine +
   2.164 -                "[r]                                             reconnect to the CEC adapter." + Environment.NewLine +
   2.165 -                "[h] or [help]                         show this help." + Environment.NewLine +
   2.166 -                "[q] or [quit]                         to quit the CEC test client and switch off all" + Environment.NewLine +
   2.167 -                "                                                    connected CEC devices." + Environment.NewLine +
   2.168 -                "================================================================================");
   2.169 -        }
   2.170 -
   2.171 -        public void MainLoop()
   2.172 -        {
   2.173 -            bool bContinue = true;
   2.174 -            string command;
   2.175 -            while (bContinue)
   2.176 -            {
   2.177 -                Console.WriteLine("waiting for input");
   2.178 -
   2.179 -                command = Console.ReadLine();
   2.180 -                if (command != null && command.Length == 0)
   2.181 -                    continue;
   2.182 -                string[] splitCommand = command.Split(' ');
   2.183 -                if (splitCommand[0] == "tx" || splitCommand[0] == "txn")
   2.184 -                {
   2.185 -                    CecCommand bytes = new CecCommand();
   2.186 -                    for (int iPtr = 1; iPtr < splitCommand.Length; iPtr++)
   2.187 -                    {
   2.188 -                        bytes.PushBack(byte.Parse(splitCommand[iPtr], System.Globalization.NumberStyles.HexNumber));
   2.189 -                    }
   2.190 -
   2.191 -                    if (command == "txn")
   2.192 -                        bytes.TransmitTimeout = 0;
   2.193 -
   2.194 -                    Lib.Transmit(bytes);
   2.195 -                }
   2.196 -                else if (splitCommand[0] == "on")
   2.197 -                {
   2.198 -                    if (splitCommand.Length > 1)
   2.199 -                        Lib.PowerOnDevices((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
   2.200 -                    else
   2.201 -                        Lib.PowerOnDevices(CecLogicalAddress.Broadcast);
   2.202 -                }
   2.203 -                else if (splitCommand[0] == "standby")
   2.204 -                {
   2.205 -                    if (splitCommand.Length > 1)
   2.206 -                        Lib.StandbyDevices((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
   2.207 -                    else
   2.208 -                        Lib.StandbyDevices(CecLogicalAddress.Broadcast);
   2.209 -                }
   2.210 -                else if (splitCommand[0] == "poll")
   2.211 -                {
   2.212 -                    bool bSent = false;
   2.213 -                    if (splitCommand.Length > 1)
   2.214 -                        bSent = Lib.PollDevice((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
   2.215 -                    else
   2.216 -                        bSent = Lib.PollDevice(CecLogicalAddress.Broadcast);
   2.217 -                    if (bSent)
   2.218 -                        Console.WriteLine("POLL message sent");
   2.219 -                    else
   2.220 -                        Console.WriteLine("POLL message not sent");
   2.221 -                }
   2.222 -                else if (splitCommand[0] == "la")
   2.223 -                {
   2.224 -                    if (splitCommand.Length > 1)
   2.225 -                        Lib.SetLogicalAddress((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
   2.226 -                }
   2.227 -                else if (splitCommand[0] == "pa")
   2.228 -                {
   2.229 -                    if (splitCommand.Length > 1)
   2.230 -                        Lib.SetPhysicalAddress(ushort.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
   2.231 -                }
   2.232 -                else if (splitCommand[0] == "osd")
   2.233 -                {
   2.234 -                    if (splitCommand.Length > 2)
   2.235 -                    {
   2.236 -                        StringBuilder osdString = new StringBuilder();
   2.237 -                        for (int iPtr = 1; iPtr < splitCommand.Length; iPtr++)
   2.238 -                        {
   2.239 -                            osdString.Append(splitCommand[iPtr]);
   2.240 -                            if (iPtr != splitCommand.Length - 1)
   2.241 -                                osdString.Append(" ");
   2.242 -                        }
   2.243 -                        Lib.SetOSDString((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber), CecDisplayControl.DisplayForDefaultTime, osdString.ToString());
   2.244 -                    }
   2.245 -                }
   2.246 -                else if (splitCommand[0] == "ping")
   2.247 -                {
   2.248 -                    Lib.PingAdapter();
   2.249 -                }
   2.250 -                else if (splitCommand[0] == "mon")
   2.251 -                {
   2.252 -                    bool enable = splitCommand.Length > 1 ? splitCommand[1] == "1" : false;
   2.253 -                    Lib.SwitchMonitoring(enable);
   2.254 -                }
   2.255 -                else if (splitCommand[0] == "bl")
   2.256 -                {
   2.257 -                    Lib.StartBootloader();
   2.258 -                }
   2.259 -                else if (splitCommand[0] == "lang")
   2.260 -                {
   2.261 -                    if (splitCommand.Length > 1)
   2.262 -                    {
   2.263 -                        string language = Lib.GetDeviceMenuLanguage((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
   2.264 -                        Console.WriteLine("Menu language: " + language);
   2.265 -                    }
   2.266 -                }
   2.267 -                else if (splitCommand[0] == "ven")
   2.268 -                {
   2.269 -                    if (splitCommand.Length > 1)
   2.270 -                    {
   2.271 -                        CecVendorId vendor = Lib.GetDeviceVendorId((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
   2.272 -                        Console.WriteLine("Vendor ID: " + Lib.ToString(vendor));
   2.273 -                    }
   2.274 -                }
   2.275 -                else if (splitCommand[0] == "ver")
   2.276 -                {
   2.277 -                    if (splitCommand.Length > 1)
   2.278 -                    {
   2.279 -                        CecVersion version = Lib.GetDeviceCecVersion((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
   2.280 -                        Console.WriteLine("CEC version: " + Lib.ToString(version));
   2.281 -                    }
   2.282 -                }
   2.283 -                else if (splitCommand[0] == "pow")
   2.284 -                {
   2.285 -                    if (splitCommand.Length > 1)
   2.286 -                    {
   2.287 -                        CecPowerStatus power = Lib.GetDevicePowerStatus((CecLogicalAddress)byte.Parse(splitCommand[1], System.Globalization.NumberStyles.HexNumber));
   2.288 -                        Console.WriteLine("power status: " + Lib.ToString(power));
   2.289 -                    }
   2.290 -                }
   2.291 -                else if (splitCommand[0] == "r")
   2.292 -                {
   2.293 -                    Console.WriteLine("closing the connection");
   2.294 -                    Lib.Close();
   2.295 -
   2.296 -                    Console.WriteLine("opening a new connection");
   2.297 -                    Connect(10000);
   2.298 -
   2.299 -                    Console.WriteLine("setting active source");
   2.300 -                    Lib.SetActiveSource(CecDeviceType.PlaybackDevice);
   2.301 -                }
   2.302 -                else if (splitCommand[0] == "scan")
   2.303 -                {
   2.304 -                    StringBuilder output = new StringBuilder();
   2.305 -                    output.AppendLine("CEC bus information");
   2.306 -                    output.AppendLine("===================");
   2.307 -                    CecLogicalAddresses addresses = Lib.GetActiveDevices();
   2.308 -                    for (int iPtr = 0; iPtr < addresses.Addresses.Length; iPtr++)
   2.309 -                    {
   2.310 -                        CecLogicalAddress address = (CecLogicalAddress)iPtr;
   2.311 -                        if (!addresses.IsSet(address))
   2.312 -                            continue;
   2.313 -
   2.314 -                        CecVendorId iVendorId = Lib.GetDeviceVendorId(address);
   2.315 -                        bool bActive = Lib.IsActiveDevice(address);
   2.316 -                        ushort iPhysicalAddress = Lib.GetDevicePhysicalAddress(address);
   2.317 -                        string strAddr = "todo: fixme"; //Lib.PhysicalAddressToString(iPhysicalAddress);
   2.318 -                        CecVersion iCecVersion = Lib.GetDeviceCecVersion(address);
   2.319 -                        CecPowerStatus power = Lib.GetDevicePowerStatus(address);
   2.320 -                        string osdName = Lib.GetDeviceOSDName(address);
   2.321 -                        string lang = Lib.GetDeviceMenuLanguage(address);
   2.322 -
   2.323 -                        output.AppendLine("device #" + iPtr + ": " + Lib.ToString(address));
   2.324 -                        output.AppendLine("address:             " + strAddr);
   2.325 -                        output.AppendLine("active source: " + (bActive ? "yes" : "no"));
   2.326 -                        output.AppendLine("vendor:                " + Lib.ToString(iVendorId));
   2.327 -                        output.AppendLine("osd string:        " + osdName);
   2.328 -                        output.AppendLine("CEC version:     " + Lib.ToString(iCecVersion));
   2.329 -                        output.AppendLine("power status:    " + Lib.ToString(power));
   2.330 -                        if (!string.IsNullOrEmpty(lang))
   2.331 -                            output.AppendLine("language:            " + lang);
   2.332 -                        output.AppendLine("");
   2.333 -                    }
   2.334 -                    Console.WriteLine(output.ToString());
   2.335 -                }
   2.336 -                else if (splitCommand[0] == "h" || splitCommand[0] == "help")
   2.337 -                    ShowConsoleHelp();
   2.338 -                else if (splitCommand[0] == "q" || splitCommand[0] == "quit")
   2.339 -                    bContinue = false;
   2.340 -                else if (splitCommand[0] == "log" && splitCommand.Length > 1)
   2.341 -                    LogLevel = int.Parse(splitCommand[1]);                
   2.342 -            }
   2.343 -        }
   2.344 -
   2.345 -        static void Main(string[] args)
   2.346 -        {
   2.347 -            Client p = new Client();
   2.348 -            if (p.Connect(10000))
   2.349 -            {
   2.350 -                p.MainLoop();
   2.351 -            }
   2.352 -            else
   2.353 -            {
   2.354 -                Console.WriteLine("Could not open a connection to the CEC adapter");
   2.355 -            }
   2.356 -        }
   2.357 -
   2.358 -        /// <summary>
   2.359 -        /// 
   2.360 -        /// </summary>
   2.361 -        public void PowerOnDevices(CecLogicalAddress aAddress)
   2.362 -        {
   2.363 -            Lib.PowerOnDevices(aAddress);
   2.364 -        }
   2.365 -
   2.366 -        /// <summary>
   2.367 -        /// 
   2.368 -        /// </summary>
   2.369 -        public void StandbyDevices(CecLogicalAddress aAddress)
   2.370 -        {
   2.371 -            Lib.StandbyDevices(aAddress);
   2.372 -        }
   2.373 -
   2.374 -
   2.375 -        private int LogLevel;
   2.376 -        private LibCecSharp Lib;
   2.377 -        private LibCECConfiguration Config;
   2.378 -    }
   2.379 -}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/Server/ConsumerElectronicControl.cs	Sat Sep 26 16:35:27 2015 +0200
     3.3 @@ -0,0 +1,81 @@
     3.4 +using System;
     3.5 +using System.Collections.Generic;
     3.6 +using System.Linq;
     3.7 +using System.Text;
     3.8 +using System.Threading.Tasks;
     3.9 +using System.Diagnostics;
    3.10 +using System.Windows.Forms;
    3.11 +using CecSharp;
    3.12 +
    3.13 +namespace SharpDisplayManager
    3.14 +{
    3.15 +    class ConsumerElectronicControl
    3.16 +    {
    3.17 +        ///
    3.18 +        private PowerManager.SettingNotifier iPowerSettingNotifier;
    3.19 +        ///
    3.20 +        private Cec.Client iCecClient;
    3.21 +
    3.22 +        /// <summary>
    3.23 +        /// 
    3.24 +        /// </summary>
    3.25 +        /// <param name="aWndHandle"></param>
    3.26 +        /// <param name="aDeviceName"></param>
    3.27 +        /// <param name="aHdmiPort"></param>
    3.28 +        public void Start(IntPtr aWndHandle, string aDeviceName, byte aHdmiPort)
    3.29 +        {
    3.30 +            //Create our power setting notifier and register the event we are insterrested in
    3.31 +            iPowerSettingNotifier = new PowerManager.SettingNotifier(aWndHandle);
    3.32 +            iPowerSettingNotifier.OnMonitorPowerOn += OnMonitorPowerOn;
    3.33 +            iPowerSettingNotifier.OnMonitorPowerOff += OnMonitorPowerOff;
    3.34 +
    3.35 +            //CEC
    3.36 +            iCecClient = new Cec.Client(aDeviceName,aHdmiPort);
    3.37 +            if (!iCecClient.Connect(1000))
    3.38 +            {
    3.39 +                Debug.WriteLine("WARNING: No CEC connection!");
    3.40 +            }
    3.41 +        }
    3.42 +
    3.43 +        //
    3.44 +        public void Stop()
    3.45 +        {
    3.46 +            //
    3.47 +            iPowerSettingNotifier.OnMonitorPowerOn -= OnMonitorPowerOn;
    3.48 +            iPowerSettingNotifier.OnMonitorPowerOff -= OnMonitorPowerOff;
    3.49 +            iPowerSettingNotifier = null;
    3.50 +            //
    3.51 +            iCecClient.Close();
    3.52 +            iCecClient.Dispose();
    3.53 +            iCecClient = null;
    3.54 +        }
    3.55 +
    3.56 +
    3.57 +        private void OnMonitorPowerOn()
    3.58 +        {
    3.59 +            Debug.WriteLine("ON");
    3.60 +            //iCecClient.Lib.PowerOnDevices(CecLogicalAddress.Tv);
    3.61 +            iCecClient.Lib.SetActiveSource(CecDeviceType.Tv);
    3.62 +        }
    3.63 +
    3.64 +        private void OnMonitorPowerOff()
    3.65 +        {
    3.66 +            Debug.WriteLine("OFF");
    3.67 +            iCecClient.Lib.StandbyDevices(CecLogicalAddress.Tv);
    3.68 +        }
    3.69 +
    3.70 +        /// <summary>
    3.71 +        /// We need to handle WM_INPUT.
    3.72 +        /// </summary>
    3.73 +        /// <param name="message"></param>
    3.74 +        public void OnWndProc(ref Message message)
    3.75 +        {
    3.76 +            //Hook in our power manager
    3.77 +            if (iPowerSettingNotifier != null)
    3.78 +            {
    3.79 +                iPowerSettingNotifier.WndProc(ref message);
    3.80 +            }
    3.81 +        }
    3.82 +
    3.83 +    }
    3.84 +}
    3.85 \ No newline at end of file
     4.1 --- a/Server/MainForm.Hid.cs	Sat Sep 26 11:56:49 2015 +0200
     4.2 +++ b/Server/MainForm.Hid.cs	Sat Sep 26 16:35:27 2015 +0200
     4.3 @@ -31,12 +31,6 @@
     4.4          /// </summary>
     4.5          private Hid.Handler iHidHandler;
     4.6  
     4.7 -        ///
     4.8 -        private PowerManager.SettingNotifier iPowerSettingNotifier;
     4.9 -
    4.10 -        ///
    4.11 -        private Cec.Client iCecClient;
    4.12 -
    4.13          /// <summary>
    4.14          /// Register HID devices so that we receive corresponding WM_INPUT messages.
    4.15          /// </summary>
    4.16 @@ -98,30 +92,9 @@
    4.17              }
    4.18              iHidHandler.OnHidEvent += HandleHidEventThreadSafe;
    4.19  
    4.20 -            //TODO: Move this some place else
    4.21 -            iPowerSettingNotifier = new PowerManager.SettingNotifier(Handle);
    4.22 -            iPowerSettingNotifier.OnMonitorPowerOn += MonitorPowerOn;
    4.23 -            iPowerSettingNotifier.OnMonitorPowerOff += MonitorPowerOff;
    4.24 -
    4.25 -            //CEC
    4.26 -            iCecClient = new Cec.Client();
    4.27 -            if (!iCecClient.Connect(1000))
    4.28 -            {
    4.29 -                Debug.WriteLine("WARNING: No CEC connection!");
    4.30 -            }
    4.31          }
    4.32  
    4.33 -        void MonitorPowerOn()
    4.34 -        {
    4.35 -            Debug.WriteLine("ON");
    4.36 -            iCecClient.PowerOnDevices(CecSharp.CecLogicalAddress.Tv);
    4.37 -        }
    4.38  
    4.39 -        void MonitorPowerOff()
    4.40 -        {
    4.41 -            Debug.WriteLine("OFF");
    4.42 -            iCecClient.StandbyDevices(CecSharp.CecLogicalAddress.Tv);
    4.43 -        }
    4.44  
    4.45  
    4.46          /// <summary>
    4.47 @@ -428,6 +401,8 @@
    4.48                  SwitchToThisWindow(existingProcesses[0].MainWindowHandle, true);
    4.49              }            
    4.50          }
    4.51 +
    4.52 +
    4.53          /// <summary>
    4.54          /// We need to handle WM_INPUT.
    4.55          /// </summary>
    4.56 @@ -443,13 +418,7 @@
    4.57                      break;
    4.58              }
    4.59  
    4.60 -            //Hook in our power manager
    4.61 -            if (iPowerSettingNotifier!=null)
    4.62 -            {
    4.63 -                iPowerSettingNotifier.WndProc(ref message);
    4.64 -            }
    4.65 -
    4.66 -            //Is that needed? Check the docs.
    4.67 +            //Pass this on to base class.
    4.68              base.WndProc(ref message);
    4.69          }
    4.70      }
     5.1 --- a/Server/MainForm.cs	Sat Sep 26 11:56:49 2015 +0200
     5.2 +++ b/Server/MainForm.cs	Sat Sep 26 16:35:27 2015 +0200
     5.3 @@ -59,7 +59,7 @@
     5.4      public delegate void SetLayoutDelegate(string SessionId, TableLayout aLayout);
     5.5      public delegate void SetClientNameDelegate(string aSessionId, string aName);
     5.6  	public delegate void PlainUpdateDelegate();
     5.7 -
     5.8 +    public delegate void WndProcDelegate(ref Message aMessage);
     5.9  
    5.10      /// <summary>
    5.11      /// Our Display manager main form
    5.12 @@ -92,8 +92,13 @@
    5.13  		private MMDevice iMultiMediaDevice;
    5.14  		//Network
    5.15  		private NetworkManager iNetworkManager;
    5.16 +
    5.17 +        /// <summary>
    5.18 +        /// CEC - Consumer Electronic Control.
    5.19 +        /// Notably used to turn TV on and off as Windows broadcast monitor on and off notifications.
    5.20 +        /// </summary>
    5.21 +        private ConsumerElectronicControl iCecManager;
    5.22  		
    5.23 -
    5.24  		/// <summary>
    5.25  		/// Manage run when Windows startup option
    5.26  		/// </summary>
    5.27 @@ -104,6 +109,11 @@
    5.28  		/// </summary>
    5.29  		private NotifyIconAdv iNotifyIcon;
    5.30  
    5.31 +        /// <summary>
    5.32 +        /// Allow user to receive window messages;
    5.33 +        /// </summary>
    5.34 +        public event WndProcDelegate OnWndProc;
    5.35 +
    5.36          public MainForm()
    5.37          {
    5.38  			iSkipFrameRendering = false;
    5.39 @@ -174,8 +184,13 @@
    5.40  			iNetworkManager.OnConnectivityChanged += OnConnectivityChanged;
    5.41  			UpdateNetworkStatus();
    5.42  
    5.43 -			//Setup notification icon
    5.44 -			SetupTrayIcon();
    5.45 +            //CEC
    5.46 +            iCecManager = new ConsumerElectronicControl();
    5.47 +            OnWndProc += iCecManager.OnWndProc;
    5.48 +            iCecManager.Start(Handle,"CEC", 2);
    5.49 +
    5.50 +            //Setup notification icon
    5.51 +            SetupTrayIcon();
    5.52  
    5.53  			// To make sure start up with minimize to tray works
    5.54  			if (WindowState == FormWindowState.Minimized && Properties.Settings.Default.MinimizeToTray)
    5.55 @@ -1279,6 +1294,7 @@
    5.56  
    5.57          private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
    5.58          {
    5.59 +            iCecManager.Stop();
    5.60  			iNetworkManager.Dispose();
    5.61  			CloseDisplayConnection();
    5.62              StopServer();
    5.63 @@ -2188,5 +2204,19 @@
    5.64              Properties.Settings.Default.OpticalDriveToEject = comboBoxOpticalDrives.SelectedItem.ToString();
    5.65              Properties.Settings.Default.Save();
    5.66          }
    5.67 +
    5.68 +        /// <summary>
    5.69 +        /// Broadcast messages to subscribers.
    5.70 +        /// </summary>
    5.71 +        /// <param name="message"></param>
    5.72 +        protected override void WndProc(ref Message aMessage)
    5.73 +        {
    5.74 +            if (OnWndProc!=null)
    5.75 +            {
    5.76 +                OnWndProc(ref aMessage);
    5.77 +            }
    5.78 +            
    5.79 +            base.WndProc(ref aMessage);
    5.80 +        }
    5.81      }
    5.82  }
     6.1 --- a/Server/SharpDisplayManager.csproj	Sat Sep 26 11:56:49 2015 +0200
     6.2 +++ b/Server/SharpDisplayManager.csproj	Sat Sep 26 16:35:27 2015 +0200
     6.3 @@ -148,7 +148,8 @@
     6.4    </ItemGroup>
     6.5    <ItemGroup>
     6.6      <Compile Include="CbtHook.cs" />
     6.7 -    <Compile Include="CecSharpClient.cs" />
     6.8 +    <Compile Include="CecClient.cs" />
     6.9 +    <Compile Include="ConsumerElectronicControl.cs" />
    6.10      <Compile Include="ClientData.cs" />
    6.11      <Compile Include="MainForm.Hid.cs">
    6.12        <DependentUpon>MainForm.cs</DependentUpon>