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