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();
   }
}