User Application Development for XenevaOS
February 21, 2026 ยท View on GitHub
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:
- Understanging XenevaOS APIs and Libraries
- Setting up the Development Environment
- Creating GUI and CLI Applications
- Interfacing with System Components (Graphics, Audio, Networking, Filesystem, etc)
XenevaOS APIs and Libraries
Xeneva Applications are divided into three category: (i) System Service, (ii) GUI Application, (iii)Terminal Application & Utilities.
-
System Services : System services runs in background to handle essential system tasks. User cannot interact with system services as it doesn't have a GUI or TUI interface attached to it, rather it can be controlled through extern GUI control system or Terminal application that uses IPC to communicate with system services. For example -- Net Manager, Deodhai Audio Server..etc.
-
GUI Application: GUI Applications are the application that user can directly interact with. XenevaOS's GUI application uses Chitralekha Graphics and Widget Library as its base. For example, The Namdapha Desktop Environment, Deodhai Window Compositor, The File Manager ...etc.
-
Terminal Application & Utilites: Terminal Applications are application that has attached TTY pipes, through which it communicate to and from Xeneva Terminal subsystem. This running applications are only visible through a running instance of Xeneva Terminal UI. For example ping, play..etc.
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,
- ChBase Object -- Responsible for creating and initializing primary usable data's like Application's default font, postbox ipc file index and creating a new postbox for this application and creating a new Chitralekha App instance where all necessary data's are stored
- ChWindow Object -- Responsible for requesting window of given size from the Window Manager. Whenever new application is launched, two types of Windows are created, (i) Server Window (ii)Client Window. A portion of Server Window with necessary informations are shared with the Client Window, i.e it can be accessed from the application's process memory. In other words, it uses Xeneva Shared Memory object to share the portion of Server window with the client application. Here's the structure of shared portion of the Server window:
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;
-
ChWidgets Object --- ChWidget objects are small objects that helps application provide valuable interface to user. In other words, ChWidget Object is base class of all types of widget that are used by user to make some meaningful task within the application. For example, user clicks a button to launch a floating window, user choosed an onoff button to turn on/off some settings. ChWidget act as a base for all type of widgets that share some common properties. For example, ChButton and ChRadioGroup will share some common properties because both the widgets are based on ChWidget object which includes fundamental properties, that makes it a widget.
-
Application Event Loop--- Application event loop runs continuously to poll its postbox for any outsource events. Whenever an event message arrives at its postbox, the event loop immediately pass that event to Application Event Handler. For example, the Window Manager continuously posts mouse event to each application window under which mouse pointer arrives. Each Window's application handles those mouse event and takes valuable action.
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.