home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
500-599
/
ff562.lza
/
Intuisup
/
Gadgets
/
source.lzh
/
gadgets1.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-25
|
34KB
|
1,227 lines
/*************************************
* *
* Gadgets v2.0 *
* by Torsten Jürgeleit in 05/91 *
* *
* Routines - Part 1 *
* *
*************************************/
/* Includes */
#include <exec/types.h>
#include <exec/memory.h>
#include <devices/inputevent.h>
#include <intuition/intuition.h>
#include <functions.h>
#include <string.h>
#include "/render/render.h"
#include "/texts/texts.h"
#include "gadgets.h"
#include "imports.h"
/* Defines */
#define QUALIFIER_SHIFT (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)
#define QUALIFIER_ALT (IEQUALIFIER_LALT | IEQUALIFIER_RALT)
/* Static data */
STATIC struct VisibleGadgetLists visible_gadget_lists = {
{ /* struct SignalSemaphore vg_Semaphore */
{ /* struct Node ss_Link */
NULL, NULL, NT_SEMAPHORE, 0, NULL
}, 0,
{ /* struct MinList ss_WaitQueue */
(struct MinNode *)&visible_gadget_lists.vg_Semaphore.ss_WaitQueue.mlh_Tail,
NULL,
(struct MinNode *)&visible_gadget_lists.vg_Semaphore.ss_WaitQueue.mlh_Head
},
{ /* struct SemaphoreRequest ss_MultipleLink */
{ /* struct MinNode sr_Link */
NULL, NULL
}, NULL
}, NULL, -1
},
{ /* struct MinList vg_MinList */
(struct MinNode *)&visible_gadget_lists.vg_MinList.mlh_Tail,
NULL,
(struct MinNode *)&visible_gadget_lists.vg_MinList.mlh_Head
}, 0
};
/* Create gadget list */
struct GadgetList *
create_gadgets(struct RenderInfo *ri, struct GadgetData *gd,
SHORT hoffset, SHORT voffset)
{
struct GadgetList *gl;
BYTE *gadget_buffer, *image_buffer = NULL;
USHORT data_entries;
ULONG gl_size, gadget_buffer_size, image_buffer_size;
if (ri && gd && (data_entries = count_gadget_data_entries(gd))) {
gl_size = sizeof(struct GadgetList) + (data_entries - 1) *
sizeof(struct ExtendedGadget *);
if (gl = AllocMem(gl_size, (LONG)MEMF_PUBLIC | MEMF_CLEAR)) {
gl->gl_RenderInfo = ri;
gl->gl_Data = gd;
gl->gl_DataEntries = data_entries;
if ((gadget_buffer_size = get_gadget_buffer_size(gl)) &&
(gadget_buffer = AllocMem(gadget_buffer_size, (LONG)
MEMF_PUBLIC | MEMF_CLEAR))) {
if (image_buffer_size = get_image_buffer_size(gl)) {
image_buffer = AllocMem(image_buffer_size, (LONG)
MEMF_PUBLIC | MEMF_CHIP);
}
if (!image_buffer_size || image_buffer) {
/* init gadget list struct */
gl->gl_GadgetBuffer = gadget_buffer;
gl->gl_GadgetBufferSize = gadget_buffer_size;
gl->gl_ImageBuffer = image_buffer;
gl->gl_ImageBufferSize = image_buffer_size;
init_gadgets(gl, hoffset, voffset);
return(gl);
}
FreeMem(gadget_buffer, gadget_buffer_size);
}
FreeMem(gl, gl_size);
}
}
return(NULL);
}
/* Free gadget list */
VOID
free_gadgets(struct GadgetList *gl)
{
if (gl) {
if (gl->gl_Flags & GADGET_LIST_FLAG_DISPLAYED) {
remove_gadgets(gl);
}
FreeMem(gl->gl_GadgetBuffer, gl->gl_GadgetBufferSize);
if (gl->gl_ImageBufferSize) {
FreeMem(gl->gl_ImageBuffer, gl->gl_ImageBufferSize);
}
FreeMem(gl, (LONG)(sizeof(struct GadgetList) +
(gl->gl_DataEntries - 1) * sizeof(struct ExtendedGadget *)));
}
}
/* Display gadget list */
VOID
display_gadgets(struct Window *win, struct GadgetList *gl)
{
struct VisibleGadgetLists *vg = &visible_gadget_lists;
struct ExtendedGadget *egad, *last_egad = NULL;
USHORT i, data_entries = gl->gl_DataEntries;
if (win && gl && !(gl->gl_Flags & GADGET_LIST_FLAG_DISPLAYED)) {
gl->gl_Window = win;
gl->gl_Flags |= GADGET_LIST_FLAG_DISPLAYED;
ObtainSemaphore(&vg->vg_Semaphore);
AddTail((struct List *)&vg->vg_MinList, (struct Node *)
&gl->gl_MinNode);
vg->vg_Count++;
ReleaseSemaphore(&vg->vg_Semaphore);
/* link gadget list */
for (i = 0; i < data_entries; i++) {
egad = gl->gl_Gadgets[i];
do {
if (last_egad) {
last_egad->eg_Gadget.NextGadget = &egad->eg_Gadget;
}
last_egad = egad;
} while (egad = egad->eg_NextGadget);
}
AddGList(win, &gl->gl_Gadgets[0]->eg_Gadget, -1L, -1L, (LONG)NULL);
refresh_gadgets(gl);
}
}
/* Refresh gadget list */
VOID
refresh_gadgets(struct GadgetList *gl)
{
USHORT i, data_entries = gl->gl_DataEntries;
if (gl && gl->gl_Flags & GADGET_LIST_FLAG_DISPLAYED) {
for (i = 0; i < data_entries; i++) {
refresh_gadget(gl->gl_Gadgets[i]);
}
}
}
/* Set gadget attributes */
ULONG
set_gadget_attributes(struct GadgetList *gl, USHORT data_entry,
ULONG flags, ULONG data1, ULONG data2, VOID *data3)
{
struct Window *win = gl->gl_Window;
struct RastPort *rp;
struct GadgetData *gd;
struct ExtendedGadget *egad, *save_egad;
struct Gadget *gad = NULL;
struct StringInfo *sinfo;
struct List *list;
struct Node *node;
struct MXData *mx;
struct SliderData *sl;
struct ScrollerData *sc;
struct CycleData *cy;
struct CountData *co;
struct ListViewData *lv;
struct PaletteData *pd;
VOID *data;
UBYTE displayed;
BYTE *buffer, *input, **text;
ULONG min, max, num, value = 0;
USHORT i, type;
if (gl && data_entry < gl->gl_DataEntries) {
/* get gadget data */
gd = gl->gl_Data + data_entry;
type = gd->gd_Type;
egad = save_egad = gl->gl_Gadgets[data_entry];
gad = &egad->eg_Gadget;
data = (VOID *)(egad + 1);
if (data1 != USE_CURRENT_VALUE || data2 != USE_CURRENT_VALUE ||
data3 != (VOID *)USE_CURRENT_VALUE) {
switch (type) {
case GADGET_DATA_TYPE_BUTTON :
if (gad->Activation & TOGGLESELECT) {
if (gad->Flags & SELECTED) {
value = 1;
}
if (data1 != USE_CURRENT_VALUE) {
if (data1) {
gad->Flags |= SELECTED;
} else {
gad->Flags &= ~SELECTED;
}
change_gadget(egad);
}
}
break;
case GADGET_DATA_TYPE_CHECK :
if (gad->Flags & SELECTED) {
value = 1;
}
if (data1 != USE_CURRENT_VALUE) {
if (data1) {
gad->Flags |= SELECTED;
} else {
gad->Flags &= ~SELECTED;
}
change_gadget(egad);
}
break;
case GADGET_DATA_TYPE_MX :
mx = data;
value = mx->mx_ActiveEntry;
if (data2 != USE_CURRENT_VALUE) {
max = mx->mx_TextEntries;
num = data2;
if (num >= max) {
num = max - 1; /* activate last entry */
}
mx->mx_ActiveEntry = num;
change_gadget(egad);
}
break;
case GADGET_DATA_TYPE_STRING :
case GADGET_DATA_TYPE_INTEGER :
sinfo = (struct StringInfo *)gad->SpecialInfo;
buffer = (BYTE *)sinfo->Buffer;
if (type == GADGET_DATA_TYPE_STRING) {
value = (ULONG)buffer;
} else {
value = sinfo->LongInt;
}
if ((ULONG)data3 != USE_CURRENT_VALUE) {
max = sinfo->MaxChars;
input = data3;
if (type == GADGET_DATA_TYPE_STRING) {
if (gd->gd_Flags &
GADGET_DATA_FLAG_STRING_UNSIGNED_DEC) {
if ((LONG)input != -1L) {
min = convert_unsigned_dec((ULONG)input, buffer);
} else {
min = 0;
}
} else {
if (gd->gd_Flags &
GADGET_DATA_FLAG_STRING_SIGNED_DEC) {
if ((LONG)input != -1L) {
min = convert_signed_dec((ULONG)input, buffer);
} else {
min = 0;
}
} else {
if (gd->gd_Flags & GADGET_DATA_FLAG_STRING_HEX) {
if ((LONG)input != -1L) {
min = convert_hex((ULONG)input, buffer);
} else {
min = 0;
}
} else {
if (gd->gd_Flags &
GADGET_DATA_FLAG_STRING_BIN) {
if ((LONG)input != -1L) {
min = convert_bin((ULONG)input, buffer);
} else {
min = 0;
}
} else {
if (input) {
if ((min = strlen(input)) > max) {
min = max;
}
strncpy(buffer, input, (size_t)min);
} else {
min = 0;
}
}
}
}
}
} else {
if ((LONG)input != -1L) {
min = convert_unsigned_dec((ULONG)input, buffer);
} else {
min = 0;
}
}
*(buffer + min) = '\0'; /* mark end of string */
sinfo->BufferPos = 0;
change_gadget(egad);
}
break;
case GADGET_DATA_TYPE_SLIDER :
sl = data;
value = sl->sl_Level;
if (data1 != USE_CURRENT_VALUE) {
min = sl->sl_Min = data1;
} else {
min = sl->sl_Min;
}
if (data2 != USE_CURRENT_VALUE) {
max = sl->sl_Max = data2;
} else {
max = sl->sl_Max;
}
if ((ULONG)data3 != USE_CURRENT_VALUE) {
num = (ULONG)data3;
} else {
num = sl->sl_Level;
}
if ((LONG)num < (LONG)min) {
num = min;
} else {
if ((LONG)num > (LONG)max) {
num = max;
}
}
sl->sl_Level = num;
change_gadget(egad);
break;
case GADGET_DATA_TYPE_SCROLLER :
sc = data;
value = sc->sc_Top;
if (data1 != USE_CURRENT_VALUE) {
min = sc->sc_Visible = data1;
} else {
min = sc->sc_Visible;
}
if (data2 != USE_CURRENT_VALUE) {
max = sc->sc_Total = data2;
} else {
max = sc->sc_Total;
}
if ((ULONG)data3 != USE_CURRENT_VALUE) {
num = (ULONG)data3;
} else {
num = sc->sc_Top;
}
if (num >= max || (max - num) < min) {
num = (max > min ? max - min : min - max);
}
sc->sc_Top = num;
change_gadget(egad);
break;
case GADGET_DATA_TYPE_CYCLE :
cy = data;
value = cy->cy_ActiveEntry;
if (data2 != USE_CURRENT_VALUE) {
text = cy->cy_TextArray;
max = cy->cy_TextEntries;
num = data2;
if (num > max) {
num = max; /* activate last entry */
}
cy->cy_ActiveEntry = num;
change_gadget(egad);
}
break;
case GADGET_DATA_TYPE_COUNT :
co = data;
value = co->co_Value;
if ((ULONG)data3 != USE_CURRENT_VALUE) {
min = co->co_Min;
max = co->co_Max;
num = (ULONG)data3;
if ((LONG)num < (LONG)min) {
num = min;
} else {
if ((LONG)num > (LONG)max) {
num = max;
}
}
co->co_Value = num;
change_gadget(egad);
}
break;
case GADGET_DATA_TYPE_LISTVIEW :
lv = data;
value = lv->lv_TopEntry;
if ((ULONG)data3 != USE_CURRENT_VALUE) {
max = 0;
num = 0;
list = data3;
if (list) {
/* count list nodes */
node = list->lh_Head;
while (node = node->ln_Succ) {
max++;
}
}
lv->lv_List = list;
lv->lv_ListEntries = max;
}
if (data2 != USE_CURRENT_VALUE || (ULONG)data3 !=
USE_CURRENT_VALUE) {
list = lv->lv_List;
min = lv->lv_VisibleEntries;
max = lv->lv_ListEntries;
node = NULL;
/* search top list node */
if (max) {
if (data2 != USE_CURRENT_VALUE) {
num = data2;
} else {
num = lv->lv_TopEntry;
}
if (num && max > min) {
if (num > max || (max - num) < min) {
num = max - min;
node = list->lh_TailPred;
for (i = max - num - 1; i; i--) {
node = node->ln_Pred;
}
} else {
node = list->lh_Head;
for (i = 0; i < num; i++) {
node = node->ln_Succ;
}
}
} else {
num = 0;
node = list->lh_Head;
}
}
/* init list view data */
lv->lv_TopEntry = num;
lv->lv_TopNode = node;
change_gadget(egad); /* before changing list entry gadget flags !!! */
/* set GADGHNONE flag for all entry gadgets without list node */
if (!(lv->lv_Flags & GADGET_DATA_FLAG_LISTVIEW_READ_ONLY)) {
egad = egad->eg_NextGadget->eg_NextGadget->eg_NextGadget; /* ptr to first entry gadget */
for (i = 0; i < min; i++, num++) {
gad = &egad->eg_Gadget;
if (num < max) {
gad->Flags = (gad->Flags & ~GADGHIGHBITS) |
GADGHCOMP;
} else {
gad->Flags = (gad->Flags & ~GADGHIGHBITS) |
GADGHNONE;
}
egad = egad->eg_NextGadget;
}
egad = save_egad;
}
}
break;
case GADGET_DATA_TYPE_PALETTE :
pd = data;
value = pd->pd_ActiveColor;
if ((ULONG)data3 != USE_CURRENT_VALUE) {
min = pd->pd_ColorOffset;
max = pd->pd_MaxColors;
num = (ULONG)data3;
if (num < min) {
num = min;
} else {
if (num >= (max + min)) {
num = max + min - 1;
}
}
pd->pd_ActiveColor = num;
change_gadget(egad);
}
break;
}
}
/* toggle able state of gadget */
if (((flags & GADGET_DATA_FLAG_DISABLED) && !(gad->Flags &
GADGDISABLED)) || (!(flags & GADGET_DATA_FLAG_DISABLED) &&
(gad->Flags & GADGDISABLED))) {
if (displayed = gl->gl_Flags & GADGET_LIST_FLAG_DISPLAYED) {
rp = win->RPort;
SetDrMd(rp, (LONG)JAM1);
SetAPen(rp, (LONG)gl->gl_RenderInfo->ri_BackPen);
}
do {
gad = &egad->eg_Gadget;
if (gad->Flags & GADGDISABLED) {
gad->Flags &= ~GADGDISABLED;
/* clear ghosted gadget select box */
if (displayed) {
RectFill(rp, (LONG)gad->LeftEdge, (LONG)gad->TopEdge,
(LONG)(gad->LeftEdge + gad->Width - 1), (LONG)
(gad->TopEdge + gad->Height - 1));
}
} else {
gad->Flags |= GADGDISABLED;
}
} while (egad = egad->eg_NextGadget);
refresh_gadget(save_egad);
}
}
return(value);
}
/* Activate string or integer imput gadget */
VOID
activate_input_gadget(struct GadgetList *gl, USHORT data_entry)
{
struct GadgetData *gd;
struct Gadget *gad;
UBYTE type;
if (data_entry < gl->gl_DataEntries) {
gd = gl->gl_Data + data_entry;
type = gd->gd_Type;
if (type == GADGET_DATA_TYPE_STRING ||
type == GADGET_DATA_TYPE_INTEGER) {
gad = &gl->gl_Gadgets[data_entry]->eg_Gadget;
if (gad->Flags & GADGDISABLED) {
if (gd->gd_Flags & GADGET_DATA_FLAG_INPUT_AUTO_ACTIVATE) {
/* !!! recurrence (in german: Rekursion) !!! */
activate_input_gadget(gl, (USHORT)
gd->gd_SpecialData.gd_InputData.gd_InputActivateNext);
}
} else {
ActivateGadget(gad, gl->gl_Window, (LONG)NULL);
}
}
}
}
/* Return gadget address */
struct Gadget *
gadget_address(struct GadgetList *gl, USHORT data_entry)
{
struct Gadget *gad;
if (data_entry >= gl->gl_DataEntries) {
gad = NULL;
} else {
gad = &gl->gl_Gadgets[data_entry]->eg_Gadget;
}
return(gad);
}
/* Remove gadget list from display */
VOID
remove_gadgets(struct GadgetList *gl)
{
struct VisibleGadgetLists *vg = &visible_gadget_lists;
struct Window *win = gl->gl_Window;
struct ExtendedGadget *egad;
USHORT i, data_entries = gl->gl_DataEntries;
if (gl && data_entries && gl->gl_Flags & GADGET_LIST_FLAG_DISPLAYED) {
ObtainSemaphore(&vg->vg_Semaphore);
Remove((struct Node *)&gl->gl_MinNode);
vg->vg_Count--;
ReleaseSemaphore(&vg->vg_Semaphore);
for (i = 0; i < data_entries; i++) {
egad = gl->gl_Gadgets[i];
do {
RemoveGList(win, &egad->eg_Gadget, 1L);
} while (egad = egad->eg_NextGadget);
}
gl->gl_Flags &= ~GADGET_LIST_FLAG_DISPLAYED;
}
}
/* Get intuition msg and perform any action to isup gadgets */
struct IntuiMessage *
get_msg(struct MsgPort *uport)
{
struct IntuiMessage *real_imsg, *imsg = NULL;
struct GadgetList *gl;
struct ExtendedGadget *egad;
if (uport) {
while (imsg == NULL && (real_imsg = (struct IntuiMessage *)
GetMsg(uport))) {
switch (real_imsg->Class) {
case GADGETDOWN :
egad = (struct ExtendedGadget *)real_imsg->IAddress;
if (egad->eg_Gadget.MutualExclude == ISUP_ID) {
imsg = perform_gadget_action(egad, real_imsg);
if ((egad->eg_Gadget.Activation & FOLLOWMOUSE) ||
egad->eg_Gadget.Activation == (GADGIMMEDIATE |
RELVERIFY)) {
/* save active gadget and set auto repeat delay counter */
gl = egad->eg_GadgetList;
gl->gl_ActiveGadget = egad;
gl->gl_AutoRepeatDelay = ARROW_AUTO_REPEAT_START_DELAY;
}
} else {
egad = NULL; /* return imsg later */
}
break;
case GADGETUP :
egad = (struct ExtendedGadget *)real_imsg->IAddress;
if (egad->eg_Gadget.MutualExclude == ISUP_ID) {
imsg = perform_gadget_action(egad, real_imsg);
/* reset saved active gadget */
egad->eg_GadgetList->gl_ActiveGadget = NULL;
} else {
egad = NULL; /* return imsg later */
}
break;
case MOUSEMOVE :
if (egad = get_active_gadget(real_imsg->IDCMPWindow)) {
imsg = perform_gadget_action(egad, real_imsg);
}
break;
case INTUITICKS :
if ((egad = get_active_gadget(real_imsg->IDCMPWindow))
&& (egad->eg_Gadget.Flags & SELECTED)) {
if (egad->eg_Gadget.Activation == (GADGIMMEDIATE |
RELVERIFY)) {
/* check auto repeat delay counter */
gl = egad->eg_GadgetList;
if (gl->gl_AutoRepeatDelay) {
gl->gl_AutoRepeatDelay--;
} else {
imsg = perform_gadget_action(egad, real_imsg);
}
}
}
break;
case VANILLAKEY :
if (egad = get_hot_key_gadget(real_imsg->IDCMPWindow,
real_imsg->Code)) {
if (!(egad->eg_Gadget.Flags & GADGDISABLED)) {
imsg = perform_hot_key_action(egad, real_imsg);
}
}
break;
default :
if (egad = get_active_gadget(real_imsg->IDCMPWindow)) {
egad->eg_GadgetList->gl_ActiveGadget = NULL;
egad = NULL; /* return imsg later */
}
break;
}
if (!imsg) {
/* if isup msg then reply it, else return it */
if (egad) {
ReplyMsg((struct Message *)real_imsg);
} else {
imsg = real_imsg;
}
}
}
}
return(imsg);
}
/* Reply intuition message and free ISUP message if any */
VOID
reply_msg(struct IntuiMessage *imsg)
{
struct IntuiMessage *real_imsg;
if (imsg) {
if (imsg->Class == ISUP_ID) {
real_imsg = *(struct IntuiMessage **)(imsg + 1); /* real IntuiMessage direct after ISUP intuition message */
FreeMem(imsg, (LONG)(sizeof(struct IntuiMessage) +
sizeof(struct IntuiMessage *)));
imsg = real_imsg;
}
ReplyMsg((struct Message *)imsg);
}
}
/* Perform ISUP gadget action */
STATIC struct IntuiMessage *
perform_gadget_action(struct ExtendedGadget *egad,
struct IntuiMessage *real_imsg)
{
struct IntuiMessage *imsg = NULL;
struct Gadget *gad = &egad->eg_Gadget;
struct GadgetList *gl = egad->eg_GadgetList;
USHORT data_entry = egad->eg_DataEntry;
struct GadgetData *gd = gl->gl_Data + data_entry;
struct ExtendedGadget *real_egad = gl->gl_Gadgets[data_entry];
struct MXData *mx;
struct SliderData *sl;
struct ScrollerData *sc;
struct CycleData *cy;
struct ListViewData *lv;
struct PaletteData *pd;
struct Node *node;
VOID *data = (VOID *)(real_egad + 1);
ULONG min, max, num, value = 0, class = real_imsg->Class,
qualifier = real_imsg->Qualifier;
USHORT i, next_input, type = egad->eg_Type;
switch (type) {
case EXTENDED_GADGET_TYPE_BUTTON :
if ((gd->gd_Flags & GADGET_DATA_FLAG_BUTTON_TOGGLE) &&
gad->Flags & SELECTED) {
value = 1;
}
change_gadget(real_egad);
break;
case EXTENDED_GADGET_TYPE_CHECK :
if (gad->Flags & SELECTED) {
value = 1;
}
break;
case EXTENDED_GADGET_TYPE_MX :
mx = data;
if (mx->mx_ActiveEntry != egad->eg_Gadget.GadgetID) {
mx->mx_ActiveEntry = value = egad->eg_Gadget.GadgetID;
} else {
real_imsg = NULL;
}
change_gadget(real_egad);
break;
case EXTENDED_GADGET_TYPE_STRING :
case EXTENDED_GADGET_TYPE_INTEGER :
if (!(qualifier & QUALIFIER_ALT) && (gd->gd_Flags &
GADGET_DATA_FLAG_INPUT_AUTO_ACTIVATE)) {
if (qualifier & QUALIFIER_SHIFT) {
next_input = gd->gd_SpecialData.gd_InputData.gd_InputActivatePrev;
} else {
next_input = gd->gd_SpecialData.gd_InputData.gd_InputActivateNext;
}
activate_input_gadget(gl, next_input);
}
if (type == EXTENDED_GADGET_TYPE_STRING) {
value = (ULONG)((struct StringInfo *)gad->SpecialInfo)->Buffer;
} else {
value = (ULONG)((struct StringInfo *)gad->SpecialInfo)->LongInt;
}
break;
case EXTENDED_GADGET_TYPE_SLIDER_PROP :
if (class == GADGETUP) {
change_gadget(real_egad);
real_imsg = NULL;
} else {
sl = data;
min = sl->sl_Min;
max = (LONG)sl->sl_Max - (LONG)min;
if (sl->sl_Flags & GADGET_DATA_FLAG_ORIENTATION_VERT) {
num = max - ((LONG)get_prop_pos(max + 1, 1L,
((struct PropInfo *)gad->SpecialInfo)->VertPot) -
(LONG)min);
} else {
num = (LONG)get_prop_pos(max + 1, 1L, ((struct PropInfo *)
gad->SpecialInfo)->HorizPot) + (LONG)min;
}
if (sl->sl_Level != num) {
sl->sl_Level = value = num;
} else {
real_imsg = NULL;
}
}
break;
case EXTENDED_GADGET_TYPE_SCROLLER_PROP :
if (class == GADGETUP) {
change_gadget(real_egad);
real_imsg = NULL;
} else {
sc = data;
min = sc->sc_Visible;
max = sc->sc_Total;
if (sc->sc_Flags & GADGET_DATA_FLAG_ORIENTATION_VERT) {
num = get_prop_pos(max, min, ((struct PropInfo *)
gad->SpecialInfo)->VertPot);
} else {
num = get_prop_pos(max, min, ((struct PropInfo *)
gad->SpecialInfo)->HorizPot);
}
if (sc->sc_Top != num) {
sc->sc_Top = value = num;
} else {
real_imsg = NULL;
}
}
break;
case EXTENDED_GADGET_TYPE_SCROLLER_LEFT :
case EXTENDED_GADGET_TYPE_SCROLLER_DOWN :
if (class == GADGETUP) {
real_imsg = NULL;
} else {
sc = data;
num = sc->sc_Top;
if (num > 0) {
sc->sc_Top = value = num - 1;
change_gadget(real_egad);
} else {
real_imsg = NULL;
}
}
break;
case EXTENDED_GADGET_TYPE_SCROLLER_RIGHT :
case EXTENDED_GADGET_TYPE_SCROLLER_UP :
if (class == GADGETUP) {
real_imsg = NULL;
} else {
sc = data;
num = sc->sc_Top;
min = sc->sc_Visible;
max = sc->sc_Total;
num++;
if (num < max && (max - num) >= min) {
sc->sc_Top = value = num;
change_gadget(real_egad);
} else {
real_imsg = NULL;
}
}
break;
case EXTENDED_GADGET_TYPE_CYCLE :
cy = data;
max = cy->cy_TextEntries;
num = cy->cy_ActiveEntry;
if (real_imsg->Qualifier & QUALIFIER_SHIFT) {
if (num > 0) {
num--;
} else {
num = max - 1;
}
} else {
if (num < (max - 1)) {
num++;
} else {
num = 0;
}
}
cy->cy_ActiveEntry = value = num;
change_gadget(real_egad);
break;
case EXTENDED_GADGET_TYPE_COUNT :
change_count_gadget(real_egad);
value = ((struct CountData *)data)->co_Value;
break;
case EXTENDED_GADGET_TYPE_LISTVIEW_PROP :
if (class == GADGETUP) {
change_gadget(real_egad);
} else {
lv = data;
min = lv->lv_VisibleEntries;
max = lv->lv_ListEntries;
num = get_prop_pos(max, min, ((struct PropInfo *)
gad->SpecialInfo)->VertPot);
if ((min = lv->lv_TopEntry) != num) {
node = lv->lv_TopNode;
if (min > num) {
for (i = min - num; i > 0; i--) {
node = node->ln_Pred;
}
} else {
for (i = num - min; i > 0; i--) {
node = node->ln_Succ;
}
}
lv->lv_TopNode = node;
lv->lv_TopEntry = num;
if (gl->gl_Flags & GADGET_LIST_FLAG_DISPLAYED) {
print_list_view_text(egad);
}
}
}
real_imsg = NULL;
break;
case EXTENDED_GADGET_TYPE_LISTVIEW_UP :
if (class != GADGETUP) {
lv = data;
num = lv->lv_TopEntry;
if (num > 0) {
lv->lv_TopNode = lv->lv_TopNode->ln_Pred;
lv->lv_TopEntry = value = num - 1;
change_gadget(real_egad);
}
}
real_imsg = NULL;
break;
case EXTENDED_GADGET_TYPE_LISTVIEW_DOWN :
if (class != GADGETUP) {
lv = data;
min = lv->lv_VisibleEntries;
max = lv->lv_ListEntries;
num = lv->lv_TopEntry + 1;
if (num < max && (max - num) >= min) {
lv->lv_TopNode = lv->lv_TopNode->ln_Succ;
lv->lv_TopEntry = value = num;
change_gadget(real_egad);
}
}
real_imsg = NULL;
break;
case EXTENDED_GADGET_TYPE_LISTVIEW_ENTRY :
lv = data;
max = lv->lv_ListEntries;
num = lv->lv_TopEntry + egad->eg_Gadget.GadgetID;
if (num < max) {
value = num;
} else {
real_imsg = NULL;
}
break;
case EXTENDED_GADGET_TYPE_PALETTE_INDICATOR :
real_imsg = NULL;
break;
case EXTENDED_GADGET_TYPE_PALETTE_COLOR :
pd = data;
num = egad->eg_Gadget.GadgetID;
if (num != pd->pd_ActiveColor) {
pd->pd_ActiveColor = value = num;
change_gadget(real_egad);
} else {
real_imsg = NULL;
}
break;
}
if (real_imsg) {
imsg = create_intui_message(real_imsg, gl, data_entry, value);
}
return(imsg);
}
/* Perform hot key gadget action */
STATIC struct IntuiMessage *
perform_hot_key_action(struct ExtendedGadget *egad,
struct IntuiMessage *real_imsg)
{
struct IntuiMessage *imsg = NULL;
struct Gadget *gad = &egad->eg_Gadget;
struct GadgetList *gl = egad->eg_GadgetList;
struct Window *win = gl->gl_Window;
struct RastPort *rp = win->RPort;
USHORT data_entry = egad->eg_DataEntry;
struct GadgetData *gd = gl->gl_Data + data_entry;
struct ExtendedGadget *real_egad = gl->gl_Gadgets[data_entry];
struct MXData *mx;
struct SliderData *sl;
struct ScrollerData *sc;
struct CycleData *cy;
struct CountData *co;
struct ListViewData *lv;
struct PaletteData *pd;
struct Node *node;
VOID *data = (VOID *)(real_egad + 1);
USHORT draw_mode, displayed = gl->gl_Flags & GADGET_LIST_FLAG_DISPLAYED;
ULONG min, max, num, value = 0, qualifier = real_imsg->Qualifier &
QUALIFIER_SHIFT;
switch (egad->eg_Type) {
case EXTENDED_GADGET_TYPE_BUTTON :
if (gd->gd_Flags & GADGET_DATA_FLAG_BUTTON_TOGGLE) {
if (gad->Flags & SELECTED) {
gad->Flags &= ~SELECTED;
} else {
gad->Flags |= SELECTED;
value = 1;
}
} else {
if (displayed) {
gad->Flags |= SELECTED;
change_gadget(real_egad);
timer_delay(0L, 100000L);
if ((gad->Flags & GADGHIGHBITS) == GADGHCOMP) {
/* if HIGHCOMP then invert gadget select box manually */
draw_mode = rp->DrawMode;
SetDrMd(win->RPort, (LONG)COMPLEMENT);
RectFill(win->RPort, (LONG)gad->LeftEdge, (LONG)
gad->TopEdge, (LONG)(gad->LeftEdge + gad->Width - 1),
(LONG)(gad->TopEdge + gad->Height - 1));
SetDrMd(win->RPort, (LONG)draw_mode); /* restore old draw mode */
}
gad->Flags &= ~SELECTED;
}
}
change_gadget(real_egad);
break;
case EXTENDED_GADGET_TYPE_CHECK :
if (gad->Flags & SELECTED) {
gad->Flags &= ~SELECTED;
} else {
gad->Flags |= SELECTED;
value = 1;
}
change_gadget(real_egad);
break;
case EXTENDED_GADGET_TYPE_MX :
mx = data;
max = mx->mx_TextEntries;
num = mx->mx_ActiveEntry;
if (qualifier) {
if (num > 0) {
num--;
} else {
num = max - 1;
}
} else {
if (num < (max - 1)) {
num++;
} else {
num = 0;
}
}
mx->mx_ActiveEntry = value = num;
change_gadget(real_egad);
break;
case EXTENDED_GADGET_TYPE_STRING :
case EXTENDED_GADGET_TYPE_INTEGER :
activate_input_gadget(gl, data_entry);
real_imsg = NULL;
break;
case EXTENDED_GADGET_TYPE_SLIDER_PROP :
sl = data;
min = sl->sl_Min;
max = sl->sl_Max;
num = sl->sl_Level;
if (qualifier) {
if ((LONG)num > (LONG)min) {
num--;
} else {
real_imsg = NULL;
}
} else {
if ((LONG)num < (LONG)max) {
num++;
} else {
real_imsg = NULL;
}
}
if (real_imsg) {
sl->sl_Level = value = num;
change_gadget(real_egad);
}
break;
case EXTENDED_GADGET_TYPE_SCROLLER_PROP :
sc = data;
min = sc->sc_Visible;
max = sc->sc_Total;
num = sc->sc_Top;
if (qualifier) {
if (num > 0) {
num--;
} else {
real_imsg = NULL;
}
} else {
if (num < (max - min)) {
num++;
} else {
real_imsg = NULL;
}
}
if (real_imsg) {
sc->sc_Top = value = num;
change_gadget(real_egad);
}
break;
case EXTENDED_GADGET_TYPE_CYCLE :
cy = data;
max = cy->cy_TextEntries;
num = cy->cy_ActiveEntry;
if (qualifier) {
if (num > 0) {
num--;
} else {
num = max - 1;
}
} else {
if (num < (max - 1)) {
num++;
} else {
num = 0;
}
}
cy->cy_ActiveEntry = value = num;
change_gadget(real_egad);
break;
case EXTENDED_GADGET_TYPE_COUNT :
co = data;
min = co->co_Min;
max = co->co_Max;
num = co->co_Value;
if (qualifier) {
if ((LONG)num > (LONG)min) {
num--;
} else {
real_imsg = NULL;
}
} else {
if ((LONG)num < (LONG)max) {
num++;
} else {
real_imsg = NULL;
}
}
if (real_imsg) {
co->co_Value = value = num;
change_gadget(real_egad);
}
break;
case EXTENDED_GADGET_TYPE_LISTVIEW_PROP :
lv = data;
min = lv->lv_VisibleEntries;
max = lv->lv_ListEntries;
num = lv->lv_TopEntry;
node = lv->lv_TopNode;
if (qualifier) {
if (num-- > 0) {
node = node->ln_Pred;
} else {
real_imsg = NULL;
}
} else {
if (++num < max && (max - num) >= min) {
node = node->ln_Succ;
} else {
real_imsg = NULL;
}
}
if (real_imsg) {
lv->lv_TopNode = node;
lv->lv_TopEntry = value = num;
change_gadget(real_egad);
real_imsg = NULL;
}
break;
case EXTENDED_GADGET_TYPE_PALETTE_INDICATOR :
case EXTENDED_GADGET_TYPE_PALETTE_COLOR :
pd = data;
min = pd->pd_ColorOffset;
max = pd->pd_MaxColors;
num = pd->pd_ActiveColor;
if (qualifier) {
if ((LONG)num > (LONG)min) {
num--;
} else {
num = min + max - 1;
}
} else {
if ((LONG)num < (LONG)(min + max - 1)) {
num++;
} else {
num = min;
}
}
pd->pd_ActiveColor = value = num;
change_gadget(real_egad);
break;
}
if (real_imsg) {
imsg = create_intui_message(real_imsg, gl, data_entry, value);
}
return(imsg);
}
/* Create special ISUP intui message */
STATIC struct IntuiMessage *
create_intui_message(struct IntuiMessage *real_imsg, struct GadgetList *gl,
USHORT data_entry, ULONG value)
{
struct IntuiMessage *imsg = NULL;
if (!(imsg = AllocMem((LONG)(sizeof(struct IntuiMessage) +
sizeof(struct IntuiMessage *)), (LONG)MEMF_PUBLIC | MEMF_CLEAR))) {
imsg = real_imsg;
} else {
imsg->Class = ISUP_ID;
imsg->Code = data_entry;
imsg->IAddress = (APTR)value;
imsg->SpecialLink = (struct IntuiMessage *)gl;
*(struct IntuiMessage **)(imsg + 1) = real_imsg; /* real IntuiMessage direct after ISUP intuition message */
}
return(imsg);
}
/* Get active gadget for given window */
STATIC struct ExtendedGadget *
get_active_gadget(struct Window *win)
{
struct VisibleGadgetLists *vg = &visible_gadget_lists;
struct GadgetList *gl;
struct ExtendedGadget *egad = NULL;
USHORT i, count;
ObtainSemaphore(&vg->vg_Semaphore);
if (count = vg->vg_Count) {
gl = (struct GadgetList *)vg->vg_MinList.mlh_Head;
for (i = 0; i < count; i++) {
if (gl->gl_Window == win && gl->gl_ActiveGadget) {
egad = gl->gl_ActiveGadget;
break;
}
gl = (struct GadgetList *)gl->gl_MinNode.mln_Succ;
}
}
ReleaseSemaphore(&vg->vg_Semaphore);
return(egad);
}
/* Get hot key gadget for given window */
STATIC struct ExtendedGadget *
get_hot_key_gadget(struct Window *win, USHORT hot_key)
{
struct VisibleGadgetLists *vg = &visible_gadget_lists;
struct GadgetList *gl;
struct ExtendedGadget *egad, *result_egad = NULL;
USHORT i, j, count, data_entries;
BOOL found = FALSE;
ObtainSemaphore(&vg->vg_Semaphore);
if (count = vg->vg_Count) {
hot_key = toupper(hot_key);
gl = (struct GadgetList *)vg->vg_MinList.mlh_Head;
for (i = 0; i < count && found == FALSE; i++) {
if (gl->gl_Window == win) {
data_entries = gl->gl_DataEntries;
for (j = 0; j < data_entries && found == FALSE; j++) {
egad = gl->gl_Gadgets[j];
if (egad->eg_Flags & EXTENDED_GADGET_FLAG_HOT_KEY &&
toupper(egad->eg_Hotkey) == hot_key) {
result_egad = egad;
found = TRUE;
}
}
}
gl = (struct GadgetList *)gl->gl_MinNode.mln_Succ;
}
}
ReleaseSemaphore(&vg->vg_Semaphore);
return(result_egad);
}