This plugin can be used to integrate the Dise Player on Windows-based POS terminals such as cash registries, self-service kiosks, fuel pumps, charging stations, etc.
The plugin allows the Dise Player to co-exist and share the screen(s) with the POS application. The POS application is in control and can make the Dise Player switch between different layouts, depending on the mode of the terminal.
Example use case
A typical scenario would be at the check-out counter, for example, at a super market, where the terminal has one operator-facing display and one customer-facing display. The operator-facing display should always show the POS software user interface. The customer-facing display can switch between two modes:
Idle mode (full-screen advertising): when no customer is being served, the entire customer-facing screen can be used to show advertising
Customer being served (split-screen): transactions are shown in one part of the screen, advertising in the other
.png?sv=2022-11-02&spr=https&st=2025-12-06T03%3A37%3A31Z&se=2025-12-06T03%3A57%3A31Z&sr=c&sp=r&sig=4GjDSqJryJGZ2lRuT8MlNecqtdK1OiOmTlUnxrpvIPI%3D)
Customer-facing POS display in split-screen mode
The POS application controls the mode of the Dise Player by writing the desired mode to a text file on the local drive of the terminal, the name and path of this file is configurable, as well as the modes themselves.
Display configuration
In the example above, let’s say that the operator display is #1 (leftmost) and customer display is #2 (rightmost) in the Windows extended desktop setup, and that both displays are 1920×1080 pixels. Furthermore, let’s say that in the split-screen mode, we would like to show advertising in 608×1080 pixels (which corresponds to 9:16 portrait format) in the left part of the customer facing display.
In addition, a fall-back mode might be needed where the Dise Player is invisible. This mode will be used if there is a problem with the multi-display setup, for example, if the customer-facing display is not functioning.
In this example, the Dise Player window would be positioned and sized as follows:
Mode | Size | Position |
|---|---|---|
0 (invisible) | 1×1 | 1920, 0 |
1 (full-screen) | 1920×1080 | 1920, 0 |
2 (split-screen) | 608×1080 | 1920, 0 |
The player window position at X=1920, Y=0 corresponds to the upper left corner of display #2.
The following sample configuration file sets the modes up as described on the example above:
{
"screens": {
"fallbackMode": "0",
"expectedScreens": [
{
"width": 1920,
"height": 1080
},
{
"width": 1920,
"height": 1080
}
]
},
"modes": {
"0": {
"window": {
"left": 1920,
"top": 0,
"width": 1,
"height": 1
}
},
"1": {
"default": true,
"window": {
"left": 1920,
"top": 0,
"width": 1920,
"height": 1080
},
"attributes": [
{
"name": "trigger.Layout01",
"active": true
},
{
"name": "trigger.Layout02",
"active": false
}
]
},
"2": {
"window": {
"left": 1920,
"top": 0,
"width": 608,
"height": 1080
},
"attributes": [
{
"name": "trigger.Layout01",
"active": false
},
{
"name": "trigger.Layout02",
"active": true
}
]
}
}
}The expectedScreens definition in the top of the configuration file defines the expected screen setup. The player will check this during startup and continuously, should the actual screen setup not match the expected, the player will invoke the defined fallbackMode to hide the player window. This is to prevent the player window from obstructing the POS application window, in the case of a display misconfiguration or malfunction.
In this example, the modes are named 0, 1, and 2, meaning that the POS application would need to write “0”, “1”, “2” to the text file to activate the different modes. (Mode 0 will be activated automatically in case of a screen problem). Any number of modes can be defined and given any names, as long as it matches the POS application.
The attributes definition is described further below.
Responsive content
For maximum impact, you would want the content to adapt in real time to the different modes. In the example above, that would mean landscape 16:9 format in mode 1 and portrait 9:16 format in mode 2. Other common screen sizes used at POS include 4:3 (1024×768), 5:4 (1280×1024), 16:10 (1280×800) - or any custom split-screen layouts.
In Dise, layouts have a fixed resolution and aspect ratio / orientation. In order to do responsive content, a dynamic layout is needed:
Dynamic layouts (*)
Set the layout and layer size to 1×1 pixels in Dise, and you will get a dynamic layout!
(*) Dise One 4.0 or later required
Given that the layout is dynamic and automatically scales to fit the current window size, there are several ways to make the content responsive.
HTML5 templates can be designed to react and adapt to changes of the window size. But most likely, you would want to show media (video or images), then you would need different different media for each of the modes.
An easy way to handle this is by using triggers and scenarios in Dise. In the example above, we create two triggers in Dise called Layout01 and Layout02, corresponding to mode 1 and 2, respectively. The attributes definition in each mode in the configuration file above defines the name of the triggers and the activation states for each mode (in mode 1, Layout01 is active and Layout02 is not; in mode 2 it’s vice versa)
You would then set up scenario 1 triggered by Layout01 with landscape content, and scenario 2 triggered by Layout02 with portrait content.
Installing and using the app
The ScreenController plugin is an addon for the Windows version of the Dise player, and needs to be installed on the actual POS terminals.
Unlike other apps in the App Library, it cannot be uploaded to the CMS as a template
Download and install the Dise player for Windows on the device.
The Dise player has a config file which defines settings for the player itself and for any plugins, this file is located in:
C:\Program Files (x86)\Dise\Player\PlayerLauncher.exe.config
We recommend that you make a backup of the existing config file before proceeding with the next steps.Download the plugin here:
Unzip the zip file to a temporary folder, it contains three files:
Plugin.ScreenController.dll
The plugin itself
ScreenConfig.json
Sample screen configuration file (described above)
PlayerLauncher.exe.config
Sample config file for the player which activates the plugin
Edit the ScreenConfig.json file to match your display setup, as described above.
Edit the the PlayerLauncher.exe.config file and set the file path of the text file used to control the display mode:
<setting name="StatusFilePath" serializeAs="String"> <value>C:\temp\mode.txt</value> </setting>Copy all three files to C:\Program Files (x86)\Dise\Player
Testing tip!
You can test switching between the different modes manually, without a POS application running, by editing the mode text file in Notepad. We recommend using the classic Windows Notepad app, as some of the other text editors will not trigger the mode change.
Reference
While the information above covers mostly everything needed to get started, the ScreenControl Plugin provides more detailed configuration options. These options cover edge cases such as having a mix of different screen sizes and setups, combining the ScreenControl Plugin with other plugins, and so on.
The JSON configuration file
This file defines the Plugin behavior. It is divided into two optional sections, "screens" and "modes".
Screens
There are three optional properties:
fallbackMode: The key of the mode to switch to if the expected screen-set does not match the comupter-setup.
sortFromLeft: true/false. Screens are normally indexed in the order received from Windows, usually with the Primary monitor first. When this is set to true, the screens are sorted from leftmost to right and secondarily top to bottom. Note that this alters the ordering of both the "expectedScreens" and the screen-index of a mode.
expectedScreens: An array of objects containing optional width and height numbers. Note that this is the minimum matching set. Requiring one screen still matches if there are multiple additional ones also connected.
Modes
An object with key-names for each mode and a mode-definition, with four optional properties:
default
Uses this mode when the mode-textfile is missing.
screen
The numeric index of a screen counted from zero. When the "window" property is not supplied for a screen, it is interpreted as full-screen.
window
Left/top/width/height properties for a window relative to the screen if supplied. Otherwise, "sortFromLeft" is used to find the base "leftTop" position - either the leftmost screen or the one set as Primary in Windows.
attributes
An array of attribute-objects. Each one has a name (required), an active boolean (required) and a data string (optional).
Example
At least two screens are required to be connected.
The leftmost one can have any resolution, the next one must be in FullHD resolution.
If the setup does not match this, the Player-Window is hidden in a 1x1 pixel in the upper-left corner of the leftmost screen.
There are 3 modes:
- Full-screen on screen 1 (index 0, leftmost)
- Full-screen on screen 2 (next in sorting order, can be to the right of screen 1, below it or even above, placed slightly more to the right).
- In a split-screen window on the left part of screen 2.
Each mode sets two attributes, one specifying whether it’s hidden, the other if the layout is split-screen.
{
"screens": {
"fallbackMode": "hidden",
"sortFromLeft": true,
"expectedScreens": [
{},
{
"width": 1920,
"height": 1080
}
]
},
"modes": {
"hidden": {
"window": {
"left": 0,
"top": 0,
"width": 1,
"height": 1
},
"attributes": [
{
"name": "trigger.Visible",
"active": false
},
{
"name": "trigger.SplitScreen",
"active": false
}
]
},
"1": {
"default": true,
"screen": 0,
"attributes": [
{
"name": "trigger.Visible",
"active": true
},
{
"name": "trigger.SplitScreen",
"active": false
}
]
},
"2": {
"screen": 1,
"attributes": [
{
"name": "trigger.Visible",
"active": true
},
{
"name": "trigger.SplitScreen",
"active": false
}
]
},
"3": {
"screen": 1,
"window": {
"left": 0,
"top": 0,
"width": 960,
"height": 1080
},
"attributes": [
{
"name": "trigger.Visible",
"active": false
},
{
"name": "trigger.SplitScreen",
"active": true
}
]
}
}
}
The PlayerLauncher.exe.config file
The plugin dll is dynamically loaded if it exists in the same folder as PlayerLauncher.exe, but requires configuration of in the PlayerLauncher.exe.config XML file. Normally, you can just edit and copy in the sample PlayerLauncher.exe.config file provided in the ZIP file, but in case you need to combine the ScreenController plugin with other plugins or other custom PlayerLauncher settings, here is a full description of how to add the ScreenController configuration parts to an existing PlayerLauncher.exe.config file:
Inside configSections/sectionGroup, add:
<section name="Plugin.ScreenController.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />Inside unity, add a container:
<container name="ScreenController">
<register name="ScreenController" type="IPlugin" mapTo="Plugin.ScreenController.Controller, Plugin.ScreenController, Version=1.0.0.0, Culture=neutral">
<lifetime type="singleton"/>
<property name="WebSocket"/>
<constructor>
<param name="commandInterfaceEndPointPath" value="/cmd"/>
</constructor>
</register>
</container>And finally, inside applicationSettings:
<Plugin.ScreenController.Properties.Settings>
<setting name="StatusFilePath" serializeAs="String">
<value>c:\temp\status.txt</value>
</setting>
<setting name="InitialCallDelaySeconds" serializeAs="String">
<value>2</value>
</setting>
<setting name="SettingsFilePath" serializeAs="String">
<value>ScreenConfig.json</value>
</setting>
</Plugin.ScreenController.Properties.Settings>SettingsFilePath
The path, relative to the Player-folder, of a JSON-file containing definitions of various "modes" with different Window pos/size and Attribute-state-sets. Each mode is referenced by a unique string (key), typically "0", "1", "2" and so on. See specfication of the file-format above.
StatusFilePath
The path to a text-file which is monitored constantly for changes. It is expected to be written to by other applications running on the system and must contain just the unique key of a mode.
InitialCallDelaySeconds
Since the Launcher starts prior to the actual player process, commands cannot be sent immediately. This delay specifies when to start communication. Note that this really is a legacy-feature because a retry mechanism is also used to make sure commands are received by the player process.