
                               Seal version 1.0

                               Copyright (c) 1999 Michal Stencl

                               stenclpmd@ba.telecom.sk







				Introduction into Seal' programming










Description :
=============

Seal is free desktop environment for DOS. It has own graphics vision and can run dynamic libraries and applications. This guide is focused on basics in programming of libraries and applications for Seal. 

Programs and libraries are programmed in DJGPP v2 in poor C.


Definitions :
=============

For compatibility with future we define all of basic symbols as int = l_int
char = l_char etc..

l_long   long
l_int    int
l_word   unsigned l_int
l_dword  unsigned l_long
l_big    l_long l_long
l_char   char
l_byte   unsigned l_char
l_ptr    void*
l_rect   l_int
l_color  int
l_font   void*
l_text   char*


Functions :
===========



String functions :
------------------



l_text  set_format_text ( l_text *dest, l_text format, ... );

- function return formated text from format, ... arguments. If argument dest is not NULL it return dest and dest will contain formated text. Supported formats are same as in printf function.




l_text  set_format_text_nice ( l_text *dest, l_int size, l_text format, ... );

- return formated text like set_format_text, but if size of text is greater then value size, it truncate it and last three chars set to "...". If size is positive it truncate end of text, if negative it truncate begin of text.


example:


l_text hello1 = set_format_text(NULL, "I %s you %s %s", love, Hanny, Banny);
l_text hello2 = set_fromat_text_nice(NULL, -12, "I %s you %s %s", love, Hanny, Banny);
l_text hello3 = set_fromat_text_nice(NULL, +12, "I %s you %s %s", love, Hanny, Banny);

in hello1 : "I love you Hanny Banny"
in hello2 : "...nny Banny"
in hello3 : "I love yo..."




l_text  insstr ( l_text dest, l_text str, l_long pos, l_long size );

- insert text (str) to string (dest) in position (pos) and by size (size). If dest not exist it allocacte memory for size = max(strlen(str), size) and copy string (str) to (dest) and return it. If (dest) exist it can grow or lessen and return (dest).



l_text  delstr ( l_text dest, l_long pos, l_long size );

- remove text from (dest) that start in pos (pos) and has size (size). Return (dest).




l_text  stridup ( l_text str, l_long num );

- allocate memory for new string in size = min(num, strlen(str)), copy old (str) in size num to this string and return new one.




l_text  stristr ( l_text s, l_text d );

- same as strstr(s, d) but ignore lower or upper chars.


example :

l_text occ = stristr("Hello YOU", "you");

occ is pointer to char 'Y'...



Error function :
----------------



l_int  (*seal_error) ( l_int errtype, l_text str, ... );


- it's pointer to error function, you can redirect it to your own function, but it's better to leave it. If you run this function you have some of choices to send information about error. Some errors are only informated and some are very difficult. For this reason we use first argument (errtype) that select what type of error it is.

following types are supported in version 1.0 by SEAL :

'ERR_NOTHING'	- no error occured
'ERR_NONREGULAR'	- it's one of bad errors
'ERR_INFO'		- it's only informated error

(str) is string that contains formtated text together with ... arguments. Supported formats are as in printf function.



Memory functions :
------------------


void afree ( void **p );

- this function free block *p and set *p to ZERO. It's same like this : free(*p);*(p) = NULL;




clear_type(p,s) 

- clear pointer (p) in size (s) by zero. Same as : memset(p, 0, s);




void*  copy_type ( void *what, l_long size );

- allocate new memory in size (size) and copy contents of (what) to this memory. Return pointer to new contents of what.




l_text  _strdup ( l_text str )

- duplacates string (str). Return duplicated string. It allocates memory for this string and copy string to allocated memory.




void   *_malloc ( size_t size )

- Allocate memory. Same as (malloc), but compatible with future versions.



void   *_realloc ( void *ptr, size_t size )

- Reallocate memory. Same as (realloc), but compatible with future versions.



void   *_calloc ( size_t num_elements, size_t size )

- Allocate memory in bytes (size) for each element ( num_elements). Same as (calloc), but compatible with future versions.



void   _free ( void *ptr )

- Free memory ( ptr ). Same as (free), but compatible with future versions.



void   _cfree ( void *ptr )

- Free memory of (ptr) prevoius allocated by _calloc function. Same as (cfree), but compatible with future versions.




File, Directory, Drives :
------------------------


"Please use these functions for standard input/output operations. SEAL is still in process so it may change something in latewr versions and by these functions you will keep compatibility with them".




l_int   io_rename ( l_text nameold, l_text namenew );

- rename file or directory (nameold) to (newnew). It finds if  nameold is directory or file and then rename it to new name (namenew). It return true if operation was succesfull, otherwise it return false.




l_int   _io_removefile ( l_text src );

- remove file or directory (src). It find if (src) is file or directory and then remove it. Return true if succesfull, else return false.
It remove only empty directory. It's low-level deleting. Use io_removefile(...) you will see later for deleting.




l_int   _io_copyfile ( l_text dst, l_text src );

- copy file or directory from file (dst) to file (src). Directory is copied only empty. Use io_copyfile(...) for full copying. Return true if all was succesfull, return false if not.




l_text  io_realpath ( l_text path, l_text file );

- get real name of file (file) that we find in path (path)and return new string. This function control if '/' was after (path) or not. If not, it will add it.


example :

l_text all1path = io_realpath("c:/seal/", "seal.exe");
l_text all2path = io_realpath("c:/seal", "seal.exe");

all1path contains "c:/seal/seal.exe"  
all2path contains "c:/seal/seal.exe" 




l_bool  io_mkdir ( l_text dir );

- same as mkdir(dir, ...), but it keep compatibility.




l_text  io_uniquedir ( l_text path );

- get unique name of directory that not exist in path (path). Return new name of this directory.


example:

