# HG changeset patch # User StephaneLenclud # Date 1469781615 -7200 # Node ID 91763ba41c0c00621e5b3117df922a76cc61d90b # Parent 6ccaa430aa23c1584c85a86808ce945e466eff2b Renaming main form. diff -r 6ccaa430aa23 -r 91763ba41c0c Server/FormMain.Designer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Server/FormMain.Designer.cs Fri Jul 29 10:40:15 2016 +0200 @@ -0,0 +1,1321 @@ +namespace SharpDisplayManager +{ + partial class FormMain + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing) + { + if (iNotifyIcon != null) + { + iNotifyIcon.Dispose(); + iNotifyIcon = null; + } + + if (components != null) + { + components.Dispose(); + } + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormMain)); + this.panelDisplay = new System.Windows.Forms.Panel(); + this.iTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel(); + this.marqueeLabelTop = new SharpDisplayManager.MarqueeLabel(); + this.marqueeLabelBottom = new SharpDisplayManager.MarqueeLabel(); + this.fontDialog = new System.Windows.Forms.FontDialog(); + this.timer = new System.Windows.Forms.Timer(this.components); + this.statusStrip = new System.Windows.Forms.StatusStrip(); + this.toolStripStatusLabelConnect = new System.Windows.Forms.ToolStripStatusLabel(); + this.toolStripStatusLabelSpring = new System.Windows.Forms.ToolStripStatusLabel(); + this.toolStripStatusLabelPower = new System.Windows.Forms.ToolStripStatusLabel(); + this.toolStripStatusLabelFps = new System.Windows.Forms.ToolStripStatusLabel(); + this.tabPageClients = new System.Windows.Forms.TabPage(); + this.iCheckBoxStartIdleClient = new System.Windows.Forms.CheckBox(); + this.iButtonStartIdleClient = new System.Windows.Forms.Button(); + this.buttonCloseClients = new System.Windows.Forms.Button(); + this.buttonStartClient = new System.Windows.Forms.Button(); + this.iTreeViewClients = new System.Windows.Forms.TreeView(); + this.tabPageDisplay = new System.Windows.Forms.TabPage(); + this.buttonShowClock = new System.Windows.Forms.Button(); + this.buttonHideClock = new System.Windows.Forms.Button(); + this.buttonPowerOff = new System.Windows.Forms.Button(); + this.buttonPowerOn = new System.Windows.Forms.Button(); + this.labelTimerInterval = new System.Windows.Forms.Label(); + this.maskedTextBoxTimerInterval = new System.Windows.Forms.MaskedTextBox(); + this.comboBoxDisplayType = new System.Windows.Forms.ComboBox(); + this.buttonSuspend = new System.Windows.Forms.Button(); + this.checkBoxConnectOnStartup = new System.Windows.Forms.CheckBox(); + this.trackBarBrightness = new System.Windows.Forms.TrackBar(); + this.buttonFill = new System.Windows.Forms.Button(); + this.buttonClear = new System.Windows.Forms.Button(); + this.buttonClose = new System.Windows.Forms.Button(); + this.buttonOpen = new System.Windows.Forms.Button(); + this.buttonCapture = new System.Windows.Forms.Button(); + this.labelWarning = new System.Windows.Forms.Label(); + this.checkBoxFixedPitchFontOnly = new System.Windows.Forms.CheckBox(); + this.checkBoxShowBorders = new System.Windows.Forms.CheckBox(); + this.buttonFont = new System.Windows.Forms.Button(); + this.tabControl = new System.Windows.Forms.TabControl(); + this.tabPageDesign = new System.Windows.Forms.TabPage(); + this.labelScrollingSpeed = new System.Windows.Forms.Label(); + this.maskedTextBoxScrollingSpeed = new System.Windows.Forms.MaskedTextBox(); + this.labelScrollLoopSeparator = new System.Windows.Forms.Label(); + this.textBoxScrollLoopSeparator = new System.Windows.Forms.TextBox(); + this.labelMinFontSize = new System.Windows.Forms.Label(); + this.maskedTextBoxMinFontSize = new System.Windows.Forms.MaskedTextBox(); + this.checkBoxScaleToFit = new System.Windows.Forms.CheckBox(); + this.checkBoxInverseColors = new System.Windows.Forms.CheckBox(); + this.checkBoxReverseScreen = new System.Windows.Forms.CheckBox(); + this.tabPageAudio = new System.Windows.Forms.TabPage(); + this.labelDefaultAudioDevice = new System.Windows.Forms.Label(); + this.checkBoxShowVolumeLabel = new System.Windows.Forms.CheckBox(); + this.checkBoxMute = new System.Windows.Forms.CheckBox(); + this.trackBarMasterVolume = new System.Windows.Forms.TrackBar(); + this.tabPageInput = new System.Windows.Forms.TabPage(); + this.comboBoxOpticalDrives = new System.Windows.Forms.ComboBox(); + this.labelOpticalDriveEject = new System.Windows.Forms.Label(); + this.pictureBoxGreenStart = new System.Windows.Forms.PictureBox(); + this.labelStartFileName = new System.Windows.Forms.Label(); + this.buttonSelectFile = new System.Windows.Forms.Button(); + this.tabPageCec = new System.Windows.Forms.TabPage(); + this.groupBoxCecLogOptions = new System.Windows.Forms.GroupBox(); + this.checkBoxCecLogNoPoll = new System.Windows.Forms.CheckBox(); + this.checkBoxCecLogTraffic = new System.Windows.Forms.CheckBox(); + this.checkBoxCecLogDebug = new System.Windows.Forms.CheckBox(); + this.checkBoxCecLogNotice = new System.Windows.Forms.CheckBox(); + this.checkBoxCecLogError = new System.Windows.Forms.CheckBox(); + this.checkBoxCecLogWarning = new System.Windows.Forms.CheckBox(); + this.checkBoxCecEnabled = new System.Windows.Forms.CheckBox(); + this.labelHdmiPort = new System.Windows.Forms.Label(); + this.comboBoxHdmiPort = new System.Windows.Forms.ComboBox(); + this.tabPageEvent = new System.Windows.Forms.TabPage(); + this.buttonActionMoveUp = new System.Windows.Forms.Button(); + this.buttonActionMoveDown = new System.Windows.Forms.Button(); + this.buttonTestAction = new System.Windows.Forms.Button(); + this.buttonDeleteAction = new System.Windows.Forms.Button(); + this.buttonAddAction = new System.Windows.Forms.Button(); + this.iTreeViewEvents = new System.Windows.Forms.TreeView(); + this.tabPageApp = new System.Windows.Forms.TabPage(); + this.checkBoxStartMinimized = new System.Windows.Forms.CheckBox(); + this.checkBoxMinimizeToTray = new System.Windows.Forms.CheckBox(); + this.checkBoxAutoStart = new System.Windows.Forms.CheckBox(); + this.buttonUpdate = new System.Windows.Forms.Button(); + this.tabPageLogs = new System.Windows.Forms.TabPage(); + this.buttonClearLogs = new System.Windows.Forms.Button(); + this.richTextBoxLogs = new System.Windows.Forms.RichTextBox(); + this.labelFontWidth = new System.Windows.Forms.Label(); + this.labelFontHeight = new System.Windows.Forms.Label(); + this.toolTip = new System.Windows.Forms.ToolTip(this.components); + this.openFileDialog = new System.Windows.Forms.OpenFileDialog(); + this.panelDisplay.SuspendLayout(); + this.iTableLayoutPanel.SuspendLayout(); + this.statusStrip.SuspendLayout(); + this.tabPageClients.SuspendLayout(); + this.tabPageDisplay.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.trackBarBrightness)).BeginInit(); + this.tabControl.SuspendLayout(); + this.tabPageDesign.SuspendLayout(); + this.tabPageAudio.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.trackBarMasterVolume)).BeginInit(); + this.tabPageInput.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBoxGreenStart)).BeginInit(); + this.tabPageCec.SuspendLayout(); + this.groupBoxCecLogOptions.SuspendLayout(); + this.tabPageEvent.SuspendLayout(); + this.tabPageApp.SuspendLayout(); + this.tabPageLogs.SuspendLayout(); + this.SuspendLayout(); + // + // panelDisplay + // + this.panelDisplay.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.panelDisplay.Controls.Add(this.iTableLayoutPanel); + this.panelDisplay.Location = new System.Drawing.Point(173, 40); + this.panelDisplay.Margin = new System.Windows.Forms.Padding(0); + this.panelDisplay.Name = "panelDisplay"; + this.panelDisplay.Size = new System.Drawing.Size(258, 66); + this.panelDisplay.TabIndex = 12; + // + // iTableLayoutPanel + // + this.iTableLayoutPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.iTableLayoutPanel.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.iTableLayoutPanel.BackColor = System.Drawing.SystemColors.ControlLightLight; + this.iTableLayoutPanel.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.Single; + this.iTableLayoutPanel.ColumnCount = 1; + this.iTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.iTableLayoutPanel.Controls.Add(this.marqueeLabelTop, 0, 0); + this.iTableLayoutPanel.Controls.Add(this.marqueeLabelBottom, 0, 1); + this.iTableLayoutPanel.GrowStyle = System.Windows.Forms.TableLayoutPanelGrowStyle.FixedSize; + this.iTableLayoutPanel.Location = new System.Drawing.Point(0, 0); + this.iTableLayoutPanel.Margin = new System.Windows.Forms.Padding(0); + this.iTableLayoutPanel.Name = "iTableLayoutPanel"; + this.iTableLayoutPanel.RowCount = 2; + this.iTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.iTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.iTableLayoutPanel.Size = new System.Drawing.Size(256, 64); + this.iTableLayoutPanel.TabIndex = 5; + this.iTableLayoutPanel.SizeChanged += new System.EventHandler(this.tableLayoutPanel_SizeChanged); + // + // marqueeLabelTop + // + this.marqueeLabelTop.AutoEllipsis = true; + this.marqueeLabelTop.AutoSize = true; + this.marqueeLabelTop.BackColor = System.Drawing.Color.Transparent; + this.marqueeLabelTop.Dock = System.Windows.Forms.DockStyle.Fill; + this.marqueeLabelTop.Location = new System.Drawing.Point(1, 1); + this.marqueeLabelTop.Margin = new System.Windows.Forms.Padding(0); + this.marqueeLabelTop.MinFontSize = 15F; + this.marqueeLabelTop.Name = "marqueeLabelTop"; + this.marqueeLabelTop.OwnTimer = false; + this.marqueeLabelTop.PixelsPerSecond = 64; + this.marqueeLabelTop.ScaleToFit = true; + this.marqueeLabelTop.Separator = "|"; + this.marqueeLabelTop.Size = new System.Drawing.Size(254, 30); + this.marqueeLabelTop.TabIndex = 2; + this.marqueeLabelTop.Text = "ABCDEFGHIJKLMNOPQRST-0123456789"; + this.marqueeLabelTop.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + this.marqueeLabelTop.UseCompatibleTextRendering = true; + // + // marqueeLabelBottom + // + this.marqueeLabelBottom.AutoEllipsis = true; + this.marqueeLabelBottom.AutoSize = true; + this.marqueeLabelBottom.Dock = System.Windows.Forms.DockStyle.Fill; + this.marqueeLabelBottom.Location = new System.Drawing.Point(1, 32); + this.marqueeLabelBottom.Margin = new System.Windows.Forms.Padding(0); + this.marqueeLabelBottom.MinFontSize = 15F; + this.marqueeLabelBottom.Name = "marqueeLabelBottom"; + this.marqueeLabelBottom.OwnTimer = false; + this.marqueeLabelBottom.PixelsPerSecond = 64; + this.marqueeLabelBottom.ScaleToFit = true; + this.marqueeLabelBottom.Separator = "|"; + this.marqueeLabelBottom.Size = new System.Drawing.Size(254, 31); + this.marqueeLabelBottom.TabIndex = 3; + this.marqueeLabelBottom.Text = "abcdefghijklmnopqrst-0123456789"; + this.marqueeLabelBottom.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + this.marqueeLabelBottom.UseCompatibleTextRendering = true; + // + // timer + // + this.timer.Interval = 50; + this.timer.Tick += new System.EventHandler(this.timer_Tick); + // + // statusStrip + // + this.statusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.toolStripStatusLabelConnect, + this.toolStripStatusLabelSpring, + this.toolStripStatusLabelPower, + this.toolStripStatusLabelFps}); + this.statusStrip.Location = new System.Drawing.Point(0, 539); + this.statusStrip.Name = "statusStrip"; + this.statusStrip.RenderMode = System.Windows.Forms.ToolStripRenderMode.Professional; + this.statusStrip.Size = new System.Drawing.Size(784, 22); + this.statusStrip.TabIndex = 1; + this.statusStrip.Text = "statusStrip"; + // + // toolStripStatusLabelConnect + // + this.toolStripStatusLabelConnect.Name = "toolStripStatusLabelConnect"; + this.toolStripStatusLabelConnect.Size = new System.Drawing.Size(86, 17); + this.toolStripStatusLabelConnect.Text = "Not connected"; + // + // toolStripStatusLabelSpring + // + this.toolStripStatusLabelSpring.Name = "toolStripStatusLabelSpring"; + this.toolStripStatusLabelSpring.Size = new System.Drawing.Size(633, 17); + this.toolStripStatusLabelSpring.Spring = true; + // + // toolStripStatusLabelPower + // + this.toolStripStatusLabelPower.Name = "toolStripStatusLabelPower"; + this.toolStripStatusLabelPower.Size = new System.Drawing.Size(24, 17); + this.toolStripStatusLabelPower.Text = "NA"; + // + // toolStripStatusLabelFps + // + this.toolStripStatusLabelFps.Name = "toolStripStatusLabelFps"; + this.toolStripStatusLabelFps.Size = new System.Drawing.Size(26, 17); + this.toolStripStatusLabelFps.Text = "FPS"; + // + // tabPageClients + // + this.tabPageClients.Controls.Add(this.iCheckBoxStartIdleClient); + this.tabPageClients.Controls.Add(this.iButtonStartIdleClient); + this.tabPageClients.Controls.Add(this.buttonCloseClients); + this.tabPageClients.Controls.Add(this.buttonStartClient); + this.tabPageClients.Controls.Add(this.iTreeViewClients); + this.tabPageClients.Location = new System.Drawing.Point(4, 22); + this.tabPageClients.Name = "tabPageClients"; + this.tabPageClients.Padding = new System.Windows.Forms.Padding(3); + this.tabPageClients.Size = new System.Drawing.Size(752, 385); + this.tabPageClients.TabIndex = 2; + this.tabPageClients.Text = "Clients"; + this.tabPageClients.UseVisualStyleBackColor = true; + // + // iCheckBoxStartIdleClient + // + this.iCheckBoxStartIdleClient.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.iCheckBoxStartIdleClient.AutoSize = true; + this.iCheckBoxStartIdleClient.Location = new System.Drawing.Point(108, 340); + this.iCheckBoxStartIdleClient.Name = "iCheckBoxStartIdleClient"; + this.iCheckBoxStartIdleClient.Size = new System.Drawing.Size(145, 17); + this.iCheckBoxStartIdleClient.TabIndex = 22; + this.iCheckBoxStartIdleClient.Text = "Start idle client on startup"; + this.iCheckBoxStartIdleClient.UseVisualStyleBackColor = true; + this.iCheckBoxStartIdleClient.CheckedChanged += new System.EventHandler(this.checkBoxStartIdleClient_CheckedChanged); + // + // iButtonStartIdleClient + // + this.iButtonStartIdleClient.Location = new System.Drawing.Point(6, 35); + this.iButtonStartIdleClient.Name = "iButtonStartIdleClient"; + this.iButtonStartIdleClient.Size = new System.Drawing.Size(96, 23); + this.iButtonStartIdleClient.TabIndex = 21; + this.iButtonStartIdleClient.Text = "Start Idle Client"; + this.iButtonStartIdleClient.UseVisualStyleBackColor = true; + this.iButtonStartIdleClient.Click += new System.EventHandler(this.ButtonStartIdleClient_Click); + // + // buttonCloseClients + // + this.buttonCloseClients.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.buttonCloseClients.Location = new System.Drawing.Point(6, 336); + this.buttonCloseClients.Name = "buttonCloseClients"; + this.buttonCloseClients.Size = new System.Drawing.Size(96, 23); + this.buttonCloseClients.TabIndex = 20; + this.buttonCloseClients.Text = "Close Clients"; + this.buttonCloseClients.UseVisualStyleBackColor = true; + this.buttonCloseClients.Click += new System.EventHandler(this.buttonCloseClients_Click); + // + // buttonStartClient + // + this.buttonStartClient.Location = new System.Drawing.Point(6, 6); + this.buttonStartClient.Name = "buttonStartClient"; + this.buttonStartClient.Size = new System.Drawing.Size(96, 23); + this.buttonStartClient.TabIndex = 19; + this.buttonStartClient.Text = "Start Test Client"; + this.buttonStartClient.UseVisualStyleBackColor = true; + this.buttonStartClient.Click += new System.EventHandler(this.buttonStartClient_Click); + // + // iTreeViewClients + // + this.iTreeViewClients.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.iTreeViewClients.Location = new System.Drawing.Point(108, 6); + this.iTreeViewClients.Name = "iTreeViewClients"; + this.iTreeViewClients.Size = new System.Drawing.Size(638, 328); + this.iTreeViewClients.TabIndex = 0; + this.iTreeViewClients.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeViewClients_AfterSelect); + // + // tabPageDisplay + // + this.tabPageDisplay.Controls.Add(this.buttonShowClock); + this.tabPageDisplay.Controls.Add(this.buttonHideClock); + this.tabPageDisplay.Controls.Add(this.buttonPowerOff); + this.tabPageDisplay.Controls.Add(this.buttonPowerOn); + this.tabPageDisplay.Controls.Add(this.labelTimerInterval); + this.tabPageDisplay.Controls.Add(this.maskedTextBoxTimerInterval); + this.tabPageDisplay.Controls.Add(this.comboBoxDisplayType); + this.tabPageDisplay.Controls.Add(this.buttonSuspend); + this.tabPageDisplay.Controls.Add(this.checkBoxConnectOnStartup); + this.tabPageDisplay.Controls.Add(this.trackBarBrightness); + this.tabPageDisplay.Controls.Add(this.buttonFill); + this.tabPageDisplay.Controls.Add(this.buttonClear); + this.tabPageDisplay.Controls.Add(this.buttonClose); + this.tabPageDisplay.Controls.Add(this.buttonOpen); + this.tabPageDisplay.Controls.Add(this.buttonCapture); + this.tabPageDisplay.Location = new System.Drawing.Point(4, 22); + this.tabPageDisplay.Name = "tabPageDisplay"; + this.tabPageDisplay.Padding = new System.Windows.Forms.Padding(3); + this.tabPageDisplay.Size = new System.Drawing.Size(752, 385); + this.tabPageDisplay.TabIndex = 0; + this.tabPageDisplay.Text = "Display"; + this.tabPageDisplay.UseVisualStyleBackColor = true; + // + // buttonShowClock + // + this.buttonShowClock.Location = new System.Drawing.Point(6, 122); + this.buttonShowClock.Name = "buttonShowClock"; + this.buttonShowClock.Size = new System.Drawing.Size(75, 23); + this.buttonShowClock.TabIndex = 23; + this.buttonShowClock.Text = "Show Clock"; + this.buttonShowClock.UseVisualStyleBackColor = true; + this.buttonShowClock.Click += new System.EventHandler(this.buttonShowClock_Click); + // + // buttonHideClock + // + this.buttonHideClock.Location = new System.Drawing.Point(6, 151); + this.buttonHideClock.Name = "buttonHideClock"; + this.buttonHideClock.Size = new System.Drawing.Size(75, 23); + this.buttonHideClock.TabIndex = 22; + this.buttonHideClock.Text = "Hide Clock"; + this.buttonHideClock.UseVisualStyleBackColor = true; + this.buttonHideClock.Click += new System.EventHandler(this.buttonHideClock_Click); + // + // buttonPowerOff + // + this.buttonPowerOff.Location = new System.Drawing.Point(6, 209); + this.buttonPowerOff.Name = "buttonPowerOff"; + this.buttonPowerOff.Size = new System.Drawing.Size(75, 23); + this.buttonPowerOff.TabIndex = 21; + this.buttonPowerOff.Text = "OFF"; + this.buttonPowerOff.UseVisualStyleBackColor = true; + this.buttonPowerOff.Click += new System.EventHandler(this.buttonPowerOff_Click); + // + // buttonPowerOn + // + this.buttonPowerOn.Location = new System.Drawing.Point(6, 180); + this.buttonPowerOn.Name = "buttonPowerOn"; + this.buttonPowerOn.Size = new System.Drawing.Size(75, 23); + this.buttonPowerOn.TabIndex = 20; + this.buttonPowerOn.Text = "ON"; + this.buttonPowerOn.UseVisualStyleBackColor = true; + this.buttonPowerOn.Click += new System.EventHandler(this.buttonPowerOn_Click); + // + // labelTimerInterval + // + this.labelTimerInterval.AutoSize = true; + this.labelTimerInterval.Location = new System.Drawing.Point(184, 45); + this.labelTimerInterval.Name = "labelTimerInterval"; + this.labelTimerInterval.Size = new System.Drawing.Size(98, 13); + this.labelTimerInterval.TabIndex = 19; + this.labelTimerInterval.Text = "Timer interval (ms) :"; + // + // maskedTextBoxTimerInterval + // + this.maskedTextBoxTimerInterval.Location = new System.Drawing.Point(288, 42); + this.maskedTextBoxTimerInterval.Mask = "000"; + this.maskedTextBoxTimerInterval.Name = "maskedTextBoxTimerInterval"; + this.maskedTextBoxTimerInterval.PromptChar = ' '; + this.maskedTextBoxTimerInterval.Size = new System.Drawing.Size(24, 20); + this.maskedTextBoxTimerInterval.TabIndex = 18; + this.maskedTextBoxTimerInterval.TextChanged += new System.EventHandler(this.maskedTextBoxTimerInterval_TextChanged); + // + // comboBoxDisplayType + // + this.comboBoxDisplayType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.comboBoxDisplayType.FormattingEnabled = true; + this.comboBoxDisplayType.Location = new System.Drawing.Point(187, 9); + this.comboBoxDisplayType.Name = "comboBoxDisplayType"; + this.comboBoxDisplayType.Size = new System.Drawing.Size(181, 21); + this.comboBoxDisplayType.TabIndex = 17; + this.comboBoxDisplayType.SelectedIndexChanged += new System.EventHandler(this.comboBoxDisplayType_SelectedIndexChanged); + // + // buttonSuspend + // + this.buttonSuspend.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.buttonSuspend.Location = new System.Drawing.Point(6, 317); + this.buttonSuspend.Name = "buttonSuspend"; + this.buttonSuspend.Size = new System.Drawing.Size(75, 23); + this.buttonSuspend.TabIndex = 16; + this.buttonSuspend.Text = "Pause"; + this.buttonSuspend.UseVisualStyleBackColor = true; + this.buttonSuspend.Click += new System.EventHandler(this.buttonSuspend_Click); + // + // checkBoxConnectOnStartup + // + this.checkBoxConnectOnStartup.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.checkBoxConnectOnStartup.AutoSize = true; + this.checkBoxConnectOnStartup.Location = new System.Drawing.Point(113, 350); + this.checkBoxConnectOnStartup.Name = "checkBoxConnectOnStartup"; + this.checkBoxConnectOnStartup.Size = new System.Drawing.Size(119, 17); + this.checkBoxConnectOnStartup.TabIndex = 13; + this.checkBoxConnectOnStartup.Text = "Connect on stratup "; + this.checkBoxConnectOnStartup.UseVisualStyleBackColor = true; + this.checkBoxConnectOnStartup.CheckedChanged += new System.EventHandler(this.checkBoxConnectOnStartup_CheckedChanged); + // + // trackBarBrightness + // + this.trackBarBrightness.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Right))); + this.trackBarBrightness.BackColor = System.Drawing.SystemColors.Window; + this.trackBarBrightness.Location = new System.Drawing.Point(704, 9); + this.trackBarBrightness.Name = "trackBarBrightness"; + this.trackBarBrightness.Orientation = System.Windows.Forms.Orientation.Vertical; + this.trackBarBrightness.Size = new System.Drawing.Size(45, 358); + this.trackBarBrightness.TabIndex = 10; + this.trackBarBrightness.TickStyle = System.Windows.Forms.TickStyle.Both; + this.toolTip.SetToolTip(this.trackBarBrightness, "Brightness adjustment"); + this.trackBarBrightness.Scroll += new System.EventHandler(this.trackBarBrightness_Scroll); + // + // buttonFill + // + this.buttonFill.Location = new System.Drawing.Point(6, 93); + this.buttonFill.Name = "buttonFill"; + this.buttonFill.Size = new System.Drawing.Size(75, 23); + this.buttonFill.TabIndex = 9; + this.buttonFill.Text = "Fill"; + this.buttonFill.UseVisualStyleBackColor = true; + this.buttonFill.Click += new System.EventHandler(this.buttonFill_Click); + // + // buttonClear + // + this.buttonClear.Location = new System.Drawing.Point(6, 64); + this.buttonClear.Name = "buttonClear"; + this.buttonClear.Size = new System.Drawing.Size(75, 23); + this.buttonClear.TabIndex = 8; + this.buttonClear.Text = "Clear"; + this.buttonClear.UseVisualStyleBackColor = true; + this.buttonClear.Click += new System.EventHandler(this.buttonClear_Click); + // + // buttonClose + // + this.buttonClose.Location = new System.Drawing.Point(6, 35); + this.buttonClose.Name = "buttonClose"; + this.buttonClose.Size = new System.Drawing.Size(75, 23); + this.buttonClose.TabIndex = 7; + this.buttonClose.Text = "Close"; + this.buttonClose.UseVisualStyleBackColor = true; + this.buttonClose.Click += new System.EventHandler(this.buttonClose_Click); + // + // buttonOpen + // + this.buttonOpen.Location = new System.Drawing.Point(6, 6); + this.buttonOpen.Name = "buttonOpen"; + this.buttonOpen.Size = new System.Drawing.Size(75, 23); + this.buttonOpen.TabIndex = 6; + this.buttonOpen.Text = "Open"; + this.buttonOpen.UseVisualStyleBackColor = true; + this.buttonOpen.Click += new System.EventHandler(this.buttonOpen_Click); + // + // buttonCapture + // + this.buttonCapture.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.buttonCapture.Location = new System.Drawing.Point(6, 346); + this.buttonCapture.Name = "buttonCapture"; + this.buttonCapture.Size = new System.Drawing.Size(75, 23); + this.buttonCapture.TabIndex = 5; + this.buttonCapture.Text = "Capture"; + this.buttonCapture.UseVisualStyleBackColor = true; + this.buttonCapture.Click += new System.EventHandler(this.buttonCapture_Click); + // + // labelWarning + // + this.labelWarning.AutoSize = true; + this.labelWarning.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.labelWarning.ForeColor = System.Drawing.Color.Red; + this.labelWarning.Location = new System.Drawing.Point(9, 9); + this.labelWarning.Name = "labelWarning"; + this.labelWarning.Size = new System.Drawing.Size(80, 16); + this.labelWarning.TabIndex = 18; + this.labelWarning.Text = "WARNING"; + this.labelWarning.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + this.labelWarning.Visible = false; + // + // checkBoxFixedPitchFontOnly + // + this.checkBoxFixedPitchFontOnly.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.checkBoxFixedPitchFontOnly.AutoSize = true; + this.checkBoxFixedPitchFontOnly.Location = new System.Drawing.Point(87, 362); + this.checkBoxFixedPitchFontOnly.Name = "checkBoxFixedPitchFontOnly"; + this.checkBoxFixedPitchFontOnly.Size = new System.Drawing.Size(120, 17); + this.checkBoxFixedPitchFontOnly.TabIndex = 17; + this.checkBoxFixedPitchFontOnly.Text = "Fixed pitch font only"; + this.checkBoxFixedPitchFontOnly.UseVisualStyleBackColor = true; + // + // checkBoxShowBorders + // + this.checkBoxShowBorders.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.checkBoxShowBorders.AutoSize = true; + this.checkBoxShowBorders.Location = new System.Drawing.Point(645, 29); + this.checkBoxShowBorders.Name = "checkBoxShowBorders"; + this.checkBoxShowBorders.Size = new System.Drawing.Size(91, 17); + this.checkBoxShowBorders.TabIndex = 11; + this.checkBoxShowBorders.Text = "Show borders"; + this.checkBoxShowBorders.UseVisualStyleBackColor = true; + this.checkBoxShowBorders.CheckedChanged += new System.EventHandler(this.checkBoxShowBorders_CheckedChanged); + // + // buttonFont + // + this.buttonFont.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.buttonFont.Location = new System.Drawing.Point(6, 356); + this.buttonFont.Name = "buttonFont"; + this.buttonFont.Size = new System.Drawing.Size(75, 23); + this.buttonFont.TabIndex = 0; + this.buttonFont.Text = "Select Font"; + this.buttonFont.UseVisualStyleBackColor = true; + this.buttonFont.Click += new System.EventHandler(this.buttonFont_Click); + // + // tabControl + // + this.tabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.tabControl.Controls.Add(this.tabPageDisplay); + this.tabControl.Controls.Add(this.tabPageClients); + this.tabControl.Controls.Add(this.tabPageDesign); + this.tabControl.Controls.Add(this.tabPageAudio); + this.tabControl.Controls.Add(this.tabPageInput); + this.tabControl.Controls.Add(this.tabPageCec); + this.tabControl.Controls.Add(this.tabPageEvent); + this.tabControl.Controls.Add(this.tabPageApp); + this.tabControl.Controls.Add(this.tabPageLogs); + this.tabControl.Location = new System.Drawing.Point(12, 125); + this.tabControl.Name = "tabControl"; + this.tabControl.SelectedIndex = 0; + this.tabControl.Size = new System.Drawing.Size(760, 411); + this.tabControl.TabIndex = 0; + // + // tabPageDesign + // + this.tabPageDesign.Controls.Add(this.labelScrollingSpeed); + this.tabPageDesign.Controls.Add(this.maskedTextBoxScrollingSpeed); + this.tabPageDesign.Controls.Add(this.labelScrollLoopSeparator); + this.tabPageDesign.Controls.Add(this.textBoxScrollLoopSeparator); + this.tabPageDesign.Controls.Add(this.labelMinFontSize); + this.tabPageDesign.Controls.Add(this.maskedTextBoxMinFontSize); + this.tabPageDesign.Controls.Add(this.checkBoxScaleToFit); + this.tabPageDesign.Controls.Add(this.checkBoxInverseColors); + this.tabPageDesign.Controls.Add(this.checkBoxFixedPitchFontOnly); + this.tabPageDesign.Controls.Add(this.buttonFont); + this.tabPageDesign.Controls.Add(this.checkBoxReverseScreen); + this.tabPageDesign.Controls.Add(this.checkBoxShowBorders); + this.tabPageDesign.Location = new System.Drawing.Point(4, 22); + this.tabPageDesign.Name = "tabPageDesign"; + this.tabPageDesign.Padding = new System.Windows.Forms.Padding(3); + this.tabPageDesign.Size = new System.Drawing.Size(752, 385); + this.tabPageDesign.TabIndex = 3; + this.tabPageDesign.Text = "Design"; + this.tabPageDesign.UseVisualStyleBackColor = true; + // + // labelScrollingSpeed + // + this.labelScrollingSpeed.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.labelScrollingSpeed.AutoSize = true; + this.labelScrollingSpeed.Location = new System.Drawing.Point(92, 248); + this.labelScrollingSpeed.Name = "labelScrollingSpeed"; + this.labelScrollingSpeed.Size = new System.Drawing.Size(115, 13); + this.labelScrollingSpeed.TabIndex = 28; + this.labelScrollingSpeed.Text = "Scrolling speed (px/s) :"; + // + // maskedTextBoxScrollingSpeed + // + this.maskedTextBoxScrollingSpeed.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.maskedTextBoxScrollingSpeed.Location = new System.Drawing.Point(213, 245); + this.maskedTextBoxScrollingSpeed.Mask = "000"; + this.maskedTextBoxScrollingSpeed.Name = "maskedTextBoxScrollingSpeed"; + this.maskedTextBoxScrollingSpeed.PromptChar = ' '; + this.maskedTextBoxScrollingSpeed.Size = new System.Drawing.Size(24, 20); + this.maskedTextBoxScrollingSpeed.TabIndex = 27; + this.maskedTextBoxScrollingSpeed.TextChanged += new System.EventHandler(this.maskedTextBoxScrollingSpeed_TextChanged); + // + // labelScrollLoopSeparator + // + this.labelScrollLoopSeparator.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.labelScrollLoopSeparator.AutoSize = true; + this.labelScrollLoopSeparator.Location = new System.Drawing.Point(98, 274); + this.labelScrollLoopSeparator.Name = "labelScrollLoopSeparator"; + this.labelScrollLoopSeparator.Size = new System.Drawing.Size(109, 13); + this.labelScrollLoopSeparator.TabIndex = 26; + this.labelScrollLoopSeparator.Text = "Scroll loop separator :"; + // + // textBoxScrollLoopSeparator + // + this.textBoxScrollLoopSeparator.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.textBoxScrollLoopSeparator.Location = new System.Drawing.Point(213, 271); + this.textBoxScrollLoopSeparator.Name = "textBoxScrollLoopSeparator"; + this.textBoxScrollLoopSeparator.Size = new System.Drawing.Size(74, 20); + this.textBoxScrollLoopSeparator.TabIndex = 25; + this.textBoxScrollLoopSeparator.TextChanged += new System.EventHandler(this.textBoxScrollLoopSeparator_TextChanged); + // + // labelMinFontSize + // + this.labelMinFontSize.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.labelMinFontSize.AutoSize = true; + this.labelMinFontSize.Location = new System.Drawing.Point(88, 323); + this.labelMinFontSize.Name = "labelMinFontSize"; + this.labelMinFontSize.Size = new System.Drawing.Size(119, 13); + this.labelMinFontSize.TabIndex = 24; + this.labelMinFontSize.Text = "Minimum font size (pts) :"; + // + // maskedTextBoxMinFontSize + // + this.maskedTextBoxMinFontSize.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.maskedTextBoxMinFontSize.Location = new System.Drawing.Point(213, 320); + this.maskedTextBoxMinFontSize.Mask = "000"; + this.maskedTextBoxMinFontSize.Name = "maskedTextBoxMinFontSize"; + this.maskedTextBoxMinFontSize.PromptChar = ' '; + this.maskedTextBoxMinFontSize.Size = new System.Drawing.Size(24, 20); + this.maskedTextBoxMinFontSize.TabIndex = 23; + this.maskedTextBoxMinFontSize.TextChanged += new System.EventHandler(this.maskedTextBoxMinFontSize_TextChanged); + // + // checkBoxScaleToFit + // + this.checkBoxScaleToFit.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.checkBoxScaleToFit.AutoSize = true; + this.checkBoxScaleToFit.Location = new System.Drawing.Point(86, 297); + this.checkBoxScaleToFit.Name = "checkBoxScaleToFit"; + this.checkBoxScaleToFit.Size = new System.Drawing.Size(201, 17); + this.checkBoxScaleToFit.TabIndex = 22; + this.checkBoxScaleToFit.Text = "Try scale font down to avoid scrolling"; + this.checkBoxScaleToFit.UseVisualStyleBackColor = true; + this.checkBoxScaleToFit.CheckedChanged += new System.EventHandler(this.checkBoxScaleToFit_CheckedChanged); + // + // checkBoxInverseColors + // + this.checkBoxInverseColors.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.checkBoxInverseColors.AutoSize = true; + this.checkBoxInverseColors.Location = new System.Drawing.Point(645, 52); + this.checkBoxInverseColors.Name = "checkBoxInverseColors"; + this.checkBoxInverseColors.Size = new System.Drawing.Size(92, 17); + this.checkBoxInverseColors.TabIndex = 21; + this.checkBoxInverseColors.Text = "Inverse colors"; + this.checkBoxInverseColors.UseVisualStyleBackColor = true; + this.checkBoxInverseColors.CheckedChanged += new System.EventHandler(this.checkBoxInverseColors_CheckedChanged); + // + // checkBoxReverseScreen + // + this.checkBoxReverseScreen.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.checkBoxReverseScreen.AutoSize = true; + this.checkBoxReverseScreen.Location = new System.Drawing.Point(645, 6); + this.checkBoxReverseScreen.Name = "checkBoxReverseScreen"; + this.checkBoxReverseScreen.Size = new System.Drawing.Size(101, 17); + this.checkBoxReverseScreen.TabIndex = 14; + this.checkBoxReverseScreen.Text = "Reverse screen"; + this.checkBoxReverseScreen.UseVisualStyleBackColor = true; + this.checkBoxReverseScreen.CheckedChanged += new System.EventHandler(this.checkBoxReverseScreen_CheckedChanged); + // + // tabPageAudio + // + this.tabPageAudio.Controls.Add(this.labelDefaultAudioDevice); + this.tabPageAudio.Controls.Add(this.checkBoxShowVolumeLabel); + this.tabPageAudio.Controls.Add(this.checkBoxMute); + this.tabPageAudio.Controls.Add(this.trackBarMasterVolume); + this.tabPageAudio.Location = new System.Drawing.Point(4, 22); + this.tabPageAudio.Name = "tabPageAudio"; + this.tabPageAudio.Padding = new System.Windows.Forms.Padding(3); + this.tabPageAudio.Size = new System.Drawing.Size(752, 385); + this.tabPageAudio.TabIndex = 5; + this.tabPageAudio.Text = "Audio"; + this.tabPageAudio.UseVisualStyleBackColor = true; + // + // labelDefaultAudioDevice + // + this.labelDefaultAudioDevice.AutoSize = true; + this.labelDefaultAudioDevice.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.labelDefaultAudioDevice.Location = new System.Drawing.Point(3, 6); + this.labelDefaultAudioDevice.Name = "labelDefaultAudioDevice"; + this.labelDefaultAudioDevice.Size = new System.Drawing.Size(120, 13); + this.labelDefaultAudioDevice.TabIndex = 19; + this.labelDefaultAudioDevice.Text = "Audio Device Unknown"; + // + // checkBoxShowVolumeLabel + // + this.checkBoxShowVolumeLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.checkBoxShowVolumeLabel.AutoSize = true; + this.checkBoxShowVolumeLabel.Location = new System.Drawing.Point(3, 329); + this.checkBoxShowVolumeLabel.Name = "checkBoxShowVolumeLabel"; + this.checkBoxShowVolumeLabel.Size = new System.Drawing.Size(115, 17); + this.checkBoxShowVolumeLabel.TabIndex = 18; + this.checkBoxShowVolumeLabel.Text = "Show volume label"; + this.checkBoxShowVolumeLabel.UseVisualStyleBackColor = true; + this.checkBoxShowVolumeLabel.CheckedChanged += new System.EventHandler(this.checkBoxShowVolumeLabel_CheckedChanged); + // + // checkBoxMute + // + this.checkBoxMute.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.checkBoxMute.AutoSize = true; + this.checkBoxMute.Location = new System.Drawing.Point(3, 352); + this.checkBoxMute.Name = "checkBoxMute"; + this.checkBoxMute.Size = new System.Drawing.Size(50, 17); + this.checkBoxMute.TabIndex = 17; + this.checkBoxMute.Text = "Mute"; + this.checkBoxMute.UseVisualStyleBackColor = true; + this.checkBoxMute.CheckedChanged += new System.EventHandler(this.checkBoxMute_CheckedChanged); + // + // trackBarMasterVolume + // + this.trackBarMasterVolume.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Right))); + this.trackBarMasterVolume.BackColor = System.Drawing.SystemColors.Window; + this.trackBarMasterVolume.Location = new System.Drawing.Point(701, 6); + this.trackBarMasterVolume.Maximum = 100; + this.trackBarMasterVolume.Name = "trackBarMasterVolume"; + this.trackBarMasterVolume.Orientation = System.Windows.Forms.Orientation.Vertical; + this.trackBarMasterVolume.Size = new System.Drawing.Size(45, 373); + this.trackBarMasterVolume.TabIndex = 0; + this.trackBarMasterVolume.TickFrequency = 10; + this.trackBarMasterVolume.TickStyle = System.Windows.Forms.TickStyle.Both; + this.toolTip.SetToolTip(this.trackBarMasterVolume, "Master Volume"); + this.trackBarMasterVolume.Scroll += new System.EventHandler(this.trackBarMasterVolume_Scroll); + // + // tabPageInput + // + this.tabPageInput.Controls.Add(this.comboBoxOpticalDrives); + this.tabPageInput.Controls.Add(this.labelOpticalDriveEject); + this.tabPageInput.Controls.Add(this.pictureBoxGreenStart); + this.tabPageInput.Controls.Add(this.labelStartFileName); + this.tabPageInput.Controls.Add(this.buttonSelectFile); + this.tabPageInput.Location = new System.Drawing.Point(4, 22); + this.tabPageInput.Name = "tabPageInput"; + this.tabPageInput.Padding = new System.Windows.Forms.Padding(3); + this.tabPageInput.Size = new System.Drawing.Size(752, 385); + this.tabPageInput.TabIndex = 6; + this.tabPageInput.Text = "Input"; + this.tabPageInput.UseVisualStyleBackColor = true; + // + // comboBoxOpticalDrives + // + this.comboBoxOpticalDrives.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.comboBoxOpticalDrives.FormattingEnabled = true; + this.comboBoxOpticalDrives.Location = new System.Drawing.Point(113, 53); + this.comboBoxOpticalDrives.Name = "comboBoxOpticalDrives"; + this.comboBoxOpticalDrives.Size = new System.Drawing.Size(55, 21); + this.comboBoxOpticalDrives.TabIndex = 18; + this.comboBoxOpticalDrives.SelectedIndexChanged += new System.EventHandler(this.comboBoxOpticalDrives_SelectedIndexChanged); + // + // labelOpticalDriveEject + // + this.labelOpticalDriveEject.AutoSize = true; + this.labelOpticalDriveEject.Location = new System.Drawing.Point(0, 56); + this.labelOpticalDriveEject.Name = "labelOpticalDriveEject"; + this.labelOpticalDriveEject.Size = new System.Drawing.Size(107, 13); + this.labelOpticalDriveEject.TabIndex = 3; + this.labelOpticalDriveEject.Text = "Optical drive to eject:"; + // + // pictureBoxGreenStart + // + this.pictureBoxGreenStart.Image = ((System.Drawing.Image)(resources.GetObject("pictureBoxGreenStart.Image"))); + this.pictureBoxGreenStart.Location = new System.Drawing.Point(3, 6); + this.pictureBoxGreenStart.Name = "pictureBoxGreenStart"; + this.pictureBoxGreenStart.Size = new System.Drawing.Size(32, 32); + this.pictureBoxGreenStart.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; + this.pictureBoxGreenStart.TabIndex = 2; + this.pictureBoxGreenStart.TabStop = false; + // + // labelStartFileName + // + this.labelStartFileName.AutoSize = true; + this.labelStartFileName.Location = new System.Drawing.Point(72, 16); + this.labelStartFileName.Name = "labelStartFileName"; + this.labelStartFileName.Size = new System.Drawing.Size(33, 13); + this.labelStartFileName.TabIndex = 1; + this.labelStartFileName.Text = "None"; + // + // buttonSelectFile + // + this.buttonSelectFile.Location = new System.Drawing.Point(41, 11); + this.buttonSelectFile.Name = "buttonSelectFile"; + this.buttonSelectFile.Size = new System.Drawing.Size(25, 23); + this.buttonSelectFile.TabIndex = 0; + this.buttonSelectFile.Text = "..."; + this.buttonSelectFile.UseVisualStyleBackColor = true; + this.buttonSelectFile.Click += new System.EventHandler(this.buttonSelectFile_Click); + // + // tabPageCec + // + this.tabPageCec.Controls.Add(this.groupBoxCecLogOptions); + this.tabPageCec.Controls.Add(this.checkBoxCecEnabled); + this.tabPageCec.Controls.Add(this.labelHdmiPort); + this.tabPageCec.Controls.Add(this.comboBoxHdmiPort); + this.tabPageCec.Location = new System.Drawing.Point(4, 22); + this.tabPageCec.Name = "tabPageCec"; + this.tabPageCec.Padding = new System.Windows.Forms.Padding(3); + this.tabPageCec.Size = new System.Drawing.Size(752, 385); + this.tabPageCec.TabIndex = 7; + this.tabPageCec.Text = "CEC"; + this.tabPageCec.UseVisualStyleBackColor = true; + // + // groupBoxCecLogOptions + // + this.groupBoxCecLogOptions.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.groupBoxCecLogOptions.Controls.Add(this.checkBoxCecLogNoPoll); + this.groupBoxCecLogOptions.Controls.Add(this.checkBoxCecLogTraffic); + this.groupBoxCecLogOptions.Controls.Add(this.checkBoxCecLogDebug); + this.groupBoxCecLogOptions.Controls.Add(this.checkBoxCecLogNotice); + this.groupBoxCecLogOptions.Controls.Add(this.checkBoxCecLogError); + this.groupBoxCecLogOptions.Controls.Add(this.checkBoxCecLogWarning); + this.groupBoxCecLogOptions.Location = new System.Drawing.Point(6, 239); + this.groupBoxCecLogOptions.Name = "groupBoxCecLogOptions"; + this.groupBoxCecLogOptions.Size = new System.Drawing.Size(165, 140); + this.groupBoxCecLogOptions.TabIndex = 25; + this.groupBoxCecLogOptions.TabStop = false; + this.groupBoxCecLogOptions.Text = "Log options"; + // + // checkBoxCecLogNoPoll + // + this.checkBoxCecLogNoPoll.AutoSize = true; + this.checkBoxCecLogNoPoll.Checked = true; + this.checkBoxCecLogNoPoll.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBoxCecLogNoPoll.Location = new System.Drawing.Point(76, 24); + this.checkBoxCecLogNoPoll.Name = "checkBoxCecLogNoPoll"; + this.checkBoxCecLogNoPoll.Size = new System.Drawing.Size(59, 17); + this.checkBoxCecLogNoPoll.TabIndex = 30; + this.checkBoxCecLogNoPoll.Text = "No poll"; + this.checkBoxCecLogNoPoll.UseVisualStyleBackColor = true; + this.checkBoxCecLogNoPoll.CheckedChanged += new System.EventHandler(this.checkBoxCecLogs_CheckedChanged); + // + // checkBoxCecLogTraffic + // + this.checkBoxCecLogTraffic.AutoSize = true; + this.checkBoxCecLogTraffic.Location = new System.Drawing.Point(6, 93); + this.checkBoxCecLogTraffic.Name = "checkBoxCecLogTraffic"; + this.checkBoxCecLogTraffic.Size = new System.Drawing.Size(56, 17); + this.checkBoxCecLogTraffic.TabIndex = 29; + this.checkBoxCecLogTraffic.Text = "Traffic"; + this.checkBoxCecLogTraffic.UseVisualStyleBackColor = true; + this.checkBoxCecLogTraffic.CheckedChanged += new System.EventHandler(this.checkBoxCecLogs_CheckedChanged); + // + // checkBoxCecLogDebug + // + this.checkBoxCecLogDebug.AutoSize = true; + this.checkBoxCecLogDebug.Location = new System.Drawing.Point(6, 116); + this.checkBoxCecLogDebug.Name = "checkBoxCecLogDebug"; + this.checkBoxCecLogDebug.Size = new System.Drawing.Size(58, 17); + this.checkBoxCecLogDebug.TabIndex = 28; + this.checkBoxCecLogDebug.Text = "Debug"; + this.checkBoxCecLogDebug.UseVisualStyleBackColor = true; + this.checkBoxCecLogDebug.CheckedChanged += new System.EventHandler(this.checkBoxCecLogs_CheckedChanged); + // + // checkBoxCecLogNotice + // + this.checkBoxCecLogNotice.AutoSize = true; + this.checkBoxCecLogNotice.Checked = true; + this.checkBoxCecLogNotice.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBoxCecLogNotice.Location = new System.Drawing.Point(6, 70); + this.checkBoxCecLogNotice.Name = "checkBoxCecLogNotice"; + this.checkBoxCecLogNotice.Size = new System.Drawing.Size(57, 17); + this.checkBoxCecLogNotice.TabIndex = 27; + this.checkBoxCecLogNotice.Text = "Notice"; + this.checkBoxCecLogNotice.UseVisualStyleBackColor = true; + this.checkBoxCecLogNotice.CheckedChanged += new System.EventHandler(this.checkBoxCecLogs_CheckedChanged); + // + // checkBoxCecLogError + // + this.checkBoxCecLogError.AutoSize = true; + this.checkBoxCecLogError.Checked = true; + this.checkBoxCecLogError.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBoxCecLogError.Location = new System.Drawing.Point(6, 24); + this.checkBoxCecLogError.Name = "checkBoxCecLogError"; + this.checkBoxCecLogError.Size = new System.Drawing.Size(48, 17); + this.checkBoxCecLogError.TabIndex = 26; + this.checkBoxCecLogError.Text = "Error"; + this.checkBoxCecLogError.UseVisualStyleBackColor = true; + this.checkBoxCecLogError.CheckedChanged += new System.EventHandler(this.checkBoxCecLogs_CheckedChanged); + // + // checkBoxCecLogWarning + // + this.checkBoxCecLogWarning.AutoSize = true; + this.checkBoxCecLogWarning.Checked = true; + this.checkBoxCecLogWarning.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBoxCecLogWarning.Location = new System.Drawing.Point(6, 47); + this.checkBoxCecLogWarning.Name = "checkBoxCecLogWarning"; + this.checkBoxCecLogWarning.Size = new System.Drawing.Size(66, 17); + this.checkBoxCecLogWarning.TabIndex = 25; + this.checkBoxCecLogWarning.Text = "Warning"; + this.checkBoxCecLogWarning.UseVisualStyleBackColor = true; + this.checkBoxCecLogWarning.CheckedChanged += new System.EventHandler(this.checkBoxCecLogs_CheckedChanged); + // + // checkBoxCecEnabled + // + this.checkBoxCecEnabled.AutoSize = true; + this.checkBoxCecEnabled.Location = new System.Drawing.Point(6, 6); + this.checkBoxCecEnabled.Name = "checkBoxCecEnabled"; + this.checkBoxCecEnabled.Size = new System.Drawing.Size(83, 17); + this.checkBoxCecEnabled.TabIndex = 21; + this.checkBoxCecEnabled.Text = "Enable CEC"; + this.checkBoxCecEnabled.UseVisualStyleBackColor = true; + this.checkBoxCecEnabled.CheckedChanged += new System.EventHandler(this.checkBoxCecEnabled_CheckedChanged); + // + // labelHdmiPort + // + this.labelHdmiPort.AutoSize = true; + this.labelHdmiPort.Location = new System.Drawing.Point(3, 26); + this.labelHdmiPort.Name = "labelHdmiPort"; + this.labelHdmiPort.Size = new System.Drawing.Size(182, 13); + this.labelHdmiPort.TabIndex = 20; + this.labelHdmiPort.Text = "TV HDMI port connected to your PC:"; + // + // comboBoxHdmiPort + // + this.comboBoxHdmiPort.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.comboBoxHdmiPort.FormattingEnabled = true; + this.comboBoxHdmiPort.Items.AddRange(new object[] { + "HDMI 1", + "HDMI 2", + "HDMI 3", + "HDMI 4", + "HDMI 5", + "HDMI 6", + "HDMI 7", + "HDMI 8", + "HDMI 9"}); + this.comboBoxHdmiPort.Location = new System.Drawing.Point(6, 42); + this.comboBoxHdmiPort.Name = "comboBoxHdmiPort"; + this.comboBoxHdmiPort.Size = new System.Drawing.Size(87, 21); + this.comboBoxHdmiPort.TabIndex = 19; + this.comboBoxHdmiPort.SelectedIndexChanged += new System.EventHandler(this.comboBoxHdmiPort_SelectedIndexChanged); + // + // tabPageEvent + // + this.tabPageEvent.Controls.Add(this.buttonActionMoveUp); + this.tabPageEvent.Controls.Add(this.buttonActionMoveDown); + this.tabPageEvent.Controls.Add(this.buttonTestAction); + this.tabPageEvent.Controls.Add(this.buttonDeleteAction); + this.tabPageEvent.Controls.Add(this.buttonAddAction); + this.tabPageEvent.Controls.Add(this.iTreeViewEvents); + this.tabPageEvent.Location = new System.Drawing.Point(4, 22); + this.tabPageEvent.Name = "tabPageEvent"; + this.tabPageEvent.Padding = new System.Windows.Forms.Padding(3); + this.tabPageEvent.Size = new System.Drawing.Size(752, 385); + this.tabPageEvent.TabIndex = 9; + this.tabPageEvent.Text = "Events"; + this.tabPageEvent.UseVisualStyleBackColor = true; + // + // buttonActionMoveUp + // + this.buttonActionMoveUp.Enabled = false; + this.buttonActionMoveUp.Location = new System.Drawing.Point(6, 327); + this.buttonActionMoveUp.Name = "buttonActionMoveUp"; + this.buttonActionMoveUp.Size = new System.Drawing.Size(96, 23); + this.buttonActionMoveUp.TabIndex = 24; + this.buttonActionMoveUp.Text = "Move Up"; + this.buttonActionMoveUp.UseVisualStyleBackColor = true; + this.buttonActionMoveUp.Click += new System.EventHandler(this.buttonActionMoveUp_Click); + // + // buttonActionMoveDown + // + this.buttonActionMoveDown.Enabled = false; + this.buttonActionMoveDown.Location = new System.Drawing.Point(6, 356); + this.buttonActionMoveDown.Name = "buttonActionMoveDown"; + this.buttonActionMoveDown.Size = new System.Drawing.Size(96, 23); + this.buttonActionMoveDown.TabIndex = 23; + this.buttonActionMoveDown.Text = "Move Down"; + this.buttonActionMoveDown.UseVisualStyleBackColor = true; + this.buttonActionMoveDown.Click += new System.EventHandler(this.buttonActionMoveDown_Click); + // + // buttonTestAction + // + this.buttonTestAction.Enabled = false; + this.buttonTestAction.Location = new System.Drawing.Point(6, 64); + this.buttonTestAction.Name = "buttonTestAction"; + this.buttonTestAction.Size = new System.Drawing.Size(96, 23); + this.buttonTestAction.TabIndex = 22; + this.buttonTestAction.Text = "Test Action"; + this.buttonTestAction.UseVisualStyleBackColor = true; + this.buttonTestAction.Click += new System.EventHandler(this.buttonTestAction_Click); + // + // buttonDeleteAction + // + this.buttonDeleteAction.Enabled = false; + this.buttonDeleteAction.Location = new System.Drawing.Point(6, 35); + this.buttonDeleteAction.Name = "buttonDeleteAction"; + this.buttonDeleteAction.Size = new System.Drawing.Size(96, 23); + this.buttonDeleteAction.TabIndex = 21; + this.buttonDeleteAction.Text = "Delete Action"; + this.buttonDeleteAction.UseVisualStyleBackColor = true; + this.buttonDeleteAction.Click += new System.EventHandler(this.buttonDeleteAction_Click); + // + // buttonAddAction + // + this.buttonAddAction.Enabled = false; + this.buttonAddAction.Location = new System.Drawing.Point(6, 6); + this.buttonAddAction.Name = "buttonAddAction"; + this.buttonAddAction.Size = new System.Drawing.Size(96, 23); + this.buttonAddAction.TabIndex = 20; + this.buttonAddAction.Text = "Add Action"; + this.buttonAddAction.UseVisualStyleBackColor = true; + this.buttonAddAction.Click += new System.EventHandler(this.buttonAddAction_Click); + // + // iTreeViewEvents + // + this.iTreeViewEvents.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.iTreeViewEvents.HideSelection = false; + this.iTreeViewEvents.Location = new System.Drawing.Point(111, 3); + this.iTreeViewEvents.Name = "iTreeViewEvents"; + this.iTreeViewEvents.Size = new System.Drawing.Size(638, 376); + this.iTreeViewEvents.TabIndex = 1; + this.iTreeViewEvents.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.iTreeViewEvents_AfterSelect); + // + // tabPageApp + // + this.tabPageApp.Controls.Add(this.checkBoxStartMinimized); + this.tabPageApp.Controls.Add(this.checkBoxMinimizeToTray); + this.tabPageApp.Controls.Add(this.checkBoxAutoStart); + this.tabPageApp.Controls.Add(this.buttonUpdate); + this.tabPageApp.Location = new System.Drawing.Point(4, 22); + this.tabPageApp.Name = "tabPageApp"; + this.tabPageApp.Padding = new System.Windows.Forms.Padding(3); + this.tabPageApp.Size = new System.Drawing.Size(752, 385); + this.tabPageApp.TabIndex = 4; + this.tabPageApp.Text = "Application"; + this.tabPageApp.UseVisualStyleBackColor = true; + // + // checkBoxStartMinimized + // + this.checkBoxStartMinimized.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.checkBoxStartMinimized.AutoSize = true; + this.checkBoxStartMinimized.Location = new System.Drawing.Point(6, 285); + this.checkBoxStartMinimized.Name = "checkBoxStartMinimized"; + this.checkBoxStartMinimized.Size = new System.Drawing.Size(96, 17); + this.checkBoxStartMinimized.TabIndex = 16; + this.checkBoxStartMinimized.Text = "Start minimized"; + this.checkBoxStartMinimized.UseVisualStyleBackColor = true; + this.checkBoxStartMinimized.CheckedChanged += new System.EventHandler(this.checkBoxStartMinimized_CheckedChanged); + // + // checkBoxMinimizeToTray + // + this.checkBoxMinimizeToTray.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.checkBoxMinimizeToTray.AutoSize = true; + this.checkBoxMinimizeToTray.Location = new System.Drawing.Point(6, 308); + this.checkBoxMinimizeToTray.Name = "checkBoxMinimizeToTray"; + this.checkBoxMinimizeToTray.Size = new System.Drawing.Size(133, 17); + this.checkBoxMinimizeToTray.TabIndex = 15; + this.checkBoxMinimizeToTray.Text = "Minimize to system tray"; + this.checkBoxMinimizeToTray.UseVisualStyleBackColor = true; + this.checkBoxMinimizeToTray.CheckedChanged += new System.EventHandler(this.checkBoxMinimizeToTray_CheckedChanged); + // + // checkBoxAutoStart + // + this.checkBoxAutoStart.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.checkBoxAutoStart.AutoSize = true; + this.checkBoxAutoStart.Location = new System.Drawing.Point(6, 331); + this.checkBoxAutoStart.Name = "checkBoxAutoStart"; + this.checkBoxAutoStart.Size = new System.Drawing.Size(143, 17); + this.checkBoxAutoStart.TabIndex = 14; + this.checkBoxAutoStart.Text = "Run on Windows startup"; + this.checkBoxAutoStart.UseVisualStyleBackColor = true; + this.checkBoxAutoStart.CheckedChanged += new System.EventHandler(this.checkBoxAutoStart_CheckedChanged); + // + // buttonUpdate + // + this.buttonUpdate.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.buttonUpdate.Location = new System.Drawing.Point(6, 354); + this.buttonUpdate.Name = "buttonUpdate"; + this.buttonUpdate.Size = new System.Drawing.Size(75, 23); + this.buttonUpdate.TabIndex = 0; + this.buttonUpdate.Text = "Update"; + this.buttonUpdate.UseVisualStyleBackColor = true; + this.buttonUpdate.Click += new System.EventHandler(this.buttonUpdate_Click); + // + // tabPageLogs + // + this.tabPageLogs.Controls.Add(this.buttonClearLogs); + this.tabPageLogs.Controls.Add(this.richTextBoxLogs); + this.tabPageLogs.Location = new System.Drawing.Point(4, 22); + this.tabPageLogs.Name = "tabPageLogs"; + this.tabPageLogs.Padding = new System.Windows.Forms.Padding(3); + this.tabPageLogs.Size = new System.Drawing.Size(752, 385); + this.tabPageLogs.TabIndex = 8; + this.tabPageLogs.Text = "Logs"; + this.tabPageLogs.UseVisualStyleBackColor = true; + // + // buttonClearLogs + // + this.buttonClearLogs.Location = new System.Drawing.Point(671, 6); + this.buttonClearLogs.Name = "buttonClearLogs"; + this.buttonClearLogs.Size = new System.Drawing.Size(75, 23); + this.buttonClearLogs.TabIndex = 2; + this.buttonClearLogs.Text = "Clear"; + this.buttonClearLogs.UseVisualStyleBackColor = true; + this.buttonClearLogs.Click += new System.EventHandler(this.buttonClearLogs_Click); + // + // richTextBoxLogs + // + this.richTextBoxLogs.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.richTextBoxLogs.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.richTextBoxLogs.DetectUrls = false; + this.richTextBoxLogs.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.richTextBoxLogs.Location = new System.Drawing.Point(6, 6); + this.richTextBoxLogs.Name = "richTextBoxLogs"; + this.richTextBoxLogs.ReadOnly = true; + this.richTextBoxLogs.Size = new System.Drawing.Size(740, 373); + this.richTextBoxLogs.TabIndex = 1; + this.richTextBoxLogs.Text = ""; + this.richTextBoxLogs.WordWrap = false; + // + // labelFontWidth + // + this.labelFontWidth.AutoSize = true; + this.labelFontWidth.Location = new System.Drawing.Point(13, 29); + this.labelFontWidth.Name = "labelFontWidth"; + this.labelFontWidth.Size = new System.Drawing.Size(56, 13); + this.labelFontWidth.TabIndex = 19; + this.labelFontWidth.Text = "Font width"; + // + // labelFontHeight + // + this.labelFontHeight.AutoSize = true; + this.labelFontHeight.Location = new System.Drawing.Point(13, 46); + this.labelFontHeight.Name = "labelFontHeight"; + this.labelFontHeight.Size = new System.Drawing.Size(60, 13); + this.labelFontHeight.TabIndex = 20; + this.labelFontHeight.Text = "Font height"; + // + // openFileDialog + // + this.openFileDialog.Filter = "EXE files (*.exe)|*.exe|All files (*.*)|*.*"; + // + // FormMain + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(784, 561); + this.Controls.Add(this.labelFontHeight); + this.Controls.Add(this.labelFontWidth); + this.Controls.Add(this.labelWarning); + this.Controls.Add(this.statusStrip); + this.Controls.Add(this.tabControl); + this.Controls.Add(this.panelDisplay); + this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); + this.MinimumSize = new System.Drawing.Size(800, 600); + this.Name = "FormMain"; + this.Text = "Sharp Display Manager"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing); + this.Load += new System.EventHandler(this.MainForm_Load); + this.SizeChanged += new System.EventHandler(this.MainForm_SizeChanged); + this.Resize += new System.EventHandler(this.MainForm_Resize); + this.panelDisplay.ResumeLayout(false); + this.iTableLayoutPanel.ResumeLayout(false); + this.iTableLayoutPanel.PerformLayout(); + this.statusStrip.ResumeLayout(false); + this.statusStrip.PerformLayout(); + this.tabPageClients.ResumeLayout(false); + this.tabPageClients.PerformLayout(); + this.tabPageDisplay.ResumeLayout(false); + this.tabPageDisplay.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.trackBarBrightness)).EndInit(); + this.tabControl.ResumeLayout(false); + this.tabPageDesign.ResumeLayout(false); + this.tabPageDesign.PerformLayout(); + this.tabPageAudio.ResumeLayout(false); + this.tabPageAudio.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.trackBarMasterVolume)).EndInit(); + this.tabPageInput.ResumeLayout(false); + this.tabPageInput.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBoxGreenStart)).EndInit(); + this.tabPageCec.ResumeLayout(false); + this.tabPageCec.PerformLayout(); + this.groupBoxCecLogOptions.ResumeLayout(false); + this.groupBoxCecLogOptions.PerformLayout(); + this.tabPageEvent.ResumeLayout(false); + this.tabPageApp.ResumeLayout(false); + this.tabPageApp.PerformLayout(); + this.tabPageLogs.ResumeLayout(false); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.FontDialog fontDialog; + private System.Windows.Forms.Timer timer; + private System.Windows.Forms.StatusStrip statusStrip; + private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabelConnect; + private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabelFps; + private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabelSpring; + private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabelPower; + private System.Windows.Forms.Panel panelDisplay; + private System.Windows.Forms.TableLayoutPanel iTableLayoutPanel; + private MarqueeLabel marqueeLabelTop; + private MarqueeLabel marqueeLabelBottom; + private System.Windows.Forms.TabPage tabPageClients; + private System.Windows.Forms.TreeView iTreeViewClients; + private System.Windows.Forms.TabPage tabPageDisplay; + private System.Windows.Forms.CheckBox checkBoxFixedPitchFontOnly; + private System.Windows.Forms.Button buttonSuspend; + private System.Windows.Forms.CheckBox checkBoxConnectOnStartup; + private System.Windows.Forms.CheckBox checkBoxShowBorders; + private System.Windows.Forms.TrackBar trackBarBrightness; + private System.Windows.Forms.Button buttonFill; + private System.Windows.Forms.Button buttonClear; + private System.Windows.Forms.Button buttonClose; + private System.Windows.Forms.Button buttonOpen; + private System.Windows.Forms.Button buttonCapture; + private System.Windows.Forms.Button buttonFont; + private System.Windows.Forms.TabControl tabControl; + private System.Windows.Forms.Button buttonCloseClients; + private System.Windows.Forms.Button buttonStartClient; + private System.Windows.Forms.Label labelWarning; + private System.Windows.Forms.TabPage tabPageDesign; + private System.Windows.Forms.CheckBox checkBoxReverseScreen; + private System.Windows.Forms.ComboBox comboBoxDisplayType; + private System.Windows.Forms.MaskedTextBox maskedTextBoxTimerInterval; + private System.Windows.Forms.Label labelTimerInterval; + private System.Windows.Forms.Button buttonPowerOff; + private System.Windows.Forms.Button buttonPowerOn; + private System.Windows.Forms.Button buttonShowClock; + private System.Windows.Forms.Button buttonHideClock; + private System.Windows.Forms.Label labelFontWidth; + private System.Windows.Forms.Label labelFontHeight; + private System.Windows.Forms.CheckBox checkBoxInverseColors; + private System.Windows.Forms.TabPage tabPageApp; + private System.Windows.Forms.Button buttonUpdate; + private System.Windows.Forms.CheckBox checkBoxAutoStart; + private System.Windows.Forms.CheckBox checkBoxStartMinimized; + private System.Windows.Forms.CheckBox checkBoxMinimizeToTray; + private System.Windows.Forms.MaskedTextBox maskedTextBoxMinFontSize; + private System.Windows.Forms.CheckBox checkBoxScaleToFit; + private System.Windows.Forms.Label labelMinFontSize; + private System.Windows.Forms.Label labelScrollLoopSeparator; + private System.Windows.Forms.TextBox textBoxScrollLoopSeparator; + private System.Windows.Forms.Label labelScrollingSpeed; + private System.Windows.Forms.MaskedTextBox maskedTextBoxScrollingSpeed; + private System.Windows.Forms.ToolTip toolTip; + private System.Windows.Forms.TabPage tabPageAudio; + private System.Windows.Forms.TrackBar trackBarMasterVolume; + private System.Windows.Forms.CheckBox checkBoxMute; + private System.Windows.Forms.CheckBox checkBoxShowVolumeLabel; + private System.Windows.Forms.Label labelDefaultAudioDevice; + private System.Windows.Forms.TabPage tabPageInput; + private System.Windows.Forms.Button buttonSelectFile; + private System.Windows.Forms.OpenFileDialog openFileDialog; + private System.Windows.Forms.Label labelStartFileName; + private System.Windows.Forms.PictureBox pictureBoxGreenStart; + private System.Windows.Forms.ComboBox comboBoxOpticalDrives; + private System.Windows.Forms.Label labelOpticalDriveEject; + private System.Windows.Forms.TabPage tabPageCec; + private System.Windows.Forms.CheckBox checkBoxCecEnabled; + private System.Windows.Forms.Label labelHdmiPort; + private System.Windows.Forms.ComboBox comboBoxHdmiPort; + private System.Windows.Forms.Button iButtonStartIdleClient; + private System.Windows.Forms.CheckBox iCheckBoxStartIdleClient; + private System.Windows.Forms.TabPage tabPageLogs; + private System.Windows.Forms.RichTextBox richTextBoxLogs; + private System.Windows.Forms.Button buttonClearLogs; + private System.Windows.Forms.GroupBox groupBoxCecLogOptions; + private System.Windows.Forms.CheckBox checkBoxCecLogWarning; + private System.Windows.Forms.CheckBox checkBoxCecLogError; + private System.Windows.Forms.CheckBox checkBoxCecLogDebug; + private System.Windows.Forms.CheckBox checkBoxCecLogNotice; + private System.Windows.Forms.CheckBox checkBoxCecLogTraffic; + private System.Windows.Forms.CheckBox checkBoxCecLogNoPoll; + private System.Windows.Forms.TabPage tabPageEvent; + private System.Windows.Forms.TreeView iTreeViewEvents; + private System.Windows.Forms.Button buttonDeleteAction; + private System.Windows.Forms.Button buttonAddAction; + private System.Windows.Forms.Button buttonActionMoveUp; + private System.Windows.Forms.Button buttonActionMoveDown; + private System.Windows.Forms.Button buttonTestAction; + } +} + diff -r 6ccaa430aa23 -r 91763ba41c0c Server/FormMain.Hid.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Server/FormMain.Hid.cs Fri Jul 29 10:40:15 2016 +0200 @@ -0,0 +1,425 @@ +using System; +using System.IO; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Windows.Forms; +using Microsoft.Win32.SafeHandles; +using System.ComponentModel; +// +using Hid = SharpLib.Hid; +using SharpLib.Win32; + +namespace SharpDisplayManager +{ + /// + /// Implement handling of HID input reports notably to be able to launch an application using the Green Start button from IR remotes. + /// + [System.ComponentModel.DesignerCategory("Code")] + public class FormMainHid : Form + { + [System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "SwitchToThisWindow")] + public static extern void SwitchToThisWindow([System.Runtime.InteropServices.InAttribute()] System.IntPtr hwnd, [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)] bool fUnknown); + // + public delegate void OnHidEventDelegate(object aSender, Hid.Event aHidEvent); + + /// + /// Use notably to handle green start key from IR remote control + /// + private Hid.Handler iHidHandler; + + /// + /// Register HID devices so that we receive corresponding WM_INPUT messages. + /// + protected void RegisterHidDevices() + { + // Register the input device to receive the commands from the + // remote device. See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwmt/html/remote_control.asp + // for the vendor defined usage page. + + RAWINPUTDEVICE[] rid = new RAWINPUTDEVICE[5]; + + int i = 0; + rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.WindowsMediaCenterRemoteControl; + rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.WindowsMediaCenter.WindowsMediaCenterRemoteControl; + rid[i].dwFlags = Const.RIDEV_INPUTSINK; + rid[i].hwndTarget = Handle; + + i++; + rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.Consumer; + rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.Consumer.ConsumerControl; + rid[i].dwFlags = Const.RIDEV_INPUTSINK; + rid[i].hwndTarget = Handle; + + i++; + rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.Consumer; + rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.Consumer.Selection; + rid[i].dwFlags = Const.RIDEV_INPUTSINK; + rid[i].hwndTarget = Handle; + + i++; + rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.GenericDesktopControls; + rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.GenericDesktop.SystemControl; + rid[i].dwFlags = Const.RIDEV_INPUTSINK; + rid[i].hwndTarget = Handle; + + i++; + rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.GenericDesktopControls; + rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.GenericDesktop.GamePad; + rid[i].dwFlags = Const.RIDEV_INPUTSINK; + rid[i].hwndTarget = Handle; + + //i++; + //rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.GenericDesktopControls; + //rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.GenericDesktop.Keyboard; + //rid[i].dwFlags = Const.RIDEV_EXINPUTSINK; + //rid[i].hwndTarget = Handle; + + //i++; + //rid[i].usUsagePage = (ushort)Hid.UsagePage.GenericDesktopControls; + //rid[i].usUsage = (ushort)Hid.UsageCollection.GenericDesktop.Mouse; + //rid[i].dwFlags = Const.RIDEV_EXINPUTSINK; + //rid[i].hwndTarget = aHWND; + + + iHidHandler = new SharpLib.Hid.Handler(rid); + if (!iHidHandler.IsRegistered) + { + Debug.WriteLine("Failed to register raw input devices: " + Marshal.GetLastWin32Error().ToString()); + } + iHidHandler.OnHidEvent += HandleHidEventThreadSafe; + + } + + + + + /// + /// Here we receive HID events from our HID library. + /// + /// + /// + public void HandleHidEventThreadSafe(object aSender, SharpLib.Hid.Event aHidEvent) + { + if (aHidEvent.IsStray) + { + //Stray event just ignore it + return; + } + + if (this.InvokeRequired) + { + //Not in the proper thread, invoke ourselves + OnHidEventDelegate d = new OnHidEventDelegate(HandleHidEventThreadSafe); + this.Invoke(d, new object[] { aSender, aHidEvent }); + } + else + { + if (aHidEvent.Usages.Count == 0) + { + //No usage, nothing to do then + return; + } + + //We are in the proper thread + if (aHidEvent.UsagePage == (ushort) Hid.UsagePage.WindowsMediaCenterRemoteControl) + { + switch (aHidEvent.Usages[0]) + { + case (ushort)Hid.Usage.WindowsMediaCenterRemoteControl.GreenStart: + HandleGreenStart(); + break; + case (ushort)Hid.Usage.WindowsMediaCenterRemoteControl.Eject: + case (ushort)Hid.Usage.WindowsMediaCenterRemoteControl.Ext2: + HandleEject(); + break; + } + } + + //Keep this for debug when only ThinkPad keyboard is available + if (aHidEvent.UsagePage == (ushort)Hid.UsagePage.Consumer && aHidEvent.Usages[0] == (ushort)Hid.Usage.ConsumerControl.ThinkPadFullscreenMagnifier) + { + HandleEject(); + } + + } + } + + /// + /// + /// + /// + private void CheckLastError(string aPrefix) + { + string errorMessage = new Win32Exception(Marshal.GetLastWin32Error()).Message; + Debug.WriteLine(aPrefix + Marshal.GetLastWin32Error().ToString() + ": " + errorMessage); + } + + /// + /// + /// + /// + /// + private IntPtr MarshalToPointer(object data) + { + IntPtr buf = Marshal.AllocHGlobal( + Marshal.SizeOf(data)); + Marshal.StructureToPtr(data, + buf, false); + return buf; + } + + /// + /// + /// + /// + private SafeFileHandle OpenVolume(string aDriveName) + { + return Function.CreateFile("\\\\.\\" + aDriveName, + SharpLib.Win32.FileAccess.GENERIC_READ, + SharpLib.Win32.FileShare.FILE_SHARE_READ | SharpLib.Win32.FileShare.FILE_SHARE_WRITE, + IntPtr.Zero, + CreationDisposition.OPEN_EXISTING, + 0, + IntPtr.Zero); + } + + /// + /// + /// + /// + /// + private bool LockVolume(SafeFileHandle aVolume) + { + //Hope that's doing what I think it does + IntPtr dwBytesReturned=new IntPtr(); + //Should not be needed but I'm not sure how to pass NULL in there. + OVERLAPPED overlapped=new OVERLAPPED(); + + int tries = 0; + const int KMaxTries = 100; + const int KSleepTime = 10; + bool success = false; + + while (!success && tries < KMaxTries) + { + success = Function.DeviceIoControl(aVolume, Const.FSCTL_LOCK_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, dwBytesReturned, ref overlapped); + System.Threading.Thread.Sleep(KSleepTime); + tries++; + } + + CheckLastError("Lock volume: "); + + return success; + } + + /// + /// + /// + /// + /// + private bool DismountVolume(SafeFileHandle aVolume) + { + //Hope that's doing what I think it does + IntPtr dwBytesReturned = new IntPtr(); + //Should not be needed but I'm not sure how to pass NULL in there. + OVERLAPPED overlapped=new OVERLAPPED(); + + bool res = Function.DeviceIoControl(aVolume, Const.FSCTL_DISMOUNT_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, dwBytesReturned, ref overlapped); + CheckLastError("Dismount volume: "); + return res; + } + + + + /// + /// + /// + /// + /// + /// + private bool PreventRemovalOfVolume(SafeFileHandle aVolume, bool aPreventRemoval) + { + //Hope that's doing what I think it does + IntPtr dwBytesReturned = new IntPtr(); + //Should not be needed but I'm not sure how to pass NULL in there. + OVERLAPPED overlapped = new OVERLAPPED(); + // + PREVENT_MEDIA_REMOVAL preventMediaRemoval = new PREVENT_MEDIA_REMOVAL(); + preventMediaRemoval.PreventMediaRemoval = Convert.ToByte(aPreventRemoval); + IntPtr preventMediaRemovalParam = MarshalToPointer(preventMediaRemoval); + + bool result = Function.DeviceIoControl(aVolume, Const.IOCTL_STORAGE_MEDIA_REMOVAL, preventMediaRemovalParam, Convert.ToUInt32(Marshal.SizeOf(preventMediaRemoval)), IntPtr.Zero, 0, dwBytesReturned, ref overlapped); + CheckLastError("Media removal: "); + Marshal.FreeHGlobal(preventMediaRemovalParam); + + return result; + } + + /// + /// Eject optical drive media opening the tray if any. + /// + /// + /// + private bool MediaEject(SafeFileHandle aVolume) + { + //Hope that's doing what I think it does + IntPtr dwBytesReturned = new IntPtr(); + //Should not be needed but I'm not sure how to pass NULL in there. + OVERLAPPED overlapped=new OVERLAPPED(); + + bool res = Function.DeviceIoControl(aVolume, Const.IOCTL_STORAGE_EJECT_MEDIA, IntPtr.Zero, 0, IntPtr.Zero, 0, dwBytesReturned, ref overlapped); + CheckLastError("Media eject: "); + return res; + } + + /// + /// Close an optical drive tray. + /// + /// + /// + private bool MediaLoad(SafeFileHandle aVolume) + { + //Hope that's doing what I think it does + IntPtr dwBytesReturned = new IntPtr(); + //Should not be needed but I'm not sure how to pass NULL in there. + OVERLAPPED overlapped=new OVERLAPPED(); + + bool res = Function.DeviceIoControl(aVolume, Const.IOCTL_STORAGE_LOAD_MEDIA, IntPtr.Zero, 0, IntPtr.Zero, 0, dwBytesReturned, ref overlapped); + CheckLastError("Media load: "); + return res; + } + + /// + /// + /// + /// + /// + private bool StorageCheckVerify(SafeFileHandle aVolume) + { + //Hope that's doing what I think it does + IntPtr dwBytesReturned = new IntPtr(); + //Should not be needed but I'm not sure how to pass NULL in there. + OVERLAPPED overlapped = new OVERLAPPED(); + + bool res = Function.DeviceIoControl(aVolume, Const.IOCTL_STORAGE_CHECK_VERIFY2, IntPtr.Zero, 0, IntPtr.Zero, 0, dwBytesReturned, ref overlapped); + + CheckLastError("Check verify: "); + + return res; + } + + + + /// + /// Perform media ejection. + /// + private void HandleEject() + { + string drive = ((FormMain)this).OpticalDriveToEject(); + if (drive.Length!=2) + { + //Not a proper drive spec. + //Probably 'None' selected. + return; + } + + SafeFileHandle handle = OpenVolume(drive); + if (handle.IsInvalid) + { + CheckLastError("ERROR: Failed to open volume: "); + return; + } + + if (LockVolume(handle) && DismountVolume(handle)) + { + Debug.WriteLine("Volume was dismounted."); + + if (PreventRemovalOfVolume(handle,false)) + { + //StorageCheckVerify(handle); + + DateTime before; + before = DateTime.Now; + bool ejectSuccess = MediaEject(handle); + double ms = (DateTime.Now - before).TotalMilliseconds; + + //We assume that if it take more than a certain time to for eject to execute it means we actually ejected. + //If our eject completes too rapidly we assume the tray is already open and we will try to close it. + if (ejectSuccess && ms > 100) + { + Debug.WriteLine("Media was ejected"); + } + else if (MediaLoad(handle)) + { + Debug.WriteLine("Media was loaded"); + } + } + } + else + { + Debug.WriteLine("Volume lock or dismount failed."); + } + + //This is needed to make sure we can open the volume next time around + handle.Dispose(); + } + + /// + /// + /// + private void HandleGreenStart() + { + //First check if the process we want to launch already exists + string procName = Path.GetFileNameWithoutExtension(Properties.Settings.Default.StartFileName); + Process[] existingProcesses = Process.GetProcessesByName(procName); + if (existingProcesses == null || existingProcesses.Length == 0) + { + // Process do not exists just try to launch it + ProcessStartInfo start = new ProcessStartInfo(); + // Enter in the command line arguments, everything you would enter after the executable name itself + //start.Arguments = arguments; + // Enter the executable to run, including the complete path + start.FileName = Properties.Settings.Default.StartFileName; + start.WindowStyle = ProcessWindowStyle.Normal; + start.CreateNoWindow = true; + start.UseShellExecute = true; + // Run the external process & wait for it to finish + Process proc = Process.Start(start); + + //SL: We could have used that too + //Shell32.Shell shell = new Shell32.Shell(); + //shell.ShellExecute(Properties.Settings.Default.StartFileName); + } + else + { + //This won't work properly until we have a manifest that enables uiAccess. + //However uiAccess just won't work with ClickOnce so we will have to use a different deployment system. + SwitchToThisWindow(existingProcesses[0].MainWindowHandle, true); + } + } + + + /// + /// We need to handle WM_INPUT. + /// + /// + protected override void WndProc(ref Message message) + { + switch (message.Msg) + { + case Const.WM_INPUT: + //Returning zero means we processed that message. + message.Result = new IntPtr(0); + iHidHandler.ProcessInput(ref message); + break; + } + + //Pass this on to base class. + base.WndProc(ref message); + } + } +} diff -r 6ccaa430aa23 -r 91763ba41c0c Server/FormMain.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Server/FormMain.cs Fri Jul 29 10:40:15 2016 +0200 @@ -0,0 +1,2922 @@ +// +// Copyright (C) 2014-2015 Stéphane Lenclud. +// +// This file is part of SharpDisplayManager. +// +// SharpDisplayManager is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// SharpDisplayManager is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with SharpDisplayManager. If not, see . +// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using System.IO; +using CodeProject.Dialog; +using System.Drawing.Imaging; +using System.ServiceModel; +using System.Threading; +using System.Diagnostics; +using System.Deployment.Application; +using System.Reflection; +//NAudio +using NAudio.CoreAudioApi; +using NAudio.CoreAudioApi.Interfaces; +using System.Runtime.InteropServices; +using CecSharp; +//Network +using NETWORKLIST; +// +using SharpDisplayClient; +using SharpDisplay; +using MiniDisplayInterop; +using SharpLib.Display; +using SharpLib.Ear; + +namespace SharpDisplayManager +{ + //Types declarations + public delegate uint ColorProcessingDelegate(int aX, int aY, uint aPixel); + + public delegate int CoordinateTranslationDelegate(System.Drawing.Bitmap aBmp, int aInt); + + //Delegates are used for our thread safe method + public delegate void AddClientDelegate(string aSessionId, ICallback aCallback); + + public delegate void RemoveClientDelegate(string aSessionId); + + public delegate void SetFieldDelegate(string SessionId, DataField aField); + + public delegate void SetFieldsDelegate(string SessionId, System.Collections.Generic.IList aFields); + + public delegate void SetLayoutDelegate(string SessionId, TableLayout aLayout); + + public delegate void SetClientNameDelegate(string aSessionId, string aName); + + public delegate void SetClientPriorityDelegate(string aSessionId, uint aPriority); + + public delegate void PlainUpdateDelegate(); + + public delegate void WndProcDelegate(ref Message aMessage); + + /// + /// Our Display manager main form + /// + [System.ComponentModel.DesignerCategory("Form")] + public partial class FormMain : FormMainHid, IMMNotificationClient + { + //public ManagerEventAction iManager = new ManagerEventAction(); + DateTime LastTickTime; + Display iDisplay; + System.Drawing.Bitmap iBmp; + bool iCreateBitmap; //Workaround render to bitmap issues when minimized + ServiceHost iServiceHost; + // Our collection of clients sorted by session id. + public Dictionary iClients; + // The name of the client which informations are currently displayed. + public string iCurrentClientSessionId; + ClientData iCurrentClientData; + // + public bool iClosing; + // + public bool iSkipFrameRendering; + //Function pointer for pixel color filtering + ColorProcessingDelegate iColorFx; + //Function pointer for pixel X coordinate intercept + CoordinateTranslationDelegate iScreenX; + //Function pointer for pixel Y coordinate intercept + CoordinateTranslationDelegate iScreenY; + //NAudio + private MMDeviceEnumerator iMultiMediaDeviceEnumerator; + private MMDevice iMultiMediaDevice; + //Network + private NetworkManager iNetworkManager; + + /// + /// CEC - Consumer Electronic Control. + /// Notably used to turn TV on and off as Windows broadcast monitor on and off notifications. + /// + private ConsumerElectronicControl iCecManager; + + /// + /// Manage run when Windows startup option + /// + private StartupManager iStartupManager; + + /// + /// System notification icon used to hide our application from the task bar. + /// + private SharpLib.Notification.Control iNotifyIcon; + + /// + /// System recording notification icon. + /// + private SharpLib.Notification.Control iRecordingNotification; + + /// + /// + /// + RichTextBoxTextWriter iWriter; + + + /// + /// Allow user to receive window messages; + /// + public event WndProcDelegate OnWndProc; + + public FormMain() + { + ManagerEventAction.Current = Properties.Settings.Default.Actions; + if (ManagerEventAction.Current == null) + { + //No actions in our settings yet + ManagerEventAction.Current = new ManagerEventAction(); + Properties.Settings.Default.Actions = ManagerEventAction.Current; + } + else + { + //We loaded actions from our settings + //We need to hook them with corresponding events + ManagerEventAction.Current.Init(); + } + iSkipFrameRendering = false; + iClosing = false; + iCurrentClientSessionId = ""; + iCurrentClientData = null; + LastTickTime = DateTime.Now; + //Instantiate our display and register for events notifications + iDisplay = new Display(); + iDisplay.OnOpened += OnDisplayOpened; + iDisplay.OnClosed += OnDisplayClosed; + // + iClients = new Dictionary(); + iStartupManager = new StartupManager(); + iNotifyIcon = new SharpLib.Notification.Control(); + iRecordingNotification = new SharpLib.Notification.Control(); + + //Have our designer initialize its controls + InitializeComponent(); + + //Redirect console output + iWriter = new RichTextBoxTextWriter(richTextBoxLogs); + Console.SetOut(iWriter); + + //Populate device types + PopulateDeviceTypes(); + + //Populate optical drives + PopulateOpticalDrives(); + + //Initial status update + UpdateStatus(); + + //We have a bug when drawing minimized and reusing our bitmap + //Though I could not reproduce it on Windows 10 + iBmp = new System.Drawing.Bitmap(iTableLayoutPanel.Width, iTableLayoutPanel.Height, + PixelFormat.Format32bppArgb); + iCreateBitmap = false; + + //Minimize our window if desired + if (Properties.Settings.Default.StartMinimized) + { + WindowState = FormWindowState.Minimized; + } + + } + + /// + /// + /// + /// + /// + private void MainForm_Load(object sender, EventArgs e) + { + //Check if we are running a Click Once deployed application + if (ApplicationDeployment.IsNetworkDeployed) + { + //This is a proper Click Once installation, fetch and show our version number + this.Text += " - v" + ApplicationDeployment.CurrentDeployment.CurrentVersion; + } + else + { + //Not a proper Click Once installation, assuming development build then + this.Text += " - development"; + } + + //NAudio + iMultiMediaDeviceEnumerator = new MMDeviceEnumerator(); + iMultiMediaDeviceEnumerator.RegisterEndpointNotificationCallback(this); + UpdateAudioDeviceAndMasterVolumeThreadSafe(); + + //Network + iNetworkManager = new NetworkManager(); + iNetworkManager.OnConnectivityChanged += OnConnectivityChanged; + UpdateNetworkStatus(); + + //CEC + iCecManager = new ConsumerElectronicControl(); + OnWndProc += iCecManager.OnWndProc; + ResetCec(); + + //Setup Events + PopulateEventsTreeView(); + + //Setup notification icon + SetupTrayIcon(); + + //Setup recording notification + SetupRecordingNotification(); + + // To make sure start up with minimize to tray works + if (WindowState == FormWindowState.Minimized && Properties.Settings.Default.MinimizeToTray) + { + Visible = false; + } + +#if !DEBUG + //When not debugging we want the screen to be empty until a client takes over + ClearLayout(); +#else + //When developing we want at least one client for testing + StartNewClient("abcdefghijklmnopqrst-0123456789", "ABCDEFGHIJKLMNOPQRST-0123456789"); +#endif + + //Open display connection on start-up if needed + if (Properties.Settings.Default.DisplayConnectOnStartup) + { + OpenDisplayConnection(); + } + + //Start our server so that we can get client requests + StartServer(); + + //Register for HID events + RegisterHidDevices(); + + //Start Idle client if needed + if (Properties.Settings.Default.StartIdleClient) + { + StartIdleClient(); + } + } + + /// + /// Called when our display is opened. + /// + /// + private void OnDisplayOpened(Display aDisplay) + { + //Make sure we resume frame rendering + iSkipFrameRendering = false; + + //Set our screen size now that our display is connected + //Our panelDisplay is the container of our tableLayoutPanel + //tableLayoutPanel will resize itself to fit the client size of our panelDisplay + //panelDisplay needs an extra 2 pixels for borders on each sides + //tableLayoutPanel will eventually be the exact size of our display + Size size = new Size(iDisplay.WidthInPixels() + 2, iDisplay.HeightInPixels() + 2); + panelDisplay.Size = size; + + //Our display was just opened, update our UI + UpdateStatus(); + //Initiate asynchronous request + iDisplay.RequestFirmwareRevision(); + + //Audio + UpdateMasterVolumeThreadSafe(); + //Network + UpdateNetworkStatus(); + +#if DEBUG + //Testing icon in debug, no arm done if icon not supported + //iDisplay.SetIconStatus(Display.TMiniDisplayIconType.EMiniDisplayIconRecording, 0, 1); + //iDisplay.SetAllIconsStatus(2); +#endif + + } + + /// + /// Populate tree view with events and actions + /// + private void PopulateEventsTreeView() + { + //Disable action buttons + buttonAddAction.Enabled = false; + buttonDeleteAction.Enabled = false; + + Event currentEvent = CurrentEvent(); + SharpLib.Ear.Action currentAction = CurrentAction(); + TreeNode treeNodeToSelect = null; + + //Reset our tree + iTreeViewEvents.Nodes.Clear(); + //Populate registered events + foreach (string key in ManagerEventAction.Current.Events.Keys) + { + Event e = ManagerEventAction.Current.Events[key]; + TreeNode eventNode = iTreeViewEvents.Nodes.Add(key, e.Name); + eventNode.Tag = e; + eventNode.Nodes.Add(key + ".Description", e.Description); + TreeNode actionsNodes = eventNode.Nodes.Add(key + ".Actions", "Actions"); + + // Add our actions for that event + foreach (SharpLib.Ear.Action a in e.Actions) + { + TreeNode actionNode = actionsNodes.Nodes.Add(a.Brief()); + actionNode.Tag = a; + if (a == currentAction) + { + treeNodeToSelect = actionNode; + } + } + } + + iTreeViewEvents.ExpandAll(); + SelectEvent(currentEvent); + + if (treeNodeToSelect != null) + { + iTreeViewEvents.SelectedNode = treeNodeToSelect; + } + else if (iTreeViewEvents.SelectedNode != null && iTreeViewEvents.SelectedNode.Nodes[1].GetNodeCount(false) > 0) + { + //Select the last action if any + iTreeViewEvents.SelectedNode = + iTreeViewEvents.SelectedNode.Nodes[1].Nodes[ + iTreeViewEvents.SelectedNode.Nodes[1].GetNodeCount(false) - 1]; + } + + } + + /// + /// Called when our display is closed. + /// + /// + private void OnDisplayClosed(Display aDisplay) + { + //Our display was just closed, update our UI consequently + UpdateStatus(); + } + + public void OnConnectivityChanged(NetworkManager aNetwork, NLM_CONNECTIVITY newConnectivity) + { + //Update network status + UpdateNetworkStatus(); + } + + /// + /// Update our Network Status + /// + private void UpdateNetworkStatus() + { + if (iDisplay.IsOpen()) + { + iDisplay.SetIconOnOff(MiniDisplay.IconType.Internet, + iNetworkManager.NetworkListManager.IsConnectedToInternet); + iDisplay.SetIconOnOff(MiniDisplay.IconType.NetworkSignal, iNetworkManager.NetworkListManager.IsConnected); + } + } + + + int iLastNetworkIconIndex = 0; + int iUpdateCountSinceLastNetworkAnimation = 0; + + /// + /// + /// + private void UpdateNetworkSignal(DateTime aLastTickTime, DateTime aNewTickTime) + { + iUpdateCountSinceLastNetworkAnimation++; + iUpdateCountSinceLastNetworkAnimation = iUpdateCountSinceLastNetworkAnimation%4; + + if (iDisplay.IsOpen() && iNetworkManager.NetworkListManager.IsConnected && + iUpdateCountSinceLastNetworkAnimation == 0) + { + int iconCount = iDisplay.IconCount(MiniDisplay.IconType.NetworkSignal); + if (iconCount <= 0) + { + //Prevents div by zero and other undefined behavior + return; + } + iLastNetworkIconIndex++; + iLastNetworkIconIndex = iLastNetworkIconIndex%(iconCount*2); + for (int i = 0; i < iconCount; i++) + { + if (i < iLastNetworkIconIndex && !(i == 0 && iLastNetworkIconIndex > 3) && + !(i == 1 && iLastNetworkIconIndex > 4)) + { + iDisplay.SetIconOn(MiniDisplay.IconType.NetworkSignal, i); + } + else + { + iDisplay.SetIconOff(MiniDisplay.IconType.NetworkSignal, i); + } + } + } + } + + + + /// + /// Receive volume change notification and reflect changes on our slider. + /// + /// + public void OnVolumeNotificationThreadSafe(AudioVolumeNotificationData data) + { + UpdateMasterVolumeThreadSafe(); + } + + /// + /// Update master volume when user moves our slider. + /// + /// + /// + private void trackBarMasterVolume_Scroll(object sender, EventArgs e) + { + //Just like Windows Volume Mixer we unmute if the volume is adjusted + iMultiMediaDevice.AudioEndpointVolume.Mute = false; + //Set volume level according to our volume slider new position + iMultiMediaDevice.AudioEndpointVolume.MasterVolumeLevelScalar = trackBarMasterVolume.Value/100.0f; + } + + + /// + /// Mute check box changed. + /// + /// + /// + private void checkBoxMute_CheckedChanged(object sender, EventArgs e) + { + iMultiMediaDevice.AudioEndpointVolume.Mute = checkBoxMute.Checked; + } + + /// + /// Device State Changed + /// + public void OnDeviceStateChanged([MarshalAs(UnmanagedType.LPWStr)] string deviceId, + [MarshalAs(UnmanagedType.I4)] DeviceState newState) + { + } + + /// + /// Device Added + /// + public void OnDeviceAdded([MarshalAs(UnmanagedType.LPWStr)] string pwstrDeviceId) + { + } + + /// + /// Device Removed + /// + public void OnDeviceRemoved([MarshalAs(UnmanagedType.LPWStr)] string deviceId) + { + } + + /// + /// Default Device Changed + /// + public void OnDefaultDeviceChanged(DataFlow flow, Role role, + [MarshalAs(UnmanagedType.LPWStr)] string defaultDeviceId) + { + if (role == Role.Multimedia && flow == DataFlow.Render) + { + UpdateAudioDeviceAndMasterVolumeThreadSafe(); + } + } + + /// + /// Property Value Changed + /// + /// + /// + public void OnPropertyValueChanged([MarshalAs(UnmanagedType.LPWStr)] string pwstrDeviceId, PropertyKey key) + { + } + + + + + /// + /// Update master volume indicators based our current system states. + /// This typically includes volume levels and mute status. + /// + private void UpdateMasterVolumeThreadSafe() + { + if (this.InvokeRequired) + { + //Not in the proper thread, invoke ourselves + PlainUpdateDelegate d = new PlainUpdateDelegate(UpdateMasterVolumeThreadSafe); + this.Invoke(d, new object[] {}); + return; + } + + //Update volume slider + float volumeLevelScalar = iMultiMediaDevice.AudioEndpointVolume.MasterVolumeLevelScalar; + trackBarMasterVolume.Value = Convert.ToInt32(volumeLevelScalar*100); + //Update mute checkbox + checkBoxMute.Checked = iMultiMediaDevice.AudioEndpointVolume.Mute; + + //If our display connection is open we need to update its icons + if (iDisplay.IsOpen()) + { + //First take care our our volume level icons + int volumeIconCount = iDisplay.IconCount(MiniDisplay.IconType.Volume); + if (volumeIconCount > 0) + { + //Compute current volume level from system level and the number of segments in our display volume bar. + //That tells us how many segments in our volume bar needs to be turned on. + float currentVolume = volumeLevelScalar*volumeIconCount; + int segmentOnCount = Convert.ToInt32(currentVolume); + //Check if our segment count was rounded up, this will later be used for half brightness segment + bool roundedUp = segmentOnCount > currentVolume; + + for (int i = 0; i < volumeIconCount; i++) + { + if (i < segmentOnCount) + { + //If we are dealing with our last segment and our segment count was rounded up then we will use half brightness. + if (i == segmentOnCount - 1 && roundedUp) + { + //Half brightness + iDisplay.SetIconStatus(MiniDisplay.IconType.Volume, i, + (iDisplay.IconStatusCount(MiniDisplay.IconType.Volume) - 1)/2); + } + else + { + //Full brightness + iDisplay.SetIconStatus(MiniDisplay.IconType.Volume, i, + iDisplay.IconStatusCount(MiniDisplay.IconType.Volume) - 1); + } + } + else + { + iDisplay.SetIconStatus(MiniDisplay.IconType.Volume, i, 0); + } + } + } + + //Take care of our mute icon + iDisplay.SetIconOnOff(MiniDisplay.IconType.Mute, iMultiMediaDevice.AudioEndpointVolume.Mute); + } + + } + + /// + /// + /// + private void UpdateAudioDeviceAndMasterVolumeThreadSafe() + { + if (this.InvokeRequired) + { + //Not in the proper thread, invoke ourselves + PlainUpdateDelegate d = new PlainUpdateDelegate(UpdateAudioDeviceAndMasterVolumeThreadSafe); + this.Invoke(d, new object[] {}); + return; + } + + //We are in the correct thread just go ahead. + try + { + //Get our master volume + iMultiMediaDevice = iMultiMediaDeviceEnumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia); + //Update our label + labelDefaultAudioDevice.Text = iMultiMediaDevice.FriendlyName; + + //Show our volume in our track bar + UpdateMasterVolumeThreadSafe(); + + //Register to get volume modifications + iMultiMediaDevice.AudioEndpointVolume.OnVolumeNotification += OnVolumeNotificationThreadSafe; + // + trackBarMasterVolume.Enabled = true; + } + catch (Exception ex) + { + Debug.WriteLine("Exception thrown in UpdateAudioDeviceAndMasterVolume"); + Debug.WriteLine(ex.ToString()); + //Something went wrong S/PDIF device ca throw exception I guess + trackBarMasterVolume.Enabled = false; + } + } + + /// + /// + /// + private void PopulateDeviceTypes() + { + int count = Display.TypeCount(); + + for (int i = 0; i < count; i++) + { + comboBoxDisplayType.Items.Add(Display.TypeName((MiniDisplay.Type) i)); + } + } + + /// + /// + /// + private void PopulateOpticalDrives() + { + //Reset our list of drives + comboBoxOpticalDrives.Items.Clear(); + comboBoxOpticalDrives.Items.Add("None"); + + //Go through each drives on our system and collected the optical ones in our list + DriveInfo[] allDrives = DriveInfo.GetDrives(); + foreach (DriveInfo d in allDrives) + { + Debug.WriteLine("Drive " + d.Name); + Debug.WriteLine(" Drive type: {0}", d.DriveType); + + if (d.DriveType == DriveType.CDRom) + { + //This is an optical drive, add it now + comboBoxOpticalDrives.Items.Add(d.Name.Substring(0, 2)); + } + } + } + + /// + /// + /// + /// + public string OpticalDriveToEject() + { + return comboBoxOpticalDrives.SelectedItem.ToString(); + } + + + + /// + /// + /// + private void SetupTrayIcon() + { + iNotifyIcon.Icon = GetIcon("vfd.ico"); + iNotifyIcon.Text = "Sharp Display Manager"; + iNotifyIcon.Visible = true; + + //Double click toggles visibility - typically brings up the application + iNotifyIcon.DoubleClick += delegate(object obj, EventArgs args) + { + SysTrayHideShow(); + }; + + //Adding a context menu, useful to be able to exit the application + ContextMenu contextMenu = new ContextMenu(); + //Context menu item to toggle visibility + MenuItem hideShowItem = new MenuItem("Hide/Show"); + hideShowItem.Click += delegate(object obj, EventArgs args) + { + SysTrayHideShow(); + }; + contextMenu.MenuItems.Add(hideShowItem); + + //Context menu item separator + contextMenu.MenuItems.Add(new MenuItem("-")); + + //Context menu exit item + MenuItem exitItem = new MenuItem("Exit"); + exitItem.Click += delegate(object obj, EventArgs args) + { + Application.Exit(); + }; + contextMenu.MenuItems.Add(exitItem); + + iNotifyIcon.ContextMenu = contextMenu; + } + + /// + /// + /// + private void SetupRecordingNotification() + { + iRecordingNotification.Icon = GetIcon("record.ico"); + iRecordingNotification.Text = "No recording"; + iRecordingNotification.Visible = false; + } + + /// + /// Access icons from embedded resources. + /// + /// + /// + public static Icon GetIcon(string aName) + { + string[] names = Assembly.GetExecutingAssembly().GetManifestResourceNames(); + foreach (string name in names) + { + //Find a resource name that ends with the given name + if (name.EndsWith(aName)) + { + using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name)) + { + return new Icon(stream); + } + } + } + + return null; + } + + + /// + /// Set our current client. + /// This will take care of applying our client layout and set data fields. + /// + /// + void SetCurrentClient(string aSessionId, bool aForce = false) + { + if (aSessionId == iCurrentClientSessionId) + { + //Given client is already the current one. + //Don't bother changing anything then. + return; + } + + ClientData requestedClientData = iClients[aSessionId]; + + //Check when was the last time we switched to that client + if (iCurrentClientData != null) + { + //Do not switch client if priority of current client is higher + if (!aForce && requestedClientData.Priority < iCurrentClientData.Priority) + { + return; + } + + + double lastSwitchToClientSecondsAgo = (DateTime.Now - iCurrentClientData.LastSwitchTime).TotalSeconds; + //TODO: put that hard coded value as a client property + //Clients should be able to define how often they can be interrupted + //Thus a background client can set this to zero allowing any other client to interrupt at any time + //We could also compute this delay by looking at the requests frequencies? + if (!aForce && + requestedClientData.Priority == iCurrentClientData.Priority && + //Time sharing is only if clients have the same priority + (lastSwitchToClientSecondsAgo < 30)) //Make sure a client is on for at least 30 seconds + { + //Don't switch clients too often + return; + } + } + + //Set current client ID. + iCurrentClientSessionId = aSessionId; + //Set the time we last switched to that client + iClients[aSessionId].LastSwitchTime = DateTime.Now; + //Fetch and set current client data. + iCurrentClientData = requestedClientData; + //Apply layout and set data fields. + UpdateTableLayoutPanel(iCurrentClientData); + } + + private void buttonFont_Click(object sender, EventArgs e) + { + //fontDialog.ShowColor = true; + //fontDialog.ShowApply = true; + fontDialog.ShowEffects = true; + fontDialog.Font = cds.Font; + + fontDialog.FixedPitchOnly = checkBoxFixedPitchFontOnly.Checked; + + //fontDialog.ShowHelp = true; + + //fontDlg.MaxSize = 40; + //fontDlg.MinSize = 22; + + //fontDialog.Parent = this; + //fontDialog.StartPosition = FormStartPosition.CenterParent; + + //DlgBox.ShowDialog(fontDialog); + + //if (fontDialog.ShowDialog(this) != DialogResult.Cancel) + if (DlgBox.ShowDialog(fontDialog) != DialogResult.Cancel) + { + //Set the fonts to all our labels in our layout + foreach (Control ctrl in iTableLayoutPanel.Controls) + { + if (ctrl is MarqueeLabel) + { + ((MarqueeLabel) ctrl).Font = fontDialog.Font; + } + } + + //Save font settings + cds.Font = fontDialog.Font; + Properties.Settings.Default.Save(); + // + CheckFontHeight(); + } + } + + /// + /// + /// + void CheckFontHeight() + { + //Show font height and width + labelFontHeight.Text = "Font height: " + cds.Font.Height; + float charWidth = IsFixedWidth(cds.Font); + if (charWidth == 0.0f) + { + labelFontWidth.Visible = false; + } + else + { + labelFontWidth.Visible = true; + labelFontWidth.Text = "Font width: " + charWidth; + } + + MarqueeLabel label = null; + //Get the first label control we can find + foreach (Control ctrl in iTableLayoutPanel.Controls) + { + if (ctrl is MarqueeLabel) + { + label = (MarqueeLabel) ctrl; + break; + } + } + + //Now check font height and show a warning if needed. + if (label != null && label.Font.Height > label.Height) + { + labelWarning.Text = "WARNING: Selected font is too height by " + (label.Font.Height - label.Height) + + " pixels!"; + labelWarning.Visible = true; + } + else + { + labelWarning.Visible = false; + } + + } + + private void buttonCapture_Click(object sender, EventArgs e) + { + System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(iTableLayoutPanel.Width, iTableLayoutPanel.Height); + iTableLayoutPanel.DrawToBitmap(bmp, iTableLayoutPanel.ClientRectangle); + //Bitmap bmpToSave = new Bitmap(bmp); + bmp.Save("D:\\capture.png"); + + ((MarqueeLabel) iTableLayoutPanel.Controls[0]).Text = "Captured"; + + /* + string outputFileName = "d:\\capture.png"; + using (MemoryStream memory = new MemoryStream()) + { + using (FileStream fs = new FileStream(outputFileName, FileMode.OpenOrCreate, FileAccess.ReadWrite)) + { + bmp.Save(memory, System.Drawing.Imaging.ImageFormat.Png); + byte[] bytes = memory.ToArray(); + fs.Write(bytes, 0, bytes.Length); + } + } + */ + + } + + private void CheckForRequestResults() + { + if (iDisplay.IsRequestPending()) + { + switch (iDisplay.AttemptRequestCompletion()) + { + case MiniDisplay.Request.FirmwareRevision: + toolStripStatusLabelConnect.Text += " v" + iDisplay.FirmwareRevision(); + //Issue next request then + iDisplay.RequestPowerSupplyStatus(); + break; + + case MiniDisplay.Request.PowerSupplyStatus: + if (iDisplay.PowerSupplyStatus()) + { + toolStripStatusLabelPower.Text = "ON"; + } + else + { + toolStripStatusLabelPower.Text = "OFF"; + } + //Issue next request then + iDisplay.RequestDeviceId(); + break; + + case MiniDisplay.Request.DeviceId: + toolStripStatusLabelConnect.Text += " - " + iDisplay.DeviceId(); + //No more request to issue + break; + } + } + } + + public static uint ColorWhiteIsOn(int aX, int aY, uint aPixel) + { + if ((aPixel & 0x00FFFFFF) == 0x00FFFFFF) + { + return 0xFFFFFFFF; + } + return 0x00000000; + } + + public static uint ColorUntouched(int aX, int aY, uint aPixel) + { + return aPixel; + } + + public static uint ColorInversed(int aX, int aY, uint aPixel) + { + return ~aPixel; + } + + public static uint ColorChessboard(int aX, int aY, uint aPixel) + { + if ((aX%2 == 0) && (aY%2 == 0)) + { + return ~aPixel; + } + else if ((aX%2 != 0) && (aY%2 != 0)) + { + return ~aPixel; + } + return 0x00000000; + } + + + public static int ScreenReversedX(System.Drawing.Bitmap aBmp, int aX) + { + return aBmp.Width - aX - 1; + } + + public int ScreenReversedY(System.Drawing.Bitmap aBmp, int aY) + { + return iBmp.Height - aY - 1; + } + + public int ScreenX(System.Drawing.Bitmap aBmp, int aX) + { + return aX; + } + + public int ScreenY(System.Drawing.Bitmap aBmp, int aY) + { + return aY; + } + + /// + /// Select proper pixel delegates according to our current settings. + /// + private void SetupPixelDelegates() + { + //Select our pixel processing routine + if (cds.InverseColors) + { + //iColorFx = ColorChessboard; + iColorFx = ColorInversed; + } + else + { + iColorFx = ColorWhiteIsOn; + } + + //Select proper coordinate translation functions + //We used delegate/function pointer to support reverse screen without doing an extra test on each pixels + if (cds.ReverseScreen) + { + iScreenX = ScreenReversedX; + iScreenY = ScreenReversedY; + } + else + { + iScreenX = ScreenX; + iScreenY = ScreenY; + } + + } + + //This is our timer tick responsible to perform our render + private void timer_Tick(object sender, EventArgs e) + { + //Not ideal cause this has nothing to do with display render + LogsUpdate(); + + //Update our animations + DateTime NewTickTime = DateTime.Now; + + UpdateNetworkSignal(LastTickTime, NewTickTime); + + //Update animation for all our marquees + foreach (Control ctrl in iTableLayoutPanel.Controls) + { + if (ctrl is MarqueeLabel) + { + ((MarqueeLabel) ctrl).UpdateAnimation(LastTickTime, NewTickTime); + } + } + + //Update our display + if (iDisplay.IsOpen()) + { + CheckForRequestResults(); + + //Check if frame rendering is needed + //Typically used when showing clock + if (!iSkipFrameRendering) + { + //Draw to bitmap + if (iCreateBitmap) + { + iBmp = new System.Drawing.Bitmap(iTableLayoutPanel.Width, iTableLayoutPanel.Height, + PixelFormat.Format32bppArgb); + iCreateBitmap = false; + } + iTableLayoutPanel.DrawToBitmap(iBmp, iTableLayoutPanel.ClientRectangle); + //iBmp.Save("D:\\capture.png"); + + //Send it to our display + for (int i = 0; i < iBmp.Width; i++) + { + for (int j = 0; j < iBmp.Height; j++) + { + unchecked + { + //Get our processed pixel coordinates + int x = iScreenX(iBmp, i); + int y = iScreenY(iBmp, j); + //Get pixel color + uint color = (uint) iBmp.GetPixel(i, j).ToArgb(); + //Apply color effects + color = iColorFx(x, y, color); + //Now set our pixel + iDisplay.SetPixel(x, y, color); + } + } + } + + iDisplay.SwapBuffers(); + } + } + + //Compute instant FPS + toolStripStatusLabelFps.Text = (1.0/NewTickTime.Subtract(LastTickTime).TotalSeconds).ToString("F0") + " / " + + (1000/timer.Interval).ToString() + " FPS"; + + LastTickTime = NewTickTime; + + } + + /// + /// Attempt to establish connection with our display hardware. + /// + private void OpenDisplayConnection() + { + CloseDisplayConnection(); + + if (!iDisplay.Open((MiniDisplay.Type) cds.DisplayType)) + { + UpdateStatus(); + toolStripStatusLabelConnect.Text = "Connection error"; + } + } + + private void CloseDisplayConnection() + { + //Status will be updated upon receiving the closed event + + if (iDisplay == null || !iDisplay.IsOpen()) + { + return; + } + + //Do not clear if we gave up on rendering already. + //This means we will keep on displaying clock on MDM166AA for instance. + if (!iSkipFrameRendering) + { + iDisplay.Clear(); + iDisplay.SwapBuffers(); + } + + iDisplay.SetAllIconsStatus(0); //Turn off all icons + iDisplay.Close(); + } + + private void buttonOpen_Click(object sender, EventArgs e) + { + OpenDisplayConnection(); + } + + private void buttonClose_Click(object sender, EventArgs e) + { + CloseDisplayConnection(); + } + + private void buttonClear_Click(object sender, EventArgs e) + { + iDisplay.Clear(); + iDisplay.SwapBuffers(); + } + + private void buttonFill_Click(object sender, EventArgs e) + { + iDisplay.Fill(); + iDisplay.SwapBuffers(); + } + + private void trackBarBrightness_Scroll(object sender, EventArgs e) + { + cds.Brightness = trackBarBrightness.Value; + Properties.Settings.Default.Save(); + iDisplay.SetBrightness(trackBarBrightness.Value); + + } + + + /// + /// CDS stands for Current Display Settings + /// + private DisplaySettings cds + { + get + { + DisplaysSettings settings = Properties.Settings.Default.DisplaysSettings; + if (settings == null) + { + settings = new DisplaysSettings(); + settings.Init(); + Properties.Settings.Default.DisplaysSettings = settings; + } + + //Make sure all our settings have been created + while (settings.Displays.Count <= Properties.Settings.Default.CurrentDisplayIndex) + { + settings.Displays.Add(new DisplaySettings()); + } + + DisplaySettings displaySettings = settings.Displays[Properties.Settings.Default.CurrentDisplayIndex]; + return displaySettings; + } + } + + /// + /// Check if the given font has a fixed character pitch. + /// + /// + /// 0.0f if this is not a monospace font, otherwise returns the character width. + public float IsFixedWidth(Font ft) + { + Graphics g = CreateGraphics(); + char[] charSizes = new char[] {'i', 'a', 'Z', '%', '#', 'a', 'B', 'l', 'm', ',', '.'}; + float charWidth = g.MeasureString("I", ft, Int32.MaxValue, StringFormat.GenericTypographic).Width; + + bool fixedWidth = true; + + foreach (char c in charSizes) + if (g.MeasureString(c.ToString(), ft, Int32.MaxValue, StringFormat.GenericTypographic).Width != + charWidth) + fixedWidth = false; + + if (fixedWidth) + { + return charWidth; + } + + return 0.0f; + } + + /// + /// Synchronize UI with settings + /// + private void UpdateStatus() + { + //Load settings + checkBoxShowBorders.Checked = cds.ShowBorders; + iTableLayoutPanel.CellBorderStyle = (cds.ShowBorders + ? TableLayoutPanelCellBorderStyle.Single + : TableLayoutPanelCellBorderStyle.None); + + //Set the proper font to each of our labels + foreach (MarqueeLabel ctrl in iTableLayoutPanel.Controls) + { + ctrl.Font = cds.Font; + } + + CheckFontHeight(); + //Check if "run on Windows startup" is enabled + checkBoxAutoStart.Checked = iStartupManager.Startup; + // + checkBoxConnectOnStartup.Checked = Properties.Settings.Default.DisplayConnectOnStartup; + checkBoxMinimizeToTray.Checked = Properties.Settings.Default.MinimizeToTray; + checkBoxStartMinimized.Checked = Properties.Settings.Default.StartMinimized; + iCheckBoxStartIdleClient.Checked = Properties.Settings.Default.StartIdleClient; + labelStartFileName.Text = Properties.Settings.Default.StartFileName; + + + //Try find our drive in our drive list + int opticalDriveItemIndex = 0; + bool driveNotFound = true; + string opticalDriveToEject = Properties.Settings.Default.OpticalDriveToEject; + foreach (object item in comboBoxOpticalDrives.Items) + { + if (opticalDriveToEject == item.ToString()) + { + comboBoxOpticalDrives.SelectedIndex = opticalDriveItemIndex; + driveNotFound = false; + break; + } + opticalDriveItemIndex++; + } + + if (driveNotFound) + { + //We could not find the drive we had saved. + //Select "None" then. + comboBoxOpticalDrives.SelectedIndex = 0; + } + + //CEC settings + checkBoxCecEnabled.Checked = Properties.Settings.Default.CecEnabled; + comboBoxHdmiPort.SelectedIndex = Properties.Settings.Default.CecHdmiPort - 1; + + //Mini Display settings + checkBoxReverseScreen.Checked = cds.ReverseScreen; + checkBoxInverseColors.Checked = cds.InverseColors; + checkBoxShowVolumeLabel.Checked = cds.ShowVolumeLabel; + checkBoxScaleToFit.Checked = cds.ScaleToFit; + maskedTextBoxMinFontSize.Enabled = cds.ScaleToFit; + labelMinFontSize.Enabled = cds.ScaleToFit; + maskedTextBoxMinFontSize.Text = cds.MinFontSize.ToString(); + maskedTextBoxScrollingSpeed.Text = cds.ScrollingSpeedInPixelsPerSecond.ToString(); + comboBoxDisplayType.SelectedIndex = cds.DisplayType; + timer.Interval = cds.TimerInterval; + maskedTextBoxTimerInterval.Text = cds.TimerInterval.ToString(); + textBoxScrollLoopSeparator.Text = cds.Separator; + // + SetupPixelDelegates(); + + if (iDisplay.IsOpen()) + { + //We have a display connection + //Reflect that in our UI + StartTimer(); + + iTableLayoutPanel.Enabled = true; + panelDisplay.Enabled = true; + + //Only setup brightness if display is open + trackBarBrightness.Minimum = iDisplay.MinBrightness(); + trackBarBrightness.Maximum = iDisplay.MaxBrightness(); + if (cds.Brightness < iDisplay.MinBrightness() || cds.Brightness > iDisplay.MaxBrightness()) + { + //Brightness out of range, this can occur when using auto-detect + //Use max brightness instead + trackBarBrightness.Value = iDisplay.MaxBrightness(); + iDisplay.SetBrightness(iDisplay.MaxBrightness()); + } + else + { + trackBarBrightness.Value = cds.Brightness; + iDisplay.SetBrightness(cds.Brightness); + } + + //Try compute the steps to something that makes sense + trackBarBrightness.LargeChange = Math.Max(1, (iDisplay.MaxBrightness() - iDisplay.MinBrightness())/5); + trackBarBrightness.SmallChange = 1; + + // + buttonFill.Enabled = true; + buttonClear.Enabled = true; + buttonOpen.Enabled = false; + buttonClose.Enabled = true; + trackBarBrightness.Enabled = true; + toolStripStatusLabelConnect.Text = "Connected - " + iDisplay.Vendor() + " - " + iDisplay.Product(); + //+ " - " + iDisplay.SerialNumber(); + + if (iDisplay.SupportPowerOnOff()) + { + buttonPowerOn.Enabled = true; + buttonPowerOff.Enabled = true; + } + else + { + buttonPowerOn.Enabled = false; + buttonPowerOff.Enabled = false; + } + + if (iDisplay.SupportClock()) + { + buttonShowClock.Enabled = true; + buttonHideClock.Enabled = true; + } + else + { + buttonShowClock.Enabled = false; + buttonHideClock.Enabled = false; + } + + + //Check if Volume Label is supported. To date only MDM166AA supports that crap :) + checkBoxShowVolumeLabel.Enabled = iDisplay.IconCount(MiniDisplay.IconType.VolumeLabel) > 0; + + if (cds.ShowVolumeLabel) + { + iDisplay.SetIconOn(MiniDisplay.IconType.VolumeLabel); + } + else + { + iDisplay.SetIconOff(MiniDisplay.IconType.VolumeLabel); + } + } + else + { + //Display connection not available + //Reflect that in our UI +#if DEBUG + //In debug start our timer even if we don't have a display connection + StartTimer(); +#else + //In production environment we don't need our timer if no display connection + StopTimer(); +#endif + checkBoxShowVolumeLabel.Enabled = false; + iTableLayoutPanel.Enabled = false; + panelDisplay.Enabled = false; + buttonFill.Enabled = false; + buttonClear.Enabled = false; + buttonOpen.Enabled = true; + buttonClose.Enabled = false; + trackBarBrightness.Enabled = false; + buttonPowerOn.Enabled = false; + buttonPowerOff.Enabled = false; + buttonShowClock.Enabled = false; + buttonHideClock.Enabled = false; + toolStripStatusLabelConnect.Text = "Disconnected"; + toolStripStatusLabelPower.Text = "N/A"; + } + + } + + + /// + /// + /// + /// + /// + private void checkBoxShowVolumeLabel_CheckedChanged(object sender, EventArgs e) + { + cds.ShowVolumeLabel = checkBoxShowVolumeLabel.Checked; + Properties.Settings.Default.Save(); + UpdateStatus(); + } + + private void checkBoxShowBorders_CheckedChanged(object sender, EventArgs e) + { + //Save our show borders setting + iTableLayoutPanel.CellBorderStyle = (checkBoxShowBorders.Checked + ? TableLayoutPanelCellBorderStyle.Single + : TableLayoutPanelCellBorderStyle.None); + cds.ShowBorders = checkBoxShowBorders.Checked; + Properties.Settings.Default.Save(); + CheckFontHeight(); + } + + private void checkBoxConnectOnStartup_CheckedChanged(object sender, EventArgs e) + { + //Save our connect on startup setting + Properties.Settings.Default.DisplayConnectOnStartup = checkBoxConnectOnStartup.Checked; + Properties.Settings.Default.Save(); + } + + private void checkBoxMinimizeToTray_CheckedChanged(object sender, EventArgs e) + { + //Save our "Minimize to tray" setting + Properties.Settings.Default.MinimizeToTray = checkBoxMinimizeToTray.Checked; + Properties.Settings.Default.Save(); + + } + + private void checkBoxStartMinimized_CheckedChanged(object sender, EventArgs e) + { + //Save our "Start minimized" setting + Properties.Settings.Default.StartMinimized = checkBoxStartMinimized.Checked; + Properties.Settings.Default.Save(); + } + + private void checkBoxStartIdleClient_CheckedChanged(object sender, EventArgs e) + { + Properties.Settings.Default.StartIdleClient = iCheckBoxStartIdleClient.Checked; + Properties.Settings.Default.Save(); + } + + private void checkBoxAutoStart_CheckedChanged(object sender, EventArgs e) + { + iStartupManager.Startup = checkBoxAutoStart.Checked; + } + + + private void checkBoxReverseScreen_CheckedChanged(object sender, EventArgs e) + { + //Save our reverse screen setting + cds.ReverseScreen = checkBoxReverseScreen.Checked; + Properties.Settings.Default.Save(); + SetupPixelDelegates(); + } + + private void checkBoxInverseColors_CheckedChanged(object sender, EventArgs e) + { + //Save our inverse colors setting + cds.InverseColors = checkBoxInverseColors.Checked; + Properties.Settings.Default.Save(); + SetupPixelDelegates(); + } + + private void checkBoxScaleToFit_CheckedChanged(object sender, EventArgs e) + { + //Save our scale to fit setting + cds.ScaleToFit = checkBoxScaleToFit.Checked; + Properties.Settings.Default.Save(); + // + labelMinFontSize.Enabled = cds.ScaleToFit; + maskedTextBoxMinFontSize.Enabled = cds.ScaleToFit; + } + + private void MainForm_Resize(object sender, EventArgs e) + { + if (WindowState == FormWindowState.Minimized) + { + // To workaround our empty bitmap bug on Windows 7 we need to recreate our bitmap when the application is minimized + // That's apparently not needed on Windows 10 but we better leave it in place. + iCreateBitmap = true; + } + } + + private void MainForm_FormClosing(object sender, FormClosingEventArgs e) + { + iCecManager.Stop(); + iNetworkManager.Dispose(); + CloseDisplayConnection(); + StopServer(); + e.Cancel = iClosing; + } + + public void StartServer() + { + iServiceHost = new ServiceHost + ( + typeof(Session), + new Uri[] {new Uri("net.tcp://localhost:8001/")} + ); + + iServiceHost.AddServiceEndpoint(typeof(IService), new NetTcpBinding(SecurityMode.None, true), + "DisplayService"); + iServiceHost.Open(); + } + + public void StopServer() + { + if (iClients.Count > 0 && !iClosing) + { + //Tell our clients + iClosing = true; + BroadcastCloseEvent(); + } + else if (iClosing) + { + if ( + MessageBox.Show("Force exit?", "Waiting for clients...", MessageBoxButtons.YesNo, + MessageBoxIcon.Warning) == DialogResult.Yes) + { + iClosing = false; //We make sure we force close if asked twice + } + } + else + { + //We removed that as it often lags for some reason + //iServiceHost.Close(); + } + } + + public void BroadcastCloseEvent() + { + Trace.TraceInformation("BroadcastCloseEvent - start"); + + var inactiveClients = new List(); + foreach (var client in iClients) + { + //if (client.Key != eventData.ClientName) + { + try + { + Trace.TraceInformation("BroadcastCloseEvent - " + client.Key); + client.Value.Callback.OnCloseOrder( /*eventData*/); + } + catch (Exception ex) + { + inactiveClients.Add(client.Key); + } + } + } + + if (inactiveClients.Count > 0) + { + foreach (var client in inactiveClients) + { + iClients.Remove(client); + Program.iFormMain.iTreeViewClients.Nodes.Remove( + Program.iFormMain.iTreeViewClients.Nodes.Find(client, false)[0]); + } + } + + if (iClients.Count == 0) + { + ClearLayout(); + } + } + + /// + /// Just remove all our fields. + /// + private void ClearLayout() + { + iTableLayoutPanel.Controls.Clear(); + iTableLayoutPanel.RowStyles.Clear(); + iTableLayoutPanel.ColumnStyles.Clear(); + iCurrentClientData = null; + } + + /// + /// Just launch a demo client. + /// + private void StartNewClient(string aTopText = "", string aBottomText = "") + { + Thread clientThread = new Thread(SharpDisplayClient.Program.MainWithParams); + SharpDisplayClient.StartParams myParams = new SharpDisplayClient.StartParams( + new Point(this.Right, this.Top), aTopText, aBottomText); + clientThread.Start(myParams); + BringToFront(); + } + + /// + /// Just launch our idle client. + /// + private void StartIdleClient(string aTopText = "", string aBottomText = "") + { + Thread clientThread = new Thread(SharpDisplayClientIdle.Program.MainWithParams); + SharpDisplayClientIdle.StartParams myParams = + new SharpDisplayClientIdle.StartParams(new Point(this.Right, this.Top), aTopText, aBottomText); + clientThread.Start(myParams); + BringToFront(); + } + + + private void buttonStartClient_Click(object sender, EventArgs e) + { + StartNewClient(); + } + + private void buttonSuspend_Click(object sender, EventArgs e) + { + ToggleTimer(); + } + + private void StartTimer() + { + LastTickTime = DateTime.Now; //Reset timer to prevent jump + timer.Enabled = true; + UpdateSuspendButton(); + } + + private void StopTimer() + { + LastTickTime = DateTime.Now; //Reset timer to prevent jump + timer.Enabled = false; + UpdateSuspendButton(); + } + + private void ToggleTimer() + { + LastTickTime = DateTime.Now; //Reset timer to prevent jump + timer.Enabled = !timer.Enabled; + UpdateSuspendButton(); + } + + private void UpdateSuspendButton() + { + if (!timer.Enabled) + { + buttonSuspend.Text = "Run"; + } + else + { + buttonSuspend.Text = "Pause"; + } + } + + + private void buttonCloseClients_Click(object sender, EventArgs e) + { + BroadcastCloseEvent(); + } + + private void treeViewClients_AfterSelect(object sender, TreeViewEventArgs e) + { + //Root node must have at least one child + if (e.Node.Nodes.Count == 0) + { + return; + } + + //If the selected node is the root node of a client then switch to it + string sessionId = e.Node.Nodes[0].Text; //First child of a root node is the sessionId + if (iClients.ContainsKey(sessionId)) //Check that's actually what we are looking at + { + //We have a valid session just switch to that client + SetCurrentClient(sessionId, true); + } + + } + + + /// + /// + /// + /// + /// + public void AddClientThreadSafe(string aSessionId, ICallback aCallback) + { + if (this.InvokeRequired) + { + //Not in the proper thread, invoke ourselves + AddClientDelegate d = new AddClientDelegate(AddClientThreadSafe); + this.Invoke(d, new object[] {aSessionId, aCallback}); + } + else + { + //We are in the proper thread + //Add this session to our collection of clients + ClientData newClient = new ClientData(aSessionId, aCallback); + Program.iFormMain.iClients.Add(aSessionId, newClient); + //Add this session to our UI + UpdateClientTreeViewNode(newClient); + } + } + + + /// + /// Find the client with the highest priority if any. + /// + /// Our highest priority client or null if not a single client is connected. + public ClientData FindHighestPriorityClient() + { + ClientData highestPriorityClient = null; + foreach (var client in iClients) + { + if (highestPriorityClient == null || client.Value.Priority > highestPriorityClient.Priority) + { + highestPriorityClient = client.Value; + } + } + + return highestPriorityClient; + } + + /// + /// + /// + /// + public void RemoveClientThreadSafe(string aSessionId) + { + if (this.InvokeRequired) + { + //Not in the proper thread, invoke ourselves + RemoveClientDelegate d = new RemoveClientDelegate(RemoveClientThreadSafe); + this.Invoke(d, new object[] {aSessionId}); + } + else + { + //We are in the proper thread + //Remove this session from both client collection and UI tree view + if (Program.iFormMain.iClients.Keys.Contains(aSessionId)) + { + Program.iFormMain.iClients.Remove(aSessionId); + Program.iFormMain.iTreeViewClients.Nodes.Remove( + Program.iFormMain.iTreeViewClients.Nodes.Find(aSessionId, false)[0]); + //Update recording status too whenever a client is removed + UpdateRecordingNotification(); + } + + if (iCurrentClientSessionId == aSessionId) + { + //The current client is closing + iCurrentClientData = null; + //Find the client with the highest priority and set it as current + ClientData newCurrentClient = FindHighestPriorityClient(); + if (newCurrentClient != null) + { + SetCurrentClient(newCurrentClient.SessionId, true); + } + } + + if (iClients.Count == 0) + { + //Clear our screen when last client disconnects + ClearLayout(); + + if (iClosing) + { + //We were closing our form + //All clients are now closed + //Just resume our close operation + iClosing = false; + Close(); + } + } + } + } + + /// + /// + /// + /// + /// + public void SetClientLayoutThreadSafe(string aSessionId, TableLayout aLayout) + { + if (this.InvokeRequired) + { + //Not in the proper thread, invoke ourselves + SetLayoutDelegate d = new SetLayoutDelegate(SetClientLayoutThreadSafe); + this.Invoke(d, new object[] {aSessionId, aLayout}); + } + else + { + ClientData client = iClients[aSessionId]; + if (client != null) + { + //Don't change a thing if the layout is the same + if (!client.Layout.IsSameAs(aLayout)) + { + Debug.Print("SetClientLayoutThreadSafe: Layout updated."); + //Set our client layout then + client.Layout = aLayout; + //So that next time we update all our fields at ones + client.HasNewLayout = true; + //Layout has changed clear our fields then + client.Fields.Clear(); + // + UpdateClientTreeViewNode(client); + } + else + { + Debug.Print("SetClientLayoutThreadSafe: Layout has not changed."); + } + } + } + } + + /// + /// + /// + /// + /// + public void SetClientFieldThreadSafe(string aSessionId, DataField aField) + { + if (this.InvokeRequired) + { + //Not in the proper thread, invoke ourselves + SetFieldDelegate d = new SetFieldDelegate(SetClientFieldThreadSafe); + this.Invoke(d, new object[] {aSessionId, aField}); + } + else + { + //We are in the proper thread + //Call the non-thread-safe variant + SetClientField(aSessionId, aField); + } + } + + + + + /// + /// Set a data field in the given client. + /// + /// + /// + private void SetClientField(string aSessionId, DataField aField) + { + //TODO: should check if the field actually changed? + + ClientData client = iClients[aSessionId]; + bool layoutChanged = false; + bool contentChanged = true; + + //Fetch our field index + int fieldIndex = client.FindSameFieldIndex(aField); + + if (fieldIndex < 0) + { + //No corresponding field, just bail out + return; + } + + //Keep our previous field in there + DataField previousField = client.Fields[fieldIndex]; + //Just update that field then + client.Fields[fieldIndex] = aField; + + if (!aField.IsTableField) + { + //We are done then if that field is not in our table layout + return; + } + + TableField tableField = (TableField) aField; + + if (previousField.IsSameLayout(aField)) + { + //If we are updating a field in our current client we need to update it in our panel + if (aSessionId == iCurrentClientSessionId) + { + Control ctrl = iTableLayoutPanel.GetControlFromPosition(tableField.Column, tableField.Row); + if (aField.IsTextField && ctrl is MarqueeLabel) + { + TextField textField = (TextField) aField; + //Text field control already in place, just change the text + MarqueeLabel label = (MarqueeLabel) ctrl; + contentChanged = (label.Text != textField.Text || label.TextAlign != textField.Alignment); + label.Text = textField.Text; + label.TextAlign = textField.Alignment; + } + else if (aField.IsBitmapField && ctrl is PictureBox) + { + BitmapField bitmapField = (BitmapField) aField; + contentChanged = true; //TODO: Bitmap comp or should we leave that to clients? + //Bitmap field control already in place just change the bitmap + PictureBox pictureBox = (PictureBox) ctrl; + pictureBox.Image = bitmapField.Bitmap; + } + else + { + layoutChanged = true; + } + } + } + else + { + layoutChanged = true; + } + + //If either content or layout changed we need to update our tree view to reflect the changes + if (contentChanged || layoutChanged) + { + UpdateClientTreeViewNode(client); + // + if (layoutChanged) + { + Debug.Print("Layout changed"); + //Our layout has changed, if we are already the current client we need to update our panel + if (aSessionId == iCurrentClientSessionId) + { + //Apply layout and set data fields. + UpdateTableLayoutPanel(iCurrentClientData); + } + } + else + { + Debug.Print("Layout has not changed."); + } + } + else + { + Debug.Print("WARNING: content and layout have not changed!"); + } + + //When a client field is set we try switching to this client to present the new information to our user + SetCurrentClient(aSessionId); + } + + /// + /// + /// + /// + public void SetClientFieldsThreadSafe(string aSessionId, System.Collections.Generic.IList aFields) + { + if (this.InvokeRequired) + { + //Not in the proper thread, invoke ourselves + SetFieldsDelegate d = new SetFieldsDelegate(SetClientFieldsThreadSafe); + this.Invoke(d, new object[] {aSessionId, aFields}); + } + else + { + ClientData client = iClients[aSessionId]; + + if (client.HasNewLayout) + { + //TODO: Assert client.Count == 0 + //Our layout was just changed + //Do some special handling to avoid re-creating our panel N times, once for each fields + client.HasNewLayout = false; + //Just set all our fields then + client.Fields.AddRange(aFields); + //Try switch to that client + SetCurrentClient(aSessionId); + + //If we are updating the current client update our panel + if (aSessionId == iCurrentClientSessionId) + { + //Apply layout and set data fields. + UpdateTableLayoutPanel(iCurrentClientData); + } + + UpdateClientTreeViewNode(client); + } + else + { + //Put each our text fields in a label control + foreach (DataField field in aFields) + { + SetClientField(aSessionId, field); + } + } + } + } + + /// + /// + /// + /// + /// + public void SetClientNameThreadSafe(string aSessionId, string aName) + { + if (this.InvokeRequired) + { + //Not in the proper thread, invoke ourselves + SetClientNameDelegate d = new SetClientNameDelegate(SetClientNameThreadSafe); + this.Invoke(d, new object[] {aSessionId, aName}); + } + else + { + //We are in the proper thread + //Get our client + ClientData client = iClients[aSessionId]; + if (client != null) + { + //Set its name + client.Name = aName; + //Update our tree-view + UpdateClientTreeViewNode(client); + } + } + } + + /// + public void SetClientPriorityThreadSafe(string aSessionId, uint aPriority) + { + if (this.InvokeRequired) + { + //Not in the proper thread, invoke ourselves + SetClientPriorityDelegate d = new SetClientPriorityDelegate(SetClientPriorityThreadSafe); + this.Invoke(d, new object[] {aSessionId, aPriority}); + } + else + { + //We are in the proper thread + //Get our client + ClientData client = iClients[aSessionId]; + if (client != null) + { + //Set its name + client.Priority = aPriority; + //Update our tree-view + UpdateClientTreeViewNode(client); + //Change our current client as per new priority + ClientData newCurrentClient = FindHighestPriorityClient(); + if (newCurrentClient != null) + { + SetCurrentClient(newCurrentClient.SessionId); + } + } + } + } + + /// + /// + /// + /// + /// + /// + public static string Truncate(string value, int maxChars) + { + return value.Length <= maxChars ? value : value.Substring(0, maxChars - 3) + "..."; + } + + /// + /// Update our recording notification. + /// + private void UpdateRecordingNotification() + { + //Go through each + bool activeRecording = false; + string text = ""; + RecordingField recField = new RecordingField(); + foreach (var client in iClients) + { + RecordingField rec = (RecordingField) client.Value.FindSameFieldAs(recField); + if (rec != null && rec.IsActive) + { + activeRecording = true; + //Don't break cause we are collecting the names/texts. + if (!String.IsNullOrEmpty(rec.Text)) + { + text += (rec.Text + "\n"); + } + else + { + //Not text for that recording, use client name instead + text += client.Value.Name + " recording\n"; + } + + } + } + + //Update our text no matter what, can't have more than 63 characters otherwise it throws an exception. + iRecordingNotification.Text = Truncate(text, 63); + + //Change visibility of notification if needed + if (iRecordingNotification.Visible != activeRecording) + { + iRecordingNotification.Visible = activeRecording; + //Assuming the notification icon is in sync with our display icon + //Take care of our REC icon + if (iDisplay.IsOpen()) + { + iDisplay.SetIconOnOff(MiniDisplay.IconType.Recording, activeRecording); + } + } + } + + /// + /// + /// + /// + private void UpdateClientTreeViewNode(ClientData aClient) + { + Debug.Print("UpdateClientTreeViewNode"); + + if (aClient == null) + { + return; + } + + //Hook in record icon update too + UpdateRecordingNotification(); + + TreeNode node = null; + //Check that our client node already exists + //Get our client root node using its key which is our session ID + TreeNode[] nodes = iTreeViewClients.Nodes.Find(aClient.SessionId, false); + if (nodes.Count() > 0) + { + //We already have a node for that client + node = nodes[0]; + //Clear children as we are going to recreate them below + node.Nodes.Clear(); + } + else + { + //Client node does not exists create a new one + iTreeViewClients.Nodes.Add(aClient.SessionId, aClient.SessionId); + node = iTreeViewClients.Nodes.Find(aClient.SessionId, false)[0]; + } + + if (node != null) + { + //Change its name + if (!String.IsNullOrEmpty(aClient.Name)) + { + //We have a name, use it as text for our root node + node.Text = aClient.Name; + //Add a child with SessionId + node.Nodes.Add(new TreeNode(aClient.SessionId)); + } + else + { + //No name, use session ID instead + node.Text = aClient.SessionId; + } + + //Display client priority + node.Nodes.Add(new TreeNode("Priority: " + aClient.Priority)); + + if (aClient.Fields.Count > 0) + { + //Create root node for our texts + TreeNode textsRoot = new TreeNode("Fields"); + node.Nodes.Add(textsRoot); + //For each text add a new entry + foreach (DataField field in aClient.Fields) + { + if (field.IsTextField) + { + TextField textField = (TextField) field; + textsRoot.Nodes.Add(new TreeNode("[Text]" + textField.Text)); + } + else if (field.IsBitmapField) + { + textsRoot.Nodes.Add(new TreeNode("[Bitmap]")); + } + else if (field.IsRecordingField) + { + RecordingField recordingField = (RecordingField) field; + textsRoot.Nodes.Add(new TreeNode("[Recording]" + recordingField.IsActive)); + } + } + } + + node.ExpandAll(); + } + } + + /// + /// Update our table layout row styles to make sure each rows have similar height + /// + private void UpdateTableLayoutRowStyles() + { + foreach (RowStyle rowStyle in iTableLayoutPanel.RowStyles) + { + rowStyle.SizeType = SizeType.Percent; + rowStyle.Height = 100/iTableLayoutPanel.RowCount; + } + } + + /// + /// Update our display table layout. + /// Will instanciated every field control as defined by our client. + /// Fields must be specified by rows from the left. + /// + /// + private void UpdateTableLayoutPanel(ClientData aClient) + { + Debug.Print("UpdateTableLayoutPanel"); + + if (aClient == null) + { + //Just drop it + return; + } + + + TableLayout layout = aClient.Layout; + + //First clean our current panel + iTableLayoutPanel.Controls.Clear(); + iTableLayoutPanel.RowStyles.Clear(); + iTableLayoutPanel.ColumnStyles.Clear(); + iTableLayoutPanel.RowCount = 0; + iTableLayoutPanel.ColumnCount = 0; + + //Then recreate our rows... + while (iTableLayoutPanel.RowCount < layout.Rows.Count) + { + iTableLayoutPanel.RowCount++; + } + + // ...and columns + while (iTableLayoutPanel.ColumnCount < layout.Columns.Count) + { + iTableLayoutPanel.ColumnCount++; + } + + //For each column + for (int i = 0; i < iTableLayoutPanel.ColumnCount; i++) + { + //Create our column styles + this.iTableLayoutPanel.ColumnStyles.Add(layout.Columns[i]); + + //For each rows + for (int j = 0; j < iTableLayoutPanel.RowCount; j++) + { + if (i == 0) + { + //Create our row styles + this.iTableLayoutPanel.RowStyles.Add(layout.Rows[j]); + } + else + { + continue; + } + } + } + + //For each field + foreach (DataField field in aClient.Fields) + { + if (!field.IsTableField) + { + //That field is not taking part in our table layout skip it + continue; + } + + TableField tableField = (TableField) field; + + //Create a control corresponding to the field specified for that cell + Control control = CreateControlForDataField(tableField); + + //Add newly created control to our table layout at the specified row and column + iTableLayoutPanel.Controls.Add(control, tableField.Column, tableField.Row); + //Make sure we specify column and row span for that new control + iTableLayoutPanel.SetColumnSpan(control, tableField.ColumnSpan); + iTableLayoutPanel.SetRowSpan(control, tableField.RowSpan); + } + + + CheckFontHeight(); + } + + /// + /// Check our type of data field and create corresponding control + /// + /// + private Control CreateControlForDataField(DataField aField) + { + Control control = null; + if (aField.IsTextField) + { + MarqueeLabel label = new SharpDisplayManager.MarqueeLabel(); + label.AutoEllipsis = true; + label.AutoSize = true; + label.BackColor = System.Drawing.Color.Transparent; + label.Dock = System.Windows.Forms.DockStyle.Fill; + label.Location = new System.Drawing.Point(1, 1); + label.Margin = new System.Windows.Forms.Padding(0); + label.Name = "marqueeLabel" + aField; + label.OwnTimer = false; + label.PixelsPerSecond = cds.ScrollingSpeedInPixelsPerSecond; + label.Separator = cds.Separator; + label.MinFontSize = cds.MinFontSize; + label.ScaleToFit = cds.ScaleToFit; + //control.Size = new System.Drawing.Size(254, 30); + //control.TabIndex = 2; + label.Font = cds.Font; + + TextField field = (TextField) aField; + label.TextAlign = field.Alignment; + label.UseCompatibleTextRendering = true; + label.Text = field.Text; + // + control = label; + } + else if (aField.IsBitmapField) + { + //Create picture box + PictureBox picture = new PictureBox(); + picture.AutoSize = true; + picture.BackColor = System.Drawing.Color.Transparent; + picture.Dock = System.Windows.Forms.DockStyle.Fill; + picture.Location = new System.Drawing.Point(1, 1); + picture.Margin = new System.Windows.Forms.Padding(0); + picture.Name = "pictureBox" + aField; + //Set our image + BitmapField field = (BitmapField) aField; + picture.Image = field.Bitmap; + // + control = picture; + } + //TODO: Handle recording field? + + return control; + } + + /// + /// Called when the user selected a new display type. + /// + /// + /// + private void comboBoxDisplayType_SelectedIndexChanged(object sender, EventArgs e) + { + //Store the selected display type in our settings + Properties.Settings.Default.CurrentDisplayIndex = comboBoxDisplayType.SelectedIndex; + cds.DisplayType = comboBoxDisplayType.SelectedIndex; + Properties.Settings.Default.Save(); + + //Try re-opening the display connection if we were already connected. + //Otherwise just update our status to reflect display type change. + if (iDisplay.IsOpen()) + { + OpenDisplayConnection(); + } + else + { + UpdateStatus(); + } + } + + private void maskedTextBoxTimerInterval_TextChanged(object sender, EventArgs e) + { + if (maskedTextBoxTimerInterval.Text != "") + { + int interval = Convert.ToInt32(maskedTextBoxTimerInterval.Text); + + if (interval > 0) + { + timer.Interval = interval; + cds.TimerInterval = timer.Interval; + Properties.Settings.Default.Save(); + } + } + } + + private void maskedTextBoxMinFontSize_TextChanged(object sender, EventArgs e) + { + if (maskedTextBoxMinFontSize.Text != "") + { + int minFontSize = Convert.ToInt32(maskedTextBoxMinFontSize.Text); + + if (minFontSize > 0) + { + cds.MinFontSize = minFontSize; + Properties.Settings.Default.Save(); + //We need to recreate our layout for that change to take effect + UpdateTableLayoutPanel(iCurrentClientData); + } + } + } + + + private void maskedTextBoxScrollingSpeed_TextChanged(object sender, EventArgs e) + { + if (maskedTextBoxScrollingSpeed.Text != "") + { + int scrollingSpeed = Convert.ToInt32(maskedTextBoxScrollingSpeed.Text); + + if (scrollingSpeed > 0) + { + cds.ScrollingSpeedInPixelsPerSecond = scrollingSpeed; + Properties.Settings.Default.Save(); + //We need to recreate our layout for that change to take effect + UpdateTableLayoutPanel(iCurrentClientData); + } + } + } + + private void textBoxScrollLoopSeparator_TextChanged(object sender, EventArgs e) + { + cds.Separator = textBoxScrollLoopSeparator.Text; + Properties.Settings.Default.Save(); + + //Update our text fields + foreach (MarqueeLabel ctrl in iTableLayoutPanel.Controls) + { + ctrl.Separator = cds.Separator; + } + + } + + private void buttonPowerOn_Click(object sender, EventArgs e) + { + iDisplay.PowerOn(); + } + + private void buttonPowerOff_Click(object sender, EventArgs e) + { + iDisplay.PowerOff(); + } + + private void buttonShowClock_Click(object sender, EventArgs e) + { + ShowClock(); + } + + private void buttonHideClock_Click(object sender, EventArgs e) + { + HideClock(); + } + + private void buttonUpdate_Click(object sender, EventArgs e) + { + InstallUpdateSyncWithInfo(); + } + + /// + /// + /// + void ShowClock() + { + if (!iDisplay.IsOpen()) + { + return; + } + + //Devices like MDM166AA don't support windowing and frame rendering must be stopped while showing our clock + iSkipFrameRendering = true; + //Clear our screen + iDisplay.Clear(); + iDisplay.SwapBuffers(); + //Then show our clock + iDisplay.ShowClock(); + } + + /// + /// + /// + void HideClock() + { + if (!iDisplay.IsOpen()) + { + return; + } + + //Devices like MDM166AA don't support windowing and frame rendering must be stopped while showing our clock + iSkipFrameRendering = false; + iDisplay.HideClock(); + } + + private void InstallUpdateSyncWithInfo() + { + UpdateCheckInfo info = null; + + if (ApplicationDeployment.IsNetworkDeployed) + { + ApplicationDeployment ad = ApplicationDeployment.CurrentDeployment; + + try + { + info = ad.CheckForDetailedUpdate(); + + } + catch (DeploymentDownloadException dde) + { + MessageBox.Show( + "The new version of the application cannot be downloaded at this time. \n\nPlease check your network connection, or try again later. Error: " + + dde.Message); + return; + } + catch (InvalidDeploymentException ide) + { + MessageBox.Show( + "Cannot check for a new version of the application. The ClickOnce deployment is corrupt. Please redeploy the application and try again. Error: " + + ide.Message); + return; + } + catch (InvalidOperationException ioe) + { + MessageBox.Show( + "This application cannot be updated. It is likely not a ClickOnce application. Error: " + + ioe.Message); + return; + } + + if (info.UpdateAvailable) + { + Boolean doUpdate = true; + + if (!info.IsUpdateRequired) + { + DialogResult dr = + MessageBox.Show("An update is available. Would you like to update the application now?", + "Update Available", MessageBoxButtons.OKCancel); + if (!(DialogResult.OK == dr)) + { + doUpdate = false; + } + } + else + { + // Display a message that the application MUST reboot. Display the minimum required version. + MessageBox.Show("This application has detected a mandatory update from your current " + + "version to version " + info.MinimumRequiredVersion.ToString() + + ". The application will now install the update and restart.", + "Update Available", MessageBoxButtons.OK, + MessageBoxIcon.Information); + } + + if (doUpdate) + { + try + { + ad.Update(); + MessageBox.Show("The application has been upgraded, and will now restart."); + Application.Restart(); + } + catch (DeploymentDownloadException dde) + { + MessageBox.Show( + "Cannot install the latest version of the application. \n\nPlease check your network connection, or try again later. Error: " + + dde); + return; + } + } + } + else + { + MessageBox.Show("You are already running the latest version.", "Application up-to-date"); + } + } + } + + + /// + /// Used to + /// + private void SysTrayHideShow() + { + Visible = !Visible; + if (Visible) + { + Activate(); + WindowState = FormWindowState.Normal; + } + } + + /// + /// Use to handle minimize events. + /// + /// + /// + private void MainForm_SizeChanged(object sender, EventArgs e) + { + if (WindowState == FormWindowState.Minimized && Properties.Settings.Default.MinimizeToTray) + { + if (Visible) + { + SysTrayHideShow(); + } + } + } + + /// + /// + /// + /// + /// + private void tableLayoutPanel_SizeChanged(object sender, EventArgs e) + { + //Our table layout size has changed which means our display size has changed. + //We need to re-create our bitmap. + iCreateBitmap = true; + } + + /// + /// + /// + /// + /// + private void buttonSelectFile_Click(object sender, EventArgs e) + { + //openFileDialog1.InitialDirectory = "c:\\"; + //openFileDialog.Filter = "EXE files (*.exe)|*.exe|All files (*.*)|*.*"; + //openFileDialog.FilterIndex = 1; + openFileDialog.RestoreDirectory = true; + + if (DlgBox.ShowDialog(openFileDialog) == DialogResult.OK) + { + labelStartFileName.Text = openFileDialog.FileName; + Properties.Settings.Default.StartFileName = openFileDialog.FileName; + Properties.Settings.Default.Save(); + } + } + + /// + /// + /// + /// + /// + private void comboBoxOpticalDrives_SelectedIndexChanged(object sender, EventArgs e) + { + //Save the optical drive the user selected for ejection + Properties.Settings.Default.OpticalDriveToEject = comboBoxOpticalDrives.SelectedItem.ToString(); + Properties.Settings.Default.Save(); + } + + + /// + /// + /// + private void LogsUpdate() + { + if (iWriter != null) + { + iWriter.Flush(); + } + + } + + /// + /// Broadcast messages to subscribers. + /// + /// + protected override void WndProc(ref Message aMessage) + { + LogsUpdate(); + + if (OnWndProc != null) + { + OnWndProc(ref aMessage); + } + + base.WndProc(ref aMessage); + } + + private void checkBoxCecEnabled_CheckedChanged(object sender, EventArgs e) + { + //Save CEC enabled status + Properties.Settings.Default.CecEnabled = checkBoxCecEnabled.Checked; + Properties.Settings.Default.Save(); + // + ResetCec(); + } + + private void comboBoxHdmiPort_SelectedIndexChanged(object sender, EventArgs e) + { + //Save CEC HDMI port + Properties.Settings.Default.CecHdmiPort = Convert.ToByte(comboBoxHdmiPort.SelectedIndex); + Properties.Settings.Default.CecHdmiPort++; + Properties.Settings.Default.Save(); + // + ResetCec(); + } + + /// + /// + /// + private void ResetCec() + { + if (iCecManager == null) + { + //Thus skipping initial UI setup + return; + } + + iCecManager.Stop(); + // + if (Properties.Settings.Default.CecEnabled) + { + iCecManager.Start(Handle, "CEC", + Properties.Settings.Default.CecHdmiPort); + + SetupCecLogLevel(); + } + } + + /// + /// + /// + private void SetupCecLogLevel() + { + //Setup log level + iCecManager.Client.LogLevel = 0; + + if (checkBoxCecLogError.Checked) + iCecManager.Client.LogLevel |= (int) CecLogLevel.Error; + + if (checkBoxCecLogWarning.Checked) + iCecManager.Client.LogLevel |= (int) CecLogLevel.Warning; + + if (checkBoxCecLogNotice.Checked) + iCecManager.Client.LogLevel |= (int) CecLogLevel.Notice; + + if (checkBoxCecLogTraffic.Checked) + iCecManager.Client.LogLevel |= (int) CecLogLevel.Traffic; + + if (checkBoxCecLogDebug.Checked) + iCecManager.Client.LogLevel |= (int) CecLogLevel.Debug; + + iCecManager.Client.FilterOutPollLogs = checkBoxCecLogNoPoll.Checked; + + } + + private void ButtonStartIdleClient_Click(object sender, EventArgs e) + { + StartIdleClient(); + } + + private void buttonClearLogs_Click(object sender, EventArgs e) + { + richTextBoxLogs.Clear(); + } + + private void checkBoxCecLogs_CheckedChanged(object sender, EventArgs e) + { + SetupCecLogLevel(); + } + + + /// + /// + /// + /// + private void SelectEvent(Event aEvent) + { + if (aEvent == null) + { + return; + } + + string key = aEvent.GetType().Name; + TreeNode[] res = iTreeViewEvents.Nodes.Find(key, false); + if (res.Length > 0) + { + iTreeViewEvents.SelectedNode = res[0]; + iTreeViewEvents.Focus(); + } + } + + + + /// + /// Get the current event based on event tree view selection. + /// + /// + private Event CurrentEvent() + { + //Walk up the tree from the selected node to find our event + TreeNode node = iTreeViewEvents.SelectedNode; + Event selectedEvent = null; + while (node != null) + { + if (node.Tag is Event) + { + selectedEvent = (Event) node.Tag; + break; + } + node = node.Parent; + } + + return selectedEvent; + } + + /// + /// Get the current action based on event tree view selection + /// + /// + private SharpLib.Ear.Action CurrentAction() + { + TreeNode node = iTreeViewEvents.SelectedNode; + if (node != null && node.Tag is SharpLib.Ear.Action) + { + return (SharpLib.Ear.Action) node.Tag; + } + + return null; + } + + /// + /// + /// + /// + /// + private void buttonAddAction_Click(object sender, EventArgs e) + { + Event selectedEvent = CurrentEvent(); + if (selectedEvent == null) + { + //We did not find a corresponding event + return; + } + + FormEditAction ea = new FormEditAction(); + DialogResult res = CodeProject.Dialog.DlgBox.ShowDialog(ea); + if (res == DialogResult.OK) + { + selectedEvent.Actions.Add(ea.Action); + Properties.Settings.Default.Actions = ManagerEventAction.Current; + Properties.Settings.Default.Save(); + PopulateEventsTreeView(); + } + } + + /// + /// + /// + /// + /// + private void buttonDeleteAction_Click(object sender, EventArgs e) + { + + SharpLib.Ear.Action action = CurrentAction(); + if (action == null) + { + //Must select action node + return; + } + + ManagerEventAction.Current.RemoveAction(action); + Properties.Settings.Default.Actions = ManagerEventAction.Current; + Properties.Settings.Default.Save(); + PopulateEventsTreeView(); + } + + private void iTreeViewEvents_AfterSelect(object sender, TreeViewEventArgs e) + { + //Enable buttons according to selected item + buttonAddAction.Enabled = CurrentEvent() != null; + + SharpLib.Ear.Action currentAction = CurrentAction(); + //If an action is selected enable the following buttons + buttonTestAction.Enabled = + buttonDeleteAction.Enabled = + buttonActionMoveUp.Enabled = + buttonActionMoveDown.Enabled = + currentAction != null; + + if (currentAction != null) + { + //If an action is selected enable move buttons if needed + buttonActionMoveUp.Enabled = iTreeViewEvents.SelectedNode.Index != 0; + buttonActionMoveDown.Enabled = iTreeViewEvents.SelectedNode.Index < + iTreeViewEvents.SelectedNode.Parent.Nodes.Count - 1; + } + + } + + /// + /// + /// + /// + /// + private void buttonTestAction_Click(object sender, EventArgs e) + { + SharpLib.Ear.Action a = CurrentAction(); + if (a != null) + { + Console.WriteLine("Action test run"); + a.Execute(); + } + iTreeViewEvents.Focus(); + } + + /// + /// + /// + /// + /// + private void buttonActionMoveUp_Click(object sender, EventArgs e) + { + SharpLib.Ear.Action a = CurrentAction(); + if (a == null || + //Action already at the top of the list + iTreeViewEvents.SelectedNode.Index == 0) + { + return; + } + + //Swap actions in event's action list + Event currentEvent = CurrentEvent(); + int currentIndex = iTreeViewEvents.SelectedNode.Index; + SharpLib.Ear.Action movingUp = currentEvent.Actions[currentIndex]; + SharpLib.Ear.Action movingDown = currentEvent.Actions[currentIndex-1]; + currentEvent.Actions[currentIndex] = movingDown; + currentEvent.Actions[currentIndex-1] = movingUp; + + //Save and populate our tree again + Properties.Settings.Default.Actions = ManagerEventAction.Current; + Properties.Settings.Default.Save(); + PopulateEventsTreeView(); + + } + + /// + /// + /// + /// + /// + private void buttonActionMoveDown_Click(object sender, EventArgs e) + { + SharpLib.Ear.Action a = CurrentAction(); + if (a == null || + //Action already at the bottom of the list + iTreeViewEvents.SelectedNode.Index == iTreeViewEvents.SelectedNode.Parent.Nodes.Count - 1) + { + return; + } + + //Swap actions in event's action list + Event currentEvent = CurrentEvent(); + int currentIndex = iTreeViewEvents.SelectedNode.Index; + SharpLib.Ear.Action movingDown = currentEvent.Actions[currentIndex]; + SharpLib.Ear.Action movingUp = currentEvent.Actions[currentIndex + 1]; + currentEvent.Actions[currentIndex] = movingUp; + currentEvent.Actions[currentIndex + 1] = movingDown; + + //Save and populate our tree again + Properties.Settings.Default.Actions = ManagerEventAction.Current; + Properties.Settings.Default.Save(); + PopulateEventsTreeView(); + } + } +} diff -r 6ccaa430aa23 -r 91763ba41c0c Server/FormMain.resx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Server/FormMain.resx Fri Jul 29 10:40:15 2016 +0200 @@ -0,0 +1,418 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + + 126, 17 + + + 206, 17 + + + 315, 17 + + + + + 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 + + + + 405, 17 + + + + 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 + CYub2lgAAAAASUVORK5CYII= + + + \ No newline at end of file diff -r 6ccaa430aa23 -r 91763ba41c0c Server/MainForm.Designer.cs --- a/Server/MainForm.Designer.cs Thu Jul 28 19:32:40 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1321 +0,0 @@ -namespace SharpDisplayManager -{ - partial class MainForm - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing) - { - if (iNotifyIcon != null) - { - iNotifyIcon.Dispose(); - iNotifyIcon = null; - } - - if (components != null) - { - components.Dispose(); - } - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.components = new System.ComponentModel.Container(); - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); - this.panelDisplay = new System.Windows.Forms.Panel(); - this.iTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel(); - this.marqueeLabelTop = new SharpDisplayManager.MarqueeLabel(); - this.marqueeLabelBottom = new SharpDisplayManager.MarqueeLabel(); - this.fontDialog = new System.Windows.Forms.FontDialog(); - this.timer = new System.Windows.Forms.Timer(this.components); - this.statusStrip = new System.Windows.Forms.StatusStrip(); - this.toolStripStatusLabelConnect = new System.Windows.Forms.ToolStripStatusLabel(); - this.toolStripStatusLabelSpring = new System.Windows.Forms.ToolStripStatusLabel(); - this.toolStripStatusLabelPower = new System.Windows.Forms.ToolStripStatusLabel(); - this.toolStripStatusLabelFps = new System.Windows.Forms.ToolStripStatusLabel(); - this.tabPageClients = new System.Windows.Forms.TabPage(); - this.iCheckBoxStartIdleClient = new System.Windows.Forms.CheckBox(); - this.iButtonStartIdleClient = new System.Windows.Forms.Button(); - this.buttonCloseClients = new System.Windows.Forms.Button(); - this.buttonStartClient = new System.Windows.Forms.Button(); - this.iTreeViewClients = new System.Windows.Forms.TreeView(); - this.tabPageDisplay = new System.Windows.Forms.TabPage(); - this.buttonShowClock = new System.Windows.Forms.Button(); - this.buttonHideClock = new System.Windows.Forms.Button(); - this.buttonPowerOff = new System.Windows.Forms.Button(); - this.buttonPowerOn = new System.Windows.Forms.Button(); - this.labelTimerInterval = new System.Windows.Forms.Label(); - this.maskedTextBoxTimerInterval = new System.Windows.Forms.MaskedTextBox(); - this.comboBoxDisplayType = new System.Windows.Forms.ComboBox(); - this.buttonSuspend = new System.Windows.Forms.Button(); - this.checkBoxConnectOnStartup = new System.Windows.Forms.CheckBox(); - this.trackBarBrightness = new System.Windows.Forms.TrackBar(); - this.buttonFill = new System.Windows.Forms.Button(); - this.buttonClear = new System.Windows.Forms.Button(); - this.buttonClose = new System.Windows.Forms.Button(); - this.buttonOpen = new System.Windows.Forms.Button(); - this.buttonCapture = new System.Windows.Forms.Button(); - this.labelWarning = new System.Windows.Forms.Label(); - this.checkBoxFixedPitchFontOnly = new System.Windows.Forms.CheckBox(); - this.checkBoxShowBorders = new System.Windows.Forms.CheckBox(); - this.buttonFont = new System.Windows.Forms.Button(); - this.tabControl = new System.Windows.Forms.TabControl(); - this.tabPageDesign = new System.Windows.Forms.TabPage(); - this.labelScrollingSpeed = new System.Windows.Forms.Label(); - this.maskedTextBoxScrollingSpeed = new System.Windows.Forms.MaskedTextBox(); - this.labelScrollLoopSeparator = new System.Windows.Forms.Label(); - this.textBoxScrollLoopSeparator = new System.Windows.Forms.TextBox(); - this.labelMinFontSize = new System.Windows.Forms.Label(); - this.maskedTextBoxMinFontSize = new System.Windows.Forms.MaskedTextBox(); - this.checkBoxScaleToFit = new System.Windows.Forms.CheckBox(); - this.checkBoxInverseColors = new System.Windows.Forms.CheckBox(); - this.checkBoxReverseScreen = new System.Windows.Forms.CheckBox(); - this.tabPageAudio = new System.Windows.Forms.TabPage(); - this.labelDefaultAudioDevice = new System.Windows.Forms.Label(); - this.checkBoxShowVolumeLabel = new System.Windows.Forms.CheckBox(); - this.checkBoxMute = new System.Windows.Forms.CheckBox(); - this.trackBarMasterVolume = new System.Windows.Forms.TrackBar(); - this.tabPageInput = new System.Windows.Forms.TabPage(); - this.comboBoxOpticalDrives = new System.Windows.Forms.ComboBox(); - this.labelOpticalDriveEject = new System.Windows.Forms.Label(); - this.pictureBoxGreenStart = new System.Windows.Forms.PictureBox(); - this.labelStartFileName = new System.Windows.Forms.Label(); - this.buttonSelectFile = new System.Windows.Forms.Button(); - this.tabPageCec = new System.Windows.Forms.TabPage(); - this.groupBoxCecLogOptions = new System.Windows.Forms.GroupBox(); - this.checkBoxCecLogNoPoll = new System.Windows.Forms.CheckBox(); - this.checkBoxCecLogTraffic = new System.Windows.Forms.CheckBox(); - this.checkBoxCecLogDebug = new System.Windows.Forms.CheckBox(); - this.checkBoxCecLogNotice = new System.Windows.Forms.CheckBox(); - this.checkBoxCecLogError = new System.Windows.Forms.CheckBox(); - this.checkBoxCecLogWarning = new System.Windows.Forms.CheckBox(); - this.checkBoxCecEnabled = new System.Windows.Forms.CheckBox(); - this.labelHdmiPort = new System.Windows.Forms.Label(); - this.comboBoxHdmiPort = new System.Windows.Forms.ComboBox(); - this.tabPageEvent = new System.Windows.Forms.TabPage(); - this.buttonActionMoveUp = new System.Windows.Forms.Button(); - this.buttonActionMoveDown = new System.Windows.Forms.Button(); - this.buttonTestAction = new System.Windows.Forms.Button(); - this.buttonDeleteAction = new System.Windows.Forms.Button(); - this.buttonAddAction = new System.Windows.Forms.Button(); - this.iTreeViewEvents = new System.Windows.Forms.TreeView(); - this.tabPageApp = new System.Windows.Forms.TabPage(); - this.checkBoxStartMinimized = new System.Windows.Forms.CheckBox(); - this.checkBoxMinimizeToTray = new System.Windows.Forms.CheckBox(); - this.checkBoxAutoStart = new System.Windows.Forms.CheckBox(); - this.buttonUpdate = new System.Windows.Forms.Button(); - this.tabPageLogs = new System.Windows.Forms.TabPage(); - this.buttonClearLogs = new System.Windows.Forms.Button(); - this.richTextBoxLogs = new System.Windows.Forms.RichTextBox(); - this.labelFontWidth = new System.Windows.Forms.Label(); - this.labelFontHeight = new System.Windows.Forms.Label(); - this.toolTip = new System.Windows.Forms.ToolTip(this.components); - this.openFileDialog = new System.Windows.Forms.OpenFileDialog(); - this.panelDisplay.SuspendLayout(); - this.iTableLayoutPanel.SuspendLayout(); - this.statusStrip.SuspendLayout(); - this.tabPageClients.SuspendLayout(); - this.tabPageDisplay.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.trackBarBrightness)).BeginInit(); - this.tabControl.SuspendLayout(); - this.tabPageDesign.SuspendLayout(); - this.tabPageAudio.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.trackBarMasterVolume)).BeginInit(); - this.tabPageInput.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBoxGreenStart)).BeginInit(); - this.tabPageCec.SuspendLayout(); - this.groupBoxCecLogOptions.SuspendLayout(); - this.tabPageEvent.SuspendLayout(); - this.tabPageApp.SuspendLayout(); - this.tabPageLogs.SuspendLayout(); - this.SuspendLayout(); - // - // panelDisplay - // - this.panelDisplay.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.panelDisplay.Controls.Add(this.iTableLayoutPanel); - this.panelDisplay.Location = new System.Drawing.Point(173, 40); - this.panelDisplay.Margin = new System.Windows.Forms.Padding(0); - this.panelDisplay.Name = "panelDisplay"; - this.panelDisplay.Size = new System.Drawing.Size(258, 66); - this.panelDisplay.TabIndex = 12; - // - // iTableLayoutPanel - // - this.iTableLayoutPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.iTableLayoutPanel.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; - this.iTableLayoutPanel.BackColor = System.Drawing.SystemColors.ControlLightLight; - this.iTableLayoutPanel.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.Single; - this.iTableLayoutPanel.ColumnCount = 1; - this.iTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.iTableLayoutPanel.Controls.Add(this.marqueeLabelTop, 0, 0); - this.iTableLayoutPanel.Controls.Add(this.marqueeLabelBottom, 0, 1); - this.iTableLayoutPanel.GrowStyle = System.Windows.Forms.TableLayoutPanelGrowStyle.FixedSize; - this.iTableLayoutPanel.Location = new System.Drawing.Point(0, 0); - this.iTableLayoutPanel.Margin = new System.Windows.Forms.Padding(0); - this.iTableLayoutPanel.Name = "iTableLayoutPanel"; - this.iTableLayoutPanel.RowCount = 2; - this.iTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); - this.iTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); - this.iTableLayoutPanel.Size = new System.Drawing.Size(256, 64); - this.iTableLayoutPanel.TabIndex = 5; - this.iTableLayoutPanel.SizeChanged += new System.EventHandler(this.tableLayoutPanel_SizeChanged); - // - // marqueeLabelTop - // - this.marqueeLabelTop.AutoEllipsis = true; - this.marqueeLabelTop.AutoSize = true; - this.marqueeLabelTop.BackColor = System.Drawing.Color.Transparent; - this.marqueeLabelTop.Dock = System.Windows.Forms.DockStyle.Fill; - this.marqueeLabelTop.Location = new System.Drawing.Point(1, 1); - this.marqueeLabelTop.Margin = new System.Windows.Forms.Padding(0); - this.marqueeLabelTop.MinFontSize = 15F; - this.marqueeLabelTop.Name = "marqueeLabelTop"; - this.marqueeLabelTop.OwnTimer = false; - this.marqueeLabelTop.PixelsPerSecond = 64; - this.marqueeLabelTop.ScaleToFit = true; - this.marqueeLabelTop.Separator = "|"; - this.marqueeLabelTop.Size = new System.Drawing.Size(254, 30); - this.marqueeLabelTop.TabIndex = 2; - this.marqueeLabelTop.Text = "ABCDEFGHIJKLMNOPQRST-0123456789"; - this.marqueeLabelTop.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - this.marqueeLabelTop.UseCompatibleTextRendering = true; - // - // marqueeLabelBottom - // - this.marqueeLabelBottom.AutoEllipsis = true; - this.marqueeLabelBottom.AutoSize = true; - this.marqueeLabelBottom.Dock = System.Windows.Forms.DockStyle.Fill; - this.marqueeLabelBottom.Location = new System.Drawing.Point(1, 32); - this.marqueeLabelBottom.Margin = new System.Windows.Forms.Padding(0); - this.marqueeLabelBottom.MinFontSize = 15F; - this.marqueeLabelBottom.Name = "marqueeLabelBottom"; - this.marqueeLabelBottom.OwnTimer = false; - this.marqueeLabelBottom.PixelsPerSecond = 64; - this.marqueeLabelBottom.ScaleToFit = true; - this.marqueeLabelBottom.Separator = "|"; - this.marqueeLabelBottom.Size = new System.Drawing.Size(254, 31); - this.marqueeLabelBottom.TabIndex = 3; - this.marqueeLabelBottom.Text = "abcdefghijklmnopqrst-0123456789"; - this.marqueeLabelBottom.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - this.marqueeLabelBottom.UseCompatibleTextRendering = true; - // - // timer - // - this.timer.Interval = 50; - this.timer.Tick += new System.EventHandler(this.timer_Tick); - // - // statusStrip - // - this.statusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.toolStripStatusLabelConnect, - this.toolStripStatusLabelSpring, - this.toolStripStatusLabelPower, - this.toolStripStatusLabelFps}); - this.statusStrip.Location = new System.Drawing.Point(0, 539); - this.statusStrip.Name = "statusStrip"; - this.statusStrip.RenderMode = System.Windows.Forms.ToolStripRenderMode.Professional; - this.statusStrip.Size = new System.Drawing.Size(784, 22); - this.statusStrip.TabIndex = 1; - this.statusStrip.Text = "statusStrip"; - // - // toolStripStatusLabelConnect - // - this.toolStripStatusLabelConnect.Name = "toolStripStatusLabelConnect"; - this.toolStripStatusLabelConnect.Size = new System.Drawing.Size(86, 17); - this.toolStripStatusLabelConnect.Text = "Not connected"; - // - // toolStripStatusLabelSpring - // - this.toolStripStatusLabelSpring.Name = "toolStripStatusLabelSpring"; - this.toolStripStatusLabelSpring.Size = new System.Drawing.Size(633, 17); - this.toolStripStatusLabelSpring.Spring = true; - // - // toolStripStatusLabelPower - // - this.toolStripStatusLabelPower.Name = "toolStripStatusLabelPower"; - this.toolStripStatusLabelPower.Size = new System.Drawing.Size(24, 17); - this.toolStripStatusLabelPower.Text = "NA"; - // - // toolStripStatusLabelFps - // - this.toolStripStatusLabelFps.Name = "toolStripStatusLabelFps"; - this.toolStripStatusLabelFps.Size = new System.Drawing.Size(26, 17); - this.toolStripStatusLabelFps.Text = "FPS"; - // - // tabPageClients - // - this.tabPageClients.Controls.Add(this.iCheckBoxStartIdleClient); - this.tabPageClients.Controls.Add(this.iButtonStartIdleClient); - this.tabPageClients.Controls.Add(this.buttonCloseClients); - this.tabPageClients.Controls.Add(this.buttonStartClient); - this.tabPageClients.Controls.Add(this.iTreeViewClients); - this.tabPageClients.Location = new System.Drawing.Point(4, 22); - this.tabPageClients.Name = "tabPageClients"; - this.tabPageClients.Padding = new System.Windows.Forms.Padding(3); - this.tabPageClients.Size = new System.Drawing.Size(752, 385); - this.tabPageClients.TabIndex = 2; - this.tabPageClients.Text = "Clients"; - this.tabPageClients.UseVisualStyleBackColor = true; - // - // iCheckBoxStartIdleClient - // - this.iCheckBoxStartIdleClient.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.iCheckBoxStartIdleClient.AutoSize = true; - this.iCheckBoxStartIdleClient.Location = new System.Drawing.Point(108, 340); - this.iCheckBoxStartIdleClient.Name = "iCheckBoxStartIdleClient"; - this.iCheckBoxStartIdleClient.Size = new System.Drawing.Size(145, 17); - this.iCheckBoxStartIdleClient.TabIndex = 22; - this.iCheckBoxStartIdleClient.Text = "Start idle client on startup"; - this.iCheckBoxStartIdleClient.UseVisualStyleBackColor = true; - this.iCheckBoxStartIdleClient.CheckedChanged += new System.EventHandler(this.checkBoxStartIdleClient_CheckedChanged); - // - // iButtonStartIdleClient - // - this.iButtonStartIdleClient.Location = new System.Drawing.Point(6, 35); - this.iButtonStartIdleClient.Name = "iButtonStartIdleClient"; - this.iButtonStartIdleClient.Size = new System.Drawing.Size(96, 23); - this.iButtonStartIdleClient.TabIndex = 21; - this.iButtonStartIdleClient.Text = "Start Idle Client"; - this.iButtonStartIdleClient.UseVisualStyleBackColor = true; - this.iButtonStartIdleClient.Click += new System.EventHandler(this.ButtonStartIdleClient_Click); - // - // buttonCloseClients - // - this.buttonCloseClients.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.buttonCloseClients.Location = new System.Drawing.Point(6, 336); - this.buttonCloseClients.Name = "buttonCloseClients"; - this.buttonCloseClients.Size = new System.Drawing.Size(96, 23); - this.buttonCloseClients.TabIndex = 20; - this.buttonCloseClients.Text = "Close Clients"; - this.buttonCloseClients.UseVisualStyleBackColor = true; - this.buttonCloseClients.Click += new System.EventHandler(this.buttonCloseClients_Click); - // - // buttonStartClient - // - this.buttonStartClient.Location = new System.Drawing.Point(6, 6); - this.buttonStartClient.Name = "buttonStartClient"; - this.buttonStartClient.Size = new System.Drawing.Size(96, 23); - this.buttonStartClient.TabIndex = 19; - this.buttonStartClient.Text = "Start Test Client"; - this.buttonStartClient.UseVisualStyleBackColor = true; - this.buttonStartClient.Click += new System.EventHandler(this.buttonStartClient_Click); - // - // iTreeViewClients - // - this.iTreeViewClients.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.iTreeViewClients.Location = new System.Drawing.Point(108, 6); - this.iTreeViewClients.Name = "iTreeViewClients"; - this.iTreeViewClients.Size = new System.Drawing.Size(638, 328); - this.iTreeViewClients.TabIndex = 0; - this.iTreeViewClients.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeViewClients_AfterSelect); - // - // tabPageDisplay - // - this.tabPageDisplay.Controls.Add(this.buttonShowClock); - this.tabPageDisplay.Controls.Add(this.buttonHideClock); - this.tabPageDisplay.Controls.Add(this.buttonPowerOff); - this.tabPageDisplay.Controls.Add(this.buttonPowerOn); - this.tabPageDisplay.Controls.Add(this.labelTimerInterval); - this.tabPageDisplay.Controls.Add(this.maskedTextBoxTimerInterval); - this.tabPageDisplay.Controls.Add(this.comboBoxDisplayType); - this.tabPageDisplay.Controls.Add(this.buttonSuspend); - this.tabPageDisplay.Controls.Add(this.checkBoxConnectOnStartup); - this.tabPageDisplay.Controls.Add(this.trackBarBrightness); - this.tabPageDisplay.Controls.Add(this.buttonFill); - this.tabPageDisplay.Controls.Add(this.buttonClear); - this.tabPageDisplay.Controls.Add(this.buttonClose); - this.tabPageDisplay.Controls.Add(this.buttonOpen); - this.tabPageDisplay.Controls.Add(this.buttonCapture); - this.tabPageDisplay.Location = new System.Drawing.Point(4, 22); - this.tabPageDisplay.Name = "tabPageDisplay"; - this.tabPageDisplay.Padding = new System.Windows.Forms.Padding(3); - this.tabPageDisplay.Size = new System.Drawing.Size(752, 385); - this.tabPageDisplay.TabIndex = 0; - this.tabPageDisplay.Text = "Display"; - this.tabPageDisplay.UseVisualStyleBackColor = true; - // - // buttonShowClock - // - this.buttonShowClock.Location = new System.Drawing.Point(6, 122); - this.buttonShowClock.Name = "buttonShowClock"; - this.buttonShowClock.Size = new System.Drawing.Size(75, 23); - this.buttonShowClock.TabIndex = 23; - this.buttonShowClock.Text = "Show Clock"; - this.buttonShowClock.UseVisualStyleBackColor = true; - this.buttonShowClock.Click += new System.EventHandler(this.buttonShowClock_Click); - // - // buttonHideClock - // - this.buttonHideClock.Location = new System.Drawing.Point(6, 151); - this.buttonHideClock.Name = "buttonHideClock"; - this.buttonHideClock.Size = new System.Drawing.Size(75, 23); - this.buttonHideClock.TabIndex = 22; - this.buttonHideClock.Text = "Hide Clock"; - this.buttonHideClock.UseVisualStyleBackColor = true; - this.buttonHideClock.Click += new System.EventHandler(this.buttonHideClock_Click); - // - // buttonPowerOff - // - this.buttonPowerOff.Location = new System.Drawing.Point(6, 209); - this.buttonPowerOff.Name = "buttonPowerOff"; - this.buttonPowerOff.Size = new System.Drawing.Size(75, 23); - this.buttonPowerOff.TabIndex = 21; - this.buttonPowerOff.Text = "OFF"; - this.buttonPowerOff.UseVisualStyleBackColor = true; - this.buttonPowerOff.Click += new System.EventHandler(this.buttonPowerOff_Click); - // - // buttonPowerOn - // - this.buttonPowerOn.Location = new System.Drawing.Point(6, 180); - this.buttonPowerOn.Name = "buttonPowerOn"; - this.buttonPowerOn.Size = new System.Drawing.Size(75, 23); - this.buttonPowerOn.TabIndex = 20; - this.buttonPowerOn.Text = "ON"; - this.buttonPowerOn.UseVisualStyleBackColor = true; - this.buttonPowerOn.Click += new System.EventHandler(this.buttonPowerOn_Click); - // - // labelTimerInterval - // - this.labelTimerInterval.AutoSize = true; - this.labelTimerInterval.Location = new System.Drawing.Point(184, 45); - this.labelTimerInterval.Name = "labelTimerInterval"; - this.labelTimerInterval.Size = new System.Drawing.Size(98, 13); - this.labelTimerInterval.TabIndex = 19; - this.labelTimerInterval.Text = "Timer interval (ms) :"; - // - // maskedTextBoxTimerInterval - // - this.maskedTextBoxTimerInterval.Location = new System.Drawing.Point(288, 42); - this.maskedTextBoxTimerInterval.Mask = "000"; - this.maskedTextBoxTimerInterval.Name = "maskedTextBoxTimerInterval"; - this.maskedTextBoxTimerInterval.PromptChar = ' '; - this.maskedTextBoxTimerInterval.Size = new System.Drawing.Size(24, 20); - this.maskedTextBoxTimerInterval.TabIndex = 18; - this.maskedTextBoxTimerInterval.TextChanged += new System.EventHandler(this.maskedTextBoxTimerInterval_TextChanged); - // - // comboBoxDisplayType - // - this.comboBoxDisplayType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.comboBoxDisplayType.FormattingEnabled = true; - this.comboBoxDisplayType.Location = new System.Drawing.Point(187, 9); - this.comboBoxDisplayType.Name = "comboBoxDisplayType"; - this.comboBoxDisplayType.Size = new System.Drawing.Size(181, 21); - this.comboBoxDisplayType.TabIndex = 17; - this.comboBoxDisplayType.SelectedIndexChanged += new System.EventHandler(this.comboBoxDisplayType_SelectedIndexChanged); - // - // buttonSuspend - // - this.buttonSuspend.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.buttonSuspend.Location = new System.Drawing.Point(6, 317); - this.buttonSuspend.Name = "buttonSuspend"; - this.buttonSuspend.Size = new System.Drawing.Size(75, 23); - this.buttonSuspend.TabIndex = 16; - this.buttonSuspend.Text = "Pause"; - this.buttonSuspend.UseVisualStyleBackColor = true; - this.buttonSuspend.Click += new System.EventHandler(this.buttonSuspend_Click); - // - // checkBoxConnectOnStartup - // - this.checkBoxConnectOnStartup.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.checkBoxConnectOnStartup.AutoSize = true; - this.checkBoxConnectOnStartup.Location = new System.Drawing.Point(113, 350); - this.checkBoxConnectOnStartup.Name = "checkBoxConnectOnStartup"; - this.checkBoxConnectOnStartup.Size = new System.Drawing.Size(119, 17); - this.checkBoxConnectOnStartup.TabIndex = 13; - this.checkBoxConnectOnStartup.Text = "Connect on stratup "; - this.checkBoxConnectOnStartup.UseVisualStyleBackColor = true; - this.checkBoxConnectOnStartup.CheckedChanged += new System.EventHandler(this.checkBoxConnectOnStartup_CheckedChanged); - // - // trackBarBrightness - // - this.trackBarBrightness.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Right))); - this.trackBarBrightness.BackColor = System.Drawing.SystemColors.Window; - this.trackBarBrightness.Location = new System.Drawing.Point(704, 9); - this.trackBarBrightness.Name = "trackBarBrightness"; - this.trackBarBrightness.Orientation = System.Windows.Forms.Orientation.Vertical; - this.trackBarBrightness.Size = new System.Drawing.Size(45, 358); - this.trackBarBrightness.TabIndex = 10; - this.trackBarBrightness.TickStyle = System.Windows.Forms.TickStyle.Both; - this.toolTip.SetToolTip(this.trackBarBrightness, "Brightness adjustment"); - this.trackBarBrightness.Scroll += new System.EventHandler(this.trackBarBrightness_Scroll); - // - // buttonFill - // - this.buttonFill.Location = new System.Drawing.Point(6, 93); - this.buttonFill.Name = "buttonFill"; - this.buttonFill.Size = new System.Drawing.Size(75, 23); - this.buttonFill.TabIndex = 9; - this.buttonFill.Text = "Fill"; - this.buttonFill.UseVisualStyleBackColor = true; - this.buttonFill.Click += new System.EventHandler(this.buttonFill_Click); - // - // buttonClear - // - this.buttonClear.Location = new System.Drawing.Point(6, 64); - this.buttonClear.Name = "buttonClear"; - this.buttonClear.Size = new System.Drawing.Size(75, 23); - this.buttonClear.TabIndex = 8; - this.buttonClear.Text = "Clear"; - this.buttonClear.UseVisualStyleBackColor = true; - this.buttonClear.Click += new System.EventHandler(this.buttonClear_Click); - // - // buttonClose - // - this.buttonClose.Location = new System.Drawing.Point(6, 35); - this.buttonClose.Name = "buttonClose"; - this.buttonClose.Size = new System.Drawing.Size(75, 23); - this.buttonClose.TabIndex = 7; - this.buttonClose.Text = "Close"; - this.buttonClose.UseVisualStyleBackColor = true; - this.buttonClose.Click += new System.EventHandler(this.buttonClose_Click); - // - // buttonOpen - // - this.buttonOpen.Location = new System.Drawing.Point(6, 6); - this.buttonOpen.Name = "buttonOpen"; - this.buttonOpen.Size = new System.Drawing.Size(75, 23); - this.buttonOpen.TabIndex = 6; - this.buttonOpen.Text = "Open"; - this.buttonOpen.UseVisualStyleBackColor = true; - this.buttonOpen.Click += new System.EventHandler(this.buttonOpen_Click); - // - // buttonCapture - // - this.buttonCapture.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.buttonCapture.Location = new System.Drawing.Point(6, 346); - this.buttonCapture.Name = "buttonCapture"; - this.buttonCapture.Size = new System.Drawing.Size(75, 23); - this.buttonCapture.TabIndex = 5; - this.buttonCapture.Text = "Capture"; - this.buttonCapture.UseVisualStyleBackColor = true; - this.buttonCapture.Click += new System.EventHandler(this.buttonCapture_Click); - // - // labelWarning - // - this.labelWarning.AutoSize = true; - this.labelWarning.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.labelWarning.ForeColor = System.Drawing.Color.Red; - this.labelWarning.Location = new System.Drawing.Point(9, 9); - this.labelWarning.Name = "labelWarning"; - this.labelWarning.Size = new System.Drawing.Size(80, 16); - this.labelWarning.TabIndex = 18; - this.labelWarning.Text = "WARNING"; - this.labelWarning.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; - this.labelWarning.Visible = false; - // - // checkBoxFixedPitchFontOnly - // - this.checkBoxFixedPitchFontOnly.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.checkBoxFixedPitchFontOnly.AutoSize = true; - this.checkBoxFixedPitchFontOnly.Location = new System.Drawing.Point(87, 362); - this.checkBoxFixedPitchFontOnly.Name = "checkBoxFixedPitchFontOnly"; - this.checkBoxFixedPitchFontOnly.Size = new System.Drawing.Size(120, 17); - this.checkBoxFixedPitchFontOnly.TabIndex = 17; - this.checkBoxFixedPitchFontOnly.Text = "Fixed pitch font only"; - this.checkBoxFixedPitchFontOnly.UseVisualStyleBackColor = true; - // - // checkBoxShowBorders - // - this.checkBoxShowBorders.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.checkBoxShowBorders.AutoSize = true; - this.checkBoxShowBorders.Location = new System.Drawing.Point(645, 29); - this.checkBoxShowBorders.Name = "checkBoxShowBorders"; - this.checkBoxShowBorders.Size = new System.Drawing.Size(91, 17); - this.checkBoxShowBorders.TabIndex = 11; - this.checkBoxShowBorders.Text = "Show borders"; - this.checkBoxShowBorders.UseVisualStyleBackColor = true; - this.checkBoxShowBorders.CheckedChanged += new System.EventHandler(this.checkBoxShowBorders_CheckedChanged); - // - // buttonFont - // - this.buttonFont.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.buttonFont.Location = new System.Drawing.Point(6, 356); - this.buttonFont.Name = "buttonFont"; - this.buttonFont.Size = new System.Drawing.Size(75, 23); - this.buttonFont.TabIndex = 0; - this.buttonFont.Text = "Select Font"; - this.buttonFont.UseVisualStyleBackColor = true; - this.buttonFont.Click += new System.EventHandler(this.buttonFont_Click); - // - // tabControl - // - this.tabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.tabControl.Controls.Add(this.tabPageDisplay); - this.tabControl.Controls.Add(this.tabPageClients); - this.tabControl.Controls.Add(this.tabPageDesign); - this.tabControl.Controls.Add(this.tabPageAudio); - this.tabControl.Controls.Add(this.tabPageInput); - this.tabControl.Controls.Add(this.tabPageCec); - this.tabControl.Controls.Add(this.tabPageEvent); - this.tabControl.Controls.Add(this.tabPageApp); - this.tabControl.Controls.Add(this.tabPageLogs); - this.tabControl.Location = new System.Drawing.Point(12, 125); - this.tabControl.Name = "tabControl"; - this.tabControl.SelectedIndex = 0; - this.tabControl.Size = new System.Drawing.Size(760, 411); - this.tabControl.TabIndex = 0; - // - // tabPageDesign - // - this.tabPageDesign.Controls.Add(this.labelScrollingSpeed); - this.tabPageDesign.Controls.Add(this.maskedTextBoxScrollingSpeed); - this.tabPageDesign.Controls.Add(this.labelScrollLoopSeparator); - this.tabPageDesign.Controls.Add(this.textBoxScrollLoopSeparator); - this.tabPageDesign.Controls.Add(this.labelMinFontSize); - this.tabPageDesign.Controls.Add(this.maskedTextBoxMinFontSize); - this.tabPageDesign.Controls.Add(this.checkBoxScaleToFit); - this.tabPageDesign.Controls.Add(this.checkBoxInverseColors); - this.tabPageDesign.Controls.Add(this.checkBoxFixedPitchFontOnly); - this.tabPageDesign.Controls.Add(this.buttonFont); - this.tabPageDesign.Controls.Add(this.checkBoxReverseScreen); - this.tabPageDesign.Controls.Add(this.checkBoxShowBorders); - this.tabPageDesign.Location = new System.Drawing.Point(4, 22); - this.tabPageDesign.Name = "tabPageDesign"; - this.tabPageDesign.Padding = new System.Windows.Forms.Padding(3); - this.tabPageDesign.Size = new System.Drawing.Size(752, 385); - this.tabPageDesign.TabIndex = 3; - this.tabPageDesign.Text = "Design"; - this.tabPageDesign.UseVisualStyleBackColor = true; - // - // labelScrollingSpeed - // - this.labelScrollingSpeed.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.labelScrollingSpeed.AutoSize = true; - this.labelScrollingSpeed.Location = new System.Drawing.Point(92, 248); - this.labelScrollingSpeed.Name = "labelScrollingSpeed"; - this.labelScrollingSpeed.Size = new System.Drawing.Size(115, 13); - this.labelScrollingSpeed.TabIndex = 28; - this.labelScrollingSpeed.Text = "Scrolling speed (px/s) :"; - // - // maskedTextBoxScrollingSpeed - // - this.maskedTextBoxScrollingSpeed.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.maskedTextBoxScrollingSpeed.Location = new System.Drawing.Point(213, 245); - this.maskedTextBoxScrollingSpeed.Mask = "000"; - this.maskedTextBoxScrollingSpeed.Name = "maskedTextBoxScrollingSpeed"; - this.maskedTextBoxScrollingSpeed.PromptChar = ' '; - this.maskedTextBoxScrollingSpeed.Size = new System.Drawing.Size(24, 20); - this.maskedTextBoxScrollingSpeed.TabIndex = 27; - this.maskedTextBoxScrollingSpeed.TextChanged += new System.EventHandler(this.maskedTextBoxScrollingSpeed_TextChanged); - // - // labelScrollLoopSeparator - // - this.labelScrollLoopSeparator.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.labelScrollLoopSeparator.AutoSize = true; - this.labelScrollLoopSeparator.Location = new System.Drawing.Point(98, 274); - this.labelScrollLoopSeparator.Name = "labelScrollLoopSeparator"; - this.labelScrollLoopSeparator.Size = new System.Drawing.Size(109, 13); - this.labelScrollLoopSeparator.TabIndex = 26; - this.labelScrollLoopSeparator.Text = "Scroll loop separator :"; - // - // textBoxScrollLoopSeparator - // - this.textBoxScrollLoopSeparator.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.textBoxScrollLoopSeparator.Location = new System.Drawing.Point(213, 271); - this.textBoxScrollLoopSeparator.Name = "textBoxScrollLoopSeparator"; - this.textBoxScrollLoopSeparator.Size = new System.Drawing.Size(74, 20); - this.textBoxScrollLoopSeparator.TabIndex = 25; - this.textBoxScrollLoopSeparator.TextChanged += new System.EventHandler(this.textBoxScrollLoopSeparator_TextChanged); - // - // labelMinFontSize - // - this.labelMinFontSize.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.labelMinFontSize.AutoSize = true; - this.labelMinFontSize.Location = new System.Drawing.Point(88, 323); - this.labelMinFontSize.Name = "labelMinFontSize"; - this.labelMinFontSize.Size = new System.Drawing.Size(119, 13); - this.labelMinFontSize.TabIndex = 24; - this.labelMinFontSize.Text = "Minimum font size (pts) :"; - // - // maskedTextBoxMinFontSize - // - this.maskedTextBoxMinFontSize.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.maskedTextBoxMinFontSize.Location = new System.Drawing.Point(213, 320); - this.maskedTextBoxMinFontSize.Mask = "000"; - this.maskedTextBoxMinFontSize.Name = "maskedTextBoxMinFontSize"; - this.maskedTextBoxMinFontSize.PromptChar = ' '; - this.maskedTextBoxMinFontSize.Size = new System.Drawing.Size(24, 20); - this.maskedTextBoxMinFontSize.TabIndex = 23; - this.maskedTextBoxMinFontSize.TextChanged += new System.EventHandler(this.maskedTextBoxMinFontSize_TextChanged); - // - // checkBoxScaleToFit - // - this.checkBoxScaleToFit.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.checkBoxScaleToFit.AutoSize = true; - this.checkBoxScaleToFit.Location = new System.Drawing.Point(86, 297); - this.checkBoxScaleToFit.Name = "checkBoxScaleToFit"; - this.checkBoxScaleToFit.Size = new System.Drawing.Size(201, 17); - this.checkBoxScaleToFit.TabIndex = 22; - this.checkBoxScaleToFit.Text = "Try scale font down to avoid scrolling"; - this.checkBoxScaleToFit.UseVisualStyleBackColor = true; - this.checkBoxScaleToFit.CheckedChanged += new System.EventHandler(this.checkBoxScaleToFit_CheckedChanged); - // - // checkBoxInverseColors - // - this.checkBoxInverseColors.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.checkBoxInverseColors.AutoSize = true; - this.checkBoxInverseColors.Location = new System.Drawing.Point(645, 52); - this.checkBoxInverseColors.Name = "checkBoxInverseColors"; - this.checkBoxInverseColors.Size = new System.Drawing.Size(92, 17); - this.checkBoxInverseColors.TabIndex = 21; - this.checkBoxInverseColors.Text = "Inverse colors"; - this.checkBoxInverseColors.UseVisualStyleBackColor = true; - this.checkBoxInverseColors.CheckedChanged += new System.EventHandler(this.checkBoxInverseColors_CheckedChanged); - // - // checkBoxReverseScreen - // - this.checkBoxReverseScreen.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.checkBoxReverseScreen.AutoSize = true; - this.checkBoxReverseScreen.Location = new System.Drawing.Point(645, 6); - this.checkBoxReverseScreen.Name = "checkBoxReverseScreen"; - this.checkBoxReverseScreen.Size = new System.Drawing.Size(101, 17); - this.checkBoxReverseScreen.TabIndex = 14; - this.checkBoxReverseScreen.Text = "Reverse screen"; - this.checkBoxReverseScreen.UseVisualStyleBackColor = true; - this.checkBoxReverseScreen.CheckedChanged += new System.EventHandler(this.checkBoxReverseScreen_CheckedChanged); - // - // tabPageAudio - // - this.tabPageAudio.Controls.Add(this.labelDefaultAudioDevice); - this.tabPageAudio.Controls.Add(this.checkBoxShowVolumeLabel); - this.tabPageAudio.Controls.Add(this.checkBoxMute); - this.tabPageAudio.Controls.Add(this.trackBarMasterVolume); - this.tabPageAudio.Location = new System.Drawing.Point(4, 22); - this.tabPageAudio.Name = "tabPageAudio"; - this.tabPageAudio.Padding = new System.Windows.Forms.Padding(3); - this.tabPageAudio.Size = new System.Drawing.Size(752, 385); - this.tabPageAudio.TabIndex = 5; - this.tabPageAudio.Text = "Audio"; - this.tabPageAudio.UseVisualStyleBackColor = true; - // - // labelDefaultAudioDevice - // - this.labelDefaultAudioDevice.AutoSize = true; - this.labelDefaultAudioDevice.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.labelDefaultAudioDevice.Location = new System.Drawing.Point(3, 6); - this.labelDefaultAudioDevice.Name = "labelDefaultAudioDevice"; - this.labelDefaultAudioDevice.Size = new System.Drawing.Size(120, 13); - this.labelDefaultAudioDevice.TabIndex = 19; - this.labelDefaultAudioDevice.Text = "Audio Device Unknown"; - // - // checkBoxShowVolumeLabel - // - this.checkBoxShowVolumeLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.checkBoxShowVolumeLabel.AutoSize = true; - this.checkBoxShowVolumeLabel.Location = new System.Drawing.Point(3, 329); - this.checkBoxShowVolumeLabel.Name = "checkBoxShowVolumeLabel"; - this.checkBoxShowVolumeLabel.Size = new System.Drawing.Size(115, 17); - this.checkBoxShowVolumeLabel.TabIndex = 18; - this.checkBoxShowVolumeLabel.Text = "Show volume label"; - this.checkBoxShowVolumeLabel.UseVisualStyleBackColor = true; - this.checkBoxShowVolumeLabel.CheckedChanged += new System.EventHandler(this.checkBoxShowVolumeLabel_CheckedChanged); - // - // checkBoxMute - // - this.checkBoxMute.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.checkBoxMute.AutoSize = true; - this.checkBoxMute.Location = new System.Drawing.Point(3, 352); - this.checkBoxMute.Name = "checkBoxMute"; - this.checkBoxMute.Size = new System.Drawing.Size(50, 17); - this.checkBoxMute.TabIndex = 17; - this.checkBoxMute.Text = "Mute"; - this.checkBoxMute.UseVisualStyleBackColor = true; - this.checkBoxMute.CheckedChanged += new System.EventHandler(this.checkBoxMute_CheckedChanged); - // - // trackBarMasterVolume - // - this.trackBarMasterVolume.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Right))); - this.trackBarMasterVolume.BackColor = System.Drawing.SystemColors.Window; - this.trackBarMasterVolume.Location = new System.Drawing.Point(701, 6); - this.trackBarMasterVolume.Maximum = 100; - this.trackBarMasterVolume.Name = "trackBarMasterVolume"; - this.trackBarMasterVolume.Orientation = System.Windows.Forms.Orientation.Vertical; - this.trackBarMasterVolume.Size = new System.Drawing.Size(45, 373); - this.trackBarMasterVolume.TabIndex = 0; - this.trackBarMasterVolume.TickFrequency = 10; - this.trackBarMasterVolume.TickStyle = System.Windows.Forms.TickStyle.Both; - this.toolTip.SetToolTip(this.trackBarMasterVolume, "Master Volume"); - this.trackBarMasterVolume.Scroll += new System.EventHandler(this.trackBarMasterVolume_Scroll); - // - // tabPageInput - // - this.tabPageInput.Controls.Add(this.comboBoxOpticalDrives); - this.tabPageInput.Controls.Add(this.labelOpticalDriveEject); - this.tabPageInput.Controls.Add(this.pictureBoxGreenStart); - this.tabPageInput.Controls.Add(this.labelStartFileName); - this.tabPageInput.Controls.Add(this.buttonSelectFile); - this.tabPageInput.Location = new System.Drawing.Point(4, 22); - this.tabPageInput.Name = "tabPageInput"; - this.tabPageInput.Padding = new System.Windows.Forms.Padding(3); - this.tabPageInput.Size = new System.Drawing.Size(752, 385); - this.tabPageInput.TabIndex = 6; - this.tabPageInput.Text = "Input"; - this.tabPageInput.UseVisualStyleBackColor = true; - // - // comboBoxOpticalDrives - // - this.comboBoxOpticalDrives.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.comboBoxOpticalDrives.FormattingEnabled = true; - this.comboBoxOpticalDrives.Location = new System.Drawing.Point(113, 53); - this.comboBoxOpticalDrives.Name = "comboBoxOpticalDrives"; - this.comboBoxOpticalDrives.Size = new System.Drawing.Size(55, 21); - this.comboBoxOpticalDrives.TabIndex = 18; - this.comboBoxOpticalDrives.SelectedIndexChanged += new System.EventHandler(this.comboBoxOpticalDrives_SelectedIndexChanged); - // - // labelOpticalDriveEject - // - this.labelOpticalDriveEject.AutoSize = true; - this.labelOpticalDriveEject.Location = new System.Drawing.Point(0, 56); - this.labelOpticalDriveEject.Name = "labelOpticalDriveEject"; - this.labelOpticalDriveEject.Size = new System.Drawing.Size(107, 13); - this.labelOpticalDriveEject.TabIndex = 3; - this.labelOpticalDriveEject.Text = "Optical drive to eject:"; - // - // pictureBoxGreenStart - // - this.pictureBoxGreenStart.Image = ((System.Drawing.Image)(resources.GetObject("pictureBoxGreenStart.Image"))); - this.pictureBoxGreenStart.Location = new System.Drawing.Point(3, 6); - this.pictureBoxGreenStart.Name = "pictureBoxGreenStart"; - this.pictureBoxGreenStart.Size = new System.Drawing.Size(32, 32); - this.pictureBoxGreenStart.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; - this.pictureBoxGreenStart.TabIndex = 2; - this.pictureBoxGreenStart.TabStop = false; - // - // labelStartFileName - // - this.labelStartFileName.AutoSize = true; - this.labelStartFileName.Location = new System.Drawing.Point(72, 16); - this.labelStartFileName.Name = "labelStartFileName"; - this.labelStartFileName.Size = new System.Drawing.Size(33, 13); - this.labelStartFileName.TabIndex = 1; - this.labelStartFileName.Text = "None"; - // - // buttonSelectFile - // - this.buttonSelectFile.Location = new System.Drawing.Point(41, 11); - this.buttonSelectFile.Name = "buttonSelectFile"; - this.buttonSelectFile.Size = new System.Drawing.Size(25, 23); - this.buttonSelectFile.TabIndex = 0; - this.buttonSelectFile.Text = "..."; - this.buttonSelectFile.UseVisualStyleBackColor = true; - this.buttonSelectFile.Click += new System.EventHandler(this.buttonSelectFile_Click); - // - // tabPageCec - // - this.tabPageCec.Controls.Add(this.groupBoxCecLogOptions); - this.tabPageCec.Controls.Add(this.checkBoxCecEnabled); - this.tabPageCec.Controls.Add(this.labelHdmiPort); - this.tabPageCec.Controls.Add(this.comboBoxHdmiPort); - this.tabPageCec.Location = new System.Drawing.Point(4, 22); - this.tabPageCec.Name = "tabPageCec"; - this.tabPageCec.Padding = new System.Windows.Forms.Padding(3); - this.tabPageCec.Size = new System.Drawing.Size(752, 385); - this.tabPageCec.TabIndex = 7; - this.tabPageCec.Text = "CEC"; - this.tabPageCec.UseVisualStyleBackColor = true; - // - // groupBoxCecLogOptions - // - this.groupBoxCecLogOptions.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.groupBoxCecLogOptions.Controls.Add(this.checkBoxCecLogNoPoll); - this.groupBoxCecLogOptions.Controls.Add(this.checkBoxCecLogTraffic); - this.groupBoxCecLogOptions.Controls.Add(this.checkBoxCecLogDebug); - this.groupBoxCecLogOptions.Controls.Add(this.checkBoxCecLogNotice); - this.groupBoxCecLogOptions.Controls.Add(this.checkBoxCecLogError); - this.groupBoxCecLogOptions.Controls.Add(this.checkBoxCecLogWarning); - this.groupBoxCecLogOptions.Location = new System.Drawing.Point(6, 239); - this.groupBoxCecLogOptions.Name = "groupBoxCecLogOptions"; - this.groupBoxCecLogOptions.Size = new System.Drawing.Size(165, 140); - this.groupBoxCecLogOptions.TabIndex = 25; - this.groupBoxCecLogOptions.TabStop = false; - this.groupBoxCecLogOptions.Text = "Log options"; - // - // checkBoxCecLogNoPoll - // - this.checkBoxCecLogNoPoll.AutoSize = true; - this.checkBoxCecLogNoPoll.Checked = true; - this.checkBoxCecLogNoPoll.CheckState = System.Windows.Forms.CheckState.Checked; - this.checkBoxCecLogNoPoll.Location = new System.Drawing.Point(76, 24); - this.checkBoxCecLogNoPoll.Name = "checkBoxCecLogNoPoll"; - this.checkBoxCecLogNoPoll.Size = new System.Drawing.Size(59, 17); - this.checkBoxCecLogNoPoll.TabIndex = 30; - this.checkBoxCecLogNoPoll.Text = "No poll"; - this.checkBoxCecLogNoPoll.UseVisualStyleBackColor = true; - this.checkBoxCecLogNoPoll.CheckedChanged += new System.EventHandler(this.checkBoxCecLogs_CheckedChanged); - // - // checkBoxCecLogTraffic - // - this.checkBoxCecLogTraffic.AutoSize = true; - this.checkBoxCecLogTraffic.Location = new System.Drawing.Point(6, 93); - this.checkBoxCecLogTraffic.Name = "checkBoxCecLogTraffic"; - this.checkBoxCecLogTraffic.Size = new System.Drawing.Size(56, 17); - this.checkBoxCecLogTraffic.TabIndex = 29; - this.checkBoxCecLogTraffic.Text = "Traffic"; - this.checkBoxCecLogTraffic.UseVisualStyleBackColor = true; - this.checkBoxCecLogTraffic.CheckedChanged += new System.EventHandler(this.checkBoxCecLogs_CheckedChanged); - // - // checkBoxCecLogDebug - // - this.checkBoxCecLogDebug.AutoSize = true; - this.checkBoxCecLogDebug.Location = new System.Drawing.Point(6, 116); - this.checkBoxCecLogDebug.Name = "checkBoxCecLogDebug"; - this.checkBoxCecLogDebug.Size = new System.Drawing.Size(58, 17); - this.checkBoxCecLogDebug.TabIndex = 28; - this.checkBoxCecLogDebug.Text = "Debug"; - this.checkBoxCecLogDebug.UseVisualStyleBackColor = true; - this.checkBoxCecLogDebug.CheckedChanged += new System.EventHandler(this.checkBoxCecLogs_CheckedChanged); - // - // checkBoxCecLogNotice - // - this.checkBoxCecLogNotice.AutoSize = true; - this.checkBoxCecLogNotice.Checked = true; - this.checkBoxCecLogNotice.CheckState = System.Windows.Forms.CheckState.Checked; - this.checkBoxCecLogNotice.Location = new System.Drawing.Point(6, 70); - this.checkBoxCecLogNotice.Name = "checkBoxCecLogNotice"; - this.checkBoxCecLogNotice.Size = new System.Drawing.Size(57, 17); - this.checkBoxCecLogNotice.TabIndex = 27; - this.checkBoxCecLogNotice.Text = "Notice"; - this.checkBoxCecLogNotice.UseVisualStyleBackColor = true; - this.checkBoxCecLogNotice.CheckedChanged += new System.EventHandler(this.checkBoxCecLogs_CheckedChanged); - // - // checkBoxCecLogError - // - this.checkBoxCecLogError.AutoSize = true; - this.checkBoxCecLogError.Checked = true; - this.checkBoxCecLogError.CheckState = System.Windows.Forms.CheckState.Checked; - this.checkBoxCecLogError.Location = new System.Drawing.Point(6, 24); - this.checkBoxCecLogError.Name = "checkBoxCecLogError"; - this.checkBoxCecLogError.Size = new System.Drawing.Size(48, 17); - this.checkBoxCecLogError.TabIndex = 26; - this.checkBoxCecLogError.Text = "Error"; - this.checkBoxCecLogError.UseVisualStyleBackColor = true; - this.checkBoxCecLogError.CheckedChanged += new System.EventHandler(this.checkBoxCecLogs_CheckedChanged); - // - // checkBoxCecLogWarning - // - this.checkBoxCecLogWarning.AutoSize = true; - this.checkBoxCecLogWarning.Checked = true; - this.checkBoxCecLogWarning.CheckState = System.Windows.Forms.CheckState.Checked; - this.checkBoxCecLogWarning.Location = new System.Drawing.Point(6, 47); - this.checkBoxCecLogWarning.Name = "checkBoxCecLogWarning"; - this.checkBoxCecLogWarning.Size = new System.Drawing.Size(66, 17); - this.checkBoxCecLogWarning.TabIndex = 25; - this.checkBoxCecLogWarning.Text = "Warning"; - this.checkBoxCecLogWarning.UseVisualStyleBackColor = true; - this.checkBoxCecLogWarning.CheckedChanged += new System.EventHandler(this.checkBoxCecLogs_CheckedChanged); - // - // checkBoxCecEnabled - // - this.checkBoxCecEnabled.AutoSize = true; - this.checkBoxCecEnabled.Location = new System.Drawing.Point(6, 6); - this.checkBoxCecEnabled.Name = "checkBoxCecEnabled"; - this.checkBoxCecEnabled.Size = new System.Drawing.Size(83, 17); - this.checkBoxCecEnabled.TabIndex = 21; - this.checkBoxCecEnabled.Text = "Enable CEC"; - this.checkBoxCecEnabled.UseVisualStyleBackColor = true; - this.checkBoxCecEnabled.CheckedChanged += new System.EventHandler(this.checkBoxCecEnabled_CheckedChanged); - // - // labelHdmiPort - // - this.labelHdmiPort.AutoSize = true; - this.labelHdmiPort.Location = new System.Drawing.Point(3, 26); - this.labelHdmiPort.Name = "labelHdmiPort"; - this.labelHdmiPort.Size = new System.Drawing.Size(182, 13); - this.labelHdmiPort.TabIndex = 20; - this.labelHdmiPort.Text = "TV HDMI port connected to your PC:"; - // - // comboBoxHdmiPort - // - this.comboBoxHdmiPort.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.comboBoxHdmiPort.FormattingEnabled = true; - this.comboBoxHdmiPort.Items.AddRange(new object[] { - "HDMI 1", - "HDMI 2", - "HDMI 3", - "HDMI 4", - "HDMI 5", - "HDMI 6", - "HDMI 7", - "HDMI 8", - "HDMI 9"}); - this.comboBoxHdmiPort.Location = new System.Drawing.Point(6, 42); - this.comboBoxHdmiPort.Name = "comboBoxHdmiPort"; - this.comboBoxHdmiPort.Size = new System.Drawing.Size(87, 21); - this.comboBoxHdmiPort.TabIndex = 19; - this.comboBoxHdmiPort.SelectedIndexChanged += new System.EventHandler(this.comboBoxHdmiPort_SelectedIndexChanged); - // - // tabPageEvent - // - this.tabPageEvent.Controls.Add(this.buttonActionMoveUp); - this.tabPageEvent.Controls.Add(this.buttonActionMoveDown); - this.tabPageEvent.Controls.Add(this.buttonTestAction); - this.tabPageEvent.Controls.Add(this.buttonDeleteAction); - this.tabPageEvent.Controls.Add(this.buttonAddAction); - this.tabPageEvent.Controls.Add(this.iTreeViewEvents); - this.tabPageEvent.Location = new System.Drawing.Point(4, 22); - this.tabPageEvent.Name = "tabPageEvent"; - this.tabPageEvent.Padding = new System.Windows.Forms.Padding(3); - this.tabPageEvent.Size = new System.Drawing.Size(752, 385); - this.tabPageEvent.TabIndex = 9; - this.tabPageEvent.Text = "Events"; - this.tabPageEvent.UseVisualStyleBackColor = true; - // - // buttonActionMoveUp - // - this.buttonActionMoveUp.Enabled = false; - this.buttonActionMoveUp.Location = new System.Drawing.Point(6, 327); - this.buttonActionMoveUp.Name = "buttonActionMoveUp"; - this.buttonActionMoveUp.Size = new System.Drawing.Size(96, 23); - this.buttonActionMoveUp.TabIndex = 24; - this.buttonActionMoveUp.Text = "Move Up"; - this.buttonActionMoveUp.UseVisualStyleBackColor = true; - this.buttonActionMoveUp.Click += new System.EventHandler(this.buttonActionMoveUp_Click); - // - // buttonActionMoveDown - // - this.buttonActionMoveDown.Enabled = false; - this.buttonActionMoveDown.Location = new System.Drawing.Point(6, 356); - this.buttonActionMoveDown.Name = "buttonActionMoveDown"; - this.buttonActionMoveDown.Size = new System.Drawing.Size(96, 23); - this.buttonActionMoveDown.TabIndex = 23; - this.buttonActionMoveDown.Text = "Move Down"; - this.buttonActionMoveDown.UseVisualStyleBackColor = true; - this.buttonActionMoveDown.Click += new System.EventHandler(this.buttonActionMoveDown_Click); - // - // buttonTestAction - // - this.buttonTestAction.Enabled = false; - this.buttonTestAction.Location = new System.Drawing.Point(6, 64); - this.buttonTestAction.Name = "buttonTestAction"; - this.buttonTestAction.Size = new System.Drawing.Size(96, 23); - this.buttonTestAction.TabIndex = 22; - this.buttonTestAction.Text = "Test Action"; - this.buttonTestAction.UseVisualStyleBackColor = true; - this.buttonTestAction.Click += new System.EventHandler(this.buttonTestAction_Click); - // - // buttonDeleteAction - // - this.buttonDeleteAction.Enabled = false; - this.buttonDeleteAction.Location = new System.Drawing.Point(6, 35); - this.buttonDeleteAction.Name = "buttonDeleteAction"; - this.buttonDeleteAction.Size = new System.Drawing.Size(96, 23); - this.buttonDeleteAction.TabIndex = 21; - this.buttonDeleteAction.Text = "Delete Action"; - this.buttonDeleteAction.UseVisualStyleBackColor = true; - this.buttonDeleteAction.Click += new System.EventHandler(this.buttonDeleteAction_Click); - // - // buttonAddAction - // - this.buttonAddAction.Enabled = false; - this.buttonAddAction.Location = new System.Drawing.Point(6, 6); - this.buttonAddAction.Name = "buttonAddAction"; - this.buttonAddAction.Size = new System.Drawing.Size(96, 23); - this.buttonAddAction.TabIndex = 20; - this.buttonAddAction.Text = "Add Action"; - this.buttonAddAction.UseVisualStyleBackColor = true; - this.buttonAddAction.Click += new System.EventHandler(this.buttonAddAction_Click); - // - // iTreeViewEvents - // - this.iTreeViewEvents.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.iTreeViewEvents.HideSelection = false; - this.iTreeViewEvents.Location = new System.Drawing.Point(111, 3); - this.iTreeViewEvents.Name = "iTreeViewEvents"; - this.iTreeViewEvents.Size = new System.Drawing.Size(638, 376); - this.iTreeViewEvents.TabIndex = 1; - this.iTreeViewEvents.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.iTreeViewEvents_AfterSelect); - // - // tabPageApp - // - this.tabPageApp.Controls.Add(this.checkBoxStartMinimized); - this.tabPageApp.Controls.Add(this.checkBoxMinimizeToTray); - this.tabPageApp.Controls.Add(this.checkBoxAutoStart); - this.tabPageApp.Controls.Add(this.buttonUpdate); - this.tabPageApp.Location = new System.Drawing.Point(4, 22); - this.tabPageApp.Name = "tabPageApp"; - this.tabPageApp.Padding = new System.Windows.Forms.Padding(3); - this.tabPageApp.Size = new System.Drawing.Size(752, 385); - this.tabPageApp.TabIndex = 4; - this.tabPageApp.Text = "Application"; - this.tabPageApp.UseVisualStyleBackColor = true; - // - // checkBoxStartMinimized - // - this.checkBoxStartMinimized.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.checkBoxStartMinimized.AutoSize = true; - this.checkBoxStartMinimized.Location = new System.Drawing.Point(6, 285); - this.checkBoxStartMinimized.Name = "checkBoxStartMinimized"; - this.checkBoxStartMinimized.Size = new System.Drawing.Size(96, 17); - this.checkBoxStartMinimized.TabIndex = 16; - this.checkBoxStartMinimized.Text = "Start minimized"; - this.checkBoxStartMinimized.UseVisualStyleBackColor = true; - this.checkBoxStartMinimized.CheckedChanged += new System.EventHandler(this.checkBoxStartMinimized_CheckedChanged); - // - // checkBoxMinimizeToTray - // - this.checkBoxMinimizeToTray.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.checkBoxMinimizeToTray.AutoSize = true; - this.checkBoxMinimizeToTray.Location = new System.Drawing.Point(6, 308); - this.checkBoxMinimizeToTray.Name = "checkBoxMinimizeToTray"; - this.checkBoxMinimizeToTray.Size = new System.Drawing.Size(133, 17); - this.checkBoxMinimizeToTray.TabIndex = 15; - this.checkBoxMinimizeToTray.Text = "Minimize to system tray"; - this.checkBoxMinimizeToTray.UseVisualStyleBackColor = true; - this.checkBoxMinimizeToTray.CheckedChanged += new System.EventHandler(this.checkBoxMinimizeToTray_CheckedChanged); - // - // checkBoxAutoStart - // - this.checkBoxAutoStart.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.checkBoxAutoStart.AutoSize = true; - this.checkBoxAutoStart.Location = new System.Drawing.Point(6, 331); - this.checkBoxAutoStart.Name = "checkBoxAutoStart"; - this.checkBoxAutoStart.Size = new System.Drawing.Size(143, 17); - this.checkBoxAutoStart.TabIndex = 14; - this.checkBoxAutoStart.Text = "Run on Windows startup"; - this.checkBoxAutoStart.UseVisualStyleBackColor = true; - this.checkBoxAutoStart.CheckedChanged += new System.EventHandler(this.checkBoxAutoStart_CheckedChanged); - // - // buttonUpdate - // - this.buttonUpdate.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.buttonUpdate.Location = new System.Drawing.Point(6, 354); - this.buttonUpdate.Name = "buttonUpdate"; - this.buttonUpdate.Size = new System.Drawing.Size(75, 23); - this.buttonUpdate.TabIndex = 0; - this.buttonUpdate.Text = "Update"; - this.buttonUpdate.UseVisualStyleBackColor = true; - this.buttonUpdate.Click += new System.EventHandler(this.buttonUpdate_Click); - // - // tabPageLogs - // - this.tabPageLogs.Controls.Add(this.buttonClearLogs); - this.tabPageLogs.Controls.Add(this.richTextBoxLogs); - this.tabPageLogs.Location = new System.Drawing.Point(4, 22); - this.tabPageLogs.Name = "tabPageLogs"; - this.tabPageLogs.Padding = new System.Windows.Forms.Padding(3); - this.tabPageLogs.Size = new System.Drawing.Size(752, 385); - this.tabPageLogs.TabIndex = 8; - this.tabPageLogs.Text = "Logs"; - this.tabPageLogs.UseVisualStyleBackColor = true; - // - // buttonClearLogs - // - this.buttonClearLogs.Location = new System.Drawing.Point(671, 6); - this.buttonClearLogs.Name = "buttonClearLogs"; - this.buttonClearLogs.Size = new System.Drawing.Size(75, 23); - this.buttonClearLogs.TabIndex = 2; - this.buttonClearLogs.Text = "Clear"; - this.buttonClearLogs.UseVisualStyleBackColor = true; - this.buttonClearLogs.Click += new System.EventHandler(this.buttonClearLogs_Click); - // - // richTextBoxLogs - // - this.richTextBoxLogs.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.richTextBoxLogs.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.richTextBoxLogs.DetectUrls = false; - this.richTextBoxLogs.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.richTextBoxLogs.Location = new System.Drawing.Point(6, 6); - this.richTextBoxLogs.Name = "richTextBoxLogs"; - this.richTextBoxLogs.ReadOnly = true; - this.richTextBoxLogs.Size = new System.Drawing.Size(740, 373); - this.richTextBoxLogs.TabIndex = 1; - this.richTextBoxLogs.Text = ""; - this.richTextBoxLogs.WordWrap = false; - // - // labelFontWidth - // - this.labelFontWidth.AutoSize = true; - this.labelFontWidth.Location = new System.Drawing.Point(13, 29); - this.labelFontWidth.Name = "labelFontWidth"; - this.labelFontWidth.Size = new System.Drawing.Size(56, 13); - this.labelFontWidth.TabIndex = 19; - this.labelFontWidth.Text = "Font width"; - // - // labelFontHeight - // - this.labelFontHeight.AutoSize = true; - this.labelFontHeight.Location = new System.Drawing.Point(13, 46); - this.labelFontHeight.Name = "labelFontHeight"; - this.labelFontHeight.Size = new System.Drawing.Size(60, 13); - this.labelFontHeight.TabIndex = 20; - this.labelFontHeight.Text = "Font height"; - // - // openFileDialog - // - this.openFileDialog.Filter = "EXE files (*.exe)|*.exe|All files (*.*)|*.*"; - // - // MainForm - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(784, 561); - this.Controls.Add(this.labelFontHeight); - this.Controls.Add(this.labelFontWidth); - this.Controls.Add(this.labelWarning); - this.Controls.Add(this.statusStrip); - this.Controls.Add(this.tabControl); - this.Controls.Add(this.panelDisplay); - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.MinimumSize = new System.Drawing.Size(800, 600); - this.Name = "MainForm"; - this.Text = "Sharp Display Manager"; - this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing); - this.Load += new System.EventHandler(this.MainForm_Load); - this.SizeChanged += new System.EventHandler(this.MainForm_SizeChanged); - this.Resize += new System.EventHandler(this.MainForm_Resize); - this.panelDisplay.ResumeLayout(false); - this.iTableLayoutPanel.ResumeLayout(false); - this.iTableLayoutPanel.PerformLayout(); - this.statusStrip.ResumeLayout(false); - this.statusStrip.PerformLayout(); - this.tabPageClients.ResumeLayout(false); - this.tabPageClients.PerformLayout(); - this.tabPageDisplay.ResumeLayout(false); - this.tabPageDisplay.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.trackBarBrightness)).EndInit(); - this.tabControl.ResumeLayout(false); - this.tabPageDesign.ResumeLayout(false); - this.tabPageDesign.PerformLayout(); - this.tabPageAudio.ResumeLayout(false); - this.tabPageAudio.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.trackBarMasterVolume)).EndInit(); - this.tabPageInput.ResumeLayout(false); - this.tabPageInput.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBoxGreenStart)).EndInit(); - this.tabPageCec.ResumeLayout(false); - this.tabPageCec.PerformLayout(); - this.groupBoxCecLogOptions.ResumeLayout(false); - this.groupBoxCecLogOptions.PerformLayout(); - this.tabPageEvent.ResumeLayout(false); - this.tabPageApp.ResumeLayout(false); - this.tabPageApp.PerformLayout(); - this.tabPageLogs.ResumeLayout(false); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.FontDialog fontDialog; - private System.Windows.Forms.Timer timer; - private System.Windows.Forms.StatusStrip statusStrip; - private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabelConnect; - private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabelFps; - private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabelSpring; - private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabelPower; - private System.Windows.Forms.Panel panelDisplay; - private System.Windows.Forms.TableLayoutPanel iTableLayoutPanel; - private MarqueeLabel marqueeLabelTop; - private MarqueeLabel marqueeLabelBottom; - private System.Windows.Forms.TabPage tabPageClients; - private System.Windows.Forms.TreeView iTreeViewClients; - private System.Windows.Forms.TabPage tabPageDisplay; - private System.Windows.Forms.CheckBox checkBoxFixedPitchFontOnly; - private System.Windows.Forms.Button buttonSuspend; - private System.Windows.Forms.CheckBox checkBoxConnectOnStartup; - private System.Windows.Forms.CheckBox checkBoxShowBorders; - private System.Windows.Forms.TrackBar trackBarBrightness; - private System.Windows.Forms.Button buttonFill; - private System.Windows.Forms.Button buttonClear; - private System.Windows.Forms.Button buttonClose; - private System.Windows.Forms.Button buttonOpen; - private System.Windows.Forms.Button buttonCapture; - private System.Windows.Forms.Button buttonFont; - private System.Windows.Forms.TabControl tabControl; - private System.Windows.Forms.Button buttonCloseClients; - private System.Windows.Forms.Button buttonStartClient; - private System.Windows.Forms.Label labelWarning; - private System.Windows.Forms.TabPage tabPageDesign; - private System.Windows.Forms.CheckBox checkBoxReverseScreen; - private System.Windows.Forms.ComboBox comboBoxDisplayType; - private System.Windows.Forms.MaskedTextBox maskedTextBoxTimerInterval; - private System.Windows.Forms.Label labelTimerInterval; - private System.Windows.Forms.Button buttonPowerOff; - private System.Windows.Forms.Button buttonPowerOn; - private System.Windows.Forms.Button buttonShowClock; - private System.Windows.Forms.Button buttonHideClock; - private System.Windows.Forms.Label labelFontWidth; - private System.Windows.Forms.Label labelFontHeight; - private System.Windows.Forms.CheckBox checkBoxInverseColors; - private System.Windows.Forms.TabPage tabPageApp; - private System.Windows.Forms.Button buttonUpdate; - private System.Windows.Forms.CheckBox checkBoxAutoStart; - private System.Windows.Forms.CheckBox checkBoxStartMinimized; - private System.Windows.Forms.CheckBox checkBoxMinimizeToTray; - private System.Windows.Forms.MaskedTextBox maskedTextBoxMinFontSize; - private System.Windows.Forms.CheckBox checkBoxScaleToFit; - private System.Windows.Forms.Label labelMinFontSize; - private System.Windows.Forms.Label labelScrollLoopSeparator; - private System.Windows.Forms.TextBox textBoxScrollLoopSeparator; - private System.Windows.Forms.Label labelScrollingSpeed; - private System.Windows.Forms.MaskedTextBox maskedTextBoxScrollingSpeed; - private System.Windows.Forms.ToolTip toolTip; - private System.Windows.Forms.TabPage tabPageAudio; - private System.Windows.Forms.TrackBar trackBarMasterVolume; - private System.Windows.Forms.CheckBox checkBoxMute; - private System.Windows.Forms.CheckBox checkBoxShowVolumeLabel; - private System.Windows.Forms.Label labelDefaultAudioDevice; - private System.Windows.Forms.TabPage tabPageInput; - private System.Windows.Forms.Button buttonSelectFile; - private System.Windows.Forms.OpenFileDialog openFileDialog; - private System.Windows.Forms.Label labelStartFileName; - private System.Windows.Forms.PictureBox pictureBoxGreenStart; - private System.Windows.Forms.ComboBox comboBoxOpticalDrives; - private System.Windows.Forms.Label labelOpticalDriveEject; - private System.Windows.Forms.TabPage tabPageCec; - private System.Windows.Forms.CheckBox checkBoxCecEnabled; - private System.Windows.Forms.Label labelHdmiPort; - private System.Windows.Forms.ComboBox comboBoxHdmiPort; - private System.Windows.Forms.Button iButtonStartIdleClient; - private System.Windows.Forms.CheckBox iCheckBoxStartIdleClient; - private System.Windows.Forms.TabPage tabPageLogs; - private System.Windows.Forms.RichTextBox richTextBoxLogs; - private System.Windows.Forms.Button buttonClearLogs; - private System.Windows.Forms.GroupBox groupBoxCecLogOptions; - private System.Windows.Forms.CheckBox checkBoxCecLogWarning; - private System.Windows.Forms.CheckBox checkBoxCecLogError; - private System.Windows.Forms.CheckBox checkBoxCecLogDebug; - private System.Windows.Forms.CheckBox checkBoxCecLogNotice; - private System.Windows.Forms.CheckBox checkBoxCecLogTraffic; - private System.Windows.Forms.CheckBox checkBoxCecLogNoPoll; - private System.Windows.Forms.TabPage tabPageEvent; - private System.Windows.Forms.TreeView iTreeViewEvents; - private System.Windows.Forms.Button buttonDeleteAction; - private System.Windows.Forms.Button buttonAddAction; - private System.Windows.Forms.Button buttonActionMoveUp; - private System.Windows.Forms.Button buttonActionMoveDown; - private System.Windows.Forms.Button buttonTestAction; - } -} - diff -r 6ccaa430aa23 -r 91763ba41c0c Server/MainForm.Hid.cs --- a/Server/MainForm.Hid.cs Thu Jul 28 19:32:40 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,425 +0,0 @@ -using System; -using System.IO; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Diagnostics; -using System.Runtime.InteropServices; -using System.Windows.Forms; -using Microsoft.Win32.SafeHandles; -using System.ComponentModel; -// -using Hid = SharpLib.Hid; -using SharpLib.Win32; - -namespace SharpDisplayManager -{ - /// - /// Implement handling of HID input reports notably to be able to launch an application using the Green Start button from IR remotes. - /// - [System.ComponentModel.DesignerCategory("Code")] - public class MainFormHid : Form - { - [System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "SwitchToThisWindow")] - public static extern void SwitchToThisWindow([System.Runtime.InteropServices.InAttribute()] System.IntPtr hwnd, [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)] bool fUnknown); - // - public delegate void OnHidEventDelegate(object aSender, Hid.Event aHidEvent); - - /// - /// Use notably to handle green start key from IR remote control - /// - private Hid.Handler iHidHandler; - - /// - /// Register HID devices so that we receive corresponding WM_INPUT messages. - /// - protected void RegisterHidDevices() - { - // Register the input device to receive the commands from the - // remote device. See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwmt/html/remote_control.asp - // for the vendor defined usage page. - - RAWINPUTDEVICE[] rid = new RAWINPUTDEVICE[5]; - - int i = 0; - rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.WindowsMediaCenterRemoteControl; - rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.WindowsMediaCenter.WindowsMediaCenterRemoteControl; - rid[i].dwFlags = Const.RIDEV_INPUTSINK; - rid[i].hwndTarget = Handle; - - i++; - rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.Consumer; - rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.Consumer.ConsumerControl; - rid[i].dwFlags = Const.RIDEV_INPUTSINK; - rid[i].hwndTarget = Handle; - - i++; - rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.Consumer; - rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.Consumer.Selection; - rid[i].dwFlags = Const.RIDEV_INPUTSINK; - rid[i].hwndTarget = Handle; - - i++; - rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.GenericDesktopControls; - rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.GenericDesktop.SystemControl; - rid[i].dwFlags = Const.RIDEV_INPUTSINK; - rid[i].hwndTarget = Handle; - - i++; - rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.GenericDesktopControls; - rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.GenericDesktop.GamePad; - rid[i].dwFlags = Const.RIDEV_INPUTSINK; - rid[i].hwndTarget = Handle; - - //i++; - //rid[i].usUsagePage = (ushort)SharpLib.Hid.UsagePage.GenericDesktopControls; - //rid[i].usUsage = (ushort)SharpLib.Hid.UsageCollection.GenericDesktop.Keyboard; - //rid[i].dwFlags = Const.RIDEV_EXINPUTSINK; - //rid[i].hwndTarget = Handle; - - //i++; - //rid[i].usUsagePage = (ushort)Hid.UsagePage.GenericDesktopControls; - //rid[i].usUsage = (ushort)Hid.UsageCollection.GenericDesktop.Mouse; - //rid[i].dwFlags = Const.RIDEV_EXINPUTSINK; - //rid[i].hwndTarget = aHWND; - - - iHidHandler = new SharpLib.Hid.Handler(rid); - if (!iHidHandler.IsRegistered) - { - Debug.WriteLine("Failed to register raw input devices: " + Marshal.GetLastWin32Error().ToString()); - } - iHidHandler.OnHidEvent += HandleHidEventThreadSafe; - - } - - - - - /// - /// Here we receive HID events from our HID library. - /// - /// - /// - public void HandleHidEventThreadSafe(object aSender, SharpLib.Hid.Event aHidEvent) - { - if (aHidEvent.IsStray) - { - //Stray event just ignore it - return; - } - - if (this.InvokeRequired) - { - //Not in the proper thread, invoke ourselves - OnHidEventDelegate d = new OnHidEventDelegate(HandleHidEventThreadSafe); - this.Invoke(d, new object[] { aSender, aHidEvent }); - } - else - { - if (aHidEvent.Usages.Count == 0) - { - //No usage, nothing to do then - return; - } - - //We are in the proper thread - if (aHidEvent.UsagePage == (ushort) Hid.UsagePage.WindowsMediaCenterRemoteControl) - { - switch (aHidEvent.Usages[0]) - { - case (ushort)Hid.Usage.WindowsMediaCenterRemoteControl.GreenStart: - HandleGreenStart(); - break; - case (ushort)Hid.Usage.WindowsMediaCenterRemoteControl.Eject: - case (ushort)Hid.Usage.WindowsMediaCenterRemoteControl.Ext2: - HandleEject(); - break; - } - } - - //Keep this for debug when only ThinkPad keyboard is available - if (aHidEvent.UsagePage == (ushort)Hid.UsagePage.Consumer && aHidEvent.Usages[0] == (ushort)Hid.Usage.ConsumerControl.ThinkPadFullscreenMagnifier) - { - HandleEject(); - } - - } - } - - /// - /// - /// - /// - private void CheckLastError(string aPrefix) - { - string errorMessage = new Win32Exception(Marshal.GetLastWin32Error()).Message; - Debug.WriteLine(aPrefix + Marshal.GetLastWin32Error().ToString() + ": " + errorMessage); - } - - /// - /// - /// - /// - /// - private IntPtr MarshalToPointer(object data) - { - IntPtr buf = Marshal.AllocHGlobal( - Marshal.SizeOf(data)); - Marshal.StructureToPtr(data, - buf, false); - return buf; - } - - /// - /// - /// - /// - private SafeFileHandle OpenVolume(string aDriveName) - { - return Function.CreateFile("\\\\.\\" + aDriveName, - SharpLib.Win32.FileAccess.GENERIC_READ, - SharpLib.Win32.FileShare.FILE_SHARE_READ | SharpLib.Win32.FileShare.FILE_SHARE_WRITE, - IntPtr.Zero, - CreationDisposition.OPEN_EXISTING, - 0, - IntPtr.Zero); - } - - /// - /// - /// - /// - /// - private bool LockVolume(SafeFileHandle aVolume) - { - //Hope that's doing what I think it does - IntPtr dwBytesReturned=new IntPtr(); - //Should not be needed but I'm not sure how to pass NULL in there. - OVERLAPPED overlapped=new OVERLAPPED(); - - int tries = 0; - const int KMaxTries = 100; - const int KSleepTime = 10; - bool success = false; - - while (!success && tries < KMaxTries) - { - success = Function.DeviceIoControl(aVolume, Const.FSCTL_LOCK_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, dwBytesReturned, ref overlapped); - System.Threading.Thread.Sleep(KSleepTime); - tries++; - } - - CheckLastError("Lock volume: "); - - return success; - } - - /// - /// - /// - /// - /// - private bool DismountVolume(SafeFileHandle aVolume) - { - //Hope that's doing what I think it does - IntPtr dwBytesReturned = new IntPtr(); - //Should not be needed but I'm not sure how to pass NULL in there. - OVERLAPPED overlapped=new OVERLAPPED(); - - bool res = Function.DeviceIoControl(aVolume, Const.FSCTL_DISMOUNT_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 0, dwBytesReturned, ref overlapped); - CheckLastError("Dismount volume: "); - return res; - } - - - - /// - /// - /// - /// - /// - /// - private bool PreventRemovalOfVolume(SafeFileHandle aVolume, bool aPreventRemoval) - { - //Hope that's doing what I think it does - IntPtr dwBytesReturned = new IntPtr(); - //Should not be needed but I'm not sure how to pass NULL in there. - OVERLAPPED overlapped = new OVERLAPPED(); - // - PREVENT_MEDIA_REMOVAL preventMediaRemoval = new PREVENT_MEDIA_REMOVAL(); - preventMediaRemoval.PreventMediaRemoval = Convert.ToByte(aPreventRemoval); - IntPtr preventMediaRemovalParam = MarshalToPointer(preventMediaRemoval); - - bool result = Function.DeviceIoControl(aVolume, Const.IOCTL_STORAGE_MEDIA_REMOVAL, preventMediaRemovalParam, Convert.ToUInt32(Marshal.SizeOf(preventMediaRemoval)), IntPtr.Zero, 0, dwBytesReturned, ref overlapped); - CheckLastError("Media removal: "); - Marshal.FreeHGlobal(preventMediaRemovalParam); - - return result; - } - - /// - /// Eject optical drive media opening the tray if any. - /// - /// - /// - private bool MediaEject(SafeFileHandle aVolume) - { - //Hope that's doing what I think it does - IntPtr dwBytesReturned = new IntPtr(); - //Should not be needed but I'm not sure how to pass NULL in there. - OVERLAPPED overlapped=new OVERLAPPED(); - - bool res = Function.DeviceIoControl(aVolume, Const.IOCTL_STORAGE_EJECT_MEDIA, IntPtr.Zero, 0, IntPtr.Zero, 0, dwBytesReturned, ref overlapped); - CheckLastError("Media eject: "); - return res; - } - - /// - /// Close an optical drive tray. - /// - /// - /// - private bool MediaLoad(SafeFileHandle aVolume) - { - //Hope that's doing what I think it does - IntPtr dwBytesReturned = new IntPtr(); - //Should not be needed but I'm not sure how to pass NULL in there. - OVERLAPPED overlapped=new OVERLAPPED(); - - bool res = Function.DeviceIoControl(aVolume, Const.IOCTL_STORAGE_LOAD_MEDIA, IntPtr.Zero, 0, IntPtr.Zero, 0, dwBytesReturned, ref overlapped); - CheckLastError("Media load: "); - return res; - } - - /// - /// - /// - /// - /// - private bool StorageCheckVerify(SafeFileHandle aVolume) - { - //Hope that's doing what I think it does - IntPtr dwBytesReturned = new IntPtr(); - //Should not be needed but I'm not sure how to pass NULL in there. - OVERLAPPED overlapped = new OVERLAPPED(); - - bool res = Function.DeviceIoControl(aVolume, Const.IOCTL_STORAGE_CHECK_VERIFY2, IntPtr.Zero, 0, IntPtr.Zero, 0, dwBytesReturned, ref overlapped); - - CheckLastError("Check verify: "); - - return res; - } - - - - /// - /// Perform media ejection. - /// - private void HandleEject() - { - string drive = ((MainForm)this).OpticalDriveToEject(); - if (drive.Length!=2) - { - //Not a proper drive spec. - //Probably 'None' selected. - return; - } - - SafeFileHandle handle = OpenVolume(drive); - if (handle.IsInvalid) - { - CheckLastError("ERROR: Failed to open volume: "); - return; - } - - if (LockVolume(handle) && DismountVolume(handle)) - { - Debug.WriteLine("Volume was dismounted."); - - if (PreventRemovalOfVolume(handle,false)) - { - //StorageCheckVerify(handle); - - DateTime before; - before = DateTime.Now; - bool ejectSuccess = MediaEject(handle); - double ms = (DateTime.Now - before).TotalMilliseconds; - - //We assume that if it take more than a certain time to for eject to execute it means we actually ejected. - //If our eject completes too rapidly we assume the tray is already open and we will try to close it. - if (ejectSuccess && ms > 100) - { - Debug.WriteLine("Media was ejected"); - } - else if (MediaLoad(handle)) - { - Debug.WriteLine("Media was loaded"); - } - } - } - else - { - Debug.WriteLine("Volume lock or dismount failed."); - } - - //This is needed to make sure we can open the volume next time around - handle.Dispose(); - } - - /// - /// - /// - private void HandleGreenStart() - { - //First check if the process we want to launch already exists - string procName = Path.GetFileNameWithoutExtension(Properties.Settings.Default.StartFileName); - Process[] existingProcesses = Process.GetProcessesByName(procName); - if (existingProcesses == null || existingProcesses.Length == 0) - { - // Process do not exists just try to launch it - ProcessStartInfo start = new ProcessStartInfo(); - // Enter in the command line arguments, everything you would enter after the executable name itself - //start.Arguments = arguments; - // Enter the executable to run, including the complete path - start.FileName = Properties.Settings.Default.StartFileName; - start.WindowStyle = ProcessWindowStyle.Normal; - start.CreateNoWindow = true; - start.UseShellExecute = true; - // Run the external process & wait for it to finish - Process proc = Process.Start(start); - - //SL: We could have used that too - //Shell32.Shell shell = new Shell32.Shell(); - //shell.ShellExecute(Properties.Settings.Default.StartFileName); - } - else - { - //This won't work properly until we have a manifest that enables uiAccess. - //However uiAccess just won't work with ClickOnce so we will have to use a different deployment system. - SwitchToThisWindow(existingProcesses[0].MainWindowHandle, true); - } - } - - - /// - /// We need to handle WM_INPUT. - /// - /// - protected override void WndProc(ref Message message) - { - switch (message.Msg) - { - case Const.WM_INPUT: - //Returning zero means we processed that message. - message.Result = new IntPtr(0); - iHidHandler.ProcessInput(ref message); - break; - } - - //Pass this on to base class. - base.WndProc(ref message); - } - } -} diff -r 6ccaa430aa23 -r 91763ba41c0c Server/MainForm.cs --- a/Server/MainForm.cs Thu Jul 28 19:32:40 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2922 +0,0 @@ -// -// Copyright (C) 2014-2015 Stéphane Lenclud. -// -// This file is part of SharpDisplayManager. -// -// SharpDisplayManager is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// SharpDisplayManager is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with SharpDisplayManager. If not, see . -// - -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; -using System.IO; -using CodeProject.Dialog; -using System.Drawing.Imaging; -using System.ServiceModel; -using System.Threading; -using System.Diagnostics; -using System.Deployment.Application; -using System.Reflection; -//NAudio -using NAudio.CoreAudioApi; -using NAudio.CoreAudioApi.Interfaces; -using System.Runtime.InteropServices; -using CecSharp; -//Network -using NETWORKLIST; -// -using SharpDisplayClient; -using SharpDisplay; -using MiniDisplayInterop; -using SharpLib.Display; -using SharpLib.Ear; - -namespace SharpDisplayManager -{ - //Types declarations - public delegate uint ColorProcessingDelegate(int aX, int aY, uint aPixel); - - public delegate int CoordinateTranslationDelegate(System.Drawing.Bitmap aBmp, int aInt); - - //Delegates are used for our thread safe method - public delegate void AddClientDelegate(string aSessionId, ICallback aCallback); - - public delegate void RemoveClientDelegate(string aSessionId); - - public delegate void SetFieldDelegate(string SessionId, DataField aField); - - public delegate void SetFieldsDelegate(string SessionId, System.Collections.Generic.IList aFields); - - public delegate void SetLayoutDelegate(string SessionId, TableLayout aLayout); - - public delegate void SetClientNameDelegate(string aSessionId, string aName); - - public delegate void SetClientPriorityDelegate(string aSessionId, uint aPriority); - - public delegate void PlainUpdateDelegate(); - - public delegate void WndProcDelegate(ref Message aMessage); - - /// - /// Our Display manager main form - /// - [System.ComponentModel.DesignerCategory("Form")] - public partial class MainForm : MainFormHid, IMMNotificationClient - { - //public ManagerEventAction iManager = new ManagerEventAction(); - DateTime LastTickTime; - Display iDisplay; - System.Drawing.Bitmap iBmp; - bool iCreateBitmap; //Workaround render to bitmap issues when minimized - ServiceHost iServiceHost; - // Our collection of clients sorted by session id. - public Dictionary iClients; - // The name of the client which informations are currently displayed. - public string iCurrentClientSessionId; - ClientData iCurrentClientData; - // - public bool iClosing; - // - public bool iSkipFrameRendering; - //Function pointer for pixel color filtering - ColorProcessingDelegate iColorFx; - //Function pointer for pixel X coordinate intercept - CoordinateTranslationDelegate iScreenX; - //Function pointer for pixel Y coordinate intercept - CoordinateTranslationDelegate iScreenY; - //NAudio - private MMDeviceEnumerator iMultiMediaDeviceEnumerator; - private MMDevice iMultiMediaDevice; - //Network - private NetworkManager iNetworkManager; - - /// - /// CEC - Consumer Electronic Control. - /// Notably used to turn TV on and off as Windows broadcast monitor on and off notifications. - /// - private ConsumerElectronicControl iCecManager; - - /// - /// Manage run when Windows startup option - /// - private StartupManager iStartupManager; - - /// - /// System notification icon used to hide our application from the task bar. - /// - private SharpLib.Notification.Control iNotifyIcon; - - /// - /// System recording notification icon. - /// - private SharpLib.Notification.Control iRecordingNotification; - - /// - /// - /// - RichTextBoxTextWriter iWriter; - - - /// - /// Allow user to receive window messages; - /// - public event WndProcDelegate OnWndProc; - - public MainForm() - { - ManagerEventAction.Current = Properties.Settings.Default.Actions; - if (ManagerEventAction.Current == null) - { - //No actions in our settings yet - ManagerEventAction.Current = new ManagerEventAction(); - Properties.Settings.Default.Actions = ManagerEventAction.Current; - } - else - { - //We loaded actions from our settings - //We need to hook them with corresponding events - ManagerEventAction.Current.Init(); - } - iSkipFrameRendering = false; - iClosing = false; - iCurrentClientSessionId = ""; - iCurrentClientData = null; - LastTickTime = DateTime.Now; - //Instantiate our display and register for events notifications - iDisplay = new Display(); - iDisplay.OnOpened += OnDisplayOpened; - iDisplay.OnClosed += OnDisplayClosed; - // - iClients = new Dictionary(); - iStartupManager = new StartupManager(); - iNotifyIcon = new SharpLib.Notification.Control(); - iRecordingNotification = new SharpLib.Notification.Control(); - - //Have our designer initialize its controls - InitializeComponent(); - - //Redirect console output - iWriter = new RichTextBoxTextWriter(richTextBoxLogs); - Console.SetOut(iWriter); - - //Populate device types - PopulateDeviceTypes(); - - //Populate optical drives - PopulateOpticalDrives(); - - //Initial status update - UpdateStatus(); - - //We have a bug when drawing minimized and reusing our bitmap - //Though I could not reproduce it on Windows 10 - iBmp = new System.Drawing.Bitmap(iTableLayoutPanel.Width, iTableLayoutPanel.Height, - PixelFormat.Format32bppArgb); - iCreateBitmap = false; - - //Minimize our window if desired - if (Properties.Settings.Default.StartMinimized) - { - WindowState = FormWindowState.Minimized; - } - - } - - /// - /// - /// - /// - /// - private void MainForm_Load(object sender, EventArgs e) - { - //Check if we are running a Click Once deployed application - if (ApplicationDeployment.IsNetworkDeployed) - { - //This is a proper Click Once installation, fetch and show our version number - this.Text += " - v" + ApplicationDeployment.CurrentDeployment.CurrentVersion; - } - else - { - //Not a proper Click Once installation, assuming development build then - this.Text += " - development"; - } - - //NAudio - iMultiMediaDeviceEnumerator = new MMDeviceEnumerator(); - iMultiMediaDeviceEnumerator.RegisterEndpointNotificationCallback(this); - UpdateAudioDeviceAndMasterVolumeThreadSafe(); - - //Network - iNetworkManager = new NetworkManager(); - iNetworkManager.OnConnectivityChanged += OnConnectivityChanged; - UpdateNetworkStatus(); - - //CEC - iCecManager = new ConsumerElectronicControl(); - OnWndProc += iCecManager.OnWndProc; - ResetCec(); - - //Setup Events - PopulateEventsTreeView(); - - //Setup notification icon - SetupTrayIcon(); - - //Setup recording notification - SetupRecordingNotification(); - - // To make sure start up with minimize to tray works - if (WindowState == FormWindowState.Minimized && Properties.Settings.Default.MinimizeToTray) - { - Visible = false; - } - -#if !DEBUG - //When not debugging we want the screen to be empty until a client takes over - ClearLayout(); -#else - //When developing we want at least one client for testing - StartNewClient("abcdefghijklmnopqrst-0123456789", "ABCDEFGHIJKLMNOPQRST-0123456789"); -#endif - - //Open display connection on start-up if needed - if (Properties.Settings.Default.DisplayConnectOnStartup) - { - OpenDisplayConnection(); - } - - //Start our server so that we can get client requests - StartServer(); - - //Register for HID events - RegisterHidDevices(); - - //Start Idle client if needed - if (Properties.Settings.Default.StartIdleClient) - { - StartIdleClient(); - } - } - - /// - /// Called when our display is opened. - /// - /// - private void OnDisplayOpened(Display aDisplay) - { - //Make sure we resume frame rendering - iSkipFrameRendering = false; - - //Set our screen size now that our display is connected - //Our panelDisplay is the container of our tableLayoutPanel - //tableLayoutPanel will resize itself to fit the client size of our panelDisplay - //panelDisplay needs an extra 2 pixels for borders on each sides - //tableLayoutPanel will eventually be the exact size of our display - Size size = new Size(iDisplay.WidthInPixels() + 2, iDisplay.HeightInPixels() + 2); - panelDisplay.Size = size; - - //Our display was just opened, update our UI - UpdateStatus(); - //Initiate asynchronous request - iDisplay.RequestFirmwareRevision(); - - //Audio - UpdateMasterVolumeThreadSafe(); - //Network - UpdateNetworkStatus(); - -#if DEBUG - //Testing icon in debug, no arm done if icon not supported - //iDisplay.SetIconStatus(Display.TMiniDisplayIconType.EMiniDisplayIconRecording, 0, 1); - //iDisplay.SetAllIconsStatus(2); -#endif - - } - - /// - /// Populate tree view with events and actions - /// - private void PopulateEventsTreeView() - { - //Disable action buttons - buttonAddAction.Enabled = false; - buttonDeleteAction.Enabled = false; - - Event currentEvent = CurrentEvent(); - SharpLib.Ear.Action currentAction = CurrentAction(); - TreeNode treeNodeToSelect = null; - - //Reset our tree - iTreeViewEvents.Nodes.Clear(); - //Populate registered events - foreach (string key in ManagerEventAction.Current.Events.Keys) - { - Event e = ManagerEventAction.Current.Events[key]; - TreeNode eventNode = iTreeViewEvents.Nodes.Add(key, e.Name); - eventNode.Tag = e; - eventNode.Nodes.Add(key + ".Description", e.Description); - TreeNode actionsNodes = eventNode.Nodes.Add(key + ".Actions", "Actions"); - - // Add our actions for that event - foreach (SharpLib.Ear.Action a in e.Actions) - { - TreeNode actionNode = actionsNodes.Nodes.Add(a.Brief()); - actionNode.Tag = a; - if (a == currentAction) - { - treeNodeToSelect = actionNode; - } - } - } - - iTreeViewEvents.ExpandAll(); - SelectEvent(currentEvent); - - if (treeNodeToSelect != null) - { - iTreeViewEvents.SelectedNode = treeNodeToSelect; - } - else if (iTreeViewEvents.SelectedNode != null && iTreeViewEvents.SelectedNode.Nodes[1].GetNodeCount(false) > 0) - { - //Select the last action if any - iTreeViewEvents.SelectedNode = - iTreeViewEvents.SelectedNode.Nodes[1].Nodes[ - iTreeViewEvents.SelectedNode.Nodes[1].GetNodeCount(false) - 1]; - } - - } - - /// - /// Called when our display is closed. - /// - /// - private void OnDisplayClosed(Display aDisplay) - { - //Our display was just closed, update our UI consequently - UpdateStatus(); - } - - public void OnConnectivityChanged(NetworkManager aNetwork, NLM_CONNECTIVITY newConnectivity) - { - //Update network status - UpdateNetworkStatus(); - } - - /// - /// Update our Network Status - /// - private void UpdateNetworkStatus() - { - if (iDisplay.IsOpen()) - { - iDisplay.SetIconOnOff(MiniDisplay.IconType.Internet, - iNetworkManager.NetworkListManager.IsConnectedToInternet); - iDisplay.SetIconOnOff(MiniDisplay.IconType.NetworkSignal, iNetworkManager.NetworkListManager.IsConnected); - } - } - - - int iLastNetworkIconIndex = 0; - int iUpdateCountSinceLastNetworkAnimation = 0; - - /// - /// - /// - private void UpdateNetworkSignal(DateTime aLastTickTime, DateTime aNewTickTime) - { - iUpdateCountSinceLastNetworkAnimation++; - iUpdateCountSinceLastNetworkAnimation = iUpdateCountSinceLastNetworkAnimation%4; - - if (iDisplay.IsOpen() && iNetworkManager.NetworkListManager.IsConnected && - iUpdateCountSinceLastNetworkAnimation == 0) - { - int iconCount = iDisplay.IconCount(MiniDisplay.IconType.NetworkSignal); - if (iconCount <= 0) - { - //Prevents div by zero and other undefined behavior - return; - } - iLastNetworkIconIndex++; - iLastNetworkIconIndex = iLastNetworkIconIndex%(iconCount*2); - for (int i = 0; i < iconCount; i++) - { - if (i < iLastNetworkIconIndex && !(i == 0 && iLastNetworkIconIndex > 3) && - !(i == 1 && iLastNetworkIconIndex > 4)) - { - iDisplay.SetIconOn(MiniDisplay.IconType.NetworkSignal, i); - } - else - { - iDisplay.SetIconOff(MiniDisplay.IconType.NetworkSignal, i); - } - } - } - } - - - - /// - /// Receive volume change notification and reflect changes on our slider. - /// - /// - public void OnVolumeNotificationThreadSafe(AudioVolumeNotificationData data) - { - UpdateMasterVolumeThreadSafe(); - } - - /// - /// Update master volume when user moves our slider. - /// - /// - /// - private void trackBarMasterVolume_Scroll(object sender, EventArgs e) - { - //Just like Windows Volume Mixer we unmute if the volume is adjusted - iMultiMediaDevice.AudioEndpointVolume.Mute = false; - //Set volume level according to our volume slider new position - iMultiMediaDevice.AudioEndpointVolume.MasterVolumeLevelScalar = trackBarMasterVolume.Value/100.0f; - } - - - /// - /// Mute check box changed. - /// - /// - /// - private void checkBoxMute_CheckedChanged(object sender, EventArgs e) - { - iMultiMediaDevice.AudioEndpointVolume.Mute = checkBoxMute.Checked; - } - - /// - /// Device State Changed - /// - public void OnDeviceStateChanged([MarshalAs(UnmanagedType.LPWStr)] string deviceId, - [MarshalAs(UnmanagedType.I4)] DeviceState newState) - { - } - - /// - /// Device Added - /// - public void OnDeviceAdded([MarshalAs(UnmanagedType.LPWStr)] string pwstrDeviceId) - { - } - - /// - /// Device Removed - /// - public void OnDeviceRemoved([MarshalAs(UnmanagedType.LPWStr)] string deviceId) - { - } - - /// - /// Default Device Changed - /// - public void OnDefaultDeviceChanged(DataFlow flow, Role role, - [MarshalAs(UnmanagedType.LPWStr)] string defaultDeviceId) - { - if (role == Role.Multimedia && flow == DataFlow.Render) - { - UpdateAudioDeviceAndMasterVolumeThreadSafe(); - } - } - - /// - /// Property Value Changed - /// - /// - /// - public void OnPropertyValueChanged([MarshalAs(UnmanagedType.LPWStr)] string pwstrDeviceId, PropertyKey key) - { - } - - - - - /// - /// Update master volume indicators based our current system states. - /// This typically includes volume levels and mute status. - /// - private void UpdateMasterVolumeThreadSafe() - { - if (this.InvokeRequired) - { - //Not in the proper thread, invoke ourselves - PlainUpdateDelegate d = new PlainUpdateDelegate(UpdateMasterVolumeThreadSafe); - this.Invoke(d, new object[] {}); - return; - } - - //Update volume slider - float volumeLevelScalar = iMultiMediaDevice.AudioEndpointVolume.MasterVolumeLevelScalar; - trackBarMasterVolume.Value = Convert.ToInt32(volumeLevelScalar*100); - //Update mute checkbox - checkBoxMute.Checked = iMultiMediaDevice.AudioEndpointVolume.Mute; - - //If our display connection is open we need to update its icons - if (iDisplay.IsOpen()) - { - //First take care our our volume level icons - int volumeIconCount = iDisplay.IconCount(MiniDisplay.IconType.Volume); - if (volumeIconCount > 0) - { - //Compute current volume level from system level and the number of segments in our display volume bar. - //That tells us how many segments in our volume bar needs to be turned on. - float currentVolume = volumeLevelScalar*volumeIconCount; - int segmentOnCount = Convert.ToInt32(currentVolume); - //Check if our segment count was rounded up, this will later be used for half brightness segment - bool roundedUp = segmentOnCount > currentVolume; - - for (int i = 0; i < volumeIconCount; i++) - { - if (i < segmentOnCount) - { - //If we are dealing with our last segment and our segment count was rounded up then we will use half brightness. - if (i == segmentOnCount - 1 && roundedUp) - { - //Half brightness - iDisplay.SetIconStatus(MiniDisplay.IconType.Volume, i, - (iDisplay.IconStatusCount(MiniDisplay.IconType.Volume) - 1)/2); - } - else - { - //Full brightness - iDisplay.SetIconStatus(MiniDisplay.IconType.Volume, i, - iDisplay.IconStatusCount(MiniDisplay.IconType.Volume) - 1); - } - } - else - { - iDisplay.SetIconStatus(MiniDisplay.IconType.Volume, i, 0); - } - } - } - - //Take care of our mute icon - iDisplay.SetIconOnOff(MiniDisplay.IconType.Mute, iMultiMediaDevice.AudioEndpointVolume.Mute); - } - - } - - /// - /// - /// - private void UpdateAudioDeviceAndMasterVolumeThreadSafe() - { - if (this.InvokeRequired) - { - //Not in the proper thread, invoke ourselves - PlainUpdateDelegate d = new PlainUpdateDelegate(UpdateAudioDeviceAndMasterVolumeThreadSafe); - this.Invoke(d, new object[] {}); - return; - } - - //We are in the correct thread just go ahead. - try - { - //Get our master volume - iMultiMediaDevice = iMultiMediaDeviceEnumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia); - //Update our label - labelDefaultAudioDevice.Text = iMultiMediaDevice.FriendlyName; - - //Show our volume in our track bar - UpdateMasterVolumeThreadSafe(); - - //Register to get volume modifications - iMultiMediaDevice.AudioEndpointVolume.OnVolumeNotification += OnVolumeNotificationThreadSafe; - // - trackBarMasterVolume.Enabled = true; - } - catch (Exception ex) - { - Debug.WriteLine("Exception thrown in UpdateAudioDeviceAndMasterVolume"); - Debug.WriteLine(ex.ToString()); - //Something went wrong S/PDIF device ca throw exception I guess - trackBarMasterVolume.Enabled = false; - } - } - - /// - /// - /// - private void PopulateDeviceTypes() - { - int count = Display.TypeCount(); - - for (int i = 0; i < count; i++) - { - comboBoxDisplayType.Items.Add(Display.TypeName((MiniDisplay.Type) i)); - } - } - - /// - /// - /// - private void PopulateOpticalDrives() - { - //Reset our list of drives - comboBoxOpticalDrives.Items.Clear(); - comboBoxOpticalDrives.Items.Add("None"); - - //Go through each drives on our system and collected the optical ones in our list - DriveInfo[] allDrives = DriveInfo.GetDrives(); - foreach (DriveInfo d in allDrives) - { - Debug.WriteLine("Drive " + d.Name); - Debug.WriteLine(" Drive type: {0}", d.DriveType); - - if (d.DriveType == DriveType.CDRom) - { - //This is an optical drive, add it now - comboBoxOpticalDrives.Items.Add(d.Name.Substring(0, 2)); - } - } - } - - /// - /// - /// - /// - public string OpticalDriveToEject() - { - return comboBoxOpticalDrives.SelectedItem.ToString(); - } - - - - /// - /// - /// - private void SetupTrayIcon() - { - iNotifyIcon.Icon = GetIcon("vfd.ico"); - iNotifyIcon.Text = "Sharp Display Manager"; - iNotifyIcon.Visible = true; - - //Double click toggles visibility - typically brings up the application - iNotifyIcon.DoubleClick += delegate(object obj, EventArgs args) - { - SysTrayHideShow(); - }; - - //Adding a context menu, useful to be able to exit the application - ContextMenu contextMenu = new ContextMenu(); - //Context menu item to toggle visibility - MenuItem hideShowItem = new MenuItem("Hide/Show"); - hideShowItem.Click += delegate(object obj, EventArgs args) - { - SysTrayHideShow(); - }; - contextMenu.MenuItems.Add(hideShowItem); - - //Context menu item separator - contextMenu.MenuItems.Add(new MenuItem("-")); - - //Context menu exit item - MenuItem exitItem = new MenuItem("Exit"); - exitItem.Click += delegate(object obj, EventArgs args) - { - Application.Exit(); - }; - contextMenu.MenuItems.Add(exitItem); - - iNotifyIcon.ContextMenu = contextMenu; - } - - /// - /// - /// - private void SetupRecordingNotification() - { - iRecordingNotification.Icon = GetIcon("record.ico"); - iRecordingNotification.Text = "No recording"; - iRecordingNotification.Visible = false; - } - - /// - /// Access icons from embedded resources. - /// - /// - /// - public static Icon GetIcon(string aName) - { - string[] names = Assembly.GetExecutingAssembly().GetManifestResourceNames(); - foreach (string name in names) - { - //Find a resource name that ends with the given name - if (name.EndsWith(aName)) - { - using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name)) - { - return new Icon(stream); - } - } - } - - return null; - } - - - /// - /// Set our current client. - /// This will take care of applying our client layout and set data fields. - /// - /// - void SetCurrentClient(string aSessionId, bool aForce = false) - { - if (aSessionId == iCurrentClientSessionId) - { - //Given client is already the current one. - //Don't bother changing anything then. - return; - } - - ClientData requestedClientData = iClients[aSessionId]; - - //Check when was the last time we switched to that client - if (iCurrentClientData != null) - { - //Do not switch client if priority of current client is higher - if (!aForce && requestedClientData.Priority < iCurrentClientData.Priority) - { - return; - } - - - double lastSwitchToClientSecondsAgo = (DateTime.Now - iCurrentClientData.LastSwitchTime).TotalSeconds; - //TODO: put that hard coded value as a client property - //Clients should be able to define how often they can be interrupted - //Thus a background client can set this to zero allowing any other client to interrupt at any time - //We could also compute this delay by looking at the requests frequencies? - if (!aForce && - requestedClientData.Priority == iCurrentClientData.Priority && - //Time sharing is only if clients have the same priority - (lastSwitchToClientSecondsAgo < 30)) //Make sure a client is on for at least 30 seconds - { - //Don't switch clients too often - return; - } - } - - //Set current client ID. - iCurrentClientSessionId = aSessionId; - //Set the time we last switched to that client - iClients[aSessionId].LastSwitchTime = DateTime.Now; - //Fetch and set current client data. - iCurrentClientData = requestedClientData; - //Apply layout and set data fields. - UpdateTableLayoutPanel(iCurrentClientData); - } - - private void buttonFont_Click(object sender, EventArgs e) - { - //fontDialog.ShowColor = true; - //fontDialog.ShowApply = true; - fontDialog.ShowEffects = true; - fontDialog.Font = cds.Font; - - fontDialog.FixedPitchOnly = checkBoxFixedPitchFontOnly.Checked; - - //fontDialog.ShowHelp = true; - - //fontDlg.MaxSize = 40; - //fontDlg.MinSize = 22; - - //fontDialog.Parent = this; - //fontDialog.StartPosition = FormStartPosition.CenterParent; - - //DlgBox.ShowDialog(fontDialog); - - //if (fontDialog.ShowDialog(this) != DialogResult.Cancel) - if (DlgBox.ShowDialog(fontDialog) != DialogResult.Cancel) - { - //Set the fonts to all our labels in our layout - foreach (Control ctrl in iTableLayoutPanel.Controls) - { - if (ctrl is MarqueeLabel) - { - ((MarqueeLabel) ctrl).Font = fontDialog.Font; - } - } - - //Save font settings - cds.Font = fontDialog.Font; - Properties.Settings.Default.Save(); - // - CheckFontHeight(); - } - } - - /// - /// - /// - void CheckFontHeight() - { - //Show font height and width - labelFontHeight.Text = "Font height: " + cds.Font.Height; - float charWidth = IsFixedWidth(cds.Font); - if (charWidth == 0.0f) - { - labelFontWidth.Visible = false; - } - else - { - labelFontWidth.Visible = true; - labelFontWidth.Text = "Font width: " + charWidth; - } - - MarqueeLabel label = null; - //Get the first label control we can find - foreach (Control ctrl in iTableLayoutPanel.Controls) - { - if (ctrl is MarqueeLabel) - { - label = (MarqueeLabel) ctrl; - break; - } - } - - //Now check font height and show a warning if needed. - if (label != null && label.Font.Height > label.Height) - { - labelWarning.Text = "WARNING: Selected font is too height by " + (label.Font.Height - label.Height) + - " pixels!"; - labelWarning.Visible = true; - } - else - { - labelWarning.Visible = false; - } - - } - - private void buttonCapture_Click(object sender, EventArgs e) - { - System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(iTableLayoutPanel.Width, iTableLayoutPanel.Height); - iTableLayoutPanel.DrawToBitmap(bmp, iTableLayoutPanel.ClientRectangle); - //Bitmap bmpToSave = new Bitmap(bmp); - bmp.Save("D:\\capture.png"); - - ((MarqueeLabel) iTableLayoutPanel.Controls[0]).Text = "Captured"; - - /* - string outputFileName = "d:\\capture.png"; - using (MemoryStream memory = new MemoryStream()) - { - using (FileStream fs = new FileStream(outputFileName, FileMode.OpenOrCreate, FileAccess.ReadWrite)) - { - bmp.Save(memory, System.Drawing.Imaging.ImageFormat.Png); - byte[] bytes = memory.ToArray(); - fs.Write(bytes, 0, bytes.Length); - } - } - */ - - } - - private void CheckForRequestResults() - { - if (iDisplay.IsRequestPending()) - { - switch (iDisplay.AttemptRequestCompletion()) - { - case MiniDisplay.Request.FirmwareRevision: - toolStripStatusLabelConnect.Text += " v" + iDisplay.FirmwareRevision(); - //Issue next request then - iDisplay.RequestPowerSupplyStatus(); - break; - - case MiniDisplay.Request.PowerSupplyStatus: - if (iDisplay.PowerSupplyStatus()) - { - toolStripStatusLabelPower.Text = "ON"; - } - else - { - toolStripStatusLabelPower.Text = "OFF"; - } - //Issue next request then - iDisplay.RequestDeviceId(); - break; - - case MiniDisplay.Request.DeviceId: - toolStripStatusLabelConnect.Text += " - " + iDisplay.DeviceId(); - //No more request to issue - break; - } - } - } - - public static uint ColorWhiteIsOn(int aX, int aY, uint aPixel) - { - if ((aPixel & 0x00FFFFFF) == 0x00FFFFFF) - { - return 0xFFFFFFFF; - } - return 0x00000000; - } - - public static uint ColorUntouched(int aX, int aY, uint aPixel) - { - return aPixel; - } - - public static uint ColorInversed(int aX, int aY, uint aPixel) - { - return ~aPixel; - } - - public static uint ColorChessboard(int aX, int aY, uint aPixel) - { - if ((aX%2 == 0) && (aY%2 == 0)) - { - return ~aPixel; - } - else if ((aX%2 != 0) && (aY%2 != 0)) - { - return ~aPixel; - } - return 0x00000000; - } - - - public static int ScreenReversedX(System.Drawing.Bitmap aBmp, int aX) - { - return aBmp.Width - aX - 1; - } - - public int ScreenReversedY(System.Drawing.Bitmap aBmp, int aY) - { - return iBmp.Height - aY - 1; - } - - public int ScreenX(System.Drawing.Bitmap aBmp, int aX) - { - return aX; - } - - public int ScreenY(System.Drawing.Bitmap aBmp, int aY) - { - return aY; - } - - /// - /// Select proper pixel delegates according to our current settings. - /// - private void SetupPixelDelegates() - { - //Select our pixel processing routine - if (cds.InverseColors) - { - //iColorFx = ColorChessboard; - iColorFx = ColorInversed; - } - else - { - iColorFx = ColorWhiteIsOn; - } - - //Select proper coordinate translation functions - //We used delegate/function pointer to support reverse screen without doing an extra test on each pixels - if (cds.ReverseScreen) - { - iScreenX = ScreenReversedX; - iScreenY = ScreenReversedY; - } - else - { - iScreenX = ScreenX; - iScreenY = ScreenY; - } - - } - - //This is our timer tick responsible to perform our render - private void timer_Tick(object sender, EventArgs e) - { - //Not ideal cause this has nothing to do with display render - LogsUpdate(); - - //Update our animations - DateTime NewTickTime = DateTime.Now; - - UpdateNetworkSignal(LastTickTime, NewTickTime); - - //Update animation for all our marquees - foreach (Control ctrl in iTableLayoutPanel.Controls) - { - if (ctrl is MarqueeLabel) - { - ((MarqueeLabel) ctrl).UpdateAnimation(LastTickTime, NewTickTime); - } - } - - //Update our display - if (iDisplay.IsOpen()) - { - CheckForRequestResults(); - - //Check if frame rendering is needed - //Typically used when showing clock - if (!iSkipFrameRendering) - { - //Draw to bitmap - if (iCreateBitmap) - { - iBmp = new System.Drawing.Bitmap(iTableLayoutPanel.Width, iTableLayoutPanel.Height, - PixelFormat.Format32bppArgb); - iCreateBitmap = false; - } - iTableLayoutPanel.DrawToBitmap(iBmp, iTableLayoutPanel.ClientRectangle); - //iBmp.Save("D:\\capture.png"); - - //Send it to our display - for (int i = 0; i < iBmp.Width; i++) - { - for (int j = 0; j < iBmp.Height; j++) - { - unchecked - { - //Get our processed pixel coordinates - int x = iScreenX(iBmp, i); - int y = iScreenY(iBmp, j); - //Get pixel color - uint color = (uint) iBmp.GetPixel(i, j).ToArgb(); - //Apply color effects - color = iColorFx(x, y, color); - //Now set our pixel - iDisplay.SetPixel(x, y, color); - } - } - } - - iDisplay.SwapBuffers(); - } - } - - //Compute instant FPS - toolStripStatusLabelFps.Text = (1.0/NewTickTime.Subtract(LastTickTime).TotalSeconds).ToString("F0") + " / " + - (1000/timer.Interval).ToString() + " FPS"; - - LastTickTime = NewTickTime; - - } - - /// - /// Attempt to establish connection with our display hardware. - /// - private void OpenDisplayConnection() - { - CloseDisplayConnection(); - - if (!iDisplay.Open((MiniDisplay.Type) cds.DisplayType)) - { - UpdateStatus(); - toolStripStatusLabelConnect.Text = "Connection error"; - } - } - - private void CloseDisplayConnection() - { - //Status will be updated upon receiving the closed event - - if (iDisplay == null || !iDisplay.IsOpen()) - { - return; - } - - //Do not clear if we gave up on rendering already. - //This means we will keep on displaying clock on MDM166AA for instance. - if (!iSkipFrameRendering) - { - iDisplay.Clear(); - iDisplay.SwapBuffers(); - } - - iDisplay.SetAllIconsStatus(0); //Turn off all icons - iDisplay.Close(); - } - - private void buttonOpen_Click(object sender, EventArgs e) - { - OpenDisplayConnection(); - } - - private void buttonClose_Click(object sender, EventArgs e) - { - CloseDisplayConnection(); - } - - private void buttonClear_Click(object sender, EventArgs e) - { - iDisplay.Clear(); - iDisplay.SwapBuffers(); - } - - private void buttonFill_Click(object sender, EventArgs e) - { - iDisplay.Fill(); - iDisplay.SwapBuffers(); - } - - private void trackBarBrightness_Scroll(object sender, EventArgs e) - { - cds.Brightness = trackBarBrightness.Value; - Properties.Settings.Default.Save(); - iDisplay.SetBrightness(trackBarBrightness.Value); - - } - - - /// - /// CDS stands for Current Display Settings - /// - private DisplaySettings cds - { - get - { - DisplaysSettings settings = Properties.Settings.Default.DisplaysSettings; - if (settings == null) - { - settings = new DisplaysSettings(); - settings.Init(); - Properties.Settings.Default.DisplaysSettings = settings; - } - - //Make sure all our settings have been created - while (settings.Displays.Count <= Properties.Settings.Default.CurrentDisplayIndex) - { - settings.Displays.Add(new DisplaySettings()); - } - - DisplaySettings displaySettings = settings.Displays[Properties.Settings.Default.CurrentDisplayIndex]; - return displaySettings; - } - } - - /// - /// Check if the given font has a fixed character pitch. - /// - /// - /// 0.0f if this is not a monospace font, otherwise returns the character width. - public float IsFixedWidth(Font ft) - { - Graphics g = CreateGraphics(); - char[] charSizes = new char[] {'i', 'a', 'Z', '%', '#', 'a', 'B', 'l', 'm', ',', '.'}; - float charWidth = g.MeasureString("I", ft, Int32.MaxValue, StringFormat.GenericTypographic).Width; - - bool fixedWidth = true; - - foreach (char c in charSizes) - if (g.MeasureString(c.ToString(), ft, Int32.MaxValue, StringFormat.GenericTypographic).Width != - charWidth) - fixedWidth = false; - - if (fixedWidth) - { - return charWidth; - } - - return 0.0f; - } - - /// - /// Synchronize UI with settings - /// - private void UpdateStatus() - { - //Load settings - checkBoxShowBorders.Checked = cds.ShowBorders; - iTableLayoutPanel.CellBorderStyle = (cds.ShowBorders - ? TableLayoutPanelCellBorderStyle.Single - : TableLayoutPanelCellBorderStyle.None); - - //Set the proper font to each of our labels - foreach (MarqueeLabel ctrl in iTableLayoutPanel.Controls) - { - ctrl.Font = cds.Font; - } - - CheckFontHeight(); - //Check if "run on Windows startup" is enabled - checkBoxAutoStart.Checked = iStartupManager.Startup; - // - checkBoxConnectOnStartup.Checked = Properties.Settings.Default.DisplayConnectOnStartup; - checkBoxMinimizeToTray.Checked = Properties.Settings.Default.MinimizeToTray; - checkBoxStartMinimized.Checked = Properties.Settings.Default.StartMinimized; - iCheckBoxStartIdleClient.Checked = Properties.Settings.Default.StartIdleClient; - labelStartFileName.Text = Properties.Settings.Default.StartFileName; - - - //Try find our drive in our drive list - int opticalDriveItemIndex = 0; - bool driveNotFound = true; - string opticalDriveToEject = Properties.Settings.Default.OpticalDriveToEject; - foreach (object item in comboBoxOpticalDrives.Items) - { - if (opticalDriveToEject == item.ToString()) - { - comboBoxOpticalDrives.SelectedIndex = opticalDriveItemIndex; - driveNotFound = false; - break; - } - opticalDriveItemIndex++; - } - - if (driveNotFound) - { - //We could not find the drive we had saved. - //Select "None" then. - comboBoxOpticalDrives.SelectedIndex = 0; - } - - //CEC settings - checkBoxCecEnabled.Checked = Properties.Settings.Default.CecEnabled; - comboBoxHdmiPort.SelectedIndex = Properties.Settings.Default.CecHdmiPort - 1; - - //Mini Display settings - checkBoxReverseScreen.Checked = cds.ReverseScreen; - checkBoxInverseColors.Checked = cds.InverseColors; - checkBoxShowVolumeLabel.Checked = cds.ShowVolumeLabel; - checkBoxScaleToFit.Checked = cds.ScaleToFit; - maskedTextBoxMinFontSize.Enabled = cds.ScaleToFit; - labelMinFontSize.Enabled = cds.ScaleToFit; - maskedTextBoxMinFontSize.Text = cds.MinFontSize.ToString(); - maskedTextBoxScrollingSpeed.Text = cds.ScrollingSpeedInPixelsPerSecond.ToString(); - comboBoxDisplayType.SelectedIndex = cds.DisplayType; - timer.Interval = cds.TimerInterval; - maskedTextBoxTimerInterval.Text = cds.TimerInterval.ToString(); - textBoxScrollLoopSeparator.Text = cds.Separator; - // - SetupPixelDelegates(); - - if (iDisplay.IsOpen()) - { - //We have a display connection - //Reflect that in our UI - StartTimer(); - - iTableLayoutPanel.Enabled = true; - panelDisplay.Enabled = true; - - //Only setup brightness if display is open - trackBarBrightness.Minimum = iDisplay.MinBrightness(); - trackBarBrightness.Maximum = iDisplay.MaxBrightness(); - if (cds.Brightness < iDisplay.MinBrightness() || cds.Brightness > iDisplay.MaxBrightness()) - { - //Brightness out of range, this can occur when using auto-detect - //Use max brightness instead - trackBarBrightness.Value = iDisplay.MaxBrightness(); - iDisplay.SetBrightness(iDisplay.MaxBrightness()); - } - else - { - trackBarBrightness.Value = cds.Brightness; - iDisplay.SetBrightness(cds.Brightness); - } - - //Try compute the steps to something that makes sense - trackBarBrightness.LargeChange = Math.Max(1, (iDisplay.MaxBrightness() - iDisplay.MinBrightness())/5); - trackBarBrightness.SmallChange = 1; - - // - buttonFill.Enabled = true; - buttonClear.Enabled = true; - buttonOpen.Enabled = false; - buttonClose.Enabled = true; - trackBarBrightness.Enabled = true; - toolStripStatusLabelConnect.Text = "Connected - " + iDisplay.Vendor() + " - " + iDisplay.Product(); - //+ " - " + iDisplay.SerialNumber(); - - if (iDisplay.SupportPowerOnOff()) - { - buttonPowerOn.Enabled = true; - buttonPowerOff.Enabled = true; - } - else - { - buttonPowerOn.Enabled = false; - buttonPowerOff.Enabled = false; - } - - if (iDisplay.SupportClock()) - { - buttonShowClock.Enabled = true; - buttonHideClock.Enabled = true; - } - else - { - buttonShowClock.Enabled = false; - buttonHideClock.Enabled = false; - } - - - //Check if Volume Label is supported. To date only MDM166AA supports that crap :) - checkBoxShowVolumeLabel.Enabled = iDisplay.IconCount(MiniDisplay.IconType.VolumeLabel) > 0; - - if (cds.ShowVolumeLabel) - { - iDisplay.SetIconOn(MiniDisplay.IconType.VolumeLabel); - } - else - { - iDisplay.SetIconOff(MiniDisplay.IconType.VolumeLabel); - } - } - else - { - //Display connection not available - //Reflect that in our UI -#if DEBUG - //In debug start our timer even if we don't have a display connection - StartTimer(); -#else - //In production environment we don't need our timer if no display connection - StopTimer(); -#endif - checkBoxShowVolumeLabel.Enabled = false; - iTableLayoutPanel.Enabled = false; - panelDisplay.Enabled = false; - buttonFill.Enabled = false; - buttonClear.Enabled = false; - buttonOpen.Enabled = true; - buttonClose.Enabled = false; - trackBarBrightness.Enabled = false; - buttonPowerOn.Enabled = false; - buttonPowerOff.Enabled = false; - buttonShowClock.Enabled = false; - buttonHideClock.Enabled = false; - toolStripStatusLabelConnect.Text = "Disconnected"; - toolStripStatusLabelPower.Text = "N/A"; - } - - } - - - /// - /// - /// - /// - /// - private void checkBoxShowVolumeLabel_CheckedChanged(object sender, EventArgs e) - { - cds.ShowVolumeLabel = checkBoxShowVolumeLabel.Checked; - Properties.Settings.Default.Save(); - UpdateStatus(); - } - - private void checkBoxShowBorders_CheckedChanged(object sender, EventArgs e) - { - //Save our show borders setting - iTableLayoutPanel.CellBorderStyle = (checkBoxShowBorders.Checked - ? TableLayoutPanelCellBorderStyle.Single - : TableLayoutPanelCellBorderStyle.None); - cds.ShowBorders = checkBoxShowBorders.Checked; - Properties.Settings.Default.Save(); - CheckFontHeight(); - } - - private void checkBoxConnectOnStartup_CheckedChanged(object sender, EventArgs e) - { - //Save our connect on startup setting - Properties.Settings.Default.DisplayConnectOnStartup = checkBoxConnectOnStartup.Checked; - Properties.Settings.Default.Save(); - } - - private void checkBoxMinimizeToTray_CheckedChanged(object sender, EventArgs e) - { - //Save our "Minimize to tray" setting - Properties.Settings.Default.MinimizeToTray = checkBoxMinimizeToTray.Checked; - Properties.Settings.Default.Save(); - - } - - private void checkBoxStartMinimized_CheckedChanged(object sender, EventArgs e) - { - //Save our "Start minimized" setting - Properties.Settings.Default.StartMinimized = checkBoxStartMinimized.Checked; - Properties.Settings.Default.Save(); - } - - private void checkBoxStartIdleClient_CheckedChanged(object sender, EventArgs e) - { - Properties.Settings.Default.StartIdleClient = iCheckBoxStartIdleClient.Checked; - Properties.Settings.Default.Save(); - } - - private void checkBoxAutoStart_CheckedChanged(object sender, EventArgs e) - { - iStartupManager.Startup = checkBoxAutoStart.Checked; - } - - - private void checkBoxReverseScreen_CheckedChanged(object sender, EventArgs e) - { - //Save our reverse screen setting - cds.ReverseScreen = checkBoxReverseScreen.Checked; - Properties.Settings.Default.Save(); - SetupPixelDelegates(); - } - - private void checkBoxInverseColors_CheckedChanged(object sender, EventArgs e) - { - //Save our inverse colors setting - cds.InverseColors = checkBoxInverseColors.Checked; - Properties.Settings.Default.Save(); - SetupPixelDelegates(); - } - - private void checkBoxScaleToFit_CheckedChanged(object sender, EventArgs e) - { - //Save our scale to fit setting - cds.ScaleToFit = checkBoxScaleToFit.Checked; - Properties.Settings.Default.Save(); - // - labelMinFontSize.Enabled = cds.ScaleToFit; - maskedTextBoxMinFontSize.Enabled = cds.ScaleToFit; - } - - private void MainForm_Resize(object sender, EventArgs e) - { - if (WindowState == FormWindowState.Minimized) - { - // To workaround our empty bitmap bug on Windows 7 we need to recreate our bitmap when the application is minimized - // That's apparently not needed on Windows 10 but we better leave it in place. - iCreateBitmap = true; - } - } - - private void MainForm_FormClosing(object sender, FormClosingEventArgs e) - { - iCecManager.Stop(); - iNetworkManager.Dispose(); - CloseDisplayConnection(); - StopServer(); - e.Cancel = iClosing; - } - - public void StartServer() - { - iServiceHost = new ServiceHost - ( - typeof(Session), - new Uri[] {new Uri("net.tcp://localhost:8001/")} - ); - - iServiceHost.AddServiceEndpoint(typeof(IService), new NetTcpBinding(SecurityMode.None, true), - "DisplayService"); - iServiceHost.Open(); - } - - public void StopServer() - { - if (iClients.Count > 0 && !iClosing) - { - //Tell our clients - iClosing = true; - BroadcastCloseEvent(); - } - else if (iClosing) - { - if ( - MessageBox.Show("Force exit?", "Waiting for clients...", MessageBoxButtons.YesNo, - MessageBoxIcon.Warning) == DialogResult.Yes) - { - iClosing = false; //We make sure we force close if asked twice - } - } - else - { - //We removed that as it often lags for some reason - //iServiceHost.Close(); - } - } - - public void BroadcastCloseEvent() - { - Trace.TraceInformation("BroadcastCloseEvent - start"); - - var inactiveClients = new List(); - foreach (var client in iClients) - { - //if (client.Key != eventData.ClientName) - { - try - { - Trace.TraceInformation("BroadcastCloseEvent - " + client.Key); - client.Value.Callback.OnCloseOrder( /*eventData*/); - } - catch (Exception ex) - { - inactiveClients.Add(client.Key); - } - } - } - - if (inactiveClients.Count > 0) - { - foreach (var client in inactiveClients) - { - iClients.Remove(client); - Program.iMainForm.iTreeViewClients.Nodes.Remove( - Program.iMainForm.iTreeViewClients.Nodes.Find(client, false)[0]); - } - } - - if (iClients.Count == 0) - { - ClearLayout(); - } - } - - /// - /// Just remove all our fields. - /// - private void ClearLayout() - { - iTableLayoutPanel.Controls.Clear(); - iTableLayoutPanel.RowStyles.Clear(); - iTableLayoutPanel.ColumnStyles.Clear(); - iCurrentClientData = null; - } - - /// - /// Just launch a demo client. - /// - private void StartNewClient(string aTopText = "", string aBottomText = "") - { - Thread clientThread = new Thread(SharpDisplayClient.Program.MainWithParams); - SharpDisplayClient.StartParams myParams = new SharpDisplayClient.StartParams( - new Point(this.Right, this.Top), aTopText, aBottomText); - clientThread.Start(myParams); - BringToFront(); - } - - /// - /// Just launch our idle client. - /// - private void StartIdleClient(string aTopText = "", string aBottomText = "") - { - Thread clientThread = new Thread(SharpDisplayClientIdle.Program.MainWithParams); - SharpDisplayClientIdle.StartParams myParams = - new SharpDisplayClientIdle.StartParams(new Point(this.Right, this.Top), aTopText, aBottomText); - clientThread.Start(myParams); - BringToFront(); - } - - - private void buttonStartClient_Click(object sender, EventArgs e) - { - StartNewClient(); - } - - private void buttonSuspend_Click(object sender, EventArgs e) - { - ToggleTimer(); - } - - private void StartTimer() - { - LastTickTime = DateTime.Now; //Reset timer to prevent jump - timer.Enabled = true; - UpdateSuspendButton(); - } - - private void StopTimer() - { - LastTickTime = DateTime.Now; //Reset timer to prevent jump - timer.Enabled = false; - UpdateSuspendButton(); - } - - private void ToggleTimer() - { - LastTickTime = DateTime.Now; //Reset timer to prevent jump - timer.Enabled = !timer.Enabled; - UpdateSuspendButton(); - } - - private void UpdateSuspendButton() - { - if (!timer.Enabled) - { - buttonSuspend.Text = "Run"; - } - else - { - buttonSuspend.Text = "Pause"; - } - } - - - private void buttonCloseClients_Click(object sender, EventArgs e) - { - BroadcastCloseEvent(); - } - - private void treeViewClients_AfterSelect(object sender, TreeViewEventArgs e) - { - //Root node must have at least one child - if (e.Node.Nodes.Count == 0) - { - return; - } - - //If the selected node is the root node of a client then switch to it - string sessionId = e.Node.Nodes[0].Text; //First child of a root node is the sessionId - if (iClients.ContainsKey(sessionId)) //Check that's actually what we are looking at - { - //We have a valid session just switch to that client - SetCurrentClient(sessionId, true); - } - - } - - - /// - /// - /// - /// - /// - public void AddClientThreadSafe(string aSessionId, ICallback aCallback) - { - if (this.InvokeRequired) - { - //Not in the proper thread, invoke ourselves - AddClientDelegate d = new AddClientDelegate(AddClientThreadSafe); - this.Invoke(d, new object[] {aSessionId, aCallback}); - } - else - { - //We are in the proper thread - //Add this session to our collection of clients - ClientData newClient = new ClientData(aSessionId, aCallback); - Program.iMainForm.iClients.Add(aSessionId, newClient); - //Add this session to our UI - UpdateClientTreeViewNode(newClient); - } - } - - - /// - /// Find the client with the highest priority if any. - /// - /// Our highest priority client or null if not a single client is connected. - public ClientData FindHighestPriorityClient() - { - ClientData highestPriorityClient = null; - foreach (var client in iClients) - { - if (highestPriorityClient == null || client.Value.Priority > highestPriorityClient.Priority) - { - highestPriorityClient = client.Value; - } - } - - return highestPriorityClient; - } - - /// - /// - /// - /// - public void RemoveClientThreadSafe(string aSessionId) - { - if (this.InvokeRequired) - { - //Not in the proper thread, invoke ourselves - RemoveClientDelegate d = new RemoveClientDelegate(RemoveClientThreadSafe); - this.Invoke(d, new object[] {aSessionId}); - } - else - { - //We are in the proper thread - //Remove this session from both client collection and UI tree view - if (Program.iMainForm.iClients.Keys.Contains(aSessionId)) - { - Program.iMainForm.iClients.Remove(aSessionId); - Program.iMainForm.iTreeViewClients.Nodes.Remove( - Program.iMainForm.iTreeViewClients.Nodes.Find(aSessionId, false)[0]); - //Update recording status too whenever a client is removed - UpdateRecordingNotification(); - } - - if (iCurrentClientSessionId == aSessionId) - { - //The current client is closing - iCurrentClientData = null; - //Find the client with the highest priority and set it as current - ClientData newCurrentClient = FindHighestPriorityClient(); - if (newCurrentClient != null) - { - SetCurrentClient(newCurrentClient.SessionId, true); - } - } - - if (iClients.Count == 0) - { - //Clear our screen when last client disconnects - ClearLayout(); - - if (iClosing) - { - //We were closing our form - //All clients are now closed - //Just resume our close operation - iClosing = false; - Close(); - } - } - } - } - - /// - /// - /// - /// - /// - public void SetClientLayoutThreadSafe(string aSessionId, TableLayout aLayout) - { - if (this.InvokeRequired) - { - //Not in the proper thread, invoke ourselves - SetLayoutDelegate d = new SetLayoutDelegate(SetClientLayoutThreadSafe); - this.Invoke(d, new object[] {aSessionId, aLayout}); - } - else - { - ClientData client = iClients[aSessionId]; - if (client != null) - { - //Don't change a thing if the layout is the same - if (!client.Layout.IsSameAs(aLayout)) - { - Debug.Print("SetClientLayoutThreadSafe: Layout updated."); - //Set our client layout then - client.Layout = aLayout; - //So that next time we update all our fields at ones - client.HasNewLayout = true; - //Layout has changed clear our fields then - client.Fields.Clear(); - // - UpdateClientTreeViewNode(client); - } - else - { - Debug.Print("SetClientLayoutThreadSafe: Layout has not changed."); - } - } - } - } - - /// - /// - /// - /// - /// - public void SetClientFieldThreadSafe(string aSessionId, DataField aField) - { - if (this.InvokeRequired) - { - //Not in the proper thread, invoke ourselves - SetFieldDelegate d = new SetFieldDelegate(SetClientFieldThreadSafe); - this.Invoke(d, new object[] {aSessionId, aField}); - } - else - { - //We are in the proper thread - //Call the non-thread-safe variant - SetClientField(aSessionId, aField); - } - } - - - - - /// - /// Set a data field in the given client. - /// - /// - /// - private void SetClientField(string aSessionId, DataField aField) - { - //TODO: should check if the field actually changed? - - ClientData client = iClients[aSessionId]; - bool layoutChanged = false; - bool contentChanged = true; - - //Fetch our field index - int fieldIndex = client.FindSameFieldIndex(aField); - - if (fieldIndex < 0) - { - //No corresponding field, just bail out - return; - } - - //Keep our previous field in there - DataField previousField = client.Fields[fieldIndex]; - //Just update that field then - client.Fields[fieldIndex] = aField; - - if (!aField.IsTableField) - { - //We are done then if that field is not in our table layout - return; - } - - TableField tableField = (TableField) aField; - - if (previousField.IsSameLayout(aField)) - { - //If we are updating a field in our current client we need to update it in our panel - if (aSessionId == iCurrentClientSessionId) - { - Control ctrl = iTableLayoutPanel.GetControlFromPosition(tableField.Column, tableField.Row); - if (aField.IsTextField && ctrl is MarqueeLabel) - { - TextField textField = (TextField) aField; - //Text field control already in place, just change the text - MarqueeLabel label = (MarqueeLabel) ctrl; - contentChanged = (label.Text != textField.Text || label.TextAlign != textField.Alignment); - label.Text = textField.Text; - label.TextAlign = textField.Alignment; - } - else if (aField.IsBitmapField && ctrl is PictureBox) - { - BitmapField bitmapField = (BitmapField) aField; - contentChanged = true; //TODO: Bitmap comp or should we leave that to clients? - //Bitmap field control already in place just change the bitmap - PictureBox pictureBox = (PictureBox) ctrl; - pictureBox.Image = bitmapField.Bitmap; - } - else - { - layoutChanged = true; - } - } - } - else - { - layoutChanged = true; - } - - //If either content or layout changed we need to update our tree view to reflect the changes - if (contentChanged || layoutChanged) - { - UpdateClientTreeViewNode(client); - // - if (layoutChanged) - { - Debug.Print("Layout changed"); - //Our layout has changed, if we are already the current client we need to update our panel - if (aSessionId == iCurrentClientSessionId) - { - //Apply layout and set data fields. - UpdateTableLayoutPanel(iCurrentClientData); - } - } - else - { - Debug.Print("Layout has not changed."); - } - } - else - { - Debug.Print("WARNING: content and layout have not changed!"); - } - - //When a client field is set we try switching to this client to present the new information to our user - SetCurrentClient(aSessionId); - } - - /// - /// - /// - /// - public void SetClientFieldsThreadSafe(string aSessionId, System.Collections.Generic.IList aFields) - { - if (this.InvokeRequired) - { - //Not in the proper thread, invoke ourselves - SetFieldsDelegate d = new SetFieldsDelegate(SetClientFieldsThreadSafe); - this.Invoke(d, new object[] {aSessionId, aFields}); - } - else - { - ClientData client = iClients[aSessionId]; - - if (client.HasNewLayout) - { - //TODO: Assert client.Count == 0 - //Our layout was just changed - //Do some special handling to avoid re-creating our panel N times, once for each fields - client.HasNewLayout = false; - //Just set all our fields then - client.Fields.AddRange(aFields); - //Try switch to that client - SetCurrentClient(aSessionId); - - //If we are updating the current client update our panel - if (aSessionId == iCurrentClientSessionId) - { - //Apply layout and set data fields. - UpdateTableLayoutPanel(iCurrentClientData); - } - - UpdateClientTreeViewNode(client); - } - else - { - //Put each our text fields in a label control - foreach (DataField field in aFields) - { - SetClientField(aSessionId, field); - } - } - } - } - - /// - /// - /// - /// - /// - public void SetClientNameThreadSafe(string aSessionId, string aName) - { - if (this.InvokeRequired) - { - //Not in the proper thread, invoke ourselves - SetClientNameDelegate d = new SetClientNameDelegate(SetClientNameThreadSafe); - this.Invoke(d, new object[] {aSessionId, aName}); - } - else - { - //We are in the proper thread - //Get our client - ClientData client = iClients[aSessionId]; - if (client != null) - { - //Set its name - client.Name = aName; - //Update our tree-view - UpdateClientTreeViewNode(client); - } - } - } - - /// - public void SetClientPriorityThreadSafe(string aSessionId, uint aPriority) - { - if (this.InvokeRequired) - { - //Not in the proper thread, invoke ourselves - SetClientPriorityDelegate d = new SetClientPriorityDelegate(SetClientPriorityThreadSafe); - this.Invoke(d, new object[] {aSessionId, aPriority}); - } - else - { - //We are in the proper thread - //Get our client - ClientData client = iClients[aSessionId]; - if (client != null) - { - //Set its name - client.Priority = aPriority; - //Update our tree-view - UpdateClientTreeViewNode(client); - //Change our current client as per new priority - ClientData newCurrentClient = FindHighestPriorityClient(); - if (newCurrentClient != null) - { - SetCurrentClient(newCurrentClient.SessionId); - } - } - } - } - - /// - /// - /// - /// - /// - /// - public static string Truncate(string value, int maxChars) - { - return value.Length <= maxChars ? value : value.Substring(0, maxChars - 3) + "..."; - } - - /// - /// Update our recording notification. - /// - private void UpdateRecordingNotification() - { - //Go through each - bool activeRecording = false; - string text = ""; - RecordingField recField = new RecordingField(); - foreach (var client in iClients) - { - RecordingField rec = (RecordingField) client.Value.FindSameFieldAs(recField); - if (rec != null && rec.IsActive) - { - activeRecording = true; - //Don't break cause we are collecting the names/texts. - if (!String.IsNullOrEmpty(rec.Text)) - { - text += (rec.Text + "\n"); - } - else - { - //Not text for that recording, use client name instead - text += client.Value.Name + " recording\n"; - } - - } - } - - //Update our text no matter what, can't have more than 63 characters otherwise it throws an exception. - iRecordingNotification.Text = Truncate(text, 63); - - //Change visibility of notification if needed - if (iRecordingNotification.Visible != activeRecording) - { - iRecordingNotification.Visible = activeRecording; - //Assuming the notification icon is in sync with our display icon - //Take care of our REC icon - if (iDisplay.IsOpen()) - { - iDisplay.SetIconOnOff(MiniDisplay.IconType.Recording, activeRecording); - } - } - } - - /// - /// - /// - /// - private void UpdateClientTreeViewNode(ClientData aClient) - { - Debug.Print("UpdateClientTreeViewNode"); - - if (aClient == null) - { - return; - } - - //Hook in record icon update too - UpdateRecordingNotification(); - - TreeNode node = null; - //Check that our client node already exists - //Get our client root node using its key which is our session ID - TreeNode[] nodes = iTreeViewClients.Nodes.Find(aClient.SessionId, false); - if (nodes.Count() > 0) - { - //We already have a node for that client - node = nodes[0]; - //Clear children as we are going to recreate them below - node.Nodes.Clear(); - } - else - { - //Client node does not exists create a new one - iTreeViewClients.Nodes.Add(aClient.SessionId, aClient.SessionId); - node = iTreeViewClients.Nodes.Find(aClient.SessionId, false)[0]; - } - - if (node != null) - { - //Change its name - if (!String.IsNullOrEmpty(aClient.Name)) - { - //We have a name, use it as text for our root node - node.Text = aClient.Name; - //Add a child with SessionId - node.Nodes.Add(new TreeNode(aClient.SessionId)); - } - else - { - //No name, use session ID instead - node.Text = aClient.SessionId; - } - - //Display client priority - node.Nodes.Add(new TreeNode("Priority: " + aClient.Priority)); - - if (aClient.Fields.Count > 0) - { - //Create root node for our texts - TreeNode textsRoot = new TreeNode("Fields"); - node.Nodes.Add(textsRoot); - //For each text add a new entry - foreach (DataField field in aClient.Fields) - { - if (field.IsTextField) - { - TextField textField = (TextField) field; - textsRoot.Nodes.Add(new TreeNode("[Text]" + textField.Text)); - } - else if (field.IsBitmapField) - { - textsRoot.Nodes.Add(new TreeNode("[Bitmap]")); - } - else if (field.IsRecordingField) - { - RecordingField recordingField = (RecordingField) field; - textsRoot.Nodes.Add(new TreeNode("[Recording]" + recordingField.IsActive)); - } - } - } - - node.ExpandAll(); - } - } - - /// - /// Update our table layout row styles to make sure each rows have similar height - /// - private void UpdateTableLayoutRowStyles() - { - foreach (RowStyle rowStyle in iTableLayoutPanel.RowStyles) - { - rowStyle.SizeType = SizeType.Percent; - rowStyle.Height = 100/iTableLayoutPanel.RowCount; - } - } - - /// - /// Update our display table layout. - /// Will instanciated every field control as defined by our client. - /// Fields must be specified by rows from the left. - /// - /// - private void UpdateTableLayoutPanel(ClientData aClient) - { - Debug.Print("UpdateTableLayoutPanel"); - - if (aClient == null) - { - //Just drop it - return; - } - - - TableLayout layout = aClient.Layout; - - //First clean our current panel - iTableLayoutPanel.Controls.Clear(); - iTableLayoutPanel.RowStyles.Clear(); - iTableLayoutPanel.ColumnStyles.Clear(); - iTableLayoutPanel.RowCount = 0; - iTableLayoutPanel.ColumnCount = 0; - - //Then recreate our rows... - while (iTableLayoutPanel.RowCount < layout.Rows.Count) - { - iTableLayoutPanel.RowCount++; - } - - // ...and columns - while (iTableLayoutPanel.ColumnCount < layout.Columns.Count) - { - iTableLayoutPanel.ColumnCount++; - } - - //For each column - for (int i = 0; i < iTableLayoutPanel.ColumnCount; i++) - { - //Create our column styles - this.iTableLayoutPanel.ColumnStyles.Add(layout.Columns[i]); - - //For each rows - for (int j = 0; j < iTableLayoutPanel.RowCount; j++) - { - if (i == 0) - { - //Create our row styles - this.iTableLayoutPanel.RowStyles.Add(layout.Rows[j]); - } - else - { - continue; - } - } - } - - //For each field - foreach (DataField field in aClient.Fields) - { - if (!field.IsTableField) - { - //That field is not taking part in our table layout skip it - continue; - } - - TableField tableField = (TableField) field; - - //Create a control corresponding to the field specified for that cell - Control control = CreateControlForDataField(tableField); - - //Add newly created control to our table layout at the specified row and column - iTableLayoutPanel.Controls.Add(control, tableField.Column, tableField.Row); - //Make sure we specify column and row span for that new control - iTableLayoutPanel.SetColumnSpan(control, tableField.ColumnSpan); - iTableLayoutPanel.SetRowSpan(control, tableField.RowSpan); - } - - - CheckFontHeight(); - } - - /// - /// Check our type of data field and create corresponding control - /// - /// - private Control CreateControlForDataField(DataField aField) - { - Control control = null; - if (aField.IsTextField) - { - MarqueeLabel label = new SharpDisplayManager.MarqueeLabel(); - label.AutoEllipsis = true; - label.AutoSize = true; - label.BackColor = System.Drawing.Color.Transparent; - label.Dock = System.Windows.Forms.DockStyle.Fill; - label.Location = new System.Drawing.Point(1, 1); - label.Margin = new System.Windows.Forms.Padding(0); - label.Name = "marqueeLabel" + aField; - label.OwnTimer = false; - label.PixelsPerSecond = cds.ScrollingSpeedInPixelsPerSecond; - label.Separator = cds.Separator; - label.MinFontSize = cds.MinFontSize; - label.ScaleToFit = cds.ScaleToFit; - //control.Size = new System.Drawing.Size(254, 30); - //control.TabIndex = 2; - label.Font = cds.Font; - - TextField field = (TextField) aField; - label.TextAlign = field.Alignment; - label.UseCompatibleTextRendering = true; - label.Text = field.Text; - // - control = label; - } - else if (aField.IsBitmapField) - { - //Create picture box - PictureBox picture = new PictureBox(); - picture.AutoSize = true; - picture.BackColor = System.Drawing.Color.Transparent; - picture.Dock = System.Windows.Forms.DockStyle.Fill; - picture.Location = new System.Drawing.Point(1, 1); - picture.Margin = new System.Windows.Forms.Padding(0); - picture.Name = "pictureBox" + aField; - //Set our image - BitmapField field = (BitmapField) aField; - picture.Image = field.Bitmap; - // - control = picture; - } - //TODO: Handle recording field? - - return control; - } - - /// - /// Called when the user selected a new display type. - /// - /// - /// - private void comboBoxDisplayType_SelectedIndexChanged(object sender, EventArgs e) - { - //Store the selected display type in our settings - Properties.Settings.Default.CurrentDisplayIndex = comboBoxDisplayType.SelectedIndex; - cds.DisplayType = comboBoxDisplayType.SelectedIndex; - Properties.Settings.Default.Save(); - - //Try re-opening the display connection if we were already connected. - //Otherwise just update our status to reflect display type change. - if (iDisplay.IsOpen()) - { - OpenDisplayConnection(); - } - else - { - UpdateStatus(); - } - } - - private void maskedTextBoxTimerInterval_TextChanged(object sender, EventArgs e) - { - if (maskedTextBoxTimerInterval.Text != "") - { - int interval = Convert.ToInt32(maskedTextBoxTimerInterval.Text); - - if (interval > 0) - { - timer.Interval = interval; - cds.TimerInterval = timer.Interval; - Properties.Settings.Default.Save(); - } - } - } - - private void maskedTextBoxMinFontSize_TextChanged(object sender, EventArgs e) - { - if (maskedTextBoxMinFontSize.Text != "") - { - int minFontSize = Convert.ToInt32(maskedTextBoxMinFontSize.Text); - - if (minFontSize > 0) - { - cds.MinFontSize = minFontSize; - Properties.Settings.Default.Save(); - //We need to recreate our layout for that change to take effect - UpdateTableLayoutPanel(iCurrentClientData); - } - } - } - - - private void maskedTextBoxScrollingSpeed_TextChanged(object sender, EventArgs e) - { - if (maskedTextBoxScrollingSpeed.Text != "") - { - int scrollingSpeed = Convert.ToInt32(maskedTextBoxScrollingSpeed.Text); - - if (scrollingSpeed > 0) - { - cds.ScrollingSpeedInPixelsPerSecond = scrollingSpeed; - Properties.Settings.Default.Save(); - //We need to recreate our layout for that change to take effect - UpdateTableLayoutPanel(iCurrentClientData); - } - } - } - - private void textBoxScrollLoopSeparator_TextChanged(object sender, EventArgs e) - { - cds.Separator = textBoxScrollLoopSeparator.Text; - Properties.Settings.Default.Save(); - - //Update our text fields - foreach (MarqueeLabel ctrl in iTableLayoutPanel.Controls) - { - ctrl.Separator = cds.Separator; - } - - } - - private void buttonPowerOn_Click(object sender, EventArgs e) - { - iDisplay.PowerOn(); - } - - private void buttonPowerOff_Click(object sender, EventArgs e) - { - iDisplay.PowerOff(); - } - - private void buttonShowClock_Click(object sender, EventArgs e) - { - ShowClock(); - } - - private void buttonHideClock_Click(object sender, EventArgs e) - { - HideClock(); - } - - private void buttonUpdate_Click(object sender, EventArgs e) - { - InstallUpdateSyncWithInfo(); - } - - /// - /// - /// - void ShowClock() - { - if (!iDisplay.IsOpen()) - { - return; - } - - //Devices like MDM166AA don't support windowing and frame rendering must be stopped while showing our clock - iSkipFrameRendering = true; - //Clear our screen - iDisplay.Clear(); - iDisplay.SwapBuffers(); - //Then show our clock - iDisplay.ShowClock(); - } - - /// - /// - /// - void HideClock() - { - if (!iDisplay.IsOpen()) - { - return; - } - - //Devices like MDM166AA don't support windowing and frame rendering must be stopped while showing our clock - iSkipFrameRendering = false; - iDisplay.HideClock(); - } - - private void InstallUpdateSyncWithInfo() - { - UpdateCheckInfo info = null; - - if (ApplicationDeployment.IsNetworkDeployed) - { - ApplicationDeployment ad = ApplicationDeployment.CurrentDeployment; - - try - { - info = ad.CheckForDetailedUpdate(); - - } - catch (DeploymentDownloadException dde) - { - MessageBox.Show( - "The new version of the application cannot be downloaded at this time. \n\nPlease check your network connection, or try again later. Error: " + - dde.Message); - return; - } - catch (InvalidDeploymentException ide) - { - MessageBox.Show( - "Cannot check for a new version of the application. The ClickOnce deployment is corrupt. Please redeploy the application and try again. Error: " + - ide.Message); - return; - } - catch (InvalidOperationException ioe) - { - MessageBox.Show( - "This application cannot be updated. It is likely not a ClickOnce application. Error: " + - ioe.Message); - return; - } - - if (info.UpdateAvailable) - { - Boolean doUpdate = true; - - if (!info.IsUpdateRequired) - { - DialogResult dr = - MessageBox.Show("An update is available. Would you like to update the application now?", - "Update Available", MessageBoxButtons.OKCancel); - if (!(DialogResult.OK == dr)) - { - doUpdate = false; - } - } - else - { - // Display a message that the application MUST reboot. Display the minimum required version. - MessageBox.Show("This application has detected a mandatory update from your current " + - "version to version " + info.MinimumRequiredVersion.ToString() + - ". The application will now install the update and restart.", - "Update Available", MessageBoxButtons.OK, - MessageBoxIcon.Information); - } - - if (doUpdate) - { - try - { - ad.Update(); - MessageBox.Show("The application has been upgraded, and will now restart."); - Application.Restart(); - } - catch (DeploymentDownloadException dde) - { - MessageBox.Show( - "Cannot install the latest version of the application. \n\nPlease check your network connection, or try again later. Error: " + - dde); - return; - } - } - } - else - { - MessageBox.Show("You are already running the latest version.", "Application up-to-date"); - } - } - } - - - /// - /// Used to - /// - private void SysTrayHideShow() - { - Visible = !Visible; - if (Visible) - { - Activate(); - WindowState = FormWindowState.Normal; - } - } - - /// - /// Use to handle minimize events. - /// - /// - /// - private void MainForm_SizeChanged(object sender, EventArgs e) - { - if (WindowState == FormWindowState.Minimized && Properties.Settings.Default.MinimizeToTray) - { - if (Visible) - { - SysTrayHideShow(); - } - } - } - - /// - /// - /// - /// - /// - private void tableLayoutPanel_SizeChanged(object sender, EventArgs e) - { - //Our table layout size has changed which means our display size has changed. - //We need to re-create our bitmap. - iCreateBitmap = true; - } - - /// - /// - /// - /// - /// - private void buttonSelectFile_Click(object sender, EventArgs e) - { - //openFileDialog1.InitialDirectory = "c:\\"; - //openFileDialog.Filter = "EXE files (*.exe)|*.exe|All files (*.*)|*.*"; - //openFileDialog.FilterIndex = 1; - openFileDialog.RestoreDirectory = true; - - if (DlgBox.ShowDialog(openFileDialog) == DialogResult.OK) - { - labelStartFileName.Text = openFileDialog.FileName; - Properties.Settings.Default.StartFileName = openFileDialog.FileName; - Properties.Settings.Default.Save(); - } - } - - /// - /// - /// - /// - /// - private void comboBoxOpticalDrives_SelectedIndexChanged(object sender, EventArgs e) - { - //Save the optical drive the user selected for ejection - Properties.Settings.Default.OpticalDriveToEject = comboBoxOpticalDrives.SelectedItem.ToString(); - Properties.Settings.Default.Save(); - } - - - /// - /// - /// - private void LogsUpdate() - { - if (iWriter != null) - { - iWriter.Flush(); - } - - } - - /// - /// Broadcast messages to subscribers. - /// - /// - protected override void WndProc(ref Message aMessage) - { - LogsUpdate(); - - if (OnWndProc != null) - { - OnWndProc(ref aMessage); - } - - base.WndProc(ref aMessage); - } - - private void checkBoxCecEnabled_CheckedChanged(object sender, EventArgs e) - { - //Save CEC enabled status - Properties.Settings.Default.CecEnabled = checkBoxCecEnabled.Checked; - Properties.Settings.Default.Save(); - // - ResetCec(); - } - - private void comboBoxHdmiPort_SelectedIndexChanged(object sender, EventArgs e) - { - //Save CEC HDMI port - Properties.Settings.Default.CecHdmiPort = Convert.ToByte(comboBoxHdmiPort.SelectedIndex); - Properties.Settings.Default.CecHdmiPort++; - Properties.Settings.Default.Save(); - // - ResetCec(); - } - - /// - /// - /// - private void ResetCec() - { - if (iCecManager == null) - { - //Thus skipping initial UI setup - return; - } - - iCecManager.Stop(); - // - if (Properties.Settings.Default.CecEnabled) - { - iCecManager.Start(Handle, "CEC", - Properties.Settings.Default.CecHdmiPort); - - SetupCecLogLevel(); - } - } - - /// - /// - /// - private void SetupCecLogLevel() - { - //Setup log level - iCecManager.Client.LogLevel = 0; - - if (checkBoxCecLogError.Checked) - iCecManager.Client.LogLevel |= (int) CecLogLevel.Error; - - if (checkBoxCecLogWarning.Checked) - iCecManager.Client.LogLevel |= (int) CecLogLevel.Warning; - - if (checkBoxCecLogNotice.Checked) - iCecManager.Client.LogLevel |= (int) CecLogLevel.Notice; - - if (checkBoxCecLogTraffic.Checked) - iCecManager.Client.LogLevel |= (int) CecLogLevel.Traffic; - - if (checkBoxCecLogDebug.Checked) - iCecManager.Client.LogLevel |= (int) CecLogLevel.Debug; - - iCecManager.Client.FilterOutPollLogs = checkBoxCecLogNoPoll.Checked; - - } - - private void ButtonStartIdleClient_Click(object sender, EventArgs e) - { - StartIdleClient(); - } - - private void buttonClearLogs_Click(object sender, EventArgs e) - { - richTextBoxLogs.Clear(); - } - - private void checkBoxCecLogs_CheckedChanged(object sender, EventArgs e) - { - SetupCecLogLevel(); - } - - - /// - /// - /// - /// - private void SelectEvent(Event aEvent) - { - if (aEvent == null) - { - return; - } - - string key = aEvent.GetType().Name; - TreeNode[] res = iTreeViewEvents.Nodes.Find(key, false); - if (res.Length > 0) - { - iTreeViewEvents.SelectedNode = res[0]; - iTreeViewEvents.Focus(); - } - } - - - - /// - /// Get the current event based on event tree view selection. - /// - /// - private Event CurrentEvent() - { - //Walk up the tree from the selected node to find our event - TreeNode node = iTreeViewEvents.SelectedNode; - Event selectedEvent = null; - while (node != null) - { - if (node.Tag is Event) - { - selectedEvent = (Event) node.Tag; - break; - } - node = node.Parent; - } - - return selectedEvent; - } - - /// - /// Get the current action based on event tree view selection - /// - /// - private SharpLib.Ear.Action CurrentAction() - { - TreeNode node = iTreeViewEvents.SelectedNode; - if (node != null && node.Tag is SharpLib.Ear.Action) - { - return (SharpLib.Ear.Action) node.Tag; - } - - return null; - } - - /// - /// - /// - /// - /// - private void buttonAddAction_Click(object sender, EventArgs e) - { - Event selectedEvent = CurrentEvent(); - if (selectedEvent == null) - { - //We did not find a corresponding event - return; - } - - FormEditAction ea = new FormEditAction(); - DialogResult res = CodeProject.Dialog.DlgBox.ShowDialog(ea); - if (res == DialogResult.OK) - { - selectedEvent.Actions.Add(ea.Action); - Properties.Settings.Default.Actions = ManagerEventAction.Current; - Properties.Settings.Default.Save(); - PopulateEventsTreeView(); - } - } - - /// - /// - /// - /// - /// - private void buttonDeleteAction_Click(object sender, EventArgs e) - { - - SharpLib.Ear.Action action = CurrentAction(); - if (action == null) - { - //Must select action node - return; - } - - ManagerEventAction.Current.RemoveAction(action); - Properties.Settings.Default.Actions = ManagerEventAction.Current; - Properties.Settings.Default.Save(); - PopulateEventsTreeView(); - } - - private void iTreeViewEvents_AfterSelect(object sender, TreeViewEventArgs e) - { - //Enable buttons according to selected item - buttonAddAction.Enabled = CurrentEvent() != null; - - SharpLib.Ear.Action currentAction = CurrentAction(); - //If an action is selected enable the following buttons - buttonTestAction.Enabled = - buttonDeleteAction.Enabled = - buttonActionMoveUp.Enabled = - buttonActionMoveDown.Enabled = - currentAction != null; - - if (currentAction != null) - { - //If an action is selected enable move buttons if needed - buttonActionMoveUp.Enabled = iTreeViewEvents.SelectedNode.Index != 0; - buttonActionMoveDown.Enabled = iTreeViewEvents.SelectedNode.Index < - iTreeViewEvents.SelectedNode.Parent.Nodes.Count - 1; - } - - } - - /// - /// - /// - /// - /// - private void buttonTestAction_Click(object sender, EventArgs e) - { - SharpLib.Ear.Action a = CurrentAction(); - if (a != null) - { - Console.WriteLine("Action test run"); - a.Execute(); - } - iTreeViewEvents.Focus(); - } - - /// - /// - /// - /// - /// - private void buttonActionMoveUp_Click(object sender, EventArgs e) - { - SharpLib.Ear.Action a = CurrentAction(); - if (a == null || - //Action already at the top of the list - iTreeViewEvents.SelectedNode.Index == 0) - { - return; - } - - //Swap actions in event's action list - Event currentEvent = CurrentEvent(); - int currentIndex = iTreeViewEvents.SelectedNode.Index; - SharpLib.Ear.Action movingUp = currentEvent.Actions[currentIndex]; - SharpLib.Ear.Action movingDown = currentEvent.Actions[currentIndex-1]; - currentEvent.Actions[currentIndex] = movingDown; - currentEvent.Actions[currentIndex-1] = movingUp; - - //Save and populate our tree again - Properties.Settings.Default.Actions = ManagerEventAction.Current; - Properties.Settings.Default.Save(); - PopulateEventsTreeView(); - - } - - /// - /// - /// - /// - /// - private void buttonActionMoveDown_Click(object sender, EventArgs e) - { - SharpLib.Ear.Action a = CurrentAction(); - if (a == null || - //Action already at the bottom of the list - iTreeViewEvents.SelectedNode.Index == iTreeViewEvents.SelectedNode.Parent.Nodes.Count - 1) - { - return; - } - - //Swap actions in event's action list - Event currentEvent = CurrentEvent(); - int currentIndex = iTreeViewEvents.SelectedNode.Index; - SharpLib.Ear.Action movingDown = currentEvent.Actions[currentIndex]; - SharpLib.Ear.Action movingUp = currentEvent.Actions[currentIndex + 1]; - currentEvent.Actions[currentIndex] = movingUp; - currentEvent.Actions[currentIndex + 1] = movingDown; - - //Save and populate our tree again - Properties.Settings.Default.Actions = ManagerEventAction.Current; - Properties.Settings.Default.Save(); - PopulateEventsTreeView(); - } - } -} diff -r 6ccaa430aa23 -r 91763ba41c0c Server/MainForm.resx --- a/Server/MainForm.resx Thu Jul 28 19:32:40 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,418 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 17, 17 - - - 126, 17 - - - 206, 17 - - - 315, 17 - - - - - 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 - - - - 405, 17 - - - - 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 - CYub2lgAAAAASUVORK5CYII= - - - \ No newline at end of file diff -r 6ccaa430aa23 -r 91763ba41c0c Server/Program.cs --- a/Server/Program.cs Thu Jul 28 19:32:40 2016 +0200 +++ b/Server/Program.cs Fri Jul 29 10:40:15 2016 +0200 @@ -32,7 +32,7 @@ { //WARNING: This is assuming we have a single instance of our program. //That is what we want but we should enforce it somehow. - public static MainForm iMainForm; + public static FormMain iFormMain; /// /// The main entry point for the application. /// @@ -70,8 +70,8 @@ // Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); - iMainForm = new MainForm(); - Application.Run(iMainForm); + iFormMain = new FormMain(); + Application.Run(iFormMain); } diff -r 6ccaa430aa23 -r 91763ba41c0c Server/Session.cs --- a/Server/Session.cs Thu Jul 28 19:32:40 2016 +0200 +++ b/Server/Session.cs Fri Jul 29 10:40:15 2016 +0200 @@ -49,27 +49,27 @@ SessionId = OperationContext.Current.SessionId; ICallback callback = OperationContext.Current.GetCallbackChannel(); // - SharpDisplayManager.Program.iMainForm.AddClientThreadSafe(SessionId,callback); + SharpDisplayManager.Program.iFormMain.AddClientThreadSafe(SessionId,callback); } public void Dispose() { Trace.TraceInformation("Server session closing."); - SharpDisplayManager.Program.iMainForm.RemoveClientThreadSafe(SessionId); + SharpDisplayManager.Program.iFormMain.RemoveClientThreadSafe(SessionId); } // public void SetName(string aClientName) { Name = aClientName; - SharpDisplayManager.Program.iMainForm.SetClientNameThreadSafe(SessionId, Name); + SharpDisplayManager.Program.iFormMain.SetClientNameThreadSafe(SessionId, Name); //Disconnect(aClientName); //Register our client and its callback interface //IDisplayServiceCallback callback = OperationContext.Current.GetCallbackChannel(); - //Program.iMainForm.iClients.Add(aClientName, callback); - //Program.iMainForm.treeViewClients.Nodes.Add(aClientName, aClientName); + //Program.iFormMain.iClients.Add(aClientName, callback); + //Program.iFormMain.treeViewClients.Nodes.Add(aClientName, aClientName); //For some reason MP still hangs on that one //callback.OnConnected(); } @@ -81,30 +81,30 @@ public void SetPriority(uint aPriority) { Priority = aPriority; - SharpDisplayManager.Program.iMainForm.SetClientPriorityThreadSafe(SessionId, Priority); + SharpDisplayManager.Program.iFormMain.SetClientPriorityThreadSafe(SessionId, Priority); } public void SetLayout(TableLayout aLayout) { - SharpDisplayManager.Program.iMainForm.SetClientLayoutThreadSafe(SessionId, aLayout); + SharpDisplayManager.Program.iFormMain.SetClientLayoutThreadSafe(SessionId, aLayout); } // public void SetField(DataField aField) { - SharpDisplayManager.Program.iMainForm.SetClientFieldThreadSafe(SessionId, aField); + SharpDisplayManager.Program.iFormMain.SetClientFieldThreadSafe(SessionId, aField); } //From IDisplayService public void SetFields(System.Collections.Generic.IList aFields) { - SharpDisplayManager.Program.iMainForm.SetClientFieldsThreadSafe(SessionId, aFields); + SharpDisplayManager.Program.iFormMain.SetClientFieldsThreadSafe(SessionId, aFields); } /// public int ClientCount() { - return SharpDisplayManager.Program.iMainForm.iClients.Count; + return SharpDisplayManager.Program.iFormMain.iClients.Count; } diff -r 6ccaa430aa23 -r 91763ba41c0c Server/SharpDisplayManager.csproj --- a/Server/SharpDisplayManager.csproj Thu Jul 28 19:32:40 2016 +0200 +++ b/Server/SharpDisplayManager.csproj Fri Jul 29 10:40:15 2016 +0200 @@ -175,6 +175,13 @@ FormEditAction.cs + + Form + + + FormMain.cs + + UserControl @@ -182,19 +189,10 @@ FxControl.cs - - MainForm.cs - - - Form - - - MainForm.cs - @@ -215,12 +213,12 @@ FormEditAction.cs + + FormMain.cs + FxControl.cs - - MainForm.cs - ProgressForm.cs