XenevaOS

User Application Development for XenevaOS

Applications in XenevaOS are Xeneva Apps or XEApps in short. XenevaOS ecosystem is incomplete without user applications. As Xeneva applications are the core of the operating system, enabling users to perform essential tasks. While the OS provides the foundational services- such as memory management, process scheduling, and hardware abstraction- user applications define the actual functionality and usability of the system. Without Xeneva applications, XenevaOS remains just a technical framework, lacking practical purpose.

About this Guide

This documentation provides a step-by-step overview and approach to building application for XenevaOS. Whether you are developing graphical user applications, system utilities, or multimedia software, this guide will walk you through:

XenevaOS APIs and Libraries

Xeneva Applications are divided into three category: (i) System Service, (ii) GUI Application, (iii)Terminal Application & Utilities.

Application environment uses two most fundamental library called the XEClib and the XECrt. XEClib is the C library used for applications and XECrt is used as the C runtime library. XECrt is responsible for setting up the basic stack and defining necessary C/C++ runtime functions before jumping to application entry point. XEClib contains all standard C functions that are used by other libraries and the applications.

Chitralekha Graphics and Widget library:

Most important and used library for GUI application development is Chitralekha Graphics and Widget library. This library defines fundamental Graphics drawing functions and Windowing system functions. The name ‘Chitralekha’ is derived from Assam’s own mythological story, we’ll discuss that in later sections.

How Chitralekha Works?

Whenever a GUI application is started, Chitralekha is responsible for communicating to Window manager and bringing up a new window for the application. Communication is done through Xeneva’s own IPC mechanism called PostBox IPC. Chitralekha library is dynamically linked to GUI applications and is a dynamic library. Here’s a step by step breakdown of how a GUI application starts within Xeneva,

typedef struct _sh_win_ {
    ChRect rect[256];   /* used to tell the server about the 
    dirty rects */
    uint32_t rectCount;     /*used to tell the server how many total dirty rect are there */
    bool dirty;   /*mark if the window is dirty and needs to be updated */
    bool updateEntireWindow; /* mark if the entire windows needs to be updated */
    
    int x;
    int y;
    int width;
    int height;
    bool alpha;
    bool hide;
    double alphaValue;
    bool windowReady;
}SharedWinInfo;

This four fundamental component makes Xeneva GUI application working.

Simple GUI Code Snippet

#include <stdint.h>
#include <chitralekha.h>
#include <sys\_kefile.h>
#include <sys\iocodes.h>
#include <widgets\base.h>
#include <widgets\button.h>
#include <widgets\window.h>

ChitralekhaApp* app;
ChWindow* mainWin;

/*
 * WindowHandleMessage -- application event message
 * handler
 * @param e -- Pointer to PostEvent message
 */
void WindowHandleMessage(PostEvent *e){
    switch(e->type){

        // handle mouse event
        case DEODHAI_REPLY_MOUSE_EVENT:{
            ChWindowHandleMouse(mainWin, e->dword, e->dword2, e->dword3);
            memset(e, 0, sizeof(PostEvent));
            break;
        }

        // handle key event
        case DEODHAI_REPLY_KEY_EVENT:{
            int code = e->dword;
            ChitralekhaProcessKey(code);
            char c = ChitralekhaKeyToASCII(code);
            //handle the key event
            memset(e, 0, sizeof(PostEvent));
            break;
        }
    }
}

/*
 * Application's entry point
 */
