634 views
in GUI Development by
Hi,

I developing a Multi-thread OSD system(One screen included two or more OSD working together), I have to make the interaction between them and I hopt through "Post event" to implement it.

For example, system has OSD A and OSD B working together. If OSD A reach a special condition, then send a key event to OSD B for close OSD.

I know can "post event" by native source code but this way is so complex. Is possible "post event" by Embeddid Wizard direct?

Thank you.

1 Answer

0 votes
by
 
Best answer

First of all, when the entire GUI software is running within a single process instance then it is absolutely important to keep and access all GUI components within one and the same thread! This is because the underlying Chora runtime environment, the graphics engine and the Mosaic framework components are not thread safe. Running the GUI in separate threads will cause unpredicable crash situations.

You can however combine the single GUI thread with any additional worker thread. The idea behind a worker thread is to do some background (not GUI related) task. As long as the worker thread don't access any of the GUI functions you can create and manage as many as you want such worker threads. They will simply coexist and don't interfer with the GUI.

Usually when following this approach, you will expect the worker threads to exchange status/data information with the GUI. For this communication you can use either:

  • polling global shared variables
  • IPC (interprocess communication) services of your OS (e.g. message queues)

Example for the approach with global variables: The worker thread is running in the background. Some time later it terminates its job and sets a globally defined variable StatusVar. On the other hand, the GUI application periodically reads the valu of this variable. This can be done within the main loop where the touch/keyboard events are read and dispatched to the GUI aplication and the screen update is performed. As soon as an alternation of such global variable is detected, a function of the GUI application can be called:

volatile int StatusVar = 0;


/* The GUI thread */
void main( void )
{

  [ ... Init application 'root' object ... ]
  

  while ( ... )
  {
    /* Did the worker thread signal a status alternation? */
    if ( StatusVar != 0 )
    {
      /* Here simply send a keyboard event to the application */
      CoreRoot__DriveKeyboardHitting( root, CoreKeyCodeF1, 0, 1 );
      CoreRoot__DriveKeyboardHitting( root, CoreKeyCodeF1, 0, 0 );

      /* Don't forget to reset the signal variable */
      StatusVar = 0;
    }

    [ ... Then Process keyboard/touch screen events ... ]
    [ ... Then Process Timers ... ]
    [ ... Then Process Signals ... ]

    [ ... Then Update Screen ... ]
    [ ... Finally Run Garbage Collection ... ]
  }
}

 

Similarly you can use an OS specific IPC  message queue to interact between the worker and the GUI thread. Like the loop in the above source code, you check periodically the message queue for new contents (messages). If such message is available, you read the message and sends an event to the GUI application. The worker thread has to post a new message to the message queue only.

In the above example the received (detected) event is delivered to the GUI application wrapped within a keyboard event. This is o.k. The approach is simple. More sophisticated, however, is to implement within the GUI application a so-called 'device class' as the (unique) interface to the underlying target. The device class can be well combined with so-called 'system events'.

In principle, when the GUI thread sees a new message in the message queue (or an alternation of a signal variable), it reads it, evaluates it (different message types wth evtl. parameters are thus possible) and calls the corresponding TriggerEvent function of the device class. Within the device class the called TriggerEvent function will propagte the just delivered event as a system event. 

The system events are dispatched automatically to all coresponding system event handler within your application. You don't need to take care about the dispatching mechanisms. The usage of device class and the system events are described in the article:

http://ask.embedded-wizard.de/292/device-class-and-device-driver-how-to-integrate-a-device?show=292#q292

The above description focuses primarily on the application case with a single process instance. This means, the entire GUI and its worker threads are running within a single process space. This is the typical application case. In particular for embedded systems.

Depending on your target system, however, it can be possible to run multiple, separate GUI process instances simultanously. For example on Linux using a window manager. The GUI of every process will appear within its own individeual window. Due to the security concepts of Linux, the processes are isolated.

If this is your desired application case, then you will need to use an OS IPC service (e.g. message queue) to establish a communication channel between the both processes. The remaining part is similarly to the descibed above. One process feeds the message queue with messages, the oter reads the messages, evaluates them and calls the corresponding GUI function (e.g. a TriggerEvent function of the device class).

Hope it helps you further.

Embedded Wizard Website | Privacy Policy | Imprint

...