2 using System.Collections.Generic;
3 using System.ComponentModel;
8 using System.Threading.Tasks;
9 using System.Windows.Forms;
11 using CodeProject.Dialog;
12 using System.Drawing.Imaging;
13 using System.ServiceModel;
14 using System.Threading;
16 using SharpDisplayInterface;
17 using SharpDisplayClient;
20 namespace SharpDisplayManager
22 public partial class MainForm : Form
24 DateTime LastTickTime;
26 System.Drawing.Bitmap iBmp;
27 bool iCreateBitmap; //Workaround render to bitmap issues when minimized
28 ServiceHost iServiceHost;
30 /// Our collection of clients
32 public Dictionary<string, IDisplayServiceCallback> iClients;
36 LastTickTime = DateTime.Now;
37 iDisplay = new Display();
38 iClients = new Dictionary<string, IDisplayServiceCallback>();
40 InitializeComponent();
44 marqueeLabelTop.Font = Properties.Settings.Default.DisplayFont;
45 marqueeLabelBottom.Font = Properties.Settings.Default.DisplayFont;
46 checkBoxShowBorders.Checked = Properties.Settings.Default.DisplayShowBorders;
47 checkBoxConnectOnStartup.Checked = Properties.Settings.Default.DisplayConnectOnStartup;
48 checkBoxReverseScreen.Checked = Properties.Settings.Default.DisplayReverseScreen;
50 tableLayoutPanel.CellBorderStyle = (checkBoxShowBorders.Checked ? TableLayoutPanelCellBorderStyle.Single : TableLayoutPanelCellBorderStyle.None);
51 //We have a bug when drawing minimized and reusing our bitmap
52 iBmp = new System.Drawing.Bitmap(tableLayoutPanel.Width, tableLayoutPanel.Height, PixelFormat.Format32bppArgb);
53 iCreateBitmap = false;
56 private void MainForm_Load(object sender, EventArgs e)
60 if (Properties.Settings.Default.DisplayConnectOnStartup)
68 private void buttonFont_Click(object sender, EventArgs e)
70 //fontDialog.ShowColor = true;
71 //fontDialog.ShowApply = true;
72 fontDialog.ShowEffects = true;
73 fontDialog.Font = marqueeLabelTop.Font;
74 //fontDialog.ShowHelp = true;
76 //fontDlg.MaxSize = 40;
77 //fontDlg.MinSize = 22;
79 //fontDialog.Parent = this;
80 //fontDialog.StartPosition = FormStartPosition.CenterParent;
82 //DlgBox.ShowDialog(fontDialog);
84 //if (fontDialog.ShowDialog(this) != DialogResult.Cancel)
85 if (DlgBox.ShowDialog(fontDialog) != DialogResult.Cancel)
88 //MsgBox.Show("MessageBox MsgBox", "MsgBox caption");
90 //MessageBox.Show("Ok");
91 marqueeLabelTop.Font = fontDialog.Font;
92 marqueeLabelBottom.Font = fontDialog.Font;
93 Properties.Settings.Default.DisplayFont = fontDialog.Font;
94 Properties.Settings.Default.Save();
95 //label1.Font = fontDlg.Font;
96 //textBox1.BackColor = fontDlg.Color;
97 //label1.ForeColor = fontDlg.Color;
101 private void buttonCapture_Click(object sender, EventArgs e)
103 System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(tableLayoutPanel.Width, tableLayoutPanel.Height);
104 tableLayoutPanel.DrawToBitmap(bmp, tableLayoutPanel.ClientRectangle);
105 //Bitmap bmpToSave = new Bitmap(bmp);
106 bmp.Save("D:\\capture.png");
108 marqueeLabelTop.Text = "Sweet";
111 string outputFileName = "d:\\capture.png";
112 using (MemoryStream memory = new MemoryStream())
114 using (FileStream fs = new FileStream(outputFileName, FileMode.OpenOrCreate, FileAccess.ReadWrite))
116 bmp.Save(memory, System.Drawing.Imaging.ImageFormat.Png);
117 byte[] bytes = memory.ToArray();
118 fs.Write(bytes, 0, bytes.Length);
125 private void CheckForRequestResults()
127 if (iDisplay.IsRequestPending())
129 switch (iDisplay.AttemptRequestCompletion())
131 case Display.TMiniDisplayRequest.EMiniDisplayRequestPowerSupplyStatus:
132 if (iDisplay.PowerSupplyStatus())
134 toolStripStatusLabelPower.Text = "ON";
138 toolStripStatusLabelPower.Text = "OFF";
140 //Issue next request then
141 iDisplay.RequestDeviceId();
144 case Display.TMiniDisplayRequest.EMiniDisplayRequestDeviceId:
145 toolStripStatusLabelConnect.Text += " - " + iDisplay.DeviceId();
146 //Issue next request then
147 iDisplay.RequestFirmwareRevision();
150 case Display.TMiniDisplayRequest.EMiniDisplayRequestFirmwareRevision:
151 toolStripStatusLabelConnect.Text += " v" + iDisplay.FirmwareRevision();
152 //No more request to issue
159 public delegate int CoordinateTranslationDelegate(System.Drawing.Bitmap aBmp, int aInt);
162 public static int ScreenReversedX(System.Drawing.Bitmap aBmp, int aX)
164 return aBmp.Width - aX - 1;
167 public int ScreenReversedY(System.Drawing.Bitmap aBmp, int aY)
169 return iBmp.Height - aY - 1;
172 public int ScreenX(System.Drawing.Bitmap aBmp, int aX)
177 public int ScreenY(System.Drawing.Bitmap aBmp, int aY)
183 //This is our timer tick responsible to perform our render
184 private void timer_Tick(object sender, EventArgs e)
186 //Update our animations
187 DateTime NewTickTime = DateTime.Now;
189 marqueeLabelTop.UpdateAnimation(LastTickTime, NewTickTime);
190 marqueeLabelBottom.UpdateAnimation(LastTickTime, NewTickTime);
193 if (iDisplay.IsOpen())
195 CheckForRequestResults();
200 iBmp = new System.Drawing.Bitmap(tableLayoutPanel.Width, tableLayoutPanel.Height, PixelFormat.Format32bppArgb);
202 tableLayoutPanel.DrawToBitmap(iBmp, tableLayoutPanel.ClientRectangle);
203 //iBmp.Save("D:\\capture.png");
205 //Select proper coordinate translation functions
206 //We used delegate/function pointer to support reverse screen without doing an extra test on each pixels
207 CoordinateTranslationDelegate screenX;
208 CoordinateTranslationDelegate screenY;
210 if (Properties.Settings.Default.DisplayReverseScreen)
212 screenX = ScreenReversedX;
213 screenY = ScreenReversedY;
221 //Send it to our display
222 for (int i = 0; i < iBmp.Width; i++)
224 for (int j = 0; j < iBmp.Height; j++)
228 uint color = (uint)iBmp.GetPixel(i, j).ToArgb();
229 //For some reason when the app is minimized in the task bar only the alpha of our color is set.
230 //Thus that strange test for rendering to work both when the app is in the task bar and when it isn't.
231 iDisplay.SetPixel(screenX(iBmp, i), screenY(iBmp, j), Convert.ToInt32(!(color != 0xFF000000)));
236 iDisplay.SwapBuffers();
240 //Compute instant FPS
241 toolStripStatusLabelFps.Text = (1.0/NewTickTime.Subtract(LastTickTime).TotalSeconds).ToString("F0") + " FPS";
243 LastTickTime = NewTickTime;
247 private void buttonOpen_Click(object sender, EventArgs e)
252 iDisplay.RequestPowerSupplyStatus();
257 toolStripStatusLabelConnect.Text = "Connection error";
262 private void buttonClose_Click(object sender, EventArgs e)
268 private void buttonClear_Click(object sender, EventArgs e)
271 iDisplay.SwapBuffers();
274 private void buttonFill_Click(object sender, EventArgs e)
277 iDisplay.SwapBuffers();
280 private void trackBarBrightness_Scroll(object sender, EventArgs e)
282 Properties.Settings.Default.DisplayBrightness = trackBarBrightness.Value;
283 Properties.Settings.Default.Save();
284 iDisplay.SetBrightness(trackBarBrightness.Value);
288 private void UpdateStatus()
290 if (iDisplay.IsOpen())
292 buttonFill.Enabled = true;
293 buttonClear.Enabled = true;
294 buttonOpen.Enabled = false;
295 buttonClose.Enabled = true;
296 trackBarBrightness.Enabled = true;
297 trackBarBrightness.Minimum = iDisplay.MinBrightness();
298 trackBarBrightness.Maximum = iDisplay.MaxBrightness();
299 trackBarBrightness.Value = Properties.Settings.Default.DisplayBrightness;
300 trackBarBrightness.LargeChange = Math.Max(1,(iDisplay.MaxBrightness() - iDisplay.MinBrightness())/5);
301 trackBarBrightness.SmallChange = 1;
302 iDisplay.SetBrightness(Properties.Settings.Default.DisplayBrightness);
304 toolStripStatusLabelConnect.Text = "Connected - " + iDisplay.Vendor() + " - " + iDisplay.Product();
305 //+ " - " + iDisplay.SerialNumber();
309 buttonFill.Enabled = false;
310 buttonClear.Enabled = false;
311 buttonOpen.Enabled = true;
312 buttonClose.Enabled = false;
313 trackBarBrightness.Enabled = false;
314 toolStripStatusLabelConnect.Text = "Disconnected";
320 private void checkBoxShowBorders_CheckedChanged(object sender, EventArgs e)
322 //Save our show borders setting
323 tableLayoutPanel.CellBorderStyle = (checkBoxShowBorders.Checked ? TableLayoutPanelCellBorderStyle.Single : TableLayoutPanelCellBorderStyle.None);
324 Properties.Settings.Default.DisplayShowBorders = checkBoxShowBorders.Checked;
325 Properties.Settings.Default.Save();
328 private void checkBoxConnectOnStartup_CheckedChanged(object sender, EventArgs e)
330 //Save our connect on startup setting
331 Properties.Settings.Default.DisplayConnectOnStartup = checkBoxConnectOnStartup.Checked;
332 Properties.Settings.Default.Save();
335 private void checkBoxReverseScreen_CheckedChanged(object sender, EventArgs e)
337 //Save our reverse screen setting
338 Properties.Settings.Default.DisplayReverseScreen = checkBoxReverseScreen.Checked;
339 Properties.Settings.Default.Save();
342 private void MainForm_Resize(object sender, EventArgs e)
344 if (WindowState == FormWindowState.Minimized)
347 //iBmp = new System.Drawing.Bitmap(tableLayoutPanel.Width, tableLayoutPanel.Height, PixelFormat.Format32bppArgb);
348 iCreateBitmap = true;
352 private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
357 public void StartServer()
359 iServiceHost = new ServiceHost
361 typeof(DisplayServer),
362 new Uri[] { new Uri("net.tcp://localhost:8001/") }
365 iServiceHost.AddServiceEndpoint(typeof(IDisplayService), new NetTcpBinding(), "DisplayService");
369 public void StopServer()
371 //Tell connected client first? Is that possible?
372 BroadcastCloseEvent();
373 iServiceHost.Close();
376 public void BroadcastCloseEvent()
378 var inactiveClients = new List<string>();
379 foreach (var client in iClients)
381 //if (client.Key != eventData.ClientName)
385 client.Value.OnServerClosing(/*eventData*/);
389 inactiveClients.Add(client.Key);
394 if (inactiveClients.Count > 0)
396 foreach (var client in inactiveClients)
398 iClients.Remove(client);
403 private void buttonStartClient_Click(object sender, EventArgs e)
405 Thread clientThread = new Thread(SharpDisplayClient.Program.Main);
406 clientThread.Start();