l_text d1 = io_uniquedir("c:/seal");
io_mkdir(io_realpath("c:/seal", d1);
l_text d2 = io_uniquedir("c:/seal");

d1 = "DIR0"
d2 = "DIR1"
...




l_bool  io_exist ( l_text file );

- return true if file or directory exist or false if not.




l_bool  io_isas ( l_text file, l_text ext );

- return true if filename (file) has extension same to (ext)




l_bool  io_isext ( l_text file );

- return true if name of file is extension or false if not.

example: 

l_bool ext = io_isext("file.*");
l_bool file = io_isext("file.bmp");

ext is true.
file is false.



l_bool  io_isfile ( l_text file );

- return true if file (file) is file and exist, else it return false.




l_bool  io_isdir ( l_text file );

- return true (file) is directory and it exist, else it return false.




l_text io_filename ( l_text filename );

- return new string for only name of file. 




l_text io_path ( l_text filename );

- return new string for only path of file.


example:

l_text onlyfile = io_filename("c:/seal.exe");
l_text onlypath = io_path("c:/seal.exe");

onlyfile contains "seal.exe"
onlypath contains "c:/"




l_bool  io_isfilename ( l_text file );

- return true if file is file or directory name, not ".", ".." etc., else return false.




l_text  io_nicelink ( l_text filename );

- return new string for filename if the extension is not ".ldv" or ".lnk". If it is, it truncate extension and return only new string of poor filename.


example:

l_text link_to_directory = io_nicelink("hello.ldv");
l_text link_to_file = io_nicelink("ciao.lnk");
l_text file = io_nicelink("image.bmp");

link_to_directory = "hello"
link_to_file = "ciao"
file = "image.bmp"




void  io_set_linkedpath ( l_text file, l_text link );

- Set link ( reference ) to directory ( link ) when you use file (file).




void  io_set_linkedfile ( l_text file, l_text link );

- Set link ( reference ) to file ( link ) when you use file (file).




l_text  io_linkedpath ( l_text file );

- return link from ".ldv" file (file). It return new path from this link. SEAL has also shortcuts to directories not only to files.




l_text  io_linkedfile ( l_text file );

- return link from ".lnk" file (file). It return new filename where the physical file is. 


example:

l_text shpath = io_linkedpath("c:/seal/desktop/pc/hd-c.ldv");
l_text shfile = io_linkedfile("c:/seal/desktop/hello.lnk");

shpath contains "c:/"
shfile contains "c:/seal/image.exe" f.e.




t_file *new_tfile ( l_text path, l_text filename, l_int attrib,                    

- allocate new memory for t_file structure and set arguments to this structure from function arguments.


When (id) of {t_data or t_list or t_object[data_type]} is set to DAT_FILE, it means that some pointer will point to this structure. We   will explain more about t_data structure and DAT_XXXX types later.

typedef struct t_file {

  l_text       path; /* path to file */
  l_text       filename; /* filename of file */
  l_int        attrib; /* atributions of file */

  l_word       time;  /* hours:5, minutes:6, (seconds/2):5 */
  l_word       date;  /* (year-1980):7, month:4, day:5 */
  l_dword      size;  /* size of file */

  l_char       reserved[24]; /* for next vesrions */

} t_file;





void    io_cleartfile ( t_file *f );


- clear memory for pointer t_file, same as 
clear_type(f, sizeof(t_file)) or memset(f, 0, sizeof(t_file))




t_file  io_filetotfile ( l_text filename );

- convert filename to t_file structure and return this structure. Filename is real path, it means it looks like this : path+'/'+file




l_text  io_tfiletofile ( t_file *f ); 

- convert pointer to t_file structure to real path and return new allocated string. Same as io_realpath(f->path, f->filename).




void    free_tfile ( void *p );

- free context of (p) and p too.




int     io_findfirst(const char *pathname, struct t_ffblk *ffblk, 			   int attrib);

- find first occurence of file pathname that is defined by atributions "attrib". Result put into t_ffblk structure. Return 0, if file was found, otherwise it return non-zero. This function is simple to findfirst function, but it support links files and it keep compatility with next versions. Please use this function for all file findings. 

! Warning ! t_ffblk is not same to ffblk ( in C ).

typedef struct t_ffblk {

   struct ffblk info; /* it's ffblk status you will get from 					 findfirst/findnext function */

   l_int        ff_reservedint; /* do not use ! */

   l_char       ff_filename[260]; /* real filename */

   WARNING : info.ff_name now contains "nice file", so it means 		   	 extension like *.ldv, *.lnk are ignored. For real file 		 name use ff_filename variable
             

   l_char       ff_reserved[24]; /* for next versions of Seal */

} t_ffblk;




int     io_findnext(struct t_ffblk *ffblk);

- find next occurence of file, that you defined in previous io_findfirst function. Return non-zero if no next file found, or ZERO  in succesfull. Use this function together with io_findfirst for all file finding. You will keep compatibility. 




t_dirinfo io_foreach_file_ex ( l_text path, l_int flags, l_int 				(*callback)(), p_object o, l_dword *ind );


- run callback function for each file in directory ( path ) and its subdirectories etc,... Callback function contains 1 argument l_text realpath, what's in path+'/'+file type. (o) is pointer to t_object structure what control process, couldn't be used, but support halt of process. If something destroy this object, then process will be halted. (*ind) is pointer to l_dword variable that contains number of files for which were callback function called. Flags may contains combination of these constants :

'DIF_SIZE' - get size of directory 
'DIF_HALT' - process was halted not use for function, it's only 	       returned argument
'DIF_DIRCALLBACK' - callback function is also called for directories, 			  not only for files.			  


- function return structure : 

typedef struct t_dirinfo {

   l_dword          dirs;  - contains number of all directories and 				     its sub-directories in directory (path)
   l_dword          files; - contains all files.
   l_dword          size;  - contains size of all files. This 					     variables is set only if flags is set to 				     DIF_SIZE, else is set to zero.
   l_int            flags; - return status. Now only ZERO if ok, else 				     DIF_HALT, if p_object (o) was destroyed. 

   l_char           reserved[24]; - used for later versions

} t_dirinfo;





l_int   io_foreach_file_copy ( l_text dst, l_text path, p_object o, 					 l_dword *ind );

- copy directories from directory (path) to destination directory (dst). (o) and (ind) have same efect as in io_foreach_file_ex function ( see above ).  

Return zero, if some error occured or zero if files was copyied.




l_int   io_removefile ( p_object ob, t_file *f, l_dword *ind );


- remove ( delete ) file/directory ( f ). (ob), (ind) have same effect as in io_foreach_file_ex function ( see above ). Return zero if some error occured, else return true. Please call this function for removing, it control all !




l_int   io_copyfile ( p_object ob, t_file *dst, t_file *src, 
			    l_dword *ind );

- copy file/directory ( src ) from file/directory (src). (ob), (ind) have same effect as in io_foreach_file_ex ( see above ). Return 
non-zero if all files was copied succesfull, otherwise return zero.
Use this function for succesfull copying.



l_int   io_numberfile ( p_object ob, t_file *dst, l_dword *ind );

- get number of files from file/directory (dst). This number is stored to (ind). Return non-zero if succesfull, otherwise it return false. (ob) is object that control process. Has same effect as in function io_foreach_file_ex ( see above ). 





Driver's functions :
--------------------

- drivers are defined in SEAL.INI file in structure [drives]. First argument is the name of the drive and the second one is path to this drive. It may be path to directory.


l_text  drv_findfirst ( p_drives *drv );

- return first name of drive from drive list from SEAL.INI file. (drv) is pointer to t_drive structure. This function use as findfirst function.


typedef struct t_drives {

   l_int            id;    - your number of drive ( f.e. a = 0, b = 				     1, c = 3, ...)
   l_text           name;  - name of driver
   l_text           path;  - path to driver

   l_char           reserved[24]; - for next versions

   struct t_drives *next;

} t_drives;





l_text  drv_findnext ( p_drives *drv );


- return next name of drive from drive list and insert new t_drive structure into drv->next = new...

Example :

t_drives d;

drv_findfirst(&d);

while ( drv_findnext(&d) ) ;

...now (d) contains information about all drives defined in SEAL.INI file, and these drives are in p_drives drives GLOBAL variable.

You can add new drive by function :

void    drv_set ( l_text namedrive, l_text path, l_int id );




l_text  drv_fixname ( l_text drive );

- return path of drive - or convert name of drive to real path.

!Do not release memory of returned text !




l_text  drv_fixreal ( l_text path );

- convert path to name of drive.

!Do not release memory of returned text !






INI's functions :
-----------------

- These functions are used for reading and writing from/into *.ini files, that usually contains inital information such as "seal.ini" file.




char *getini_fromfile ( char *filename, char *ininame, char *ixname );

- read value that is set in file "filename" in structure "ininame" and in line "ixname"

Example :

seal.ini file :
...
[SEAL]
info = "desktop environment"
version = 1
...

to get, what is set in [SEAL], [info] line you simple call

char *i = getini_fromfile("seal.ini", "SEAL", "info");


to get, what is set in [SEAL], [version] line you simple call

long  v = *((long *)getini_fromfile("seal.ini", "SEAL", "version"));


(i) now contains text : "desktop environment" and (v) number 1.





void  setini_tofile ( char *filename, char *ininame, char *ixname, char *value, int type );

- set or write "value" into file "filename" to structure "ininame" and to line "ixname". Value is pointer to value ( text or number ), type is type of pointer. ( INI_DECANUM, INI_HEXANUM, INI_STRING ).

Example :

int i = 1;

setini_tofile("seal.ini", "SEAL", "info", "FREE desktop environment", INI_STRING);
setini_tofile("seal.ini", "SEAL", "version", &i, INI_DECANUM);
setini_tofile("seal.ini", "SEAL", "hexa version", &i, INI_HEXANUM);

Output of seal.ini file :
...
[SEAL]
info = "FREE desktop environment"
version = 1
hexa version = 0x1
...



ini_data *getinidata_fromfile ( char *filename, char *ininame );

- read data from file "filename" and structure "ininame". This read all lines from structure [ininame] to next structure or to end of the file.



char *getini_value ( ini_data *dat, char *ixname );

- read line "ixname" from inidata "dat" you have got by previous funtion.




int   getini_linenum ( ini_data *dat );

- get number of lines in structure "dat"


Example:

seal.ini file :
...
[SEAL]
info = "desktop environment"
version = 1
...

ini_data *d = getinidata_fromfile("seal.ini", "SEAL");
int lines = getini_linenum(d);

(lines) now equals to 2 = number of lines in [SEAL] structure.





char *getini_line ( char **def, ini_data *dat, int line );

- return information about line "line" from structure "dat".

Example:

...
[SEAL]
info = "desktop environment"
version = 1
...

ini_data *d = getinidata_fromfile("seal.ini", "SEAL");
char *head = NULL;
char *def = getini_line ( &head, d, 1);

(def) now contains text "desktop environment" and (head) contains text "info".




ini_rgb  getini_color ( char *filename, char *ininame, char *ixname );

- return color from INI file (filename), from structure (ininame), from line (ixname).

typedef struct ini_rgb {

  int r; - index of red color
  int g; - index of green color
  int b; - index of blue color
  int x; - reserved

} ini_rgb;


Example:

seal.ini file :
...
[colors]
desktop = "255, 0, 128"
...

ini_rgb rgb = geini_color("seal.ini", "colors", "desktop");

now rgb contains in r (255), in g (0) and in b (128). 





EXEDLX functions
----------------

These functions run "files" ( applications & libraries ) for specified files formats.


l_int    run_file ( l_char *args );

- run application for specified file format defined in "args". These file formats and their applications are defined in "seal.ini" file in structure [extension_runners].

Example :

seal.ini file :
...
[extension_runners]
"exe" = "libos-x"
"dlx" = "libos-x"
"bmp" = "imager.exe"
...

run_file("hello.bmp");

This run "./programs/imager.exe" and ap_args set to "hello.bmp"

run_file("hello.exe");

Only run "hello.exe" and set ap_args to NULL



l_int    run_file_args ( l_text file, l_char *args );

- run file (file) by arguments defined in (args). Return 1, if file was run succesfull.




void     put_into_runners ( l_char *ext, l_char *program );

- set extension "ext" for specified application "program"




l_char*  get_from_runners ( l_char *ext );

- return application that was set for extension "ext"




BITMAP*  get_icon_for_file ( l_text filename, l_int attrib, l_int *ownmem );

- return BITMAP that's icon for file/directory "filename". (ownmen) will return information, if icon must be release or not. If ownmem = 1, we must free memory by Allegro's destroy_bitmap(), otherwise we couldn't.





BITMAP*  get_icon_for_file_ex ( l_text filename, l_int attrib, l_int *ownmem, l_int size );

- same as previous function, but we define size of icon. Size may be one of following : 16 = ICON_16, 32 = ICON_32;




p_list   get_args ( l_char *args );

- return list of arguments, from args text, same as dos-line. Each argument must be spaced by ' '. 




extern void  (*dos_command) ( l_text newpath, l_text command );

- this run DOS program (command), and change path to (newpath).

 


extern l_int (*read_set_file)(l_char *_filename);

- run all files in file "_filename". This file must have "*.set" structure and files to be run are defined between after function "call" (see "app.set" file)




Application/Libary functions :
------------------------------

- DLX is Dynamic Loading and eXecution by Nanosoft, Inc. I added some functions and now I think it's very good tool for Seal's libraries/applications.


AP_CALL 			   - get information, how many times was this 				     application executed.


AP_SETNUMOFCALLS(l_long x) - set maximum number of calls for this 				     application. 


AP_SETOVERLOAD(x)   	   - if (x) is non-zero, it enable to 					     overload this application, otherwise it  				     locks overloading. Overload means that 				     this application will be once in memory 				     and the second, 3rd, ... once it only 				     runs main function. Default it's locked.


AP_ISOVERLOAD		   - return NON-ZERO, if this 						     application/library can be overloaded, 				     otherwise it return ZERO.


AP_DATAFILE			   - return datafile from this 						     library/application. This datafile is 				     placed at the and of application/library 				     executable file and we can add this file 				     from Allegro's DATAFILE by program 					     dlxinsd.exe my_app.dlx my_app.dat from 				     command line. Once we have this 					     datafile, this function return pointer 				     to new allocated DATAFILE structure. At 				     the end please, release this datafile by 				     function unload_datafile() see 					     Allegro.txt.


AP_EXPORTLIB()		   - export functions/variables. It's used in 				     libraries, when we must set 						     functions/variables as exportable for 				     other programs. Exportable 						     functions/variables will get by program 				     dlxmake.exe -x my_dlx.exp my_dlx.o from 				     command line. Then include file 					     my_dlx.exp to your library by ( #include 				     "my_dlx.exp" ) and compile your library 				     again and then call program dlxgen.exe 				     my_dlx.dlx my_dlx.o from command line. 




How to build your own application running under Seal:
-----------------------------------------------------


	Seal applications and libraries are in DLX format. It means that files from COFF ( common object file format ) are translated to DLX format by dlxgen.exe. Imagine we have an file hello.c. This file must have some structure in depend of application EXE or library DLX end file.


Structure of Seal' application :

#include"allegro.h"
#include"seal.h"

/*
....allegro.h is header file of Allegro's functions ( graphics library' functions )

....seal.h is main header file of Seal. 

All Seal's applications/libraries must include these files. 
These files are placed in INCLUDE directory of Seal.
*/


app_begin ( void ) {

} app_end;


/* it's main function of Seal's applicationm, it has same efect as main function in C/C++ DOS EXE file */


Seal's application and libraries get some varaibles from Seal.h. These variables are ap_id, ap_process, ap_args you will find in Seal.h ( DLX.H ). 

Meaning of these variables is following :



ap_id - identify new application identification. Each application 	  have self ap_id. This ap_id is long pointer to memory, where 	  internal info about application is placed. Use this variable 	  for unloading application or file by DLXUnload(ap_id); and 	  DLXLoad("hello.exe"); return same id that will be set in 	  "hello.exe" application as ap_id.


!! ONLY ap_id IS GLOBAL FOR ALL APPLICATION/LIBRARY, OTHER ONES ARE LOCAL FOR ap_begin/lib_begin FUNCTION!!



ap_process - define process of application. When application or
		 library is loaded into memory, function app_begin ( for
		 application ) is called and ap_process is first one set
		 to AP_ALLOC. Then it's set to AP_INIT and in each other
		 call it's set only to AP_INIT if AP_ISOVERLOAD is set to 
		 non-zero ( see above ). If not this process is repeat
		 for all application calls. When application is released
		 then ap_process is set to AP_DONE and at last release is 
		 set to AP_FREE. In each AP_INIT is AP_CALL increased by
		 1 and in AP_DONE decreased by 1. In AP_ALLOC this value
		 is ZERO, in AP_FREE also ZERO.



ap_args - define arguments of file. These arguments are placed in one 	    string devided by space char " " (0x20, 32 in ASCII code). 	    You can get list of all these arguments by function
	    get_args(ap_args) ( see sections "EXEDLX functions",
	    "object LIST" ).




Once we have an application main function we can make a application Window.


t_rect   r = rect_assign(100, 100, 300, 200);
p_appwin w = appwin_init(malloc(sizeof(t_appwin)), r, "Hello world",
				 0, ap_id, NULL);

OBJECT(desktop)->insert(OBJECT(destop), OBJECT(w));


All these functions are explained in other sections.

rect_assign - assign the corners of object (appwin) local to desktop.
appwin_init - init new appwin object by name "Hello world", flags (0), 		  application id (ap_id) and event control function of 	  	  application is NULL. 
Then insert new object (appwin) to desktop. OBJECT(o) is defined in Seal.h in object.h section. 

!! WHEN APPWIN ( WINDOW ) IS CLOSED, THE APPLICATION IS RELEASED !!

Now all together in hello.c file :


#include"allegro.h"
#include"seal.h"
#include"app.h" /* we use appwin_init that's defined in app.h file */


void my_init_window ( void ) {

	t_rect   r = rect_assign(100, 100, 300, 200);
	p_appwin w = appwin_init(malloc(sizeof(t_appwin)), r, "Hello 					 world", 0, ap_id, NULL);
	OBJECT(desktop)->insert(OBJECT(destop), OBJECT(w));
	
};

ap_begin ( void ) {


	if ( ap_process == AP_ALLOC ) {
	} else
	if ( ap_process == AP_INIT ) {

		AP_SETNUMOFCALLS(1);
		
		/* ... call some init function */

		my_init_window();
		
	else 
	if ( ap_process == AP_DONE ) {
	} else
	if ( ap_process == AP_FREE ) {
	};

} ap_end;



Compiling :
-----------

- So, when we have hello.c file we can compile it in DJGPP. Now we have two files : hello.c and hello.o. We will go to the shell command-line and type dlxgen.exe hello.exe hello.o, then press enter. Now we have hello.exe file what's the end step of making Seal' application.



Structure of Seal' library file :
---------------------------------

Difference between Seal' applications and libraries is in structure of main function. Seal' library make export table about functions that will be exported from library. This table is exported by function AP_EXPORTLIB() in process AP_ALLOC ( only this process is 
sure called only once and at the begining ). When library is released, no one application can use their functions or variables. Library can export all type of DJGPP exportable tags.

If you add some text to your library/application please type this style of text :

#ifndef TXT_HELLOWORLD 
#define TXT_HELLOWORLD INI_TEXT("Hello world")
#endif

for lower cases you will use strlwr(TXT_HELLOWORLD)

- this keep lenguage indenpendent in new versions.

INI_TEXT will find "Hello world" that will contains your lenguage name as "Halo welt" in German f.e. 
It may be in structure "Hello world" = "Halo welt" in file german.lng, but this all in next version. But please, keep compatibility and your applications will be translated automatically.




Structure of Seal' library :


/* hellolib.c */

#include"allegro.h"
#include"seal.h"

/* same as in application */


void hello_function ( void ) {

	
};

lib_exportlib;

lib_begin ( void ) {


	if ( ap_process == AP_INIT ) {

		AP_EXPORTLIB();

	};

} lib_end;


	All variables as in application are supported. lib_exportlib is definition you will find in Seal.h ( section DLX.H ) and default set functions/variables to be exported from library to nothing. So noone function/variable is exported from library. Then compile this file in DJGPP and you will get file hellolib.o file. Go to command shell and type dlxmake.exe -x hellolib.exp hellolib.o and press ENTER. This make new file hellolib.exp wich contains table of all export-able variables and functions from library. So, it only contains ( hello_function ) function. When you don't want to export your function or variable, you only type static to your code before function/varaible like this:

static void hello_function ( void ) {
};

Now, when we have hellolib.exp file, we must return to hellolib.c file and release definiton lib_exportable; and put newone definition that include hellolib.exp file. The new version of library will be looked like this :



/* hellolib.c */

#include"allegro.h"
#include"seal.h"

/* same as in application */


void hello_function ( void ) {

	
};

/*lib_exportlib;*/
#include"hellolib.exp"

lib_begin ( void ) {


	if ( ap_process == AP_INIT ) {

		AP_EXPORTLIB();

	};

} lib_end;


- now compile it again and go back to command shell and type dlxgen.exe hellolib.dlx hellolib.o and press ENTER. It's all. This library name of library copy to file app.set and all applications and libraries run after this call will be able to use function hello_function.





object LIST
-----------

- list functions and structure is used for grouping data into one stream. 


For initializing t_list structure use function :



p_list  list_init ( p_list o, void (*func_free)(void *), l_big tag );

- where (o) is pointer to new t_list structure, (func_free) is function that will be used for data releasing and (tag) is identification number of data ( default is 0 ). Function return new object of t_list structure.


List items are defined in t_item structure :


typedef struct t_item {

  void   *rec;   - place for data
  l_big   tag;   - identification of data

  void  (*func_free) ( void* ); - function for data (rec) releasing

  p_item  prev;  - prev item in group of items
  p_item  next;  - next item in group of items

  l_char  reserved[12]; /* reserved for later versions */

} t_item;



Structure of t_list object


typedef struct t_list {



  p_item   last;

  - point to last item in data group. First item is defined as 
    last->next.




  l_big    tag;

  - default identification number of data, that's placed in address
    t_item.rec.



  void   (*func_free) ( void* );

  - default function for releasing of data. Default function is 
    free(void*) function. If some item t_item.func_free is set to
    ZERO,this default function func_free is called in releasing of data
    t_data.rec.




  l_bool   (*done)( p_list o );

  - removes items from list, but not frees data in items. Return true
    if list was succesfull destroyed. Otherwise returns false.




  void  *(*first_rec) ( p_list o );

  - return first data in list. Same as last->next->rec, but tests
    existance of all pointers.




  p_item (*first) ( p_list o );

  - return first item in list.




  p_item (*at_item)( p_list o, l_long index );

  - return the (index)th item from the list




  void  *(*at)( p_list o, l_long index );

  - return the (index)th data in the list




  l_long (*index_of)( p_list o, void *rec );

  - return the number of position where data rec are placed in the
    list




  l_long (*index_of_item)( p_list o, p_item item );

  - return the number of position where item is stored in the list




  l_long (*get_max_item)(p_list o);


  - return number of items in list.




  void   (*copy_ctx) ( p_list dst, p_list src );

  - copy context of list (dst) to end of another list (src).




  p_item (*find_rec)( p_list o, void *rec );

  - return item that contains data rec




  l_long (*insert_ex)( p_list o, void *rec, void (*f_free)(void *),
  			     l_big tag );

  - insert new data to item, that will be inserted into the list.
    (rec) will be deallocated by function (f_free). If this function
    is NULL, it use default list' func_free function. Return index of 
    new item.




  l_long (*insert)(p_list o, void *rec);

  - same as insert_ex, but 3rd and 4th arguments are set to ZERO. So
    use defaults values defined by list_init function. Return index
    of new item.




  void   (*remove_index)(p_list o, l_long index );

  - remove the (index)th item from list, but not frees data
    t_item.rec.




  void   (*remove_item)(p_list o,  p_item item );

  - remove item from list, but not frees data from item->rec.




  void   (*free_index)(p_list o, l_long index );

  - remove the (index)th item from list, and frees data from the item
    t_item.rec pointer and also free memory of item strucure.




  void   (*free_item)(p_list o, p_item item );

  - remove item from list, t_item.rec pointer and also free memory of
    item strucure.




  void   (*free_all)(p_list o );

  - remove all items from the list, and frees data from each item and
    also free memory allocated for each item. This memory is
    allocated in function insert_ex.




  l_bool (*for_each_item) ( p_list o, void *ob, l_int (*callback)(),
  				    l_dword *ind );

  - call function callback by arguments (ob), (item->rec) and (ind)
    for each item's data (item->rec) in the list. If callback return
    ZERO process will be broken, otherwise continue. Return true, if
    process was broken, else false if not.




  l_bool (*for_each_item_to_item) ( p_list o, void *ob, void *item,
				   l_int (*callback)(), l_dword *ind );

  - call function callback by arguments (ob), (item), (item->rec) and
    (ind) for each item's data (item->rec) in the list. If callback
    return ZERO process will be broken, otherwise continue. Return
    true, if process was broken, else false if not.



  l_bool (*collect_by_name_from)(p_list o, p_item from, 
					   l_int rec_delta);

  - collect data by name. List must contains group of text data or
    structures where text is ocurred in first position. (from) is
    pointer from which list must be collect data (NULL = from last
    item) to last item. If tag of item->tag is DAT_TEXT it means that
    item->rec is string, otherwise use structure, where first 4 bytes
    are pointer to string. Return true.


} t_list;




p_list  list_init ( p_list o, void (*func_free)(void *), l_big tag );

- where (o) is pointer to new t_list structure, (func_free) is function that will be used for data releasing and (tag) is identification number of data ( default is 0 ). Function return new object of t_list structure.




void    dispose_list ( p_list *o, l_bool freeitem );

- dispose list structure and if freeitem is true, it also frees context of each t_item.rec pointer in the list. Use this function for releasing t_list structure.




Example :
---------

p_list p = list_init(malloc(sizeof(t_list)), &free, 0);

p->insert(p, (void*)strdup("Hello world !"));
p->insert(p, (void*)strdup("SEAL is free desktop environmnet"));
p->insert(p, (void*)strdup("Hello Mr. Stencl !"));
collect_by_name(p, 0);

...now list (p) contains 3 items, and in the each of them are strings.

p->free_index(p, 0);

This function remove 0th item, that contains ("Hello world !") data and this data are free by function free(void*), that is declared in list_init function.

/*
  p->free_all(p);
  p->done(p);

  free(p);
*/

or 

dispose_list(p, true);




DRIVERS declarations
--------------------


extern l_font *font_system;

- contains regular system font, defined in seal.ini file as regular




extern l_font *font_system_bd;


- contains bold system font, defined in seal.ini file as bold




extern l_font *font_system_i;



- contains italic system font, defined in seal.ini file as regular




extern l_font *font_system_bi;


- contains bold+italic system font, defined in seal.ini file as
  bold+italic




extern void (*screen_shot) ( void );

- set this function for Seal begining screen, before componets
 (libraries, fonts, images, ...) are loaded into memory.




l_int FONT_GETSTRWIDTH(l_font *f, l_text str, l_int l)

- return width of string (str), defined by font (f) and by length of
  string (l)




l_int FONT_GETSTRHEIGHT(l_font *f)     

- return height of font




l_int FONT_GETWIDTH(l_font *f, l_byte ch)    

- return width of char (ch) defined by font (f).




l_int FONT_GETHEIGHT(l_font *f)

- return height of font (f). Same as FONT_GETSTRHEIGHT



Manipulating with fonts:



l_font* load_font ( char* _filename, char *xxname, int w, int h, 
 			  int from, int to);

- load font from file (_filename), (xxname) set to ZERO, in width (w) and height (h), from char (from) to char (to). Return new loaded font. This function support TTF,PCX,TIFF + FNT fonts.




void    unload_font ( l_font *f );

- unload font (f).




int     add_font_to_system ( l_font *font, char *name, int weight );

- add font (font) defined by name (name) and weight (weight) to system table of fonts. (name) is identification name of font, not file name. Use this function before loading your own font by function get_font_in_size




void    load_supported_fonts ( char *ini_array_name, l_bool in_mem);

- load fonts from Seal.ini file from structure ini_array_name. use false in in_mem when you don't want to use many chars of fonts. Displaying of these fonts is slower, but loading of font is in high speed.




l_font *get_font_in_size ( char *fontname, int w, int h );

- return font defined by fontname in width (w) and height(h). This font name is not file name of font, but it's identification, defined by function add_font_to_system.




void textout_draw(BITMAP *bmp, l_font *f, unsigned char *s, int len,
			int x1, int y1, int align, GrColor color,
			GrColor bcolor );


- draw text (s) to Allegro' output (bmp). This text will be draw in font (f), in size of text (len) to coordination (x1), (y1), by
alignment (align), foreground color (color) and background color
(bcolor).

If (len) is (-1), it draws all text (s).

Supported Alignments :
----------------------

'TX_ALIGN_LEFT'	  - align text to left (default in x)
'TX_ALIGN_TOP'      - align text to top (default in y)
'TX_ALIGN_RIGHT'    - align text to right
'TX_ALIGN_BOTTOM'   - align text to bottom
'TX_ALIGN_CENTERX'  - center text in x
'TX_ALIGN_CENTERY'  - center text in y
'TX_ALIGN_CENTER'   - center text in both x & y
'TX_ALIGN_DEFAULT'  - default alignment
'TX_UNDERLINE'      - underline text
'TX_STRIKELINE'     - strike line through the text


If (bcolor) is TX_NOCOLOR it not draw background of text, otherwise it draw background defined by color (bcolor)





void textout_draw_rect(BITMAP *bmp, l_font *f, unsigned char *s,
			     int len,int x1, int y1, int x2, int y2,
			     int align, GrColor color, GrColor bcolor,
			     int clip );

- draw text (s) to Allegro' output (bmp). Text is defined by length(len), bounds (x1), (y1), (x2), (y2), alignment (align), foreground color (color), background color (bcolor) and clip (clip).
Text is align to rectangle (x1, y1, x2, y2). Clip use when you want to clip text to lower left/upper corner of x1,y1 and BITMAP clip and higher right/bottom corner of x2, y2 and BITMAP clip.




void textout_printf(BITMAP *bmp, void *f, int len, int x1, int y1, 
			  int x2, int y2, int align, GrColor color,
			  GrColor bcolor, int clip, char *s, ... );


- same as text_draw_rect function but in formated style.





void draw_double_text ( BITMAP *out, GrFONT *f, unsigned char *txt,
				int size, int x1, int y1, int x2, int y2,
				int align,GrCOLOR f1, GrCOLOR f2, int clip );


- same as text_draw_rect function but (f1) is color of foreground text and (f2) is color of second text under the higher defined in (f1).




void draw_selected_text ( BITMAP *out, GrFONT *f, unsigned char
				*txt, int size, int sfrom, int sto, int x1,
				int y1,int x2, int y2, int align, GrCOLOR 
				f1, GrCOLOR b1, GrCOLOR f2, GrCOLOR b2,
				int clip);

- same as text_draw_rect function but, (sfrom) is position from where must be text drawn in (f2, b2) colors and (sto) is end position.

!! This function may only be draw in TX_ALIGN_DEFAULT alignment in this version of Seal !!




Seal' Object style of programming
---------------------------------


- Seal was programed in object progtraming style. It's not in OOP (
object oriented programing ) as Uniforms, but in poor C that use structures and pointers to this structures. Main structure is t_object structure. Each structure in Seal has pointer type to structure defined by p_ and name of object. For example t_object has pointer type p_object. It looks like this :

typedef struct t_object *p_object;


Object (structure) t_object is object that can group others objects that inherit functions and variables from t_object. When you want to make new object with additional functions you simple type this :

typedef struct t_hallo *p_hallo;
typedef struct t_hallo {


	struct t_object  obclass;


	/* ...additional functions */

} t_hallo;

#define HALLO(o) (p_hallo(o))


!! name "obclass" is not important, you may use your own name, but all Seal' objects use this name for inherited structure, 
BUT YOU MUST DECLARE IT BEFORE ALL OTHER DATA !!


When you want to make object that inherited functions/variables from t_button structure and make some additional functions declare this :


typedef struct t_newbutton *p_newbutton;
typedef struct t_newbutton {

	struct t_button  obclass;

	/* ...your additional data */

} t_newbutton;

#define NEWBUTTON(o) ((p_newbutton)(o))


You may see that NEWBUTTON, HALLO, OBJECT, VIEW, BUTTON, ... are only  definitions that replace conversions of types. By this conversion you can use data from t_newbutton in function f.e. 
void draw ( p_object o ) . 

When you build new object you allocate memory that contains size also from t_button structure. So you can use functions from this structure, but you must talk to compiler it's OK, I have a memory for this operation. When you build your new structure obclass you must make your new initialization function such as 

p_newbutton newbutton_init ( p_newbutton o, t_rect r, l_text title ) {

	if ( !o ) return NULL;

	clear_type(o, sizeof(t_newbutton));

	...clear_type is same as memset(o, NULL, sizeof(t_newbutton))

	button_init(BUTTON(o), r, title, 0, 0);

	...you must call initialization function that initialize
	functions and variables in obclass structure. You can also call 
	this like button_init(&(o->obclass), r, title, 0, 0), but it's
	better to use standard macro.

	.... declarations for your object

	VIEW(o)->draw = &newbutton_draw;

	...This redeclare function draw from t_view structure to your
	new draw function. This structure is son of these objects :

	t_object  OBJECT(o)-> 
	   |
	 t_view   VIEW(o)->
	   |
	t_button  BUTTON(o)->

	...so you can use all functions/variables from these
	structures.

	return o;
};


Now you can build this object by calling :

p_newbutton b = newbutton_init(malloc(sizeof(t_newbutton)),
					 r,
					 "Hello button");

malloc(sizeof(t_newbutton)) - allocate memory for new object.
r 	- rectangular area of object where will be placed local to
        object where will be inserted.
"Hello button" - title of new button f.e.


Now insert your button (b) to the desktop object by function :

p_object insert ( p_object dst, p_object son ); you will find in t_object structure.

OBJECT(desktop)->insert(OBJECT(desktop), OBJECT(b));


Example of button structure that only redefine some functions that are used in t_object, t_view, t_button structures:

void  new_trans_ev ( p_object o, p_event event ) {

	RETVIEW(o, event); /* I explain later */

	button_translate_event(o, event);


};

void  draw ( p_view o ) {

	button_draw(o); 

	/* call old draw button' function, you can't use o->draw(o);
	becouse you will call this function again and you will flow
	stack over */
	
};

void  draw_state ( p_button o, l_int press ) {

	button_draw_state(o, press);

};


p_button o = button_init(malloc(sizeof(t_button)),
				 r,
				 "Hello world"
				 0,
				 0);

OBJECT(o)->translate_event = &new_trans_ev;
VIEW(o)->draw = &new_draw;
BUTTON(o)->draw_state = &new_draw_state;




Structure t_rect and t_point
----------------------------


All GUI's ( Graphics User Interface ) must have some rectangular objects so we must define  some functions and types for this purpose.


   t_point {
     l_rect x;
     l_rect y;
   };

   
- t_point is structure of 1 point in 2D perspective.




   t_rect {
     t_point a;
     t_point b;
   };


- t_rect contains 2 points - a.x & a.y is left-upper corner of rectangle and b.x & b.y is right-bottom corner of rectangle.




rect_empty 

- global variable for empty rectangle






t_point  point_assign ( l_rect x, l_rect y );

-  return structure of t_point that contains x and y.
same as t_point p = {x, y};





t_rect  rect_assign ( l_rect ax, l_rect ay, l_rect bx, l_rect by );

-  return structure of t_rect that contains ax, ay, bx, by.

   When we type
   ...
   t_rect r = rect_assign(100, 150, 200, 250);
   ...
   we have rectangle by these values

   r.a.x = 100
   r.a.y = 150
   r.b.x = 200
   r.b.y = 250





t_rect  rect_move ( t_rect r, l_rect mx, l_rect my );

- add "mx" to r.a.x and r.b.x and "my" to r.a.y and r.b.y and return this t_rect.





t_point rect_size ( t_rect r );

- return size of t_rect, where p.x is size of x and p.y size of y





t_rect  rect_cliped ( t_rect r, t_rect d );

- clip rect "r" to rect "d" and return clipped rect. if they not overlay them it return rect_empty





l_bool  rect_overlay ( t_rect r, t_rect d );

- return true if r overlay d, else return false


WARNING ! Do not change t_rect by l_rect !




object OBJECT
-------------


Seal is based on objects. Every object can own other object and all of them own others. The basic structure for this system is t_object structure that only sets some variables and consists of main functions.

For example : object "drivers" own objects "t_mouse" and "t_keyboard" and you can add other object by function (insert) ....see t_object structure.

When function translate_event is called,  it call both of these objects and return state of events in t_event structure. We explain this function later.


p_object  obj_init ( p_object o );

- this function initialize "o" object.





t_object structure
------------------


VARIABLES:


l_dword   tag;

- id of object type. It's only information about object. Do not change this values. It's for internal use. 

TAG_NONE
TAG_DISPOSE		- when this tag is set, the object was done, or not 			  exist.
TAG_OBJECT		- object inherit data from t_object
TAG_VIEW		- object inherit data from t_view
TAG_WINDOW		- 			    from t_window
TAG_BUTTON		- 			    from t_button




l_int     process_tick;

- miliseconds that define difference between each call of your function void func_callback ( p_object o ); This milisec set by function init_stillprocess ( p_object o, l_int milisec ); You can dispose still-process by function done_stillprocess ( p_object o );
It's used for movies-drawing for example, when you want to redraw your frames each process_tick milisecond. If you want to redraw your frame each 20 milisecs, you redefine function func_callback and point it to your function from where will be draw function called.



l_dword   state;

- current status of object state of object couldn't be same in all objects. F.e. state of t_mouse  object could be one of O_SF_MOUSExxxx 
( see mouse.h ) but in t_keyboard could be one of KB_SF_KEYxxxx ( see keyboard.h ), but all of them must start their values from last OB_SF_xxxx value = 0x020, because it cannot be overlayed. 




l_dword   options;

- options of object. All objects has some initial options and these set the first object's services.


  

l_big     data_type;

- all of objects can store information to clipboard by function set_data and get information from clipboard by get_data function. To know, what type this object knows, it is used this variable. The object can know more than one type so it's better to use it as bit - combination. This types are also used for t_list.tag/t_item.tag variable and for object' t_data structure.

'DAT_NONE'      - none data type
'DAT_TEXT'      - single text ended by zero 
'DAT_IMAGE'     - type of BITMAP
'DAT_TFILE'     - t_file structure 
'DAT_LIST'      - pointer to list ( p_list)
'DAT_ALLKNOW'   - all data types are accepted   





p_object  owner;

- to know which parent is parent of object we use this pointer. If the owner is NULL it's ,,oldest parent".




p_object  next;

- point to object that's after this object in group where's parent is
"owner". The system is following :

    / <- next\  / <- next\  / <- next\
  last  <-   3rd  <-    2nd   <-    1st  <-|
   \ next ---------------------------------|




p_object  prev;

- it's same as next but it point to object before

      / next = \  / next = \  / next = \
 | -> last  ->   3rd  ->    2nd   ->  1st
 |------------------------------- next /





p_object  last;

- we also must know the pointer where are stored sub-objects. For this purpose we use pointer "last" that point to the last sub-object. When the "last" is NULL it means this object is not parent. Otherwise it is and "last->owner = this object"




l_char    reserved[48];

- it's reserved for others variables





FUNCTIONS :


void  (*done) ( p_object o );

- this function end object and take it from group.





p_object   (*owner_view) ( p_object o );

- return first graphics objects. In this GUI can exist graphics and not graphics objects. Graphics objects are defined by struct t_view, that we will explain later.





p_object   (*next_view) ( p_object o );

- return next view in the group. It looks for next object that can be
visible.




p_object   (*prev_view) ( p_object o );

- return previous view in the group.




p_object   (*last_view) ( p_object o );

- same as last, but in view




p_object   (*first_view) ( p_object o );

- same as first(o), but in view




p_object   (*prev_view_to_first) ( p_object o );

- if previous view is not first view it, return previous view else it
return NULL




p_object   (*next_view_to_last) ( p_object o );

- if next view is not last view, it return next view, else it return
NULL




void       (*setup) ( p_object o );

- this functions is calling always when the object is putting into the group by function insert.





p_object   (*insert) ( p_object o, p_object sub );

- insert object "sub" into the group "o", return "sub".





p_object   (*insert_before) ( p_object o, p_object sub,
					p_object before );

- insert object "sub" into the group "o" before object "before", return "sub"





void       (*put_in_front_of) ( p_object o, p_object before );

- replace object "o" from its position before "before" object





void       (*remove) ( p_object o, p_object sub );

- remove object "sub" from group "o"




p_object   (*first) ( p_object o );

- return the first object in the "group"




void       (*func_callback) ( p_object s );

- function that will be called each process_tick, that you select by function void init_stillprocess ( p_object o, l_int milis ); This function set options to OB_OF_STILLPROCESS and process_tick to milis.




void       (*set_state) ( p_object o, l_dword st, l_bool set );

- function for state settings. See "object.c" [obj_set_state] function.




void       (*set_options) ( p_object o, l_dword op, l_bool set );

- same as set_state, but in options.




l_bool     (*is_state) ( p_object o, l_dword st );

- return boolean value if variable "state" contains flag "st".




l_bool     (*is_options) ( p_object o, l_dword op );

- return boolean value if variable "options" contains flag "op".




void       (*translate_event) ( p_object o, t_event *event );

- it's the main function of event translating. Whenever some
event occurs this functions are called. Calling of functions
in group is by their positions. So function, which is prefer
is called at the first position, then first object in the group....
....to last object in the group.


Structure of t_event :

     l_dword   type;

     - type of event ( EV_MOUSE, EV_KEYBOARD, EV_MESSAGE....)


     p_object  obj;

     - when the type of event is set, then "obj" point to object that 
	 set this type. F.e., when the type is EV_MOUSE then "obj"
	 point to "mouse" object.



Object Data System
------------------

SEAL support drag&drop system, so it's important to make standard copy and deleting process. For this reason there are two functions : get_data and set_data.

If you want to get f.e. text from object you set t_data.id = DAT_TEXT and call function get_data that return true if operation was succesfull, this function also set t_data.rec to some text. If you want to set this text to other object you call set_data function.

Example:

t_data dat;
dat.id = DAT_TEXT;
dat.style = DS_SELECTED; --- get selected text

if ( obj1->get_data(obj1, &dat) )

  obj2->set_data(obj2, &dat);


or....


t_data dat;
dat.id = DAT_TEXT;
dat.style = DS_ALL; --- get all text from obj1

if ( obj1->get_data(obj1, &dat) )

  obj2->set_data(obj2, &dat);

or....

t_data dat;
dat.id = DAT_TEXT;
dat.style = DS_DELETE+DS_ALL; --- delete all text from obj2

obj2->set_data(obj2, &dat);



other's object' functions
-------------------------

t_object*  dispose ( t_object *o );

- done and free memory from object (o) and their sub-objects.




void       dispose_all ( t_object *o );

- only done object (o), dispose sub-objects, but not frees memory from object (o).




void       init_stillprocess ( p_object o, l_int milis );

- set object to still process. (milis) are miliseconds, that define each tick you want to call your function o->func_callback. Options of this object is set to OB_OF_STILLPROCESS




void       done_stillprocess ( p_object o );

- reset object to old status, so your function o->func_callback, will be not further call.




void       set_event ( t_event *event, l_dword type, 
			     l_dword message, p_object obj );

- set event (event) to values (type), (message), (obj).





void       set_event_info ( t_event *event, l_dword type, 
				 l_dword message, p_object obj, void *rec );

- set event (event) to values (type), (message), (obj), and 
event->info will be set to (rec).





void       message_all_info ( l_dword type, l_dword message, 
					p_object obj, void *info );

- set event to types (type), (message), (obj), (info) and call by these settings all objects in hierarchy from top object (&program).




void       message_info ( p_object o, l_dword type, l_dword message, 				  p_object obj, void *info );

- set event to types (type), (message), (obj), (info) and call by these settings only object (o) and their sub-objects.




void    message ( p_object o, l_dword type, l_dword message, 
			p_object obj);

- same as message_info, but (info) is set to ZERO.





void    message_all ( l_dword type, l_dword message, 
			    p_object obj );

- same as message_all_info, but (info) is set to ZERO.





l_int  obj_exist ( p_object o );

- get information if (o) exists. Return -1 if (o) is NULL, return ZERO if object was disposed, other value if object exists.




How to secure task switching
----------------------------

#define _while(t)      

- define multitasking while mechanism. If this (while) you use, you secure your process can be stoped and others processes run.


For example :

_while(1) {

	...do something

}; 




#define _for(t1,t2,t3) 

- same as _while, but in (for) directive.





object VIEW
-----------

View structure is used for visible objects. When we need show something to the screen we use this structure, that also inherits functions/variables from t_object structure. When we need draw window to screen f.e., we need to make view structure by view_init functions and then set (*draw) function to new drawing function that show window. For drawing are used all functions from Allegro, but for text output use Seal' functions, you will find in section Manipulating with fonts.



FLAGS :


Options settings


#define VW_OF_VISIBILITY      0x0000020

- object can be visible at the begining, when object is inserted to other object.




#define VW_OF_IGNORELIM       0x0000040

- ignores owner's limits




Drag mode settings


#define DM_DRAGMOVE           0x0000001

- by this setting it's possible to drag and move the object



#define DM_DRAGGROW           0x0000002

- by this setting it's possible to drag and grow the object





Draw mode settings


#define DWM_TESTSUBVIEWS      0x0000001

- test sub views in Draw function.



#define DWM_ONLYTOBUFFER      0x0000002

- draw only to buffer



#define DWM_ONLYTOSCREEN      0x0000004

- draw only to screen




Brush states


#define BRUSH_STRETCH         0x0000001

- background is stretched



#define BRUSH_SELFIMG         0x0000002 

- image was created for this brush only. When object is disposing, memory for image is free too.



#define BRUSH_GRADIENT        0x0000004 

- color is gradient to color2 



#define BRUSH_GRADIENT_HOR    0x0000008 

- if this bits are set, gradient is horizontal, otherwise is vertical




BRUSH Structure :


   typedef struct t_brush {

      l_long     state;

      - flags of background drawing. f.e. BRUSH_STRETCH ...


      l_color    color;

      - color of background. It's ingored, if background is set.


      BITMAP    *background;

      - image of background


      l_color    color2;

      - Second color to what will be gradient (color), when state is 	  set to BRUSH_GRADIENT.


      l_char     reserved[22];

	- reserved for further versions

   } t_brush;





struct  t_view
--------------


p_view  view_init ( p_view o, t_rect r );

- this function initialize view "o", and sets some important values. All objects that inherit functions/variables from t_view such as t_window, t_button, t_textline, ... must use this function in their initializating functions.




VARIABLES:



struct t_object   obclass;

- say we want to inherit functions/variables from t_object structure.



struct t_brush    brush;

- brush structure for background drawing. This structure is used when you use function background



struct t_rect     bounds;

- local rectangular area. This origins are aligned to owner.



struct t_rect     clip;

- rectangle of view, where we can draw.



BITMAP           *draw_buffer;

- buffer of view. It's aligned to size of screen. This is returned from begin_paint function. 



BITMAP           *draw_out;

- default value is screen.



l_int             drag_mode;

- mode of dragging. You must set it before the first calling of drag_view function. Flags are DM_xxxx, see above.



l_int             draw_mode;

- mode of drawing. F.e. DWM_TESTSUBVIEWS, DWM_ONLYTOBUFFER ...



l_text            info_text;

- text that will be displayed, when crursor is under view and CTRL+F1 is pressed.



l_int             align;

- alignments of view. Use same values as in text alignments : TX_ALIGN_xxxxx. Use it before inserting.



l_font           *font;

- font of view' text



l_int             cursor;

- cursor that will be displayed when mouse is placed under view.
See object MOUSE available values.



l_color          *palette;

- palette of view. Colors from this palette gets by function 
o->get_color(o, index); Set palette before first calling of draw function.




FUNCTIONS :


void    (*drag_view) ( p_view o, l_word mode, t_event *event );

- drag view and move it or change its area. "mode" can be one of DM_xxx modes. You must set drag_mode flags of "o" to same flags as "mode". F.e. if you want to move window, you must first in init function set drag_mode |= DM_DRAGMOVE; and then you can use this function by DM_DRAGMOVE argument.




t_point (*size_minimum) ( p_view o );

- return minimum size of object.




void    (*draw) ( p_view o );

- virtual functions of drawing. This function contains functions for
drawing. The first function before others must be :

BITMAP *out = o->begin_paint(o, &p, o->get_local_extent(o));

where &p is pointer to point structure and it return global position
from left,top corner in buffer screen

  .... allegro functions...such as...

if ( out ) {

  rectfill(out, p.x, p.y, p.x+100, p.y+100);

};

  ...all allegro functions must be end by

o->end_of_paint(o, ,,same as begin_paint 3rd argument");





void    (*draw_view) ( p_view o );

- main function for object redrawing. If you want to redraw object by it's sub-objects, please call this function.




void    (*draw_sub_views) ( p_view o, p_view from, p_view to );

- draw sub-objects of object "o".





BITMAP* (*begin_paint) ( p_view o, t_point *p, t_rect rwhere );

 - this function must be placed before all allegro's drawing functions. "p" is pointer of t_point structure and return global origin of view from eft,top corner of screen.

"rwhere" is rectangular area, where we want to draw. Something as clip. "rwhere" must be same area as in end_of_paint function.

return BITMAP where the object will be drawn. This value use in allegro's functions.




void    (*end_of_paint) ( p_view o, t_rect rwhere );

- this function must be placed after all allegro's drawing functions.
"rwhere" is rectangular area, where we want to draw. Something as clip. "rwhere" must be same area as in begin_paint function.




void    (*draw_in_rect) ( p_view o, t_rect r );

- draw view in rect "r"




void    (*draw_me) ( p_view o );

- draw only this object without any sub-objects, BUT not redraw sub-objects.




t_rect  (*get_local_extent) ( p_view o );

- return (0,0, width of object, height of object)




t_rect  (*get_global_bounds) ( p_view o, t_rect r );

- return global bounds from "r" to screen bounds.




void    (*show) ( p_view o );

- show view




void    (*hide) ( p_view o );

- hide view





void    (*set_draw_mode) ( p_view o, l_int dm, l_bool set );

- sets flags "dm" to draw_mode variable if "set" = true




l_bool  (*is_draw_mode) ( p_view o, l_int dm );

- return boolean value if draw_mode contains "dm" flags




t_rect  (*size_limits) ( p_view o );

- return limits of object. These limits are used for sub-object working area.




void    (*change_bounds) ( p_view o, t_rect nr );

- change bounds of object to new "nr" bounds.




void    (*background) ( p_view o, t_rect r );

- draw background of object.




Example of draw function :

void   my_draw ( p_view o )
{
  /* return {0, 0, rect_sizex(o->bounds), rect_sizey(o->bounds)}*/
  t_rect  r = o->get_local_extent(o); 
  t_point p;

  BITMAP *out = o->begin_paint(o, &p, r);

  if ( out ) {


    o->background(o, out, rect_move(r, p.x, p.y));
    
    button(out, p.x+r.a.x, p.y+r.a.y, p.x+r.b.x, p.y+r.b.y, 
	     COLOR(CO_BLACK), COLOR(CO_WHITE));


  };

  o->end_of_paint(o, r);
};


p_view v = view_init(malloc(sizeof(t_view)), r);
v->draw = &my_draw;
OBJECT(desktop)->insert(OBJECT(desktop), OBJECT(v));






object KEYB ( t_keyboard )
--------------------------


- object t_keyboard is used for getting information from keyboard. This object is placed in t_driver object. Whenever is 
OBJECT(driver)->translate_event... called it calls also translate_event function from t_keyboard, t_mouse, ... structures. 




typedef struct t_keyboard {



struct t_object obclass; 

- inherit functions from t_object



l_int     code;

- code of key. When you want to know if key was pressed you use object' variable (state).



Example:

if ( key->obclass.state & KB_SF_KEYDOWN )

or

if ( OBJECT(key)->state & KB_SF_KEYDOWN ) - use this please.



  ...for ALT+X you type

if ( OBJECT(key)->state & KB_SF_KEYDOWN && 
						key->code == TO_ALT(KB_X))



  ...for CTRL+F5 you type

if ( OBJECT(key)->state & KB_SF_KEYDOWN && 
						key->code == TO_CTRL(KB_F5))


l_int     shifts;

- shifts contains information about shifts that was pressed.


These shifts are supported by Allegro.

#define KB_SHIFT_FLAG         0x0001
#define KB_CTRL_FLAG          0x0002
#define KB_ALT_FLAG           0x0004
#define KB_LWIN_FLAG          0x0008
#define KB_RWIN_FLAG          0x0010
#define KB_MENU_FLAG          0x0020
#define KB_SCROLOCK_FLAG      0x0100
#define KB_NUMLOCK_FLAG       0x0200
#define KB_CAPSLOCK_FLAG      0x0400
#define KB_INALTSEQ_FLAG      0x0800
#define KB_ACCENT1_FLAG       0x1000
#define KB_ACCENT1_S_FLAG     0x2000
#define KB_ACCENT2_FLAG       0x4000
#define KB_ACCENT2_S_FLAG     0x8000



l_char    keychar;

- contains char of key.



void   (*simulate_keypress) ( p_keyboard o, l_int keycode );

- simulate your finger on keyboard


} t_keyboard;





object MOUSE
------------

- object t_mouse is used for getting information from mouse and set cursors, speed, range, etc... This object is placed in t_driver object together with t_keyboard. Whenever is 
OBJECT(driver)->translate_event... called it calls also translate_event function from t_mouse structures. 
 

typedef struct t_mouse {


struct t_object  obclass;

- inherit functions/variables from t_object structure




struct t_point   speed;

- speed of mouse, speed.x = 0 is maximal speed in x coord and 
speed.x = 10 is minimal speed. It's same in speed.y




struct t_point   where;

- point of mouse, where cursor is placed in screen




l_char           buttons;

- number of buttons for mouse




BITMAP*   (*get_cursor)(p_mouse o);

- return BITMAP of cursor




t_point   (*get_focus)(p_mouse o);

- return focus point of cursor. It's delta point from begining of cursor' BITMAP, where focus is placed.




t_rect    (*get_range)(p_mouse o);

- return bounds of cursor in screen




l_bool    (*is_visible)(p_mouse o);

- return true if cursor is visible on screen, else return false




void      (*set_dclick_diff)(p_mouse o, l_int mili);

- set double-click difference. Miliseconds between two clicks, when it declare as double-click




l_bool    (*show)(p_mouse o);

- show cursor on screen. True if ok, false if not




l_bool    (*hide)(p_mouse o);

- hide mouse from screen, true if ok, false if not




l_int     (*block)(p_mouse o, t_rect r );

- block mouse in bounds. When curosr is visible and it's placed somewhere in this bounds, it hides cursor and return non-zero, otherwise it return zero and not hide mouse. This value use later in MOUSE->unblock function, when you want to mouse show on screen.




void      (*unblock)(p_mouse o, l_int i );

- unblock mouse, (i) is returned value from MOUSE->block function. This functions are used as push/pop in assempler.




l_bool    (*is_block)(p_mouse o );

- return true, if mouse is blocked and it's not visible and false if isn't blocked




void      (*set_pos)( p_mouse o, t_point where );

- set position of cursor to (where) point on the screen




l_bool    (*set_cursor)(p_mouse o, BITMAP *cursor);

- set cursor of mouse to BITMAP (cursor). Returns true if cursor was succesfull set, else returns false




l_bool   (*set_cursor_focus)(p_mouse o, BITMAP *cursor, t_point p );

- set cursor to BITMAP ( cursor ) and set focus point of cursor 
to (p). Return true if all is ok, else return false




void      (*set_range)(p_mouse o, t_rect r );

- set bounds (r) of cursor




void      (*set_speed)(p_mouse o, t_point speed );

- set speed to (speed). This speed further get by MOUSE->speed




void     (*set_focus)(p_mouse o, t_point focus );

- set focus of cursor




l_bool   (*set_mode)(p_mouse o, l_int mode, l_color col, t_rect r );

- set cursor mode (mode) in color (color) and rect (r).
You can choose from these modes :

MO_MO_RECT - efect like drag-window frame
MO_MO_GROW - efect like resize-window frame

Return true, if all is ok, else return false

} t_mouse;


void mouse_set_cursor_focus_id ( l_int id )

- set cursor from standard cursor' types, where (id) maybe one of these values :


CUR_ARROW	- standard arrow
CUR_MOVE	- move cursor
CUR_GROW	- grow cursor
CUR_TEXT	- text cursor
CUR_CLOCK	- clock
CUR_PENCIL
CUR_TARGET
CUR_TARGET2
CUR_STOP
CUR_ZOOM
CUR_SCRUP
CUR_SCRDN
CUR_SCRLF
CUR_SCRRG
CUR_TEXT2
CUR_DRAG	- drag cursor - used for drag & drop
CUR_FINGER	- finger cursor - used for html target

These values use also for t_view.cursor


Available states for t_mouse structure :

MO_SF_MOUSEMOVE	- mouse is moved
MO_SF_MOUSELDOWN  - left button on mouse was pressed
MO_SF_MOUSELUP    - left button on mouse was released
MO_SF_MOUSERDOWN
MO_SF_MOUSERUP
MO_SF_MOUSEMDOWN
MO_SF_MOUSEMUP
MO_SF_MOUSELAUTO  - left button is still pushing
MO_SF_MOUSEMAUTO
MO_SF_MOUSERAUTO
MO_SF_MOUSELDOUBLE - left button was double-clicked
MO_SF_MOUSERDOUBLE
MO_SF_MOUSEMDOUBLE

MO_SF_MOUSEDOUBLE - one of buttons was double-clicked
MO_SF_MOUSEAUTO	- one of buttons is still pushing
MO_SF_MOUSEDOWN	- one of buttons was pressed
MO_SF_MOUSEUP	- one of buttons was released
MO_SF_MOUSEPRESS  - one of button is down
MO_SF_MOUSELPRESS	- left button is down
MO_SF_MOUSEMPRESS	
MO_SF_MOUSERPRESS


Example :

  if ( event->type & EV_MOUSE ) {

     if ( OBJECT(mouse)->state & MO_SF_MOUSELDOWN ) {

	   ...left button pressed 

     };


  };





object WINDOW
-------------

- object t_window is used for window drawing. This is only simple dialog window. Use t_appwin structure for windows with close buttons and other addons.


p_window  win_init ( p_window o, t_rect r, l_text caption,
			   l_int flags );

- initialize window. (r) are bounds of area where will be window placed. (caption) is title of window. (flags) - still ZERO in this object.



pal_window 

- palette of window, you get color from this palette by function 
VIEW(o)->get_color(VIEW(o), #num_color);

#num_color

0 - background of window
1 - active title 
2 - gradient color of active title
3 - passive title
4 - gradient color to passive title
5 - active caption ( text )
6 - passive caption ( text )



struct t_window {


struct t_view  obclass;

- inherit functions from t_view structure



l_text         caption;

- text of caption



l_int          flags;

- flags of window. ZERO.



void       (*draw_title) ( p_window o );

- function for title drawing


} t_window;







Seal' LIBRARIES
----------------

These libraries are run at the begining of the Seal. You may find it in *.set file, that run all of programs at the begining of the Seal.



APP LIBRARY
-----------

- include "app.h" for using this library in your sources. This library contains main application window appwin_init, message boxes, etc...


object APPWIN
-------------

pal_appwin - palette of application window. It has same context as pal_window



p_appwin  window_init ( p_appwin o, t_rect r, l_text caption, 
				l_int flags );

- init window supported flags of window. Use this init function for window creating when you want to support window buttons such as close, minimalization, maximalization, resize buttons.

Available flags for window_init and appwin_init :

You can use combination of these values :

0 		  - defualt - only close button is included into window
'WF_MAXIMIZE' - maximalization button is included
'WF_MINIMIZE' - minimalization button is included
'WF_MINSIZE'  - window is minimalized

These values are not supported, it will be supported by main desktop menu. When one of these values is supported, window can message one of these values, when button is pressed.



#define   MSG_MAXIMIZE   101

- when maximize button is pressed, it call this message for window and t_event.info is set to pointer on this structure :

typedef struct t_appinfo {

   l_text      title; - title of window
   p_object    obj;   - window structure pointer

   l_char      reserved[48]; - reserved for further versions of Seal

} t_appinfo;




#define   MSG_MINIMIZE   102

- same as maximize, but in minimize button



#define   MSG_RESIZE     103

- same as maximize, but in resize button




p_appwin  appwin_init ( p_appwin o, t_rect r, l_text caption, 
				l_int flags, l_hdlx id, 
				void (*trans_ev)( p_object o, t_event *e ));


- make new application window, where (flags) is has same efect as in window_init function ( see above ). (id) is (ap_id) of application (see section How to build your own application/library...). (trans_ev) is trnalsate_event function for application. Return new object of window.


Example :

t_rect r = rect_assign(100, 100, 500, 300);
p_appwin  w = window_init ( malloc(sizeof(t_window)), r, "Hello 			  window", 0/* only close button is supported*/);
OBJECT(desktop)->insert(OBJECT(desktop), OBJECT(w));




message boxes ( dialogs )
-------------------------

- message boxes show text ( information, errors, warnings, ... ) on the desktop. Whenever you want to show information on the screen you may use one of these functions. When error occured use seal_error function for compatibility ( see section Error function ).


Message boxed use these flags : 

wflags - message window' flags

MW_WARNING      - it's warning message box
MW_ERROR        - it's error message box
MW_INFO         - it's info message box
MW_QUESTION     - it's question message box
MW_UNAVAILABLE  - it's unavailable message box



bflags - message button' flags. You can use combination of these buttons for message. When you press one of button it call message for this button.

MB_CLOSE      - message box contains button CLOSE
MB_CANCEL     - message box contains button CANCEL
MB_YES        - ...
MB_NO         - ...
MB_HELP       - ...
MB_OK         - ...

When button is pressed message box return one of values defined for these buttons:

MB_CLOSE  - MSG_CLOSE
MB_CANCEL - MSG_CANCEL
MB_HELP   - MSG_HELP
MB_YES    - MSG_YES
MB_NO     - MSG_NO
MB_OK     - MSG_OK




l_dword  msgbox ( l_dword wflags, l_dword  bflags, l_text in_text, 			... );

- show message box, where wflags and bflags are flags defined above and in_text+... is formated text of message box. Return one of values  defined above MSG_XXXX.




l_dword  msgboxsize ( l_rect minx, l_dword wflags, l_dword  bflags, 			    l_text in_text, ... );

- same as msgbox function, but it set minimal size of width to minx, because msgbox set width & height to text.




p_appwin msginfo ( l_rect minx, l_dword wflags, 
			 l_text in_text, ... );

- make messgae box by wflags = MW_INFO and return pointer to this box.




void* show_info ( l_rect minx, l_dword wflags, 
			l_text in_text, ... );

- create message info box and return pointer in (void*). You may later dipose this message box by function hide_info(o)




void  hide_info ( void *o )

- dispose message info box, that was created by function show_info




p_appwin msgprocess ( l_rect minx, l_text process_title, 
			    l_text in_text, l_dword size, l_dword *ind );

- make process window, where (minx) is minimal size of window, process_title is name of window, (in_text) is text for process, (size) is size for process and (ind) is pointer to l_dword variable where we want safe information about process. It return pointer to this window. See also object PROCESS.




void *show_process ( l_text process_tile, l_text in_text, 
			   l_dword size, l_dword *ind )

- make new msgprocess in minimal size (minx = 400). At the and of process, dispose this window by function hide_process(o)




void hide_process ( void *o )

- dispose message process, that was created by function show_process


Example :

l_dword ind = 0;
void *x = show_process("Process", "Calling 1000x", 1000, &ind);

for ((*ind); (*ind) < 1000; (*ind)++) {

	delay(50);

};

hide_process(x);





object FRAME
------------

- it's same as object WINDOW, but it draw frame around the window only. Not draw title and caption. This object is used in imager.c appication that show images on the desktop. You can close this object by ALT+F4 as all windows.

p_window  frame_init ( p_window o, t_rect r );

- return new frame. (r) is area of frame.






object BUTTON
-------------

- I don't know what's the definition of Button ? - It's simple 
BUTTON. I hope that everybody knows what's it. OK. I will explain how 
button works. When you make new button, you must set "message" of 
button. When button is pressed,it make new event with message of 
button. This event is send to object's hierarchy and when some object 
know it, it performs the task.

For button operations use file button.h


p_button  button_init ( p_button o, t_rect r, l_text caption, 
				l_dword message, l_int flags );

- create BUTTON in area (r) by title (cpation) by message (message) and by combination of supported flags :

'BF_NORMAL'      - normal button
'BF_DEFAULT'     - normal button, but when enter in other object in 			 group is pressed it call message (message). In
			 normal mode it call message only if button is
			 focused.
'BF_PUSH'        - button can't be selected. For example close button 
			 of window is set to this flag.
'BF_DARROUND'    - button is double arounded
'BF_UNDERSEL'    - 


struct t_button {


t_view    obclass;

- inherit functions from t_view structure




l_int     flags;

- flags of t_button, you will find above




l_text    caption;

- caption of button




l_dword   message;

- message of button. Message is call whenever is enter or mouse
button pressed in button view. This operation will find it button.c
file in void button_translate_event ( p_object o, p_event event )
function.




void     (*draw_state) ( p_button o, l_int press );

- draw state of button. If press is true, button is pushed, otherwise 
it's normal.




l_bool   (*is_default) ( p_button o );

- return true if button is default in group, when enter is pressed.



} t_button;





MENUS
-----

- hmmmmmm. (It's 6:16 a.m. I'm a little tired. A little ? MUCH ! 
Well, it's better to go to the bed.)

Fine. In the Seal there are two menu types : Vertical menu, Horizontal menu. We will explain all you need to support menu in Seal' application or library. All menus are declared in menus.h include file, you must included before operations with menus.




Information about menu
----------------------

All menus operate with menu' information you set at the begining of  the menu-creating. Use following functions for storing information into the menu.




p_menu      new_menu ( p_menuitem item ); 

- make new section for the menu. (item) is the first item of the menu. Return pointer you will use in initalization menu functions.




p_menuitem  new_menu_line ( p_menuitem next ); 

- make new menu-line. Return pointer to information about menu line.




p_menuitem  new_sub_menu_ex ( l_text name, l_bool enable, 
					l_text info_text, l_font *font, 
					BITMAP *icon, l_font *font_symbol,
					l_byte chr, p_menu menu, 
					p_menuitem next );

- make new submenu. Return pointer to info about this submenu( to new t_menuitem structure ). (name) is name of the item, (enable) is set to true if the item is enable and can be pushed, otherwise is set to false. (info_text) is text that will be showed whenever CTRL+F1 and mouse cursor are under this menu-item. (font) is font that will be used for this item. (icon) is icon of the item. (font_symbol) - sometimes you need to use some of the font symbols instead of the icon. (chr) is character of the symbol. If you not use it, simple set zero. (menu) is new menu that contains other menu-items. (next) is next item in this hierarchy.




p_menuitem  new_menu_item_ex (l_text name, l_text param, 
					l_int hotkey, l_dword message, 
					l_bool enable, l_text info_text, 
					l_int flags, l_font *font,
					BITMAP *icon, 
					l_font *font_symbol,l_byte chr,
					p_menuitem next );

- make new menuitem. Return pointer to info about this item( to new t_menuitem structure ). (name) is the name of the item, (param) is text that will be showed for (hotkey)-what's keycode of the item.(message) is the message that is called even when the item is pushed down.(enable) is set to true if the item is enable and can be pushed, otherwise is set to false. (info_text) is text that will be showed whenever CTRL+F1 and mouse cursor are under this menu-item. (font) is font that will be used for this item. (icon) is icon of the item. (font_symbol) - sometimes you need to use some of the font symbols instead of the icon. (chr) is character of the symbol. If you not use it, simple set zero. (menu) is new menu that contains other menu-items. (next) is next item in this hierarchy.




p_menuitem new_sub_menu ( l_text name, p_menu menu, 
				  p_menuitem next);

- it's short version of new_sub_menu_ex function.




p_menuitem new_menu_item ( l_text name, l_text param, l_int hotkey,
				   l_dword message, l_text info_text,
				   p_menuitem next )

- it's short version of new_menu_item_ex function.




p_menuitem new_menu_check_item ( l_text name, l_text param, 
					 l_bool is_check, l_int hotkey, 
					 l_dword message, l_text info_text,
					 p_menuitem next);

- make new menu check item. This item is same like menuitem, but when you hit it, it shows (~/) - checkbox symbol.



When you have get some action from the menu, you can use the following functions for more information about the action. An Action may be difference by messages, but sometimes you need to distinguish two items that have the same message. The best example is the desktop menu, that contains same messages for file running. You can use these two function for distinguish it:

p_menuitem  menu_get_lastitem_called ( p_menu m );

- return pointer t_menuitem structure, that contains information about last pushed item. When menu was closed without pushing, this return NULL. (m) is pointer to menu, from where you want to check the state. 



l_int       menu_get_item_flags ( p_menu m, l_dword message );

- return (flags) from the item that's defined by the message (message).





t_menuitem structure
--------------------

  p_menuitem next;		- pointer to next item in the hierarchy

  l_text     name;		- name of the item
  l_text     param;		- text for the keycode information
  l_int      hotkey;		- hotkey of the item
  l_dword    message;		- message of the item
  l_bool     enable;		- true if enable, false if disable
  l_bool     lastcall;		- is set, when right this item was 	
					  pushed at the end
  l_text     info_text;		- info text of the menu, you will 						  showed when CTRL+F1 is pressed and 
					  mouse cursor is under the item
  l_int      flags;		- flags of the item. May combination of 
					  the be following :

				MIF_CHECK	 - it's check-item
			      MIF_CHECKOK  - was checked down
				MIF_SELFICON - icon has own memory for BITMAP 
						   in the item

  l_font    *font;		- font of the item
  l_font    *font_symbol;	- font for the symbol
  l_byte     char_symbol;	- symbol
  BITMAP    *icon;		- icon of the item

  l_char     reserved[16];	- used for further versions

  p_menu     submenu;		- pointer to submenu, when item is not 					  menuitem, but submenu




Vertical menu - MENUVIEW
------------------------

- it's like Windows menu you have get by the right mouse-button.



p_menuview  menuview_init ( p_menuview o, t_rect r, p_menu menu );

- this function initialize menu to rect (r). Information about menu are stored in (menu) pointer we explained above. If r.b.x < r.a.x, it automaticaly set r.b.x to minimum width of menu, r.b.y is set automaticaly to minimum height.




Horizontal menu - HORMENU
-------------------------

- it's horizontal menu mainly used at top of the window.



p_menuview  hormenu_init ( p_menuview o, t_rect r, p_menu menu );

- function is same like menuview_init function but optimalized for the horizontal menu.



Example :

t_rect r = rect_assign(100, 100, 0, 0);

p_menu p = new_menu(

                new_menu_item_ex("Hello", NULL, 0, MSG_CLOSE, true,
                                 "Info about Hello", MIF_NONE, 						   font_system_bi, NULL, NULL, 0,
                new_menu_line(
                new_menu_item_ex("Quit", NULL, 0, MSG_QUIT, true,
                                 "This quit Seal", MIF_NONE, 						    font_system_bd, NULL, NULL, 0,
               NULL)))
            );



p_object menu = OBJECT(menuview_init(
                               malloc(sizeof(t_menuview)),
                               r,
                               p)
                        );


/* show menu into the desktop */

desktop->execute_view(desktop, VIEW(menu)); 




object TEXTLINE
---------------

- this object is used for text editing in one line. You are able to set this object for writing or only for reading. This object is declared in the file dialogs.h. TEXTLINE support DRUG&DROP. When text is selected you will copy only selected text, otherwise you will copy all text.




p_textline  textline_init ( p_textline o, t_rect r, l_int limit,
				    l_int flags );

- create new textline to rect (r). (limit) is maximum number of characters, that can be displayed in the current textline. (flags) are settings for the textline, you can use as combination of the following :


'TF_REWRITEUNABLE'  - textline is read-only



If you wan to set text for the textline you can use function :

l_bool textline::set_text ( p_textline o, l_text text );

or set_data function


For getting text use get_data function or textline::text variable.



p_textline  worktextline_init( p_textline o, t_rect r, 
					 l_int limit );

- create new textline, that is not pushed down, but only arrounded by the black rectangle.



Example :

t_rect r = rect_assign(100, 100, 300, 120);

p_textline o = textline_init ( malloc(sizeof(t_textline)), 
					 r, 
					 100, /* limit */
				    	 0); /* rewrite able */

OBJECT(desktop)->insert(OBJECT(desktop), OBJECT(o));

o->set_text("Hello world"); /* set text to "Hello world" */

if ( !strcmp(o->text, "Hello world") ) /* text is "Hello world" ?*/

	o->set_text("Hello Mr. Michal Stencl");




object STATTEXT
---------------

- this object is used for formated text output. You can show text into the window right by this object.


p_stattext stattext_init ( p_stattext o, t_rect r, l_int align,
				   l_text format, ... );


- create new stattext into the rect (r). (align) is one of alignment you will find above ( TX_ALIGN_LEFT, TX_ALIGN_CENTERX, ...). (format) is formated text cooperate with ... Work same as printf function.

or for argument list use :


p_stattext stattext_init_ex ( p_stattext o, t_rect r, l_int align,
					l_text text, va_list argp );



Example :

t_rect r = rect_assign(100, 100, 300, 120);

p_stattext o = stattext_init ( malloc(sizeof(t_stattext)), 
					 r, 
					 TX_ALIGN_CENTERX, /* limit */
				    	 "Hello %s ! It's year %i", 
					 "world", 
					 2000); 

OBJECT(desktop)->insert(OBJECT(desktop), OBJECT(o));




object LISTBOX
--------------

- You can also put the box with some of lists. The list is define by p_list we explained in t_list section. You are able to put the new listbox to your application by function


p_listbox   listbox_init ( p_listbox o, t_rect r, p_list list, 
			 	   l_byte rows, l_int flags );

- where (r) is area, where this listbox will be placed, (list) is list of items that will be shown, (rows) is number of rows. When <=1, it will scroll down and up, otherwise left and right. (flags) can be combination of followings :

LF_UNDERSEL       - select item whenever is mouse under it 
LF_SELECTABLE     - select more item for copying 



p_list must contains compatible record items with t_listbox_item

typedef struct t_listbox_item {

  l_text    name;
  BITMAP   *icon;
  l_bool    sel;
  l_int     flags;

  l_char    reserved[12];

} t_listbox_item;


p_listbox_item   new_listbox_item ( l_text name, BITMAP *icon, 
						l_bool sel, l_int flags );

- make new item. Insert name (name) by function _strdup, icon (icon),  sel if it's selected, (flags) - combination of following :

LIF_MEMORY  - icon has own memory for the item and must be free when 		  item is free


Example :
---------


p_list get_list ( void )
{

   p_list list = list_init(malloc(sizeof(t_list)), 						 	   &free_listbox_item, DAT_LIST); 

   /* list's items->rec will be freed by function free_listbox_item*/

   if ( list ) {

      list->insert(list, new_listbox_item("Name", NULL/*icon*/, 					true, LIF_NONE));
      list->insert(list, new_listbox_item("New Name", NULL/*icon*/, 					true, LIF_NONE));

   };

   return list;

};

t_rect r = rect_assign(100, 100, 200, 200);

p_listbox box = listbox_init(malloc(sizeof(t_listbox)), r, 
					get_list(), 1, 0);

OBJECT(desktop)->insert(OBJECT(desktop), OBJECT(box));




object HISTORY
--------------

- this object is used for pulldown lists, where you will see only a line with selected item and a button. When you pressed the button, list is pulled down. You can use two types of t_history for now. One is by using text writing as in t_textline object and the second one is read-only type.


p_history   history_init ( p_history o, t_rect r, p_list list, 
				   l_int limit, l_int flags );

- init new history object. (r) is rectangular area of the object, (list) is list of pulldown box. (limit) is a limit of maximum characters that can be write in case of writeable history. (flags) may be one or  combination of followings :

HF_NONE			- ZERO
HF_REWRITEUNABLE		- It's readonly history



Example :
---------


p_list get_list ( void )
{

   p_list list = list_init(malloc(sizeof(t_list)), 						 	   &free_listbox_item, DAT_LIST); 

   /* list's items->rec will be freed by function free_listbox_item*/

   if ( list ) {

      list->insert(list, new_listbox_item("Name", NULL/*icon*/, 					true, LIF_NONE));
      list->insert(list, new_listbox_item("New Name", NULL/*icon*/, 					true, LIF_NONE));

   };

   return list;

};


t_rect r = rect_assign(100, 100, 120, 200);

p_history his = history_init(malloc(sizeof(t_history)), r, 
					get_list(), 
				      100,  /* max number of chars in line */
					HF_REWRITEUNABLE); /* readonly ! */

OBJECT(desktop)->insert(OBJECT(desktop), OBJECT(his));

r = rect_assign(100, 130, 200, 150);

his = history_init(malloc(sizeof(t_history)), r, 
					get_list(), 
				      60,  /* max number of chars in line */
					HF_NONE); /* read/write */

OBJECT(desktop)->insert(OBJECT(desktop), OBJECT(his));






object PROCESS
--------------

- used for drawing process status. It's useable in displaying of information about copy status.


p_process  process_init ( p_process o, t_rect r, l_dword size,
				  l_dword *where );

- init object process to area (r). (size) is the end of where. 
For example you can use this argument for size of file. (where) is pointer from 0 to (size). This may be position in file as is copying. 


Example :
---------

l_dword size = 100000;
l_dword pos  = 0;

p_process x = process_init(malloc(sizeof(t_process)), r, size, &pos);

OBJECT(desktop)->insert(OBJECT(desktop), OBJECT(x));

_while ( pos++ < size ); /* multitasking while ( _while ) */








                             ------------------
                            | object hierarchy |
                             ------------------

                                 t_object
                                    |
             drivers - t_mouse - t_view - program - t_keyboard
                                    |
  desktop - t_menuview - t_listbox  - t_window - t_button - t_textline - t_htmload
                |                        |           |
            t_hormenu                 t_appwin     t_icon




drivers
|----------------------|
| t_mouse - mouse      |
| t_keyboard - keyb    |
|                      |
| ...others            |
|----------------------|

program
|-----------------------------------|
| desktop                           |
|                                   |
| ...run drivers translate_events   |
|-----------------------------------|


VISIBLE CLASSES
===============

  o   t_window      - standard dialog window
  o   t_button      - button class
  o   t_textline    - input box, where we can write text
  o   t_appwin      - application window by close button on the right
  o   t_history     - textline with box of other items
  o   t_listbox     - box of items - texts
  o   t_menuview    - vertical menu box
  o   t_hormenu     - horizontal menu
  o   t_icon        - icon class
  o   t_htmload     - HTML 4.0 loader
  o   desktop       - desktop, it's top view for all visible objects




------------------------
  Michal Stencl

