Syntax: | call(a) |
Description: | Call a machine language routine that starts at address a. This routine must execute a RET instruction #C3 to return control to Euphoria. The routine should save and restore any registers that it uses. |
Comments: | You can allocate a block of memory for the routine and then poke in the bytes of machine code. You might allocate other blocks of memory for data and parameters that the machine code can operate on. The addresses of these blocks could be poked into the machine code. |
Example Program: | demo\callmach.ex |
See Also: | allocate, free, peek, poke, poke4, c_proc, define_c_proc |
Platform: | WIN32, Linux, FreeBSD |
Syntax: | include dll.e a = call_back(i) or a = call_back({i1, i}) |
Description: | Get a machine address for the Euphoria routine with routine id i. This address can be used by Windows, or an external C routine in a Windows .dll or Linux/FreeBSD shared library (.so), as a 32-bit "call-back" address for calling your Euphoria routine. On Windows, you can specify i1, which determines the C calling convention that can be used to call your routine. If i1 is '+', then your routine will work with the cdecl calling convention. By default it will work with the stdcall convention. On Linux and FreeBSD you should only use the first form, as there is just one standard calling convention |
Comments: | You can set up as many call-back functions as you like, but they
must all be Euphoria functions (or types) with 0 to 9 arguments.
If your routine has nothing to return (it should really be a procedure),
just return 0 (say), and the calling C routine can ignore the result.
When your routine is called, the argument values will all be 32-bit unsigned (positive) values. You should declare each parameter of your routine as atom, unless you want to impose tighter checking. Your routine must return a 32-bit integer value. You can also use a call-back address to specify a Euphoria routine as an exception handler in the Linux/FreeBSD signal() function. For example, you might want to catch the SIGTERM signal, and do a graceful shutdown. Some Web hosts send a SIGTERM to a CGI process that has used too much CPU time. A call-back routine that uses the cdecl convention and returns a floating-point result, might not work with exw. This is because the Watcom C compiler (used to build exw) has a non-standard way of handling cdecl floating-point return values. |
Example Program: | demo\win32\window.exw, demo\linux\qsort.exu |
See Also: | routine_id, platform.doc |
Platform: | WIN32, Linux, FreeBSD |
Syntax: | a = c_func(i, s) |
Description: | Call the C function, or machine code routine, with routine id i. i must be a valid routine id returned by define_c_func(). s is a sequence of argument values of length n, where n is the number of arguments required by the function. a will be the result returned by the C function. |
Comments: | If the C function does not take any arguments then s should
be {}.
If you pass an argument value which contains a fractional part, where the C function expects a C integer type, the argument will be rounded towards 0. e.g. 5.9 will be passed as 5, -5.9 will be passed as -5. The C function could be part of a .dll created by the Euphoria To C Translator. |
Example: | |
atom user32, hwnd, ps, hdc integer BeginPaint -- open user32.dll - it contains the BeginPaint C function user32 = open_dll("user32.dll") -- the C function BeginPaint takes a C int argument and -- a C pointer, and returns a C int as a result: BeginPaint = define_c_func(user32, "BeginPaint", {C_INT, C_POINTER}, C_INT) -- call BeginPaint, passing hwnd and ps as the arguments, -- hdc is assigned the result: hdc = c_func(BeginPaint, {hwnd, ps}) | |
See Also: | c_proc, define_c_func, open_dll, platform.doc |
Platform: | WIN32, Linux, FreeBSD |
Syntax: | c_proc(i, s) |
Description: | Call the C function, or machine code routine, with routine id i. i must be a valid routine id returned by define_c_proc(). s is a sequence of argument values of length n, where n is the number of arguments required by the function. |
Comments: | If the C function does not take any arguments then s should
be {}.
If you pass an argument value which contains a fractional part, where the C function expects a C integer type, the argument will be rounded towards 0. e.g. 5.9 will be passed as 5, -5.9 will be passed as -5. The C function could be part of a .dll created by the Euphoria To C Translator. |
Example: | |
atom user32, hwnd, rect integer GetClientRect -- open user32.dll - it contains the GetClientRect C function user32 = open_dll("user32.dll") -- GetClientRect is a VOID C function that takes a C int -- and a C pointer as its arguments: GetClientRect = define_c_proc(user32, "GetClientRect", {C_INT, C_POINTER}) -- pass hwnd and rect as the arguments c_proc(GetClientRect, {hwnd, rect}) | |
See Also: | c_func, call, define_c_proc, open_dll, platform.doc |
Syntax: | x = call_func(i, s) |
Description: | Call the user-defined Euphoria function with routine id i. i must be a valid routine id returned by routine_id(). s must be a sequence of argument values of length n, where n is the number of arguments required by function i. x will be the result returned by function i. |
Comments: | If function i does not take any arguments then s should be {}. |
Example Program: | demo\csort.ex |
See Also: | call_proc, routine_id |
Syntax: | call_proc(i, s) |
Description: | Call the user-defined Euphoria procedure with routine id i. i must be a valid routine id returned by routine_id(). s must be a sequence of argument values of length n, where n is the number of arguments required by procedure i. |
Comments: | If procedure i does not take any arguments then s should be {}. |
Example: | |
global integer foo_id procedure x() call_proc(foo_id, {1, "Hello World\n"}) end procedure procedure foo(integer a, sequence s) puts(a, s) end procedure foo_id = routine_id("foo") x() | |
See Also: | call_func, routine_id |
Syntax: | include file.e i = chdir(s) |
Description: | Set the current directory to the path given by sequence s. s must name an existing directory on the system. If successful, chdir() returns 1. If unsuccessful, chdir() returns 0. |
Comments: | By setting the current directory, you can refer to files in that
directory using just the file name.
The function current_dir() will return the name of the current directory. On DOS32 and WIN32 the current directory is a global property shared by all the processes running under one shell. On Linux/FreeBSD, a subprocess can change the current directory for itself, but this won't affect the current directory of its parent process. |
Example: | |
if chdir("c:\\euphoria") then f = open("readme.doc", "r") else puts(1, "Error: No euphoria directory?\n") end if | |
See Also: | current_dir |
Syntax: | include file.e i = check_break() |
Description: | Return the number of times that control-c or control-Break have been pressed since the last call to check_break(), or since the beginning of the program if this is the first call. |
Comments: | This is useful after you have called allow_break(0) which
prevents control-c or control-Break from terminating your
program. You can use check_break() to find out if the user
has pressed one of these keys. You might then perform some action
such as a graceful shutdown of your program.
Neither control-c nor control-Break will be returned as input characters when you read the keyboard. You can only detect them by calling check_break(). |
Example: | |
k = get_key() if check_break() then temp = graphics_mode(-1) puts(1, "Shutting down...") save_all_user_data() abort(1) end if | |
See Also: | allow_break, get_key |
Syntax: | clear_screen() |
Description: | Clear the screen using the current background color (may be set by bk_color()). |
Comments: | This works in all text and pixel-graphics modes. |
See Also: | bk_color, graphics_mode |
Syntax: | close(fn) |
Description: | Close a file or device and flush out any still-buffered characters. |
Comments: | Any still-open files will be closed automatically when your program terminates. |
See Also: | open, flush |
Syntax: | s = command_line() |
Description: | Return a sequence of strings, where each string is a word from the command-line that started your program. The first word will be the path to either the Euphoria executable, ex.exe, exw.exe or exu, or to your bound executable file. The next word is either the name of your Euphoria main file, or (again) the path to your bound executable file. After that will come any extra words typed by the user. You can use these words in your program. |
Comments: | The Euphoria interpreter itself does not use any
command-line options. You are free to use any options for your own program.
The user can put quotes around a series of words to make them into a single argument. If you convert your program into an executable file, either by binding it, or translating it to C, you will find that all command-line arguments remain the same, except for the first two, even though your user no longer types "ex" on the command-line (see examples below). |
Example 1: | |
-- The user types: ex myprog myfile.dat 12345 "the end" cmd = command_line() -- cmd will be: {"C:\EUPHORIA\BIN\EX.EXE", "myprog", "myfile.dat", "12345", "the end"} | |
Example 2: | |
-- Your program is bound with the name "myprog.exe" -- and is stored in the directory c:\myfiles -- The user types: myprog myfile.dat 12345 "the end" cmd = command_line() -- cmd will be: {"C:\MYFILES\MYPROG.EXE", "C:\MYFILES\MYPROG.EXE", -- place holder "myfile.dat", "12345", "the end" } -- Note that all arguments remain the same as example 1 -- except for the first two. The second argument is always -- the same as the first and is inserted to keep the numbering -- of the subsequent arguments the same, whether your program -- is bound or translated as a .exe, or not. | |
See Also: | getenv |
Syntax: | i = compare(x1, x2) |
Description: | Return 0 if objects x1 and x2 are identical, 1 if x1 is greater than x2, -1 if x1 is less than x2. Atoms are considered to be less than sequences. Sequences are compared "alphabetically" starting with the first element until a difference is found. |
Example 1: | |
x = compare({1,2,{3,{4}},5}, {2-1,1+1,{3,{4}},6-1}) -- identical, x is 0 | |
Example 2: | |
if compare("ABC", "ABCD") < 0 then -- -1 -- will be true: ABC is "less" because it is shorter end if | |
Example 3: | |
x = compare({12345, 99999, -1, 700, 2}, {12345, 99999, -1, 699, 3, 0}) -- x will be 1 because 700 > 699 | |
Example 4: | |
x = compare('a', "a") -- x will be -1 because 'a' is an atom -- while "a" is a sequence | |
See Also: | equal, relational operators, operations on sequences |
Syntax: | x2 = cos(x1) |
Description: | Return the cosine of x1, where x1 is in radians. |
Comments: | This function may be applied to an atom or to all elements of a sequence. |
Example: | |
x = cos({.5, .6, .7}) -- x is {0.8775826, 0.8253356, 0.7648422} | |
See Also: | sin, tan, log, sqrt |
Syntax: | include machine.e crash_file(s) |
Description: | Specify a file name, s, for holding error diagnostics if Euphoria must stop your program due to a compile-time or run-time error. |
Comments: | Normally Euphoria prints a diagnostic message such as
"syntax error" or "divide by zero" on the screen, as well as
dumping debugging information into
ex.err in the current directory.
By calling crash_file()
you can control the directory and file name where the debugging information
will be written.
s may be empty, i.e. "". In this case no diagnostics or debugging information will be written to either a file or the screen. s might also be "NUL" or "/dev/null", in which case diagnostics will be written to the screen, but the ex.err information will be discarded. You can call crash_file() as many times as you like from different parts of your program. The file specified by the last call will be the one used. |
Example: | |
crash_file("\\tmp\\mybug") | |
See Also: | abort, crash_message, crash_routine, debugging and profiling |
Syntax: | include machine.e crash_message(s) |
Description: | Specify a string, s, to be printed on the screen in the event that Euphoria must stop your program due to a run-time error. |
Comments: | Normally Euphoria prints a diagnostic message such as
"subscript out of bounds", or "divide by zero" on the screen,
as well as dumping debugging information into
ex.err. Euphoria's error
messages will not be meaningful for your users unless they
happen to be Euphoria programmers. By calling crash_message()
you can control the message that will appear on the screen.
Debugging information will still be stored in
ex.err. You won't
lose any information by doing this.
s may contain '\n', new-line characters, so your message can span several lines on the screen. Euphoria will switch to the top of a clear text-mode screen before printing your message. You can call crash_message() as many times as you like from different parts of your program. The message specified by the last call will be the one displayed. |
Example: | |
crash_message("An unexpected error has occurred!\n" & "Please contact john_doe@whoops.com\n" & "Do not delete the file \"ex.err\".\n") | |
See Also: | abort, crash_file, crash_routine, debugging and profiling |
Syntax: | include machine.e crash_routine(i) |
Description: | Pass the routine id of a function that you want Euphoria to call in the event that a run-time error is detected and your program must be shut down. Your function should take one argument of type object. The object that is passed to your function is currently always 0. In future releases of Euphoria, a more meaningful value may be passed. You can call crash_routine many times with many different routine id's. When a crash occurs, Euphoria will call your crash routines, the most recently specified first, working back to the first one specified. Normally each routine should return 0. If any routine returns a non-zero value, the chain of calls will terminate immediately. |
Comments: | By specifying a crash routine, you give your program a chance to
handle fatal run-time errors, such as subscript out of bounds,
in a more graceful way. You might save some critical data to disk.
You might inform the user about what has happened, and what he can
do about it. You might also save some key debugging information.
In fact, when your crash routine is called, ex.err will have already
been written. Your crash routine could save ex.err somewhere,
or even open it and extract information from it, such as the
error message.
crash_routine can be used with the Interpreter or the Translator. Translated code does not check for as many run-time errors, and does not provide a full ex.err dump, but machine-level exceptions are caught, and a crash routine will give you an excellent opportunity to save some variable values to disk for debugging. The developer of a library might want to specify a crash routine for his library. It could tidy things up by unlocking and closing files, releasing resources etc. The developer of the main program could have his own crash routine. Both routines would be called by Euphoria, unless the first one called (the last one specified) returned non-zero. A crash routine can't resume execution at the point of the crash, but there is no limitation on what else it can do. It doesn't have to return. It could even reinitialize global variables and effectively restart the program. If another error occurs while a crash routine is running, a new error dump will occur, but the file name this time will be ex_crash.err, rather than ex.err. At this point no more calls to crash routines will be allowed. You will have to look at both ex.err and ex_crash.err to fully understand what took place. |
Example: | |
function crash(object x) -- in case of fire ... -- (on Linux) send an e-mail containing ex.err system("mail -s \"crash!\" myname@xxx.com < ex.err > /dev/null", 2) return 0 end function crash_routine(routine_id("crash")) | |
See Also: | abort, crash_file, crash_message, debugging and profiling |
Syntax: | include file.e s = current_dir() |
Description: | Return the name of the current working directory. |
Comments: | There will be no slash or backslash on the end of the current directory, except under DOS/Windows, at the top-level of a drive, e.g. C:\ |
Example: | |
sequence s s = current_dir() -- s would have "C:\EUPHORIA\DOC" if you were in that directory | |
See Also: | dir, chdir, getenv |
Platform: | WIN32, DOS32 |
Syntax: | include graphics.e cursor(i) |
Description: | Select a style of cursor. graphics.e contains: |
global constant NO_CURSOR = #2000, UNDERLINE_CURSOR = #0607, THICK_UNDERLINE_CURSOR = #0507, HALF_BLOCK_CURSOR = #0407, BLOCK_CURSOR = #0007 | |
The second and fourth hex digits (from the left) determine the top and bottom rows of pixels in the cursor. The first digit controls whether the cursor will be visible or not. For example, #0407 turns on the 4th through 7th rows. | |
Comments: | In pixel-graphics modes no cursor is displayed. |
Example: | |
cursor(BLOCK_CURSOR) | |
See Also: | graphics_mode, text_rows |
Syntax: | include sort.e s2 = custom_sort(i, s1) |
Description: | Sort the elements of sequence s1, using a compare function with routine id i. |
Comments: | Your compare function must be a function of two arguments similar to Euphoria's compare(). It will compare two objects and return -1, 0 or +1. |
Example Program: | demo\csort.ex |
See Also: | sort, compare, routine_id |
Syntax: | s = date() |
Description: | Return a sequence with the following information: |
{ year, -- since 1900 month, -- January = 1 day, -- day of month, starting at 1 hour, -- 0 to 23 minute, -- 0 to 59 second, -- 0 to 59 day of the week, -- Sunday = 1 day of the year} -- January 1st = 1 | |
Example: | |
now = date() -- now has: {95,3,24,23,47,38,6,83} -- i.e. Friday March 24, 1995 at 11:47:38pm, day 83 of the year | |
Comments: | The value returned for the year is actually the number of years since 1900 (not the last 2 digits of the year). In the year 2000 this value will be 100. In 2001 it will be 101, etc. |
See Also: | time |
Syntax: | include dll.e i1 = define_c_func(x1, x2, s1, i2) |
Description: | Define the characteristics of either a C function, or a machine-code
routine that returns a value. A small integer, i1,
known as a routine id, will be
returned. Use this routine id as the first argument to c_func() when
you wish to call the function from Euphoria.
When defining a C function, x1 is the address of the library containing the C function, while x2 is the name of the C function. x1 is a value returned by open_dll(). If the C function can't be found, -1 will be returned as the routine id. On Windows, you can add a '+' character as a prefix to the function name. This indicates to Euphoria that the function uses the cdecl calling convention. By default, Euphoria assumes that C routines accept the stdcall convention. When defining a machine code routine, x1 must be the empty sequence, "" or {}, and x2 indicates the address of the machine code routine. You can poke the bytes of machine code into a block of memory reserved using allocate(). On Windows, the machine code routine is normally expected to follow the stdcall calling convention, but if you wish to use the cdecl convention instead, you can code {'+', address} instead of address for x2. s1 is a list of the parameter types for the function. i2 is the return type of the function. A list of C types is contained in dll.e, and these can be used to define machine code parameters as well: |
global constant C_CHAR = #01000001, C_UCHAR = #02000001, C_SHORT = #01000002, C_USHORT = #02000002, C_INT = #01000004, C_UINT = #02000004, C_LONG = C_INT, C_ULONG = C_UINT, C_POINTER = C_ULONG, C_FLOAT = #03000004, C_DOUBLE = #03000008 | |
The C function that you define could be one created by the Euphoria To C Translator, in which case you can pass Euphoria data to it, and receive Euphoria data back. A list of Euphoria types is contained in dll.e: | |
global constant E_INTEGER = #06000004, E_ATOM = #07000004, E_SEQUENCE= #08000004, E_OBJECT = #09000004 | |
Comments: | You can pass or return any C integer type or pointer type.
You can also pass a Euphoria atom as a C double or float, and get
a C double or float returned to you as a Euphoria atom.
Parameter types which use 4 bytes or less are all passed the same way, so it is not necessary to be exact when choosing a 4-byte parameter type. However the distinction between signed and unsigned may be important when you specify the return type of a function. Currently, there is no way to pass a C structure by value or get a C structure as a return result. You can only pass a pointer to a structure and get a pointer to a structure as a result. If you are not interested in using the value returned by the C function, you should instead define it with define_c_proc() and call it with c_proc(). If you use exw to call a cdecl C routine that returns a floating-point value, it might not work. This is because the Watcom C compiler (used to build exw) has a non-standard way of handling cdecl floating-point return values. Passing floating-point values to a machine code routine will be faster if you use c_func() rather than call() to call the routine, since you won't have to use atom_to_float64() and poke() to get the floating-point values into memory. ex.exe (DOS) uses calls to WATCOM floating-point routines (which then use hardware floating-point instructions if available), so floating-point values are generally passed and returned in integer register-pairs rather than floating-point registers. You'll have to disassemble some Watcom code to see how it works. |
Example: | |
atom user32 integer LoadIcon -- open user32.dll - it contains the LoadIconA C function user32 = open_dll("user32.dll") -- It takes a C pointer and a C int as parameters. -- It returns a C int as a result. LoadIcon = define_c_func(user32, "LoadIconA", {C_POINTER, C_INT}, C_INT) -- We use "LoadIconA" here because we know that LoadIconA -- needs the stdcall convention, as do -- all standard .dll routines in the WIN32 API. -- To specify the cdecl convention, we would have used "+LoadIconA". if LoadIcon = -1 then puts(1, "LoadIconA could not be found!\n") end if | |
See Also: | euphoria\demo\callmach.ex, c_func, define_c_proc, c_proc, open_dll, platform.doc |
Syntax: | include dll.e i1 = define_c_proc(x1, x2, s1) |
Description: | Define the characteristics of either a C function, or a machine-code routine
that you wish to call as a procedure from your Euphoria program.
A small integer, known as
a routine id,
will be returned. Use this routine id as the first argument to
c_proc() when you wish to call the routine from Euphoria.
When defining a C function, x1 is the address of the library containing the C function, while x2 is the name of the C function. x1 is a value returned by open_dll(). If the C function can't be found, -1 will be returned as the routine id. On Windows, you can add a '+' character as a prefix to the function name. This tells Euphoria that the function uses the cdecl calling convention. By default, Euphoria assumes that C routines accept the stdcall convention. When defining a machine code routine, x1 must be the empty sequence, "" or {}, and x2 indicates the address of the machine code routine. You can poke the bytes of machine code into a block of memory reserved using allocate(). On Windows, the machine code routine is normally expected to follow the stdcall calling convention, but if you wish to use the cdecl convention instead, you can code {'+', address} instead of address. s1 is a list of the parameter types for the function. A list of C types is contained in dll.e, and shown above. These can be used to define machine code parameters as well. |
The C function that you define could be one created by the Euphoria To C Translator, in which case you can pass Euphoria data to it, and receive Euphoria data back. A list of Euphoria types is contained in dll.e, and shown above. | |
Comments: | You can pass any C integer type or pointer type.
You can also pass a Euphoria atom as a C double or float.
Parameter types which use 4 bytes or less are all passed the same way, so it is not necessary to be exact. Currently, there is no way to pass a C structure by value. You can only pass a pointer to a structure. The C function can return a value but it will be ignored. If you want to use the value returned by the C function, you must instead define it with define_c_func() and call it with c_func(). |
Example: | |
atom user32 integer ShowWindow -- open user32.dll - it contains the ShowWindow C function user32 = open_dll("user32.dll") -- It has 2 parameters that are both C int. ShowWindow = define_c_proc(user32, "ShowWindow", {C_INT, C_INT}) -- If ShowWindow used the cdecl convention, -- we would have coded "+ShowWindow" here if ShowWindow = -1 then puts(1, "ShowWindow not found!\n") end if | |
See Also: | c_proc, define_c_func, c_func, open_dll, platform.doc |
Platform: | WIN32, Linux, FreeBSD |
Syntax: | include dll.e a1 = define_c_var(a2, s) |
Description: | a2 is the address of a Linux or FreeBSD shared library, or Windows .dll, as returned by open_dll(). s is the name of a global C variable defined within the library. a1 will be the memory address of variable s. |
Comments: | Once you have the address of a C variable, and you know its type, you can use peek() and poke() to read or write the value of the variable. |
Example Program: | euphoria/demo/linux/mylib.exu |
See Also: | c_proc, define_c_func, c_func, open_dll, platform.doc |
Syntax: | include file.e x = dir(st) |
Description: | Return directory information for the file or directory named by
st. If there is no file or directory with this name then -1 is
returned. On Windows and DOS st can contain * and ? wildcards to select multiple
files.
This information is similar to what you would get from the DOS DIR command. A sequence is returned where each element is a sequence that describes one file or subdirectory. If st names a directory you may have entries for "." and "..", just as with the DOS DIR command. If st names a file then x will have just one entry, i.e. length(x) will be 1. If st contains wildcards you may have multiple entries. Each entry contains the name, attributes and file size as well as the year, month, day, hour, minute and second of the last modification. You can refer to the elements of an entry with the following constants defined in file.e: |
global constant D_NAME = 1, D_ATTRIBUTES = 2, D_SIZE = 3, D_YEAR = 4, D_MONTH = 5, D_DAY = 6, D_HOUR = 7, D_MINUTE = 8, D_SECOND = 9 | |
The attributes element is a string sequence containing characters chosen from: | |
'd' -- directory 'r' -- read only file 'h' -- hidden file 's' -- system file 'v' -- volume-id entry 'a' -- archive file | |
A normal file without special attributes would just have an empty string, "", in this field. | |
Comments: | The top level directory, e.g. c:\ does not have "." or ".."
entries.
This function is often used just to test if a file or directory exists. Under WIN32, st can have a long file or directory name anywhere in the path. Under Linux/FreeBSD, the only attribute currently available is 'd'. DOS32: The file name returned in D_NAME will be a standard DOS 8.3 name. (See Archive Web page for a better solution). WIN32: The file name returned in D_NAME will be a long file name. |
Example: | |
d = dir(current_dir()) -- d might have: { {".", "d", 0 1994, 1, 18, 9, 30, 02}, {"..", "d", 0 1994, 1, 18, 9, 20, 14}, {"fred", "ra", 2350, 1994, 1, 22, 17, 22, 40}, {"sub", "d" , 0, 1993, 9, 20, 8, 50, 12} } d[3][D_NAME] would be "fred" | |
Example Program: | bin\search.ex |
See Also: | wildcard_file, current_dir, open |
Platform: | DOS32 |
Syntax: | include image.e display_image(s1, s2) |
Description: | Display at point s1 on a pixel-graphics screen the 2-d sequence of pixels contained in s2. s1 is a two-element sequence {x, y}. s2 is a sequence of sequences, where each sequence is one horizontal row of pixel colors to be displayed. The first pixel of the first sequence is displayed at s1. It is the top-left pixel. All other pixels appear to the right or below of this point. |
Comments: | s2 might be the result of a previous call to save_image(), or
read_bitmap(), or it could be something you have created.
The sequences (rows) of the image do not have to all be the same length. |
Example: | |
display_image({20,30}, {{7,5,9,4,8}, {2,4,1,2}, {1,0,1,0,4,6,1}, {5,5,5,5,5,5}}) -- This will display a small image containing 4 rows of -- pixels. The first pixel (7) of the top row will be at -- {20,30}. The top row contains 5 pixels. The last row -- contains 6 pixels ending at {25,33}. | |
Example Program: | demo\dos32\bitmap.ex |
See Also: | save_image, read_bitmap, display_text_image |
Syntax: | include image.e display_text_image(s1, s2) |
Description: | Display the 2-d sequence of characters and attributes contained in s2 at line s1[1], column s1[2]. s2 is a sequence of sequences, where each sequence is a string of characters and attributes to be displayed. The top-left character is displayed at s1. Other characters appear to the right or below this position. The attributes indicate the foreground and background color of the preceding character. On DOS32, the attribute should consist of the foreground color plus 16 times the background color. |
Comments: | s2 would normally be the result of a previous call to
save_text_image(), although you could construct it yourself.
This routine only works in text modes. You might use save_text_image()/display_text_image() in a text-mode graphical user interface, to allow "pop-up" dialog boxes, and drop-down menus to appear and disappear without losing what was previously on the screen. The sequences of the text image do not have to all be the same length. |
Example: | |
clear_screen() display_text_image({1,1}, {{'A', WHITE, 'B', GREEN}, {'C', RED+16*WHITE}, {'D', BLUE}}) -- displays: AB C D -- at the top left corner of the screen. -- 'A' will be white with black (0) background color, -- 'B' will be green on black, -- 'C' will be red on white, and -- 'D' will be blue on black. | |
See Also: | save_text_image, display_image, put_screen_char |
Platform: | DOS32 |
Syntax: | include machine.e s2 = dos_interrupt(i, s1) |
Description: | Call DOS software interrupt number i. s1 is a 10-element sequence of 16-bit register values to be used as input to the interrupt routine. s2 is a similar 10-element sequence containing output register values after the call returns. machine.e has the following declaration which shows the order of the register values in the input and output sequences. |
global constant REG_DI = 1, REG_SI = 2, REG_BP = 3, REG_BX = 4, REG_DX = 5, REG_CX = 6, REG_AX = 7, REG_FLAGS = 8, REG_ES = 9, REG_DS = 10 | |
Comments: | The register values returned in s2 are always positive values
between 0 and #FFFF (65535).
The flags value in s1[REG_FLAGS] is ignored on input. On output the least significant bit of s2[REG_FLAGS] has the carry flag, which usually indicates failure if it is set to 1. Certain interrupts require that you supply addresses of blocks of memory. These addresses must be conventional, low-memory addresses. You can allocate/deallocate low-memory using allocate_low() and free_low(). With DOS software interrupts you can perform a wide variety of specialized operations, anything from formatting your floppy drive to rebooting your computer. For documentation on these interrupts consult a technical manual such as Peter Norton's "PC Programmer's Bible", or download Ralf Brown's Interrupt List from the Web: http://www.cs.cmu.edu/afs/cs.cmu.edu/user/ralf/pub/WWW/files.html |
Example: | |
sequence registers registers = repeat(0, 10) -- no registers need to be set -- call DOS interrupt 5: Print Screen registers = dos_interrupt(#5, registers) | |
Example Program: | demo\dos32\dosint.ex |
See Also: | allocate_low, free_low |
Platform: | DOS32 |
Syntax: | include graphics.e draw_line(i, s) |
Description: | Draw a line on a pixel-graphics screen connecting two or more points in s, using color i. |
Example: | |
draw_line(WHITE, {{100, 100}, {200, 200}, {900, 700}}) -- This would connect the three points in the sequence using -- a white line, i.e. a line would be drawn from {100, 100} to -- {200, 200} and another line would be drawn from {200, 200} to -- {900, 700}. | |
See Also: | polygon, ellipse, pixel |