int main(int argc, char* argv[]){
   app = ChitralekhaStartApp(argc, argv);
   mainWin = ChCreateWindow(app, WINDOW_FLAG_MOVABLE, "App Title", 100,100,500,400);

   //Create a button in 10-x position and 60-y position
   //with the size of 50 as width, 35 as height

   ChButton *button = ChCreateButton(10,60,50,35,"Hello World!");

   //now add the button widget to the mainWin that
   //we've created earlier

   ChWindowAddWidget(mainWin, (ChWidget*)button);

   //Now render the entire window on the application side
   //and tell the window manager to compose it on the 
   //display

   ChWindowPaint(mainWin);

   PostEvent e;
   memset(&e, 0, sizeof(PostEvent));

   //setjmp is used, incase if a subwindow get closed
   //the application jumps directly to the event loop's
   //instruction

   setjmp(mainWin->jump);
   while(1){
      int err = _KeFileIoControl(app->postboxfd,   POSTBOX_GET_EVENT, &e);
      WindowHandleMessage(&e);
      if (err == POSTBOX_NO_EVENT)
         _KePauseThread();
   }
}

Application Event Loop

When an application is newly created, it gets a handle_id from the Window Manager. The handle_id is specific to each window, i.e if an application has two window created, it will include two unique handle_id for each window. Applications continuously waits for new events in its life time either from the Window Manager or from any external sources from the Operating System or from the application itself. These events can include user interactions such as keyboard input, mouse movements, touch gestures, hand gestures movements or system notifications. In XenevaOS, events are being send or receive through PostBox IPC kernel module, which is a message queue based IPC designed for Xeneva GUI system. Each GUI events received includes the handle_id attached to it, which further the application can use it to locate the desired window within the application. The event loop typically retrieves events and dispatches them to the appropriate window and then put the application to pause state until a next event arrives. Each application creates there own PostBox within the PostBox IPC module.

When a new application is created, ChitralekhaStartApp(argc, argv) automatically creates a new PostBox for this application and stores the file descriptor to the PostBox within ChitralekhaApp data structure. PostBox IPC can be controlled via KeFileIoControl(app->postboxfd, code, &ptr_to_ev_datastruct). Here are some predefined code within PostBox IPC module.

Code Name Value in Integer Description
POSTBOX_CREATE 401 Create a new postbox, automatically get created by ChitralekhaStartApp(argc, argv)
POSTBOX_DESTROY 402 Destroys a postbox within the PostBox IPC module, application can no longer use the postbox, after commanding this.
POST_PUT_EVENT 403 Put an event message in its application’s own postbox
POSTBOX_GET_EVENT 404 Checks for event within its own postbox
POSTBOX_CREATE_ROOT 405 Only usable by the Window Manager, application cannot use this command
POSTBOX_GET_EVENT_ROOT 406 Only usable by Window Manager, application cannot use this command

Event structure format

PostEvent defines the core event message structure used by the PostBox IPC to describe the event occured for particular application. It encapsulates essential routing information, including the event type type, destination thread id to_id and source thread id from_id, followed by a payload region. The payload consists of multiple 32-bit data fields (dword through dword8) for parameter passing, along with pointer-based fields (pValue, pValue1) and character buffers for transferring structured or tectual data. This structure allows a single event format to represent a wide range of GUI, system, and application-level events while maintaining a compact and good memory layout.

Layout of PostEvent structure:

typedef struct _post_event_ {
    uint8_t type;
    uint16_t to_id;
    uint16_t from_id;
    uint32_t dword;
    uint32_t dword2;
    uint32_t dword3;
    uint32_t dword4;
    uint32_t dword5;
    uint32_t dword6;
    uint32_t dword7;
    uint32_t dword8;
    uint32_t* pValue;
    uint32_t* pValue1;
    char* charValue;
    unsigned char* charValue2;
    char charValue3[100];
}PostEvent;
Field name Description
type Type of this event, for example DEODHAI_REPLY_MOUSE_EVENT which expands to integer value of 151
to_id Destination thread’s id number
from_id Source thread’s id number
dword-dword8 General purpose 32 bit parametar passing fields
pValue-pValue1 Used for passing pointer values
charValue Used for passing string values
charValue2 Used for passing string and single byte aligned pointer value
charValue3 Used for passing textual data

Using _KeFileIoControl(postboxfd, POSTBOX_GET_EVENT, &event) application can receive event message direct to the pointer to event message.