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