home *** CD-ROM | disk | FTP | other *** search
- /*************************************
- * *
- * 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);
- }
-