#define GENEVA_COOKIE 0x476E7661L /* "Gnva" */ #define CJar_xbios 0x434A /* "CJ" */ #define CJar_OK 0x6172 /* "ar" */ #define CJar(mode,cookie,value) xbios(CJar_xbios,mode,cookie,value)G_COOKIE *result; Geneva_is_installed =
CJar( 0, GENEVA_COOKIE, &result )==CJar_OK && result!=0L;See the New Data Types section for a description of the G_COOKIE structure.
Extended ob_type(MSB) | ob_type(LSB) | Description | |
---|---|---|---|
X_MOVER | 17 | G_BUTTON | Mover box |
X_RADCHKUND | 18 | G_BUTTON | Radio/checkbox |
X_UNDERLINE | 19 | G_qpRING | Title |
X_GROUP | 20 | G_BUTTON | Outlined group |
X_HELP,/td> | 21 | any | Help key activates |
X_UNDO | 31 | any | Undo key activates |
Bit | Name | Description |
---|---|---|
6 | X_PREFER | Use user-defined fill color/pattern |
7 | X_DRAW3D | Draw the object in 3D |
8 | X_ROUNDED | Draw the object with rounded corners |
8 | X_KBD_EQUIV | Scan for keyboard equivalents, like "C[ancel" (for [Alternate][A]) |
10 | X_SMALLTEXT | Use the small (icon) font. Saves using a TEDINFO. |
Bit | Name | Description |
---|---|---|
14 | X_BOLD | Bold text |
15 | X_ITALICS | Italics text |
ESC, TAB, RET, RETURN, BKSP, BACKSP, DEL, DELETE, HELP, UNDO, INS, INSERT, CLR, HOME, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, ENT, ENTER, KP(, KP), KP/, KP*, KP7, KP8, KP9, KP-, KP4, KP5, KP6, KP+, KP1, KP2, KP3, KP0, KP.
[Shift] up arrow character (ASCII 1) [Control] ^ [Alternate] ~ or the "close box" character (ASCII 7)
Help Help [Help] key Open... ^O [Control][O] Bookmark 1 ~Kp1 [Alternate][1] (keypad 1)The ob_flags bits 13-15 and ob_state bits 8-15 of the menu entry are used internally. This means that if you intend to use this method of keyboard equivalents, the individual menu entries must not use these bits. To prevent one entry from being considered for a keyboard equivalent, in a menu tree which would otherwise use this method, set the entry's ob_state bits 12-15 to 9 (ob_state|=X_MAGIC).
int buf[8]im { AC_OPEN, 5, 0, my_apid, -1 }; appl_write( 5, 16, buf );Sending an AC_OPEN message to a desk accessory will cause it to open if it is not already open, or it will make its window topmost (by sending a WM_TOPPED message) if the desk accessory has a window open. An application will receive a WM_TOPPED message, if it has a window open.
When this happens, "ev_mmgpbuff" word 2 contains the index of the object within the dialog which was selected. If the object was a TOUCHEXIT button and the user double-clicked on it, then bit 15 will be set, similar to the way form_do() works. Word 3 of the message buffer "ev_mmgpbuff" contains the window handle of the window in which the event occurred.
This feature is used in conjunction with the wind_set() option X_WF_DIALOG, described in detail, below.
Portion | Contents |
---|---|
Word 0 | 0xE000 |
Word 3 | The object index of the menu title selected |
Word 4 | The object index of the selected menu item |
Word 5, 6 | The object tree of the menu item selected |
Word 7 | The handle of the window containing the menu |
If the user clicks on one of the normal scroll gadgets or arrows,
a standard WM_ARROWED message is sent to the application.
However, when the user clicks on any other gadget, an
X_WM_SELECTED message is sent:
Word 0: 0xE100 Word 3: The object index of the window tree object the user clicked on.
The message is actually comprised of two parts. When the application sees the X_GET_HELP message, it must then use the appl_read() function to get the entire remainder of the message, whether it intends to use the whole thing or not. The first part of the message is comprised of the following values:
Portion | Contents |
---|---|
Word 0 | 0xE200 |
Word 1 | Application ID |
Word 2 | Length of the second part ofthe message |
Word 3 | Length of the topic portion of the message, including the NUL terminator |
Word 4 | Length of the filename portion of the message, including the NUL terminator |
Word 5 | Upper/lowercase sensitivity. If non-zero, the topic is case-sensitive. |
The second part of the message contains the actual text of the topic and filename fields. This can be read with one or more calls to appl_read().
Example: void read_string( char *s, int max, int size ) { char dummy; if( size<=max ) /* the whole string fits */ appl_read( my_application_id, size, s ); else { /* read what we can */ appl_read( my_application_id, max-1, s ); s[max-1] = '\0'; /* terminate the string */ /* now, get the remaining bytes of the string */ for( size=size-(max-1); size>0; size-- ) appl_read( my_application_id, 1, &dummy ); } } main() { int msgbuf[8], caps_sens; char topic[20], filename[100]; evnt_mesag( msgbuf ); switch( msgbuf[0] ) { case X_GET_HELP: caps_sens = msgbuf[5]; /* Read the topic portion */ read_string( topic, sizeof(topic), msgbuf[3] ); /* Read the filename portion */ read_string( filename, sizeof(filename). msgbuf[4] ); /* Do whatever with it... */
Portion | Contents |
---|---|
Word 0 | 0xE400 |
Word 1/td | Application ID |
Word 2 | 0 |
Word 3 | Handle of the window being affected |
Word 4 | The new offset (in pixels) of the split bar |
The application is then free to either act upon this message and change the split bar position with wind_set( X_WF_HSPLIT, or to ignore the message completely.
See the x_wind_create() function for more information.
See the x_wind_create() function for more information.
Under Geneva, the alert string can contain left bracket ("[") characters within the text of the buttons. These denote the keyboard equivalents to be used for the buttons. For example, this defines an alert with the equivalents [Alternate][H] and [Alternate][Y]:
form_alert( 1, "[1][Hi there!][[Hi!|B[ye!]" );
If an alert button does not contain a pre-defined keyboard equivalent, it will be considered for an automatic keyboard equivalent.
Note:DO NOT use this type of alert string when running without Geneva, as this will have unpredictable results.
Additionally, if an alert would normally not have a default button, Geneva always forces the rightmost button to be the default. For example:
form_alert( 2, "[1][Hi!][OK]" ); /* OK is the default */
These modes allow a program to display a dialog and then quickly undraw the dialog afterward. Example:
OBJECT *tree; GRECT rect; int saved; /* include the border, by using x_form_center */ x_form_center( tree, &rect.g_x, &rect.g_y, &rect.g_w, &rect.g_h ); saved = form_dial( X_FMD_START, 0, 0, 0, 0, rect.g_x, rect.g_y, rect.g_w, rect.g_h ); /* save what's there */ objc_draw( tree, 0, 8, rect.g_x, rect.g_y, rect.g_w, rect.g_h ); /* display the dialog */ form_do( tree, 0 ); /* get user input */ if( saved ) /* was it saved before?*/ form_dial( X_FMD_FINISH, 0, 0, 0, 0, rect.g_x, rect.g_y, rect.g_w, rect.g_h ); /* restore it quickly */ else form_dial( FMD_FINISH, 0, 0, 0, 0, rect.g_x, rect.g_y, rect.g_w, rect.g_h ); /* normal (slow) redraw*/
This same example can be modified to include a mover box, so that the dialog can be moved around on the screen by the user. This example assumes that object #1 of "tree" is a TOUCHEXIT G_BUTTON of extended type X_MOVER:
int delta; /* include the border, by using x_form_center */x_form_center( tree, &rect.g_x, &rect.g_y, &rect.g_w, &rect.g_h ); /* find out how far from the object's border to its position */ delta = tree[0].ob_x - rect.g_x; saved = form_dial( X_FMD_START, 0, 0, 0, 0, rect.g_x, rect.g_y, rect.g_w, rect.g_h ); /* save what's there */ if( !saved ) /* form_dial ran out of memory */ tree[1].ob_flags |= HIDETREE; /* so hide the mover */ else tree[1].ob_flags &= ~HIDETREE; /* otherwise, show it */ objc_draw( tree, 0, 8, rect.g_x, rect.g_y, rect.g_w, rect.g_h ); /* display the dialog */ form_do( tree, 0 ); /* get user input */ /* account for any movement of "tree" by adjusting rect */ rect.g_x = tree[0].ob_x - delta; rect.g_y = tree[0].ob_y - delta; if( saved )...same as before...
Note:If there is a TOUCHEXIT G_BUTTON with
extended type of X_MOVER (which is not hidden) in any tree that
is processed by form_do(), then a successful call to
form_dial( X_FMD_START must be made before the form_do().
beginning of section
top of page
If this function is passed a negative number, it is interpreted as a GEMDOS/BIOS error code, and an appropriate error message is displayed. For instance, the call:
form_error(-33);produces an alert with the text "There is no file with this name".
Several new modes are supported:
hidecount = graf_mouse( X_MGET, MFORM *mouse );
In this mode, if "mouse" is non-zero, then the MFORM it
points to is filled-in with the shape of the last mouse set with
graf_mouse(). "hidecount" gets the number of times the
mouse was hidden using graf_mouse(M_OFF...). If this number is greater than zero, the mouse is hidden that number of times. If it is zero, the mouse is shown once. If it is less than zero, the mouse is "shown" more than once.
graf_mouse( X_MRESET, 0L );
Resets the mouse so that it is "on" just once, and also updates graf_mouse's idea of the hide count.
If the "frames" portion of the ANI_MOUSE structure is one, then no animation is performed. Otherwise, it should be the number of frames contained in the mouse animation sequence. The "delay" value is the number of 50 Hz timer tics to pause between each frame in the animation. The "form" portion of the structure only needs to be initialized for the number of frames, so if there are only two frames, this means that only form[0] and form[1] are used. If a NULL pointer is passed, instead of a pointer to an ANI_MOUSE structure, then the mouse shape is restored to its default.
It doesßot matter if the application which sets a new shape terminates without resetting the mouse shape, as this call allocates memory internally to hold the new shape data.
The meaning of the "gr_slvh" parameter has changed slightly, to provide for real-time updating of sliders:
LSB | 0 for horizontal slider, 1 for vertical |
MSB | 0 for old-style, dotted outline drag box |
1 to describe the area to be scrolled in real-time | |
2 to initialize real-time scrolling | |
3 to process the scroll bar in real time |
1.Call graf_slidebox() with gr_slvh mode 0x1XX (where "XX" is 00 for a horizontal slider, and 01 for vertical). In this mode, the "gr_slparent" parameter describes the size of the entire area to be scrolled, and "gr_slobject" describes the size of the area whict is visible at one time. Both of these values can be in any units the programmer chooses.
2.Call graf_slidebox() with gr_slvh mode 0x2XX. In this mode, "gr_slparent" and "gr_slobject" have the same meaning they normally do. The return value will either be -1, if the user has released the slider, or it will be a number >= 0 which represents the new position of the slider. This number is based on the numbers passed in Step 1. The call does not return until th> slider has either moved enough to change the position within the list, or the mouse button has been released.
3.If the result of the last graf_slidebox() call was -1, then continue on with the rest of the program. Otherwise, perform whatever action is necessary to redraw the list of items, starting at the returned index. The slider position is updated automatically by Geneva; the program must not alter it.
4.Call graf_slidebox() with gr_slvh mode 0x3XX. In this mode, "gr_slparent" and "gr_slobject" have the same meaning they normally do. Go to Step 3.
Example: Process a list of 100 items, 10 of which are visible at once
if( graf_slidebox( 0L, 100, 10, 0x101 ) >= 0 ) { i = graf_slidebox( object_tree, parent_obj, slider_obj, 0x201 ); while( i>=0 ) { redraw_list_starting_at(i); i = graf_slidebox( object_tree, parent_obj, slider_obj, 0x301 ); } }
Resource files larger than 64 kilobytes in size can be loaded by using the following modified resource file header:
typedef struct rshdr2 { unsigned int rsh_vrsn; /* should be 3 */ unsigned int rsh_extvrsn; /* set to "IN" for Interface */ unsigned long rsh_object; unsigned long rsh_tedinfo; unsigned long rsh_iconblk; unsigned long rsh_bitblk; unsigned long rsh_frstr; unsigned long rsh_string; unsigned long rsh_imdata; /* image data */ unsigned long rsh_frimg; unsigned long rsh_trindex; unsigned long rsh_nobs; /* counts of various structs */ unsigned long rsh_ntree; unsigned long rsh_nted; unsigned long rsh_nib; unsigned long rsh_nbb; unsigned long rsh_nstring; unsigned long rsh_nimages; unsigned long rsh_rssize; /* total bytes in resource */ } RSHDR2;
The "rsh_versn" field must be set to 3, and the "rsh_extvrsn" field must be set to X_LONGRSC (0x494E). Note that this header is exactly twice as large as a normal resource file header.
beginning of section
top of page
If "sw_doex" has bit 8 set, then the Psetlimit() value (contained in the second longword of the list pointed to by "sh_wpcmd") will be copied into the program's runtime flags automatically, regardless of whether or not the MiNT kernel is being used.
A program can cause a windowed dialog to scroll by sending a WM_ARROWED message to Geneva, by way of "sw_doex" mode 10 (SHW_SENDTOAES).
Example: int msg[8]; msg[0] = WM_ARROWED; msg[3] = window_handle; msg[4] = WA_UPPAGE; shel_write( SHW_SENDTOAES, 0, 0, (char *)msg, 0L );
In all cases, the wind_get() function can be used to retrieve the following information for a particular window. wind_set() can be used to set the values.
Example: int handle; OBJECT *menu; handle = wind_create( MOVER|X_MENU, 20, 20, 200, 200 ); if( handle>0 ) { wind_set( handle, X_WF_M U, menu ); wind_open( handle, 20, 20, 200, 200 ); }
The "wi_sw1" parameter should have the high word of the address of the object tree containing the dialog. "wi_sw2" contains the low word of the address. If a NULL address is passed, there will be no dialog associated with the window, and it will receive events normally.
If the window does not have horizontal or vertical sliders, then the size of the root object of the dialog will automatically be sized to fit the entire working area of the window. If the window has sliders, then the dialog will automatically scroll and update as the user operates them. No action is necessary on the part of the program.
If the window is open when this call occurs, the entire dialog is always redrawn and the sliders, if present, are updated. All slider updates can be turned off by clearing the X_WTFL_SLIDERS attribute for the window, by way of the x_wind_tree() function.
Refer to the section describing shel_write() for information on how to cause a windowed dialog to scroll by sending a message to Geneva.
Example: int handle; OBJECT dial = { -1, -1, -1, G_BOX, 0, 0, 0x021131L, 0, 0, 1000, 1000 }; /* a large, filled rectangle */ handle = wind_create( MOVER|SIZER|CLOSER|UPARROW|DNARROW|\ VSLIDE|LFARROW|RTARROW|HSLIDE, 20, 20, 200, 200 ); if( handle>0 ) { wind_set( handle, X_WF_DIALOG, &dial ); wind_set( handle, X_WF_DIALHT, 10 ); /* vert. scroll jump */ wind_set( handle, X_WF_DIALWID, 10 ); /* horiz. scroll jump */ wind_open( handle, 20, 20, 200, 200 ); }
Since, by default, Geneva will use a blit operation to move most of a windowed dialog's contents when scrolling, unpredictable redraw errors can occur when redrawing the unblitted area of a dialog, if the dialog uses a patterned fill and X_WF_DIALWID is not a multiple of 16 pixels.
Since, by default, Geneva will use a blit operation to move most
of a windowed dialog's contents when scrolling, unpredictable redraw
errors can occur when redrawing the unblitted area of a dialog, if the
dialog uses a patterned fill and X_WF_DIALWID is not a multiple of 16 pixels.
If the application which has changed the default desktop terminates, the default gray pattern is resumed automatically.
By default, Geneva calculates a minimum window size that is large enough to contain all of the window gadgets without overlapping. The maximum size always defaults to the working area of the entire desktop.
The "wi_sw1" and "wi_sw2" parameters are the minimum window width and height, respectively, and "wi_sw3" and "wi_sw4" are the maximum width and height of the window. Passing a value of -1 in any of these parameters in a call to wind_set() will cause no change to occur in that one value.
The "wi_sw1" parameter is the new location of the bar, in pixels. If the value is zero, the bar will be all the way to the left edge; if it is -1 (which is the default) it will be all the way to the right.
Note: The value returned by wind_get() may not be equal to the value supplied to wind_set(), if the user has either changed the size of the window or if the value was too large or not large enough to exceed the minimum bar position.
See the x_wind_create() function and the X_WF_SPLMIN option, below, for more information.
The "wi_sw1" parameter is the new location of the bar, in pixels. If the value is zero, the bar will be at the very top; if it is -1 (which is the default) it will be at the very bottom. Note that the value returned to wind_get() may not be equal to the value supplied by wind_set(), if the user has either changed the size of the window or if the value was too large or not large enough to exceed the minimum bar position. See the x_wind_create() function and the X_WF_SPLMIN option, below, for more information.
Parameter | Description |
---|---|
wi_sw1 | Minimum width of region to left of horizontal split |
wi_sw2 | Minimum width of region to right of horizontal split |
wi_sw3 | Minimum height of region above vertical split |
wi_sw4 | Minimum height of region below vertical split |
When the user drags a plit bar, these values are checked. He will not be able to drag the bar if it the window is too small to fit two regions having these sizes. When a wind_set() call is made to set the position of one of the split bars, they will be "snapped" to one edge or the other if the position is less than 1/2 of the minimum distance away from the edge. Furthermore, when the window is made smaller, the positions of the split bars are automatically changed so as to satisfy these minimum values. For this reason, a program should never assume that they have not changed.
Passing a value of -1 in any of these parameters in a call to wind_set() will cause no change to occur in that one value.