Server/MainForm.cs
author sl
Thu, 14 Aug 2014 00:23:18 +0200
changeset 21 274a6b27c3f9
parent 20 e3d394dd0388
child 22 cac466b1b6e6
permissions -rw-r--r--
Adding server closing notification to clients.
     1 using System;
     2 using System.Collections.Generic;
     3 using System.ComponentModel;
     4 using System.Data;
     5 using System.Drawing;
     6 using System.Linq;
     7 using System.Text;
     8 using System.Threading.Tasks;
     9 using System.Windows.Forms;
    10 using System.IO;
    11 using CodeProject.Dialog;
    12 using System.Drawing.Imaging;
    13 using System.ServiceModel;
    14 
    15 
    16 namespace SharpDisplayManager
    17 {
    18     public partial class MainForm : Form
    19     {
    20         DateTime LastTickTime;
    21         Display iDisplay;
    22         System.Drawing.Bitmap iBmp;
    23         bool iCreateBitmap; //Workaround render to bitmap issues when minimized
    24         ServiceHost iServiceHost;
    25         /// <summary>
    26         /// Our collection of clients
    27         /// </summary>
    28         public Dictionary<string, IDisplayServiceCallback> iClients;
    29 
    30         public MainForm()
    31         {
    32             LastTickTime = DateTime.Now;
    33             iDisplay = new Display();
    34             iClients = new Dictionary<string, IDisplayServiceCallback>();
    35 
    36             InitializeComponent();
    37             UpdateStatus();
    38 
    39             //Load settings
    40             marqueeLabelTop.Font = Properties.Settings.Default.DisplayFont;
    41             marqueeLabelBottom.Font = Properties.Settings.Default.DisplayFont;
    42             checkBoxShowBorders.Checked = Properties.Settings.Default.DisplayShowBorders;
    43             checkBoxConnectOnStartup.Checked = Properties.Settings.Default.DisplayConnectOnStartup;
    44             checkBoxReverseScreen.Checked = Properties.Settings.Default.DisplayReverseScreen;
    45             //
    46             tableLayoutPanel.CellBorderStyle = (checkBoxShowBorders.Checked ? TableLayoutPanelCellBorderStyle.Single : TableLayoutPanelCellBorderStyle.None);
    47             //We have a bug when drawing minimized and reusing our bitmap
    48             iBmp = new System.Drawing.Bitmap(tableLayoutPanel.Width, tableLayoutPanel.Height, PixelFormat.Format32bppArgb);
    49             iCreateBitmap = false;
    50         }
    51 
    52         private void MainForm_Load(object sender, EventArgs e)
    53         {
    54             StartServer();
    55 
    56             if (Properties.Settings.Default.DisplayConnectOnStartup)
    57             {
    58                 iDisplay.Open();
    59                 UpdateStatus();
    60             }
    61         }
    62 
    63 
    64         private void buttonFont_Click(object sender, EventArgs e)
    65         {
    66             //fontDialog.ShowColor = true;
    67             //fontDialog.ShowApply = true;
    68             fontDialog.ShowEffects = true;
    69             fontDialog.Font = marqueeLabelTop.Font;
    70             //fontDialog.ShowHelp = true;
    71 
    72             //fontDlg.MaxSize = 40;
    73             //fontDlg.MinSize = 22;
    74 
    75             //fontDialog.Parent = this;
    76             //fontDialog.StartPosition = FormStartPosition.CenterParent;
    77 
    78             //DlgBox.ShowDialog(fontDialog);
    79 
    80             //if (fontDialog.ShowDialog(this) != DialogResult.Cancel)
    81             if (DlgBox.ShowDialog(fontDialog) != DialogResult.Cancel)
    82             {
    83 
    84                 //MsgBox.Show("MessageBox MsgBox", "MsgBox caption");
    85 
    86                 //MessageBox.Show("Ok");
    87                 marqueeLabelTop.Font = fontDialog.Font;
    88                 marqueeLabelBottom.Font = fontDialog.Font;
    89                 Properties.Settings.Default.DisplayFont = fontDialog.Font;
    90                 Properties.Settings.Default.Save();
    91                 //label1.Font = fontDlg.Font;
    92                 //textBox1.BackColor = fontDlg.Color;
    93                 //label1.ForeColor = fontDlg.Color;
    94             }
    95         }
    96 
    97         private void buttonCapture_Click(object sender, EventArgs e)
    98         {
    99             System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(tableLayoutPanel.Width, tableLayoutPanel.Height);
   100             tableLayoutPanel.DrawToBitmap(bmp, tableLayoutPanel.ClientRectangle);
   101             //Bitmap bmpToSave = new Bitmap(bmp);
   102             bmp.Save("D:\\capture.png");
   103 
   104             marqueeLabelTop.Text = "Sweet";
   105 
   106             /*
   107             string outputFileName = "d:\\capture.png";
   108             using (MemoryStream memory = new MemoryStream())
   109             {
   110                 using (FileStream fs = new FileStream(outputFileName, FileMode.OpenOrCreate, FileAccess.ReadWrite))
   111                 {
   112                     bmp.Save(memory, System.Drawing.Imaging.ImageFormat.Png);
   113                     byte[] bytes = memory.ToArray();
   114                     fs.Write(bytes, 0, bytes.Length);
   115                 }
   116             }
   117              */
   118 
   119         }
   120 
   121         private void CheckForRequestResults()
   122         {
   123             if (iDisplay.IsRequestPending())
   124             {
   125                 switch (iDisplay.AttemptRequestCompletion())
   126                 {
   127                     case Display.TMiniDisplayRequest.EMiniDisplayRequestPowerSupplyStatus:
   128                         if (iDisplay.PowerSupplyStatus())
   129                         {
   130                             toolStripStatusLabelPower.Text = "ON";
   131                         }
   132                         else
   133                         {
   134                             toolStripStatusLabelPower.Text = "OFF";
   135                         }
   136                         //Issue next request then
   137                         iDisplay.RequestDeviceId();
   138                         break;
   139 
   140                     case Display.TMiniDisplayRequest.EMiniDisplayRequestDeviceId:
   141                         toolStripStatusLabelConnect.Text += " - " + iDisplay.DeviceId();
   142                         //Issue next request then
   143                         iDisplay.RequestFirmwareRevision();
   144                         break;
   145 
   146                     case Display.TMiniDisplayRequest.EMiniDisplayRequestFirmwareRevision:
   147                         toolStripStatusLabelConnect.Text += " v" + iDisplay.FirmwareRevision();
   148                         //No more request to issue
   149                         break;
   150                 }
   151             }
   152         }
   153 
   154 
   155         public delegate int CoordinateTranslationDelegate(System.Drawing.Bitmap aBmp, int aInt);
   156 
   157 
   158         public static int ScreenReversedX(System.Drawing.Bitmap aBmp, int aX)
   159         {
   160             return aBmp.Width - aX - 1;
   161         }
   162 
   163         public int ScreenReversedY(System.Drawing.Bitmap aBmp, int aY)
   164         {
   165             return iBmp.Height - aY - 1;
   166         }
   167 
   168         public int ScreenX(System.Drawing.Bitmap aBmp, int aX)
   169         {
   170             return aX;
   171         }
   172 
   173         public int ScreenY(System.Drawing.Bitmap aBmp, int aY)
   174         {
   175             return aY;
   176         }
   177 
   178 
   179         //This is our timer tick responsible to perform our render
   180         private void timer_Tick(object sender, EventArgs e)
   181         {
   182             //Update our animations
   183             DateTime NewTickTime = DateTime.Now;
   184 
   185             marqueeLabelTop.UpdateAnimation(LastTickTime, NewTickTime);
   186             marqueeLabelBottom.UpdateAnimation(LastTickTime, NewTickTime);
   187 
   188             //Update our display
   189             if (iDisplay.IsOpen())
   190             {
   191                 CheckForRequestResults();
   192 
   193                 //Draw to bitmap                
   194                 if (iCreateBitmap)
   195                 {
   196                     iBmp = new System.Drawing.Bitmap(tableLayoutPanel.Width, tableLayoutPanel.Height, PixelFormat.Format32bppArgb);
   197                 }
   198                 tableLayoutPanel.DrawToBitmap(iBmp, tableLayoutPanel.ClientRectangle);
   199                 //iBmp.Save("D:\\capture.png");
   200 
   201                 //Select proper coordinate translation functions
   202                 //We used delegate/function pointer to support reverse screen without doing an extra test on each pixels
   203                 CoordinateTranslationDelegate screenX;
   204                 CoordinateTranslationDelegate screenY;
   205 
   206                 if (Properties.Settings.Default.DisplayReverseScreen)
   207                 {
   208                     screenX = ScreenReversedX;
   209                     screenY = ScreenReversedY;
   210                 }
   211                 else
   212                 {
   213                     screenX = ScreenX;
   214                     screenY = ScreenY;
   215                 }
   216                 
   217                 //Send it to our display
   218                 for (int i = 0; i < iBmp.Width; i++)
   219                 {
   220                     for (int j = 0; j < iBmp.Height; j++)
   221                     {
   222                         unchecked
   223                         {
   224                             uint color = (uint)iBmp.GetPixel(i, j).ToArgb();
   225                             //For some reason when the app is minimized in the task bar only the alpha of our color is set.
   226                             //Thus that strange test for rendering to work both when the app is in the task bar and when it isn't.
   227                             iDisplay.SetPixel(screenX(iBmp, i), screenY(iBmp, j), Convert.ToInt32(!(color != 0xFF000000)));
   228                         }
   229                     }
   230                 }
   231 
   232                 iDisplay.SwapBuffers();
   233 
   234             }
   235 
   236             //Compute instant FPS
   237             toolStripStatusLabelFps.Text = (1.0/NewTickTime.Subtract(LastTickTime).TotalSeconds).ToString("F0") + " FPS";
   238 
   239             LastTickTime = NewTickTime;
   240 
   241         }
   242 
   243         private void buttonOpen_Click(object sender, EventArgs e)
   244         {
   245             if (iDisplay.Open())
   246             {
   247                 UpdateStatus();
   248                 iDisplay.RequestPowerSupplyStatus();
   249             }
   250             else
   251             {
   252                 UpdateStatus();
   253                 toolStripStatusLabelConnect.Text = "Connection error";
   254             }
   255 
   256         }
   257 
   258         private void buttonClose_Click(object sender, EventArgs e)
   259         {
   260             iDisplay.Close();
   261             UpdateStatus();
   262         }
   263 
   264         private void buttonClear_Click(object sender, EventArgs e)
   265         {
   266             iDisplay.Clear();
   267             iDisplay.SwapBuffers();
   268         }
   269 
   270         private void buttonFill_Click(object sender, EventArgs e)
   271         {
   272             iDisplay.Fill();
   273             iDisplay.SwapBuffers();
   274         }
   275 
   276         private void trackBarBrightness_Scroll(object sender, EventArgs e)
   277         {
   278             Properties.Settings.Default.DisplayBrightness = trackBarBrightness.Value;
   279             Properties.Settings.Default.Save();
   280             iDisplay.SetBrightness(trackBarBrightness.Value);
   281 
   282         }
   283 
   284         private void UpdateStatus()
   285         {
   286             if (iDisplay.IsOpen())
   287             {
   288                 buttonFill.Enabled = true;
   289                 buttonClear.Enabled = true;
   290                 buttonOpen.Enabled = false;
   291                 buttonClose.Enabled = true;
   292                 trackBarBrightness.Enabled = true;
   293                 trackBarBrightness.Minimum = iDisplay.MinBrightness();
   294                 trackBarBrightness.Maximum = iDisplay.MaxBrightness();
   295                 trackBarBrightness.Value = Properties.Settings.Default.DisplayBrightness;
   296                 trackBarBrightness.LargeChange = Math.Max(1,(iDisplay.MaxBrightness() - iDisplay.MinBrightness())/5);
   297                 trackBarBrightness.SmallChange = 1;
   298                 iDisplay.SetBrightness(Properties.Settings.Default.DisplayBrightness);
   299 
   300                 toolStripStatusLabelConnect.Text = "Connected - " + iDisplay.Vendor() + " - " + iDisplay.Product();
   301                 //+ " - " + iDisplay.SerialNumber();
   302             }
   303             else
   304             {
   305                 buttonFill.Enabled = false;
   306                 buttonClear.Enabled = false;
   307                 buttonOpen.Enabled = true;
   308                 buttonClose.Enabled = false;
   309                 trackBarBrightness.Enabled = false;
   310                 toolStripStatusLabelConnect.Text = "Disconnected";
   311             }
   312         }
   313 
   314 
   315 
   316         private void checkBoxShowBorders_CheckedChanged(object sender, EventArgs e)
   317         {
   318             //Save our show borders setting
   319             tableLayoutPanel.CellBorderStyle = (checkBoxShowBorders.Checked ? TableLayoutPanelCellBorderStyle.Single : TableLayoutPanelCellBorderStyle.None);
   320             Properties.Settings.Default.DisplayShowBorders = checkBoxShowBorders.Checked;
   321             Properties.Settings.Default.Save();
   322         }
   323 
   324         private void checkBoxConnectOnStartup_CheckedChanged(object sender, EventArgs e)
   325         {
   326             //Save our connect on startup setting
   327             Properties.Settings.Default.DisplayConnectOnStartup = checkBoxConnectOnStartup.Checked;
   328             Properties.Settings.Default.Save();
   329         }
   330 
   331         private void checkBoxReverseScreen_CheckedChanged(object sender, EventArgs e)
   332         {
   333             //Save our reverse screen setting
   334             Properties.Settings.Default.DisplayReverseScreen = checkBoxReverseScreen.Checked;
   335             Properties.Settings.Default.Save();
   336         }
   337 
   338         private void MainForm_Resize(object sender, EventArgs e)
   339         {
   340             if (WindowState == FormWindowState.Minimized)
   341             {
   342                 // Do some stuff
   343                 //iBmp = new System.Drawing.Bitmap(tableLayoutPanel.Width, tableLayoutPanel.Height, PixelFormat.Format32bppArgb);
   344                 iCreateBitmap = true;
   345             }
   346         }
   347 
   348         private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
   349         {
   350             StopServer();
   351         }
   352 
   353         public void StartServer()
   354         {
   355             iServiceHost = new ServiceHost
   356                 (
   357                     typeof(DisplayServer),
   358                     new Uri[] { new Uri("net.tcp://localhost:8001/") }
   359                 );
   360 
   361             iServiceHost.AddServiceEndpoint(typeof(IDisplayService), new NetTcpBinding(), "DisplayService");
   362             iServiceHost.Open();
   363         }
   364 
   365         public void StopServer()
   366         {
   367             //Tell connected client first? Is that possible?
   368             BroadcastCloseEvent();
   369             iServiceHost.Close();
   370         }
   371 
   372         public void BroadcastCloseEvent()
   373         {
   374             var inactiveClients = new List<string>();
   375             foreach (var client in iClients)
   376             {
   377                 //if (client.Key != eventData.ClientName)
   378                 {
   379                     try
   380                     {
   381                         client.Value.OnServerClosing(/*eventData*/);
   382                     }
   383                     catch (Exception ex)
   384                     {
   385                         inactiveClients.Add(client.Key);
   386                     }
   387                 }
   388             }
   389 
   390             if (inactiveClients.Count > 0)
   391             {
   392                 foreach (var client in inactiveClients)
   393                 {
   394                     iClients.Remove(client);
   395                 }
   396             }
   397         }
   398 
   399 
   400 
   401     }
   402 }