// Render an object to the main window void backdrop_render_object( BackdropInfo *info, BackdropObject *object, UWORD flags) { // Lock window GetSemaphore(&info->window_lock,SEMF_EXCLUSIVE,0); // Window open? if (info->window) { // Install clip? if (flags&BRENDERF_CLIP && info->clip_region) InstallClipRegion(info->window->WLayer,info->clip_region); // Draw object backdrop_draw_object( info, object, flags|BRENDERF_REAL, &info->rp, object->pos.Left, object->pos.Top); // Remove clip region if (flags&BRENDERF_CLIP && info->clip_region) InstallClipRegion(info->window->WLayer,0); } // Unlock window FreeSemaphore(&info->window_lock); }
VOID DoHouseKeeping(BOOL Manual) { time_t NOW; UpdateWP(); DeleteLogFiles(); RemoveKilledMessages(); ExpireMessages(); GetSemaphore(&AllocSemaphore, 0); ExpireBIDs(); FreeSemaphore(&AllocSemaphore); if (LatestMsg > MaxMsgno) { GetSemaphore(&MsgNoSemaphore, 0); GetSemaphore(&AllocSemaphore, 0); Renumber_Messages(); FreeSemaphore(&AllocSemaphore); FreeSemaphore(&MsgNoSemaphore); } if (!SuppressMaintEmail) MailHousekeepingResults(); LastHouseKeepingTime = NOW = time(NULL); #ifndef LINBPQ if (Manual) DialogBox(hInst, MAKEINTRESOURCE(IDD_MAINTRESULTS), hWnd, HKDialogProc); #endif if (SendWP) CreateWPMessage(); return; }
// Close a lister display void lister_close(Lister *lister,BOOL run_script) { // Lock window GetSemaphore(&lister->backdrop_info->window_lock,SEMF_EXCLUSIVE,0); // Close window lister_close_window(lister,run_script); // Unlock window FreeSemaphore(&lister->backdrop_info->window_lock); }
// Unlock a list/lock void unlock_listlock(struct ListLock *list) { FreeSemaphore(&list->lock); /* // Check list integrity if (list->list.lh_TailPred->ln_Succ!=(struct Node *)&list->list.lh_Tail || list->list.lh_Head->ln_Pred!=(struct Node *)&list->list.lh_Head) { D(bug("*** List integrity failure\n")); } */ }
// Allocate a filerequester APTR alloc_filereq(void) { struct IBox coords; // Get current requester coordinates GetSemaphore(&GUI->req_lock,SEMF_SHARED,0); coords=GUI->req_coords; FreeSemaphore(&GUI->req_lock); // Allocate filerequester return AllocAslRequestTags( ASL_FileRequest, ASLFR_InitialLeftEdge,coords.Left, ASLFR_InitialTopEdge,coords.Top, ASLFR_InitialWidth,coords.Width, ASLFR_InitialHeight,coords.Height, TAG_END); }
// Open a lister display struct Window *lister_open(Lister *lister,struct Screen *screen) { struct Window *window; // No screen? if (!screen && !(screen=GUI->screen_pointer)) return 0; // Lock window GetSemaphore(&lister->backdrop_info->window_lock,SEMF_EXCLUSIVE,0); // Open window window=lister_open_window(lister,screen); // Unlock window FreeSemaphore(&lister->backdrop_info->window_lock); return window; }
// Solicit a font short request_font( struct Window *parent, char *title, char *buffer, short *size, ULONG flags, unsigned short font_pen_count, unsigned char *font_pen_table, short *fpen, short *bpen) { struct IBox coords; struct FontRequester *fontreq; short ret; // Get current requester coordinates GetSemaphore(&GUI->req_lock,SEMF_SHARED,0); coords=GUI->req_coords; FreeSemaphore(&GUI->req_lock); // Allocate fontrequester if (!(fontreq=AllocAslRequestTags(ASL_FontRequest, ASLFO_Window,parent, ASLFO_TitleText,title, ASLFO_InitialName,buffer, ASLFO_InitialSize,*size, ASLFO_Flags,flags|FOF_PRIVATEIDCMP, ASLFO_InitialLeftEdge,coords.Left, ASLFO_InitialTopEdge,coords.Top, ASLFO_InitialWidth,coords.Width, ASLFO_InitialHeight,coords.Height, ASLFO_MaxFrontPen,font_pen_count, ASLFO_MaxBackPen,font_pen_count, ASLFO_FrontPens,font_pen_table, ASLFO_BackPens,font_pen_table, ASLFO_InitialFrontPen,(fpen)?*fpen:0, ASLFO_InitialBackPen,(bpen)?*bpen:0, TAG_END))) { return 0; } // Display requester ret=AslRequest(fontreq,0); // Success? if (ret) { // Store new font strcpy(buffer,fontreq->fo_Attr.ta_Name); *size=fontreq->fo_Attr.ta_YSize; // Store colours if (fpen) *fpen=map_font_colour(fontreq->fo_FrontPen); if (bpen) *bpen=map_font_colour(fontreq->fo_BackPen); } // Save coordinates GetSemaphore(&GUI->req_lock,SEMF_EXCLUSIVE,0); GUI->req_coords=*((struct IBox *)&fontreq->fo_LeftEdge); FreeSemaphore(&GUI->req_lock); // Free font requester FreeAslRequest(fontreq); return ret; }
// add a variable to the environment or alias to the alias list int add_list( char *envstr, PCH pchList ) { char *line; PCH feptr, env_arg, env_end, last_var; unsigned int length; int rval = 0; ULONG size; // size of environment or alias blocks // OS/2 & NT need semaphores to keep processes from simultaneously // writing the alias list HMTX SemHandle = 0; char szVarName[32]; if ( pchList == 0L ) pchList = glpEnvironment; line = envstr; if ( *line == '=' ) { return ( error( ERROR_4DOS_BAD_SYNTAX, envstr )); } for ( ; (( *line ) && ( *line != '=' )); line++ ) { if ( pchList == glpAliasList ) { if ( iswhite( *line )) { strcpy( line, skipspace( line ) ); break; } } else // ensure environment entry is in upper case *line = (unsigned char)_ctoupper( *line ); } if ( *line == '=' ) { // point to the first char of the argument line++; // collapse whitespace around '=' in aliases, but not in env // variables, for COMMAND.COM compatibility (set abc def= ghi) if ( pchList == glpAliasList ) strcpy( line, skipspace( line )); } else if ( *line ) { // add the missing '=' strins( line, "=" ); line++; } // removing single back quotes at the beginning and end of an alias // argument (they're illegal there; the user is probably making a // mistake with ALIAS /R) if (( *line == SINGLE_QUOTE ) && ( pchList == glpAliasList )) { // remove leading single quote strcpy( line, line + 1 ); // remove trailing single quote if ((( length = strlen( line )) != 0 ) && ( line[--length] == SINGLE_QUOTE )) line[length] = '\0'; } // block other processes & threads while updating alias list if ( pchList == glpAliasList ) { // disable signals temporarily HoldSignals(); // get & lock a semaphore RequestSemaphore( &SemHandle, SEMAPHORE_NAME ); } // get pointers to beginning & end of alias/environment space size = QueryMemSize( pchList ); env_end = pchList + ( size - 4 ); // get pointer to end of environment or alias variables last_var = end_of_env( pchList ); length = strlen( envstr ) + 1; // special case for BeginLIBPATH and EndLIBPATH sscanf( envstr, "%31[^=]", szVarName ); if (stricmp( szVarName, BEGINLIBPATH ) == 0) { if ((DosSetExtLIBPATH( line, BEGIN_LIBPATH ) == NO_ERROR)) return 0; return ERROR_EXIT; } if (stricmp( szVarName, ENDLIBPATH ) == 0) { if ((DosSetExtLIBPATH( line, END_LIBPATH ) == NO_ERROR)) return 0; return ERROR_EXIT; } // check for modification or deletion of existing entry if (( env_arg = get_list( envstr, pchList )) != 0L ) { // get the start of the alias or variable name for ( feptr = env_arg; (( feptr > pchList ) && ( feptr[-1] != '\0' )); feptr-- ) ; if ( *line == '\0' ) { // delete an alias or environment variable memmove( feptr, next_env( feptr ), (unsigned int)( last_var - next_env(feptr)) + 1); } else { // get the relative length (vs. the old variable) length = strlen( line ) - strlen( env_arg ); } } if ( *line != '\0' ) { // check for out of environment space if (( last_var + length ) >= env_end ) { // boost environment or alias list size if ( ReallocMem( pchList, size + ENVIRONMENT_SIZE ) == NULL) { rval = error((( pchList == glpAliasList ) ? ERROR_4DOS_OUT_OF_ALIAS : ERROR_4DOS_OUT_OF_ENVIRONMENT), NULL); goto add_bye; } // adjust the environment / alias list size size = QueryMemSize( pchList ); if ( pchList == glpEnvironment ) gpIniptr->EnvSize = (unsigned int)size; else if ( pchList == glpAliasList ) gpIniptr->AliasSize = (unsigned int)size; } if ( env_arg != 0L ) { // modify an existing alias or environment variable // adjust the space & insert new value feptr = next_env( feptr ); memmove(( feptr + length ), feptr, (unsigned int)( last_var - feptr) + 1 ); strcpy( env_arg, line ); } else { // put it at the end & add an extra null strcpy( last_var, envstr ); last_var[length] = '\0'; } } add_bye: if ( pchList == glpAliasList ) { // clear the semaphore FreeSemaphore( SemHandle ); EnableSignals(); } return rval; }
// Refresh buttons display void buttons_refresh(Buttons *buttons,ULONG type) { int x,y; Cfg_Button *button; // Lock bank GetSemaphore(&buttons->bank->lock,SEMF_SHARED,0); // Make selector visible if (type&BUTREFRESH_SELECTOR) { if (buttons_visible_select(buttons)) type|=BUTREFRESH_REFRESH; } // Font reset if (type&BUTREFRESH_FONT) { // See if font has changed if ((strcmp( buttons->window->RPort->Font->tf_Message.mn_Node.ln_Name, buttons->bank->window.font_name))!=0 || buttons->window->RPort->Font->tf_YSize!=buttons->bank->window.font_size) { // Get new font buttons_get_font(buttons); // Do full reset type=BUTREFRESH_RESIZE|BUTREFRESH_REFRESH; // Clear resized flag buttons->flags&=~BUTTONF_RESIZED; } } // Resize event? if (type&BUTREFRESH_RESIZE) { unsigned short min_width,min_height; unsigned short max_width,max_height; short border_x=0,border_y=0; // Borderless window? if (buttons->flags&BUTTONF_BORDERLESS) { ULONG flags; short old_width,old_height; ULONG old_border; // Save drag gadget flags and size flags=buttons->drag_gadget.Flags; old_width=buttons->drag_gadget.Width; old_height=buttons->drag_gadget.Height; old_border=buttons->border_type; // See if drag bar orientation has changed if (buttons_fix_drag(buttons)) { short width,height; // Get current width/height width=buttons->window->Width; height=buttons->window->Height; // If bar is now horizontal, it used to be vertical if (buttons->drag_gadget.Flags&GFLG_RELWIDTH && flags&GFLG_RELHEIGHT) { // Adjust accordingly width-=old_width; height+=buttons->drag_gadget.Height; } // And vice versa else if (buttons->drag_gadget.Flags&GFLG_RELHEIGHT && flags&GFLG_RELWIDTH) { // Adjust height-=old_height; width+=buttons->drag_gadget.Width; } // No drag bar else if (!(buttons->drag_gadget.Flags&(GFLG_RELWIDTH|GFLG_RELHEIGHT))) { // Adjust size if (flags&GFLG_RELHEIGHT) { if (old_border&BTNWF_RIGHT_BELOW) border_x=old_width; width-=old_width; } else if (flags&GFLG_RELWIDTH) { if (old_border&BTNWF_RIGHT_BELOW) border_y=old_height; height-=old_height; } } // State of right/below flag changed else if (!(old_border&BTNWF_RIGHT_BELOW) && (buttons->bank->window.flags&BTNWF_RIGHT_BELOW)) { // Move window up or right depending on border if (buttons->bank->window.flags&BTNWF_HORIZ) border_y=-((GUI->screen_info&SCRI_LORES)?DRAG_LO_HEIGHT:DRAG_HI_HEIGHT); else if (buttons->bank->window.flags&BTNWF_VERT) border_x=-DRAG_WIDTH; } // Is size not changing? if (buttons->window->Width==width && buttons->window->Height==height) { // Refresh buttons display type|=BUTREFRESH_REFRESH; RefreshGList(&buttons->drag_gadget,buttons->window,0,1); } // Size is changing so window will be refreshed automatically else { // Resize window ChangeWindowBox( buttons->window, buttons->window->LeftEdge+border_x,buttons->window->TopEdge+border_y, width,height); buttons->flags|=BUTTONF_RESIZED; } // Recalculate internal size buttons_fix_internal(buttons); } // Refresh drag gadget else { RefreshGList(&buttons->drag_gadget,buttons->window,0,1); } } // Get the maximum size of a button buttons_get_max_size(buttons,&max_width,&max_height); // Graphical buttons? if (buttons->bank->window.flags&BTNWF_GFX) { // Maximum is also minimum min_width=max_width; } // Text buttons else { // Get minimum width min_width=TextLength(buttons->window->RPort,"a",1)*6; // Border? if (!(buttons->flags&BUTTONF_BORDERLESS)) { // Calculate button size from window max_width=buttons->window->GZZWidth/buttons->bank->window.columns; } // Is button width less than minimum? if (max_width<min_width) max_width=min_width; } // Store button size buttons->button_width=max_width; buttons->button_height=max_height; // No border or toolbar? if (buttons->flags&(BUTTONF_BORDERLESS|BUTTONF_TOOLBAR)) { short side_borders,top_borders; // Start with maximum columns/rows buttons->button_cols=buttons->bank->window.columns; buttons->button_rows=buttons->bank->window.rows; // Calculate window size max_width=buttons->button_width*buttons->button_cols; max_height=buttons->button_height*buttons->button_rows; // Calculate border sizes side_borders=buttons->window->Width-buttons->internal.Width; top_borders=buttons->window->Height-buttons->internal.Height; // Too big for screen? if (max_width+side_borders>buttons->window->WScreen->Width) { buttons->button_cols=(buttons->window->WScreen->Width-side_borders)/buttons->button_width; max_width=buttons->button_cols*buttons->button_width; } if (max_height+top_borders>buttons->window->WScreen->Height) { buttons->button_rows=(buttons->window->WScreen->Height-top_borders)/buttons->button_height; max_height=buttons->button_rows*buttons->button_height; } // Add border size max_width+=side_borders; max_height+=top_borders; // Minimum is the maximum min_width=max_width; min_height=max_height; } // Normal borders else { // Get columns/rows buttons->button_cols=buttons->window->GZZWidth/buttons->button_width; buttons->button_rows=buttons->window->GZZHeight/buttons->button_height; // Check columns/rows don't exceed actual number of buttons if (buttons->button_cols>buttons->bank->window.columns) buttons->button_cols=buttons->bank->window.columns; if (buttons->button_rows>buttons->bank->window.rows) buttons->button_rows=buttons->bank->window.rows; // Get window minimum size min_width+=buttons->window->BorderLeft+buttons->window->BorderRight; min_height=buttons->window->BorderTop+buttons->window->BorderBottom+buttons->button_height; // Get window maximum size max_width=(!(buttons->bank->window.flags&BTNWF_GFX))?buttons->window->WScreen->Width: buttons->window->BorderLeft+ buttons->window->BorderRight+ buttons->bank->window.columns*buttons->button_width; max_height= buttons->window->BorderTop+ buttons->window->BorderBottom+ buttons->button_height*buttons->bank->window.rows; } // Set window limits WindowLimits(buttons->window,0,0,(ULONG)-1,(ULONG)-1); // See if window size can be changed if (!(buttons->flags&BUTTONF_RESIZED)) { short width,height; // No border? if (buttons->flags&BUTTONF_BORDERLESS) { // Get desired size width=max_width; height=max_height; } // Normal borders else { // Get initial size width=buttons->window->Width; height=buttons->window->Height; // Is window narrower than minimum? if (buttons->window->Width<min_width) width=min_width; // Or wider than maximum? else if (buttons->window->Width>max_width) width=max_width; // Otherwise, size to button boundary else { // Drop back to last whole column width-=buttons->window->GZZWidth-(buttons->button_cols*buttons->button_width); // Size to make window bigger? if (buttons->window->Width>buttons->last_position.Width && buttons->button_cols<buttons->bank->window.columns) { short new_width; // Get new width new_width=width+buttons->button_width; // Would this be legal? if (buttons->window->LeftEdge+new_width<=buttons->window->WScreen->Width) width=new_width; } } // Is window shorter than minimum? if (buttons->window->Height<min_height) height=min_height; // Or taller than maximum? else if (buttons->window->Height>max_height) height=max_height; // Otherwise, size to button boundary else { // Drop back to last whole row height-=buttons->window->GZZHeight-(buttons->button_rows*buttons->button_height); // Size to make window bigger? if (buttons->window->Height>buttons->last_position.Height && buttons->button_rows<buttons->bank->window.rows) { short new_height; // Get new height new_height=height+buttons->button_height; // Would this be legal? if (buttons->window->TopEdge+new_height<=buttons->window->WScreen->Height) height=new_height; } } } // Does window need to be resized? if (buttons->window->Width!=width || buttons->window->Height!=height) { // Resize window ChangeWindowBox( buttons->window, buttons->window->LeftEdge+border_x,buttons->window->TopEdge+border_y, width,height); buttons->flags|=BUTTONF_RESIZED; // Set window limits WindowLimits(buttons->window, min_width, min_height, max_width, max_height); // Unlock bank FreeSemaphore(&buttons->bank->lock); return; } } // Returned from a resize; refresh frame else RefreshWindowFrame(buttons->window); // Save window position buttons->last_position=*((struct IBox *)&buttons->window->LeftEdge); // Set window limits WindowLimits(buttons->window, min_width, min_height, max_width, max_height); // Fix sliders if (buttons->vert_scroll) { SetGadgetAttrs(buttons->vert_scroll,buttons->window,0, PGA_Total,buttons->bank->window.rows, PGA_Visible,buttons->button_rows, TAG_END); } if (buttons->horiz_scroll) { SetGadgetAttrs(buttons->horiz_scroll,buttons->window,0, PGA_Total,buttons->bank->window.columns, PGA_Visible,buttons->button_cols, TAG_END); } // Make sure selector is visible if (buttons->editor) buttons_visible_select(buttons); } // Refresh event if (type&BUTREFRESH_REFRESH) { // Get vertical position if (buttons->vert_scroll) GetAttr(PGA_Top,buttons->vert_scroll,(ULONG *)&buttons->button_top); else buttons->button_top=0; // Horizontal if (buttons->horiz_scroll) GetAttr(PGA_Top,buttons->horiz_scroll,(ULONG *)&buttons->button_left); else buttons->button_left=0; // Draw buttons button=(Cfg_Button *)buttons->bank->buttons.lh_Head; for (y=0;y<buttons->bank->window.rows;y++) { for (x=0;x<buttons->bank->window.columns;x++) { // Check button is valid if (button && !button->node.ln_Succ) button=0; // Is button visible? if (y>=buttons->button_top && y<buttons->button_top+buttons->button_rows && x>=buttons->button_left && x<buttons->button_left+buttons->button_cols) { // Draw button buttons_show_button( buttons, button, x-buttons->button_left, y-buttons->button_top, (button)?button->current:0,0); } // Get next button if (button) button=(Cfg_Button *)button->node.ln_Succ; } } } // Clear resized flag buttons->flags&=~BUTTONF_RESIZED; // Unlock bank FreeSemaphore(&buttons->bank->lock); }
// Solicit a file request_file( struct Window *parent, char *title, char *buffer, char *def, ULONG flags, char *pattern) { struct IBox coords; struct FileRequester *filereq; char *path,*file=0; int ret; // Allocate path if (!(path=AllocVec(300,MEMF_CLEAR))) return 0; // Get current path if (buffer[0]) strcpy(path,buffer); else if (def) strcpy(path,def); if (path[0]) { file=FilePart(path); if (file && file>path) { strcpy(path+256,file); *file=0; file=path+256; } } // Get current requester coordinates GetSemaphore(&GUI->req_lock,SEMF_SHARED,0); coords=GUI->req_coords; FreeSemaphore(&GUI->req_lock); // Allocate filerequester if (!(filereq=AllocAslRequestTags(ASL_FileRequest, (flags&(1<<30))?ASLFR_Screen:ASLFR_Window,parent, ASLFR_TitleText,title, (file)?ASLFR_InitialFile:TAG_IGNORE,file, (*path)?ASLFR_InitialDrawer:TAG_IGNORE,path, ASLFR_Flags1,(flags|FRF_PRIVATEIDCMP)&~((1<<31)|(1<<30)|(1<<29)), ASLFR_Flags2,(flags&(1<<31))?0:FRF_REJECTICONS, ASLFR_InitialLeftEdge,coords.Left, ASLFR_InitialTopEdge,coords.Top, ASLFR_InitialWidth,coords.Width, ASLFR_InitialHeight,coords.Height, (flags&(1<<29))?ASLFR_InitialPattern:TAG_IGNORE,pattern, TAG_END))) { FreeVec(path); return 0; } // Display requester ret=AslRequest(filereq,0); // Build path strcpy(buffer,filereq->fr_Drawer); AddPart(buffer,filereq->fr_File,256); if (!*buffer || !*filereq->fr_File) ret=0; // Save coordinates GetSemaphore(&GUI->req_lock,SEMF_EXCLUSIVE,0); GUI->req_coords=*((struct IBox *)&filereq->fr_LeftEdge); FreeSemaphore(&GUI->req_lock); // Free file requester FreeAslRequest(filereq); FreeVec(path); return ret; }
// Handle some appstuff BOOL buttons_app_message(Buttons *buttons,DOpusAppMessage *msg) { short col,row; Cfg_Button *button; Cfg_Function *function; struct ArgArray *arg_array; IPCData *ipc; // Lock process list lock_listlock(&GUI->process_list,FALSE); // See if button editor is running ipc=IPC_FindProc(&GUI->process_list,NAME_BUTTON_EDITOR_RUN,FALSE,0); // Unlock process list unlock_listlock(&GUI->process_list); // Editor running? if (ipc) { // Send button if (buttons_edit_bank(buttons,-1,-1,0,(struct AppMessage *)msg,0)) { // Message was swallowed return 1; } } // Lock bank GetSemaphore(&buttons->bank->lock,SEMF_SHARED,0); // Get button and function we dropped on col=msg->da_Msg.am_MouseX; row=msg->da_Msg.am_MouseY; if (!(button=button_from_point(buttons,&col,&row)) || !(function=button_valid(button,button->current))) { FreeSemaphore(&buttons->bank->lock); return 0; } // Get arg array if ((arg_array=AppArgArray(msg,AAF_ALLOW_DIRS))) { BPTR lock; char pathname[256]; // Get pathname of first file DevNameFromLockDopus(msg->da_Msg.am_ArgList[0].wa_Lock,pathname,256); // Need source directory; if no name, get parent if ((!msg->da_Msg.am_ArgList[0].wa_Name || !*msg->da_Msg.am_ArgList[0].wa_Name) && (lock=ParentDir(msg->da_Msg.am_ArgList[0].wa_Lock))) { // Get pathname of parent DevNameFromLockDopus(lock,pathname,256); UnLock(lock); } // Launch function function_launch( FUNCTION_RUN_FUNCTION_EXTERNAL, function, 0, 0, 0,0, pathname,0, arg_array,0, buttons); } // Unlock button lock FreeSemaphore(&buttons->bank->lock); return 0; }
// Build user menu void display_build_user_menu(void) { Cfg_Button *button; AppEntry *appmenu; short count=0,tool_count=0; // Lock menus GetSemaphore(&GUI->user_menu_lock,SEMF_SHARED,0); // Free existing menu FreeVec(GUI->user_menu_data); // Got user menu? if (GUI->user_menu) { // Go through user menu for (button=(Cfg_Button *)GUI->user_menu->buttons.lh_Head; button->node.ln_Succ; button=(Cfg_Button *)button->node.ln_Succ) { // Title? if (button->button.flags&BUTNF_TITLE) ++count; // Otherwise else { Cfg_ButtonFunction *func; short num; // First item, default title? if (count==0) count=1; // Add this item ++count; // Go through functions for (func=(Cfg_ButtonFunction *)button->function_list.mlh_Head,num=0; func->node.ln_Succ; func=(Cfg_ButtonFunction *)func->node.ln_Succ) { // Ignore function if empty if ((!function_label(func) || !*function_label(func)) && IsListEmpty((struct List *)&func->instructions)) continue; // Skip first function until we know there's more if (num>0) { // Increment count ++count; if (num==1) ++count; } // Increment function count ++num; } } } } // Showing Tools menu? if (environment->env->display_options&DISPOPTF_SHOW_TOOLS && !(GUI->flags&GUIF_NO_TOOLS_MENU)) { // Lock AppList appmenu=LockAppList(); // Count tool (app) menus while ((appmenu=NextAppEntry(appmenu,APP_MENU)) && (++tool_count)<63); // Unlock AppList UnlockAppList(); // Add tools title if (tool_count>0) ++count; } // Add end node ++count; // Allocate data for user menus if ((GUI->user_menu_data=AllocVec(sizeof(MenuData)*(count+tool_count),MEMF_CLEAR))) { short num=0; // Got a user menu? if (GUI->user_menu) { short item; // Go through user menu for (button=(Cfg_Button *)GUI->user_menu->buttons.lh_Head,item=0; button->node.ln_Succ; button=(Cfg_Button *)button->node.ln_Succ,item++) { Cfg_ButtonFunction *func; short title=0; // Title? if (button->button.flags&BUTNF_TITLE) title=1; // Otherwise else { // First item, default title? if (item==0) title=2; } // Need to do title? if (title) { // Get button function if (title==1) func=(Cfg_ButtonFunction *) FindFunctionType((struct List *)&button->function_list,FTYPE_LEFT_BUTTON); else func=0; // Fill in data GUI->user_menu_data[num].type=NM_TITLE; GUI->user_menu_data[num].id=(ULONG)func; if (func) { if (!(GUI->user_menu_data[num].name=(ULONG)function_label(func))) GUI->user_menu_data[num].name=(ULONG)GUI->null_string; } else GUI->user_menu_data[num].name=(ULONG)GetString(&locale,MSG_USER_MENU); GUI->user_menu_data[num].flags=MENUFLAG_TEXT_STRING; ++num; } // Real function? if (title!=1) { Cfg_ButtonFunction *first=0; short type=NM_ITEM; short tot; // Go through functions for (func=(Cfg_ButtonFunction *)button->function_list.mlh_Head,tot=0; func->node.ln_Succ; func=(Cfg_ButtonFunction *)func->node.ln_Succ) { // Ignore function if empty if ((!function_label(func) || !*function_label(func)) && IsListEmpty((struct List *)&func->instructions)) continue; // On the second function? if (tot==1) { // Did the first function have instructions? if (!(IsListEmpty((struct List *)&first->instructions))) { // Use it again func=first; } } // Fill in menu data GUI->user_menu_data[num].type=type; GUI->user_menu_data[num].id=(ULONG)func; // Bar label? if (function_label(func) && strncmp(function_label(func),"---",3)==0) GUI->user_menu_data[num].name=(ULONG)NM_BARLABEL; // Normal function else { // Get name if (!(GUI->user_menu_data[num].name=(ULONG)function_label(func))) GUI->user_menu_data[num].name=(ULONG)GUI->null_string; GUI->user_menu_data[num].flags=MENUFLAG_TEXT_STRING; // Does function have a right-amiga hotkey? if (func->function.qual&IEQUALIFIER_RCOMMAND) { char key; // Convert from rawkey if (ConvertRawKey(func->function.code,0,&key)) { unsigned short qual; // For letters, shift is always down if (key>='a' && key<='z') qual=IEQUALIFIER_LSHIFT; // Otherwise, it might be down else qual=func->function.qual&IEQUAL_ANYSHIFT; // Convert again if (ConvertRawKey(func->function.code,qual,&key)) { // Set flags for hotkey GUI->user_menu_data[num].flags|=MENUFLAG_USE_SEQ; GUI->user_menu_data[num].flags|=MENUFLAG_MAKE_SEQ(key); } } } } // Change type to sub-item type=NM_SUB; ++num; // Remember first function if (!first) first=func; // Increment count ++tot; } } } } // Tool menu? if (tool_count>0) { short tot=0; // Build tool title GUI->user_menu_data[num].type=NM_TITLE; GUI->user_menu_data[num].id=MENU_TOOL_MENU; GUI->user_menu_data[num++].name=MSG_TOOL_MENU; // Lock AppList appmenu=LockAppList(); // Fill in tool menus while ((appmenu=NextAppEntry(appmenu,APP_MENU)) && (++tot)<63) { // Fill in menu data GUI->user_menu_data[num].type=NM_ITEM; GUI->user_menu_data[num].id=(ULONG)appmenu; // Separator? if (strncmp(appmenu->text,"---",3)==0) { GUI->user_menu_data[num].name=(ULONG)NM_BARLABEL; } // Normal string else { GUI->user_menu_data[num].name=(ULONG)appmenu->text; GUI->user_menu_data[num].flags=MENUFLAG_TEXT_STRING; } // Increment count ++num; } // Unlock AppList UnlockAppList(); } // Last menu GUI->user_menu_data[num].type=NM_END; } // Go through fixed menus, look for NM_NEXT for (count=0;dopus_menus[count].type!=NM_NEXT;count++); // Point fixed menus on to user menu dopus_menus[count].name=(ULONG)GUI->user_menu_data; // Unlock menus FreeSemaphore(&GUI->user_menu_lock); }
// Stop dragging a button void buttons_stop_drag(Buttons *buttons,short x,short y) { struct Layer *layer; struct Window *window; ULONG id=0; BOOL swap_local=0; IPCData *ipc=0; BOOL ok=0; // Free drag info FreeDragInfo(buttons->drag_info); buttons->drag_info=0; // Nothing selected now buttons->editor_sel_col=-1; buttons->editor_sel_row=-1; buttons->button_sel_button=0; IPC_Command( buttons->editor, BUTTONEDIT_SELECT_BUTTON, -1, (APTR)-1, 0, 0); // Invalid coordinates? if (x==-1 || y==-1) return; // Lock layer LockScreenLayer(buttons->window->WScreen); // Find which layer we dropped it on if (layer=WhichLayer( &buttons->window->WScreen->LayerInfo, x+buttons->window->LeftEdge, y+buttons->window->TopEdge)) { // Does layer have a window? if ((window=layer->Window)) { // Is it our own window? if (window==buttons->window) { // Set flag to swap with local button swap_local=1; } else { // Get window ID id=GetWindowID(window); // Forbid to get IPC Forbid(); if (!(ipc=(IPCData *)GetWindowAppPort(window))) Permit(); } } } // Unlock layer UnlockScreenLayer(buttons->window->WScreen); // Got an IPC port? if (ipc) { // Button editor or another button bank? if (id==WINDOW_BUTTON_CONFIG || id==WINDOW_BUTTONS || id==WINDOW_FUNCTION_EDITOR) { Cfg_Button *button; Point *pos; // Store position (screen relative) if (pos=AllocVec(sizeof(Point),0)) { pos->x=x+buttons->window->LeftEdge; pos->y=y+buttons->window->TopEdge; } // Copy current button if (button=CopyButton(buttons->button_drag_button,0,-1)) { // Send button IPC_Command(ipc,BUTTONEDIT_CLIP_BUTTON,0,button,pos,0); ok=1; } } // Permit now we've sent the message Permit(); } // Swapping local buttons? else if (swap_local) { Cfg_Button *swap; // Lock bank GetSemaphore(&buttons->bank->lock,SEMF_SHARED,0); // Get swap button if (swap=button_from_point(buttons,&x,&y)) { // Different button? if (swap!=buttons->button_drag_button) { // Swap buttons SwapListNodes( &buttons->bank->buttons, (struct Node *)buttons->button_drag_button, (struct Node *)swap); // Redraw buttons buttons_show_button( buttons, swap, buttons->drag_col, buttons->drag_row, swap->current,0); buttons_show_button( buttons, buttons->button_drag_button, x, y, buttons->button_drag_button->current,0); buttons->flags|=BUTTONF_CHANGED; } } // Unlock bank FreeSemaphore(&buttons->bank->lock); ok=1; } // Failed? if (!ok) DisplayBeep(buttons->window->WScreen); }
// Scroll the icons void backdrop_scroll_objects(BackdropInfo *info,short off_x,short off_y) { // Lock window GetSemaphore(&info->window_lock,SEMF_EXCLUSIVE,0); // Window open? if (info->window) { short damage=0,clear=0; // Bounds-check the deltas if (off_x<0 && off_x<-RECTWIDTH(&info->size)) clear=1; else if (off_x>0 && off_x>RECTWIDTH(&info->size)) clear=1; else if (off_y<0 && off_y<-RECTHEIGHT(&info->size)) clear=1; else if (off_y>0 && off_y>RECTHEIGHT(&info->size)) clear=1; // Clear instead of scrolling? if (clear) { // Clear the whole window EraseRect( info->window->RPort, info->size.MinX, info->size.MinY, info->size.MaxX, info->size.MaxY); } // Scroll else { // Check for 39 if(((struct Library *)GfxBase)->lib_Version>=39) { // Scroll backdrop window ScrollRasterBF( info->window->RPort, off_x,off_y, info->size.MinX, info->size.MinY, info->size.MaxX, info->size.MaxY); } // No backfills else { // Scroll backdrop window ScrollRaster( info->window->RPort, off_x,off_y, info->size.MinX, info->size.MinY, info->size.MaxX, info->size.MaxY); } // Damaged simple-refresh? if (info->window->Flags&WFLG_SIMPLE_REFRESH && info->window->WLayer->Flags&LAYERREFRESH) { // Forbid #ifdef LOCKLAYER_OK LockScreenLayer(info->window->WScreen); #else Forbid(); #endif // Begin refreshing BeginRefresh(info->window); // Clear the new bits EraseRect( info->window->RPort, info->size.MinX, info->size.MinY, info->size.MaxX, info->size.MaxY); // End refreshing for the moment EndRefresh(info->window,FALSE); damage=1; } } // Got temporary region? if (info->temp_region) { struct Rectangle rect; // Get refresh region rect.MinX=(off_x==0)?info->size.MinX:((off_x>0)?info->size.MaxX-off_x:info->size.MinX); rect.MaxX=(off_x==0)?info->size.MaxX:((off_x>0)?info->size.MaxX:info->size.MinX-off_x); rect.MinY=(off_y==0)?info->size.MinY:((off_y>0)?info->size.MaxY-off_y:info->size.MinY); rect.MaxY=(off_y==0)?info->size.MaxY:((off_y>0)?info->size.MaxY:info->size.MinY-off_y); // Bounds check region if (rect.MinX<info->size.MinX) rect.MinX=info->size.MinX; if (rect.MinY<info->size.MinY) rect.MinY=info->size.MinY; if (rect.MaxX>info->size.MaxX) rect.MaxX=info->size.MaxX; if (rect.MaxY>info->size.MaxY) rect.MaxY=info->size.MaxY; // Add to damage list? if (damage) { // Or rectangle in OrRectRegion(info->window->WLayer->DamageList,&rect); } // Manually refresh else { // Set refresh region ClearRegion(info->temp_region); OrRectRegion(info->temp_region,&rect); // Install region InstallClipRegion(info->window->WLayer,info->temp_region); } } // Manual refresh? if (!damage) { // Refresh backdrop_show_objects(info,BDSF_NO_CLIP); // Remove clip region InstallClipRegion(info->window->WLayer,0); } // Automatic refresh else { // Lister? if (info->lister) lister_refresh_callback(IDCMP_REFRESHWINDOW,info->window,info->lister); // Other type else { struct IntuiMessage msg; // Fake IntuiMessage msg.Class=IDCMP_REFRESHWINDOW; // Handle refresh backdrop_idcmp(info,&msg,0); } // Enable multi-tasking #ifdef LOCKLAYER_OK UnlockScreenLayer(info->window->WScreen); #else Permit(); #endif } } // Unlock window FreeSemaphore(&info->window_lock); }
// Menu item help void help_menu_help(long id,char *generic) { short a; char *header=0; Cfg_Button *button; APTR appitem; // Go through menu help table for (a=0; menu_help_data[a].name; a++) { // New header? if (menu_help_data[a].id==0) header=menu_help_data[a].name; // Match ID? else if (menu_help_data[a].id==id) { char buf[80]; // Build help string if (header) { strcpy(buf,header); strcat(buf," - "); } else buf[0]=0; strcat(buf,menu_help_data[a].name); // Show help help_show_help(buf,0); return; } } // Lock user menu GetSemaphore(&GUI->user_menu_lock,SEMF_SHARED,0); // Go through menu, look for this function for (button=(Cfg_Button *)GUI->user_menu->buttons.lh_Head; button->node.ln_Succ; button=(Cfg_Button *)button->node.ln_Succ) { Cfg_ButtonFunction *func; // Go through functions for (func=(Cfg_ButtonFunction *)button->function_list.mlh_Head; func->node.ln_Succ; func=(Cfg_ButtonFunction *)func->node.ln_Succ) { // Match function if (func==(Cfg_ButtonFunction *)id) { // Show help for user menu function help_button_help(button,(Cfg_Function *)func,0xffff,func->function.func_type,GENERIC_USER_MENU); FreeSemaphore(&GUI->user_menu_lock); return; } } } // Unlock user menu FreeSemaphore(&GUI->user_menu_lock); // Lock app list appitem=LockAppList(); // Search appmenu list, see if that's what was hit while ((appitem=NextAppEntry(appitem,APP_MENU))) { // Item we want? if (appitem==(APTR)id) { // Show help for AppItems generic=HELP_APPMENUITEM; break; } } // Unlock list UnlockAppList(); // Show generic help help_show_help(generic,0); }
// Show the backdrop objects void backdrop_show_objects(BackdropInfo *info,UWORD flags) { BackdropObject *object; // Lock backdrop list lock_listlock(&info->objects,0); // Lock window GetSemaphore(&info->window_lock,SEMF_EXCLUSIVE,0); // Window open? if (info->window) { // Are we in a refresh? if (flags&BDSF_IN_REFRESH) { // Lock layers #ifdef LOCKLAYER_OK LockScreenLayer(info->window->WScreen); #else Forbid(); #endif // End refresh temporarily EndRefresh(info->window,FALSE); // Install new clip region if we have it if (info->clip_region) InstallClipRegion(info->window->WLayer,info->clip_region); // Continue refresh BeginRefresh(info->window); } // Or, are we meant to be refreshing? else if (flags&BDSF_REFRESH) { // Start refresh here? if ((flags&BDSF_REFRESH_DONE)==BDSF_REFRESH_DONE) { // Lock layers #ifdef LOCKLAYER_OK LockScreenLayer(info->window->WScreen); #else Forbid(); #endif } // And our region with damagelist if (info->clip_region) AndRegionRegion(info->clip_region,info->window->WLayer->DamageList); // Begin the refresh BeginRefresh(info->window); } // Install clip region if we have it else if (!(flags&BDSF_NO_CLIP) && info->clip_region) InstallClipRegion(info->window->WLayer,info->clip_region); // Clear backdrop window if (flags&BDSF_CLEAR) { EraseRect(&info->rp, info->size.MinX, info->size.MinY, info->size.MaxX, info->size.MaxY); } // Not just clearing? if ((flags&BDSF_CLEAR_ONLY)!=BDSF_CLEAR_ONLY) { // Go through backdrop list (backwards) for (object=(BackdropObject *)info->objects.list.lh_TailPred; object->node.ln_Pred; object=(BackdropObject *)object->node.ln_Pred) { // Reset? if (flags&BDSF_RESET) { // Need to get masks? if (!backdrop_icon_border(object) && !object->image_mask[0]) { // Get masks for this icon backdrop_get_masks(object); } } // Valid position? if (!(object->flags&BDOF_NO_POSITION)) { // Render this object backdrop_draw_object( info, object, BRENDERF_REAL, &info->rp, object->pos.Left, object->pos.Top); } } } // Refresh? if (flags&BDSF_REFRESH) { EndRefresh(info->window,((flags&BDSF_REFRESH_DONE)==BDSF_REFRESH_DONE)?TRUE:FALSE); // End refresh here? if ((flags&BDSF_REFRESH_DONE)==BDSF_REFRESH_DONE) { // Unlock layers #ifdef LOCKLAYER_OK UnlockScreenLayer(info->window->WScreen); #else Permit(); #endif } } // In refresh? else if (flags&BDSF_IN_REFRESH) { // End refresh temporarily EndRefresh(info->window,FALSE); // Remove clip region if (info->clip_region) InstallClipRegion(info->window->WLayer,0); // Continue refresh BeginRefresh(info->window); // Unlock layers #ifdef LOCKLAYER_OK UnlockScreenLayer(info->window->WScreen); #else Permit(); #endif } // Remove clip region else if (!(flags&BDSF_NO_CLIP) && info->clip_region) InstallClipRegion(info->window->WLayer,0); // Update virtual size if (flags&BDSF_RECALC) backdrop_calc_virtual(info); } // Unlock window FreeSemaphore(&info->window_lock); // Unlock backdrop list unlock_listlock(&info->objects); }
// Save an environment int environment_save(Cfg_Environment *env,char *name,short snapshot,CFG_ENVR *data) { APTR iff; long success=0; struct OpenEnvironmentData *opendata=0; #ifdef __AROS__ CFG_ENVR *env_be; #endif // Invalid name? if (!name || !*name) return 0; // Get data pointer if not supplied if (!data) data=env->env; #ifdef __AROS__ if (!(env_be=AllocVec(sizeof(CFG_ENVR),MEMF_CLEAR))) return 0; #endif // Update main window position if (snapshot&ENVSAVE_WINDOW) { GetSemaphore(&GUI->backdrop->window_lock,SEMF_SHARED,0); display_store_pos(); FreeSemaphore(&GUI->backdrop->window_lock); } // Not snapshotting listers? if (!(snapshot&ENVSAVE_LAYOUT)) { if ((opendata=AllocMemH(env->volatile_memory,sizeof(struct OpenEnvironmentData)))) { opendata->memory=env->desktop_memory; opendata->volatile_memory=env->volatile_memory; opendata->flags=OEDF_BANK|OEDF_LSTR; OpenEnvironment(name,opendata); } } // Try to open file to write while ((iff=IFFOpen(name,MODE_NEWFILE,ID_EPUS))) { IPCData *ipc; Lister *lister; Buttons *buttons; Cfg_Desktop *desk; struct MinNode *node; Cfg_SoundEntry *sound; // Write environment settings #ifdef __AROS__ CopyMem(data,env_be,sizeof(CFG_ENVR)); { int i; env_be->screen_mode = AROS_LONG2BE(env_be->screen_mode); env_be->screen_flags = AROS_WORD2BE(env_be->screen_flags); env_be->screen_depth = AROS_WORD2BE(env_be->screen_depth); env_be->screen_width = AROS_WORD2BE(env_be->screen_width); env_be->screen_height = AROS_WORD2BE(env_be->screen_height); for (i=0; i<50; i++) env_be->palette[i] = AROS_LONG2BE(env_be->palette[i]); env_be->window_pos.Left = AROS_WORD2BE(env_be->window_pos.Left); env_be->window_pos.Top = AROS_WORD2BE(env_be->window_pos.Top); env_be->window_pos.Width = AROS_WORD2BE(env_be->window_pos.Width); env_be->window_pos.Height = AROS_WORD2BE(env_be->window_pos.Height); env_be->general_screen_flags = AROS_LONG2BE(env_be->general_screen_flags); env_be->palette_count = AROS_WORD2BE(env_be->palette_count); for (i=0; i<CUST_PENS; i++) { env_be->env_Colours[i][0][0] = AROS_LONG2BE(env_be->env_Colours[i][0][0]); env_be->env_Colours[i][0][1] = AROS_LONG2BE(env_be->env_Colours[i][0][1]); env_be->env_Colours[i][0][2] = AROS_LONG2BE(env_be->env_Colours[i][0][2]); env_be->env_Colours[i][1][0] = AROS_LONG2BE(env_be->env_Colours[i][1][0]); env_be->env_Colours[i][1][1] = AROS_LONG2BE(env_be->env_Colours[i][1][1]); env_be->env_Colours[i][1][2] = AROS_LONG2BE(env_be->env_Colours[i][1][2]); } env_be->env_ColourFlag = AROS_LONG2BE(env_be->env_ColourFlag); env_be->env_NewIconsFlags = AROS_LONG2BE(env_be->env_NewIconsFlags); env_be->display_options = AROS_WORD2BE(env_be->display_options); env_be->main_window_type = AROS_WORD2BE(env_be->main_window_type); env_be->hotkey_flags = AROS_WORD2BE(env_be->hotkey_flags); env_be->hotkey_code = AROS_WORD2BE(env_be->hotkey_code); env_be->hotkey_qual = AROS_WORD2BE(env_be->hotkey_qual); env_be->default_stack = AROS_LONG2BE(env_be->default_stack); env_be->lister_options = AROS_WORD2BE(env_be->lister_options); env_be->flags = AROS_LONG2BE(env_be->flags); env_be->lister_popup_code = AROS_WORD2BE(env_be->lister_popup_code); env_be->lister_popup_qual = AROS_WORD2BE(env_be->lister_popup_qual); env_be->env_flags = AROS_LONG2BE(env_be->env_flags); env_be->clock_left = AROS_WORD2BE(env_be->clock_left); env_be->clock_top = AROS_WORD2BE(env_be->clock_top); env_be->lister_width = AROS_WORD2BE(env_be->lister_width); env_be->lister_height = AROS_WORD2BE(env_be->lister_height); env_be->version = AROS_WORD2BE(env_be->version); env_be->desktop_flags = AROS_LONG2BE(env_be->desktop_flags); for (i=0; i<4; i++) env_be->env_BackgroundFlags[i] = AROS_WORD2BE(env_be->env_BackgroundFlags[i]); env_be->settings.copy_flags = AROS_LONG2BE(env_be->settings.copy_flags); env_be->settings.delete_flags = AROS_LONG2BE(env_be->settings.delete_flags); env_be->settings.error_flags = AROS_LONG2BE(env_be->settings.error_flags); env_be->settings.general_flags = AROS_LONG2BE(env_be->settings.general_flags); env_be->settings.icon_flags = AROS_LONG2BE(env_be->settings.icon_flags); env_be->settings.replace_method = AROS_WORD2BE(env_be->settings.replace_method); env_be->settings.replace_flags = AROS_WORD2BE(env_be->settings.replace_flags); env_be->settings.update_flags = AROS_LONG2BE(env_be->settings.update_flags); env_be->settings.dir_flags = AROS_LONG2BE(env_be->settings.dir_flags); env_be->settings.view_flags = AROS_LONG2BE(env_be->settings.view_flags); env_be->settings.max_buffer_count = AROS_WORD2BE(env_be->settings.max_buffer_count); env_be->settings.date_format = AROS_WORD2BE(env_be->settings.date_format); env_be->settings.date_flags = AROS_WORD2BE(env_be->settings.date_flags); env_be->settings.pop_code = AROS_WORD2BE(env_be->settings.pop_code); env_be->settings.pop_qual = AROS_WORD2BE(env_be->settings.pop_qual); env_be->settings.pop_qual_mask = AROS_WORD2BE(env_be->settings.pop_qual_mask); env_be->settings.pop_qual_same = AROS_WORD2BE(env_be->settings.pop_qual_same); env_be->settings.popup_delay = AROS_WORD2BE(env_be->settings.popup_delay); env_be->settings.max_openwith = AROS_WORD2BE(env_be->settings.max_openwith); env_be->settings.command_line_length = AROS_WORD2BE(env_be->settings.command_line_length); env_be->settings.max_filename = AROS_WORD2BE(env_be->settings.max_filename); env_be->settings.flags = AROS_LONG2BE(env_be->settings.flags); for (i=0; i<4; i++) env_be->env_BackgroundBorderColour[i] = AROS_LONG2BE(env_be->env_BackgroundBorderColour[i]); } if (!(IFFWriteChunk(iff,env_be,ID_ENVR,sizeof(CFG_ENVR)))) #else if (!(IFFWriteChunk(iff,data,ID_ENVR,sizeof(CFG_ENVR)))) #endif { success=IoErr(); break; } // Write some path names if ((success=write_env_string(iff,env->toolbar_path,ID_TBAR)) || (success=write_env_string(iff,env->menu_path,ID_LMEN)) || (success=write_env_string(iff,env->user_menu_path,ID_UMEN)) || (success=write_env_string(iff,env->scripts_path,ID_SCRP)) || (success=write_env_string(iff,env->hotkeys_path,ID_HKEY))) break; // Not snapshotting? if (!(snapshot&ENVSAVE_LAYOUT) && opendata) { ButtonBankNode *button; OpenListerNode *lister; // Go through existing listers for (lister=(OpenListerNode *)opendata->listers.mlh_Head; lister->node.ln_Succ;) { OpenListerNode *next=(OpenListerNode *)lister->node.ln_Succ; // Write lister data if (!(SaveListerDef(iff,(Cfg_Lister *)lister->lister))) break; // Remove this node, get next Remove((struct Node *)lister); lister=next; } // Go through buttons to open for (button=(ButtonBankNode *)opendata->buttons.mlh_Head; button->node.ln_Succ;) { ButtonBankNode *next=(ButtonBankNode *)button->node.ln_Succ; ULONG pad[5]; #ifdef __AROS__ struct IBox pos_be; #endif // Write bank header if (!(IFFPushChunk(iff,ID_BANK))) break; // Fill out padding pad[0]=0; pad[1]=0; pad[2]=button->icon_pos_x; pad[3]=button->icon_pos_y; pad[4]=button->flags&BUTTONF_ICONIFIED; #ifdef __AROS__ CopyMem(&button->pos,&pos_be,sizeof(struct IBox)); pos_be.Left = AROS_WORD2BE(pos_be.Left); pos_be.Top = AROS_WORD2BE(pos_be.Top); pos_be.Width = AROS_WORD2BE(pos_be.Width); pos_be.Height = AROS_WORD2BE(pos_be.Height); pad[2] = AROS_LONG2BE(pad[2]); pad[3] = AROS_LONG2BE(pad[3]); pad[4] = AROS_LONG2BE(pad[4]); if (!(IFFWriteChunkBytes(iff,pad,sizeof(pad))) || !(IFFWriteChunkBytes(iff,&pos_be,sizeof(struct IBox))) || !(IFFWriteChunkBytes(iff,button->node.ln_Name,strlen(button->node.ln_Name)+1)) || !(IFFPopChunk(iff))) break; #else // Write padding and position and path if (!(IFFWriteChunkBytes(iff,pad,sizeof(pad))) || !(IFFWriteChunkBytes(iff,&button->pos,sizeof(struct IBox))) || !(IFFWriteChunkBytes(iff,button->node.ln_Name,strlen(button->node.ln_Name)+1)) || !(IFFPopChunk(iff))) break; #endif // Remove this node, get next Remove((struct Node *)button); button=next; } // Go through StartMenus to open for (button=(ButtonBankNode *)opendata->startmenus.mlh_Head; button->node.ln_Succ;) { ButtonBankNode *next=(ButtonBankNode *)button->node.ln_Succ; ULONG pad[5]; #ifdef __AROS__ struct IBox pos_be; #endif // Write bank header if (!(IFFPushChunk(iff,ID_STRT))) break; // Fill out padding pad[0]=0; pad[1]=0; pad[2]=button->icon_pos_x; pad[3]=button->icon_pos_y; pad[4]=button->flags; #ifdef __AROS__ CopyMem(&button->pos,&pos_be,sizeof(struct IBox)); pos_be.Left = AROS_WORD2BE(pos_be.Left); pos_be.Top = AROS_WORD2BE(pos_be.Top); pos_be.Width = AROS_WORD2BE(pos_be.Width); pos_be.Height = AROS_WORD2BE(pos_be.Height); pad[2] = AROS_LONG2BE(pad[2]); pad[3] = AROS_LONG2BE(pad[3]); pad[4] = AROS_LONG2BE(pad[4]); if (!(IFFWriteChunkBytes(iff,pad,sizeof(pad))) || !(IFFWriteChunkBytes(iff,&pos_be,sizeof(struct IBox))) || !(IFFWriteChunkBytes(iff,button->node.ln_Name,strlen(button->node.ln_Name)+1)) || !(IFFPopChunk(iff))) break; #else // Write padding and position and path if (!(IFFWriteChunkBytes(iff,pad,sizeof(pad))) || !(IFFWriteChunkBytes(iff,&button->pos,sizeof(struct IBox))) || !(IFFWriteChunkBytes(iff,button->node.ln_Name,strlen(button->node.ln_Name)+1)) || !(IFFPopChunk(iff))) break; #endif // Remove this node, get next Remove((struct Node *)button); button=next; } } // Otherwise, snapshotting current layout else { // Lock lister list lock_listlock(&GUI->lister_list,FALSE); // Write lister definitions for (ipc=(IPCData *)GUI->lister_list.list.lh_Head; ipc->node.mln_Succ; ipc=(IPCData *)ipc->node.mln_Succ) { // Get lister lister=IPCDATA(ipc); // Valid lister definition? if (lister->lister) { // Update lister lister_update(lister); // Write lister data if (!(SaveListerDef(iff,lister->lister))) break; } } // Unlock lister list unlock_listlock(&GUI->lister_list); // Fail? if (ipc->node.mln_Succ) { success=IoErr(); break; } // Lock buttons list lock_listlock(&GUI->buttons_list,FALSE); // Write button file paths for (ipc=(IPCData *)GUI->buttons_list.list.lh_Head; ipc->node.mln_Succ; ipc=(IPCData *)ipc->node.mln_Succ) { // Get buttons pointer buttons=IPCDATA(ipc); // Valid button configuration? if (buttons->bank && buttons->bank->path[0]) { ULONG pad[5]; #ifdef __AROS__ struct IBox pos_be; #endif // Update buttons buttons_update(buttons); // Write bank header if (!(IFFPushChunk(iff,ID_BANK))) break; // Fill out padding pad[0]=0; pad[1]=0; pad[2]=buttons->icon_pos_x; pad[3]=buttons->icon_pos_y; pad[4]=buttons->flags&BUTTONF_ICONIFIED; #ifdef __AROS__ CopyMem(&buttons->pos,&pos_be,sizeof(struct IBox)); pos_be.Left = AROS_WORD2BE(pos_be.Left); pos_be.Top = AROS_WORD2BE(pos_be.Top); pos_be.Width = AROS_WORD2BE(pos_be.Width); pos_be.Height = AROS_WORD2BE(pos_be.Height); pad[2] = AROS_LONG2BE(pad[2]); pad[3] = AROS_LONG2BE(pad[3]); pad[4] = AROS_LONG2BE(pad[4]); if (!(IFFWriteChunkBytes(iff,pad,sizeof(pad))) || !(IFFWriteChunkBytes(iff,&pos_be,sizeof(struct IBox))) || !(IFFWriteChunkBytes(iff,buttons->bank->path,strlen(buttons->bank->path)+1)) || !(IFFPopChunk(iff))) break; #else // Write padding and position and path if (!(IFFWriteChunkBytes(iff,pad,sizeof(pad))) || !(IFFWriteChunkBytes(iff,&buttons->pos,sizeof(struct IBox))) || !(IFFWriteChunkBytes(iff,buttons->bank->path,strlen(buttons->bank->path)+1)) || !(IFFPopChunk(iff))) break; #endif } } // Unlock buttons list unlock_listlock(&GUI->buttons_list); // Fail? if (ipc->node.mln_Succ) { success=IoErr(); break; } // Lock StartMenu list lock_listlock(&GUI->startmenu_list,FALSE); // Write StartMenu paths for (ipc=(IPCData *)GUI->startmenu_list.list.lh_Head; ipc->node.mln_Succ; ipc=(IPCData *)ipc->node.mln_Succ) { StartMenu *menu; // Get menu pointer menu=(StartMenu *)IPCDATA(ipc); // Lock the bank GetSemaphore(&menu->lock,SEMF_SHARED,0); // Valid configuration? if (menu->bank && menu->bank->path[0]) { ULONG pad[5]; struct IBox pos; // Get position pos.Left=menu->bank->window.pos.Left; pos.Top=menu->bank->window.pos.Top; #ifdef __AROS__ pos.Left = AROS_WORD2BE(pos.Left); pos.Top = AROS_WORD2BE(pos.Top); #endif // Write menu header if (!(IFFPushChunk(iff,ID_STRT))) break; // Fill out padding pad[0]=0; pad[1]=0; pad[2]=0; pad[3]=0; pad[4]=0; // Write padding and position and path if (!(IFFWriteChunkBytes(iff,pad,sizeof(pad))) || !(IFFWriteChunkBytes(iff,&pos,sizeof(struct IBox))) || !(IFFWriteChunkBytes(iff,menu->bank->path,strlen(menu->bank->path)+1)) || !(IFFPopChunk(iff))) break; } // Unlock bank FreeSemaphore(&menu->lock); } // Unlock startmenu list unlock_listlock(&GUI->startmenu_list); // Fail? if (ipc->node.mln_Succ) success=IoErr(); } // Failed? if (success) break; // Go through desktop list for (desk=(Cfg_Desktop *)env->desktop.mlh_Head; desk->node.mln_Succ; desk=(Cfg_Desktop *)desk->node.mln_Succ) { #ifdef __AROS__ char buffer[64]; // 12 bytes CFG_DESK + 34 bytes device name + 18 bytes extra CFG_DESK *desk_be = (CFG_DESK *)buffer; CopyMem(&desk->data,desk_be,desk->data.dt_Size); desk_be->dt_Type = AROS_WORD2BE(desk_be->dt_Type); desk_be->dt_Size = AROS_WORD2BE(desk_be->dt_Size); desk_be->dt_Flags = AROS_LONG2BE(desk_be->dt_Flags); if (desk->data.dt_Type != DESKTOP_HIDE_BAD && desk->data.dt_Type != DESKTOP_HIDE) desk_be->dt_Data = AROS_LONG2BE(desk_be->dt_Data); if (!(IFFWriteChunk(iff,desk_be,ID_DESK,desk->data.dt_Size))) #else // Write chunk if (!(IFFWriteChunk(iff,&desk->data,ID_DESK,desk->data.dt_Size))) #endif { success=IoErr(); break; } } // Go through pathlist for (node=env->path_list.mlh_Head;node->mln_Succ;node=node->mln_Succ) { // Write chunk if (!(IFFWriteChunk(iff,(char *)(node+1),ID_PATH,strlen((char *)(node+1))))) { success=IoErr(); break; } } // Go through sound list for (sound=(Cfg_SoundEntry *)env->sound_list.mlh_Head;sound->dse_Node.ln_Succ;sound=(Cfg_SoundEntry *)sound->dse_Node.ln_Succ) { #ifdef __AROS__ Cfg_SoundEntry sound_be; CopyMem(&sound,&sound_be,sizeof(Cfg_SoundEntry)); sound_be.dse_Volume = AROS_WORD2BE(sound_be.dse_Volume); sound_be.dse_Flags = AROS_WORD2BE(sound_be.dse_Flags); if (!(IFFWriteChunk(iff,sound_be.dse_Name,ID_SNDX,32+2+2+strlen(sound->dse_Sound)+1))) #else // Write chunk if (!(IFFWriteChunk(iff,sound->dse_Name,ID_SNDX,32+2+2+strlen(sound->dse_Sound)+1))) #endif { success=IoErr(); break; } } break; } // Close file if (!iff) success=IoErr(); else IFFClose(iff); #ifdef __AROS__ FreeVec(env_be); #endif // Write icon if successful (and enabled) if ((!success) && (GUI->flags&GUIF_SAVE_ICONS)) { WriteFileIcon("dopus5:icons/Environment",name); } // Free stuff FreeMemH(opendata); ClearMemHandle(env->volatile_memory); return success; }
// Do a bank-specific function int buttons_do_function(Buttons *buttons,ULONG func) { int result=1; // Look at function switch (func) { // New/Open/Defaults/Last Saved case MENU_TOOLBAR_BUTTONS_NEW: case MENU_OPEN_BUTTONS_LOCAL: case MENU_TOOLBAR_RESET_DEFAULTS: case MENU_TOOLBAR_LAST_SAVED: buttons_new_bank(buttons,func,0); break; // Restore case MENU_TOOLBAR_RESTORE: buttons_new_bank(buttons,func,buttons->backup); break; // Save case MENU_SAVE_BUTTONS: { BOOL ok=0; // Lock bank GetSemaphore(&buttons->bank->lock,SEMF_SHARED,0); // Valid path? if (buttons->bank->path[0]) { buttons_save(buttons,buttons->bank->path); ok=1; } // Unlock bank FreeSemaphore(&buttons->bank->lock); if (ok) break; } // Save as case MENU_SAVEAS_BUTTONS: GetSemaphore(&buttons->bank->lock,SEMF_SHARED,0); buttons_saveas(buttons); FreeSemaphore(&buttons->bank->lock); break; // Close case MENU_CLOSE_BUTTONS: if (buttons_check_change(buttons,1)) result=0; break; // Iconify case MENU_ICONIFY_BUTTONS: if (buttons_iconify(buttons)) buttons_close(buttons,0); break; // Don't understand it default: result=-1; break; } return result; }
// Launch a generic process int ASM L_IPC_Launch( REG(a0, struct ListLock *list), REG(a1, IPCData **storage), REG(a2, char *name), REG(d0, ULONG entry), REG(d1, ULONG stack), REG(d2, ULONG data), REG(a3, struct Library *dos_base), REG(a6, struct MyLibrary *libbase)) { struct LibData *libdata; IPCData *ipc; BOOL path=0; struct TagItem *tags; #ifdef __amigaos4__ libbase = dopuslibbase_global; #endif // Want path? if (stack&IPCF_GETPATH) path=1; // Get data pointer libdata=(struct LibData *)libbase->ml_UserData; // Clear storage if (storage) *storage=0; // Allocate data if (!(ipc=AllocVec(sizeof(IPCData),MEMF_CLEAR)) || !((tags=AllocVec(sizeof(struct TagItem)*8,MEMF_ANY)))) { FreeVec(ipc); return 0; } // Store memory and list pointers ipc->memory=libdata->memory; ipc->list=list; // Fill out process tags tags[0].ti_Tag=NP_Entry; tags[0].ti_Data = IPC_GET_ENTRY(entry); tags[1].ti_Tag=NP_Name; tags[1].ti_Data=(ULONG)name; tags[2].ti_Tag=NP_WindowPtr; tags[2].ti_Data=(ULONG)-1; tags[3].ti_Tag=NP_StackSize; tags[3].ti_Data=IPCM_STACK(stack); tags[4].ti_Tag=NP_Priority; tags[4].ti_Data=0; #if defined(__MORPHOS__) if (IPC_GET_CODETYPE(entry) == CODETYPE_PPC) { tags[3].ti_Tag = NP_CodeType; // Overwriting NP_StackSize (it is not required in PPC native code) tags[3].ti_Data = IPC_GET_CODETYPE(entry); } #endif // Want a path? if (path) { BPTR pathlist; #define DOpusBase (libdata->dopus_base) // Lock path list GetSemaphore(&libdata->path_lock,SEMF_SHARED,0); // Get path list copy pathlist=GetDosPathList(libdata->path_list); // Unlock path list FreeSemaphore(&libdata->path_lock); #undef DOpusBase // Fill out tags tags[5].ti_Tag=NP_Cli; tags[5].ti_Data=TRUE; tags[6].ti_Tag=NP_Path; tags[6].ti_Data=(ULONG)pathlist; tags[7].ti_Tag=TAG_END; } else tags[5].ti_Tag=TAG_END; #define DOSBase (dos_base) // Launch process ipc->proc=CreateNewProc(tags); #undef DOSBase // Free tags now FreeVec(tags); // Failed to launch? if (!ipc->proc) { FreeVec(ipc); return 0; } // Store pointer if (storage) *storage=ipc; // Send startup message return L_IPC_Startup(ipc,(APTR)data,0); }
VOID SendNonDeliveryMessage(struct MsgInfo * OldMsg, BOOL Unread, int Age) { struct MsgInfo * Msg = AllocateMsgRecord(); BIDRec * BIDRec; char MailBuffer[1000]; char MsgFile[MAX_PATH]; FILE * hFile; int WriteLen=0; char From[100]; char * Via; struct UserInfo * FromUser; // Try to create a from Address. ( ? check RMS) strcpy(From, OldMsg->from); if (strcmp(From, "SYSTEM") == 0) return; // Don't send non-deliverys SYSTEM messages FromUser = LookupCall(OldMsg->from); if (FromUser) { if (FromUser->HomeBBS[0]) sprintf(From, "%s@%s", OldMsg->from, FromUser->HomeBBS); else sprintf(From, "%s@%s", OldMsg->from, BBSName); } else { WPRecP WP = LookupWP(OldMsg->from); if (WP) sprintf(From, "%s@%s", OldMsg->from, WP->first_homebbs); } GetSemaphore(&MsgNoSemaphore, 0); Msg->number = ++LatestMsg; MsgnotoMsg[Msg->number] = Msg; FreeSemaphore(&MsgNoSemaphore); strcpy(Msg->from, SYSOPCall); Via = strlop(From, '@'); strcpy(Msg->to, From); if (Via) strcpy(Msg->via, Via); if (strcmp(From, "RMS:") == 0) { strcpy(Msg->to, "RMS"); strcpy(Msg->via, OldMsg->emailfrom); } if (strcmp(From, "smtp:") == 0) { Msg->to[0] = 0; strcpy(Msg->via, OldMsg->emailfrom); } if (Msg->to[0] == 0) return; strcpy(Msg->title, "Non-delivery Notification"); if (Unread) Msg->length = sprintf(MailBuffer, "Your Message ID %s Subject %s to %s has not been read for %d days.\r\nMessage had been deleted.\r\n", OldMsg->bid, OldMsg->title, OldMsg->to, Age); else Msg->length = sprintf(MailBuffer, "Your Message ID %s Subject %s to %s could not be delivered in %d days.\r\nMessage had been deleted.\r\n", OldMsg->bid, OldMsg->title, OldMsg->to, Age); Msg->type = 'P'; Msg->status = 'N'; Msg->datereceived = Msg->datechanged = Msg->datecreated = time(NULL); sprintf_s(Msg->bid, sizeof(Msg->bid), "%d_%s", LatestMsg, BBSName); BIDRec = AllocateBIDRecord(); strcpy(BIDRec->BID, Msg->bid); BIDRec->mode = Msg->type; BIDRec->u.msgno = LOWORD(Msg->number); BIDRec->u.timestamp = LOWORD(time(NULL)/86400); sprintf_s(MsgFile, sizeof(MsgFile), "%s/m_%06d.mes", MailDir, Msg->number); hFile = fopen(MsgFile, "wb"); if (hFile) { fwrite(MailBuffer, 1, Msg->length, hFile); fclose(hFile); } MatchMessagetoBBSList(Msg, NULL); }
BOOL RemoveKilledMessages() { struct MsgInfo * Msg; struct MsgInfo ** NewMsgHddrPtr; char MsgFile[MAX_PATH]; int i, n; Removed = 0; GetSemaphore(&MsgNoSemaphore, 0); GetSemaphore(&AllocSemaphore, 0); FirstMessageIndextoForward = 0; NewMsgHddrPtr = zalloc((NumberofMessages+1) * 4); NewMsgHddrPtr[0] = MsgHddrPtr[0]; // Copy Control Record i = 0; for (n = 1; n <= NumberofMessages; n++) { Msg = MsgHddrPtr[n]; if (Msg->status == 'K') { sprintf_s(MsgFile, sizeof(MsgFile), "%s/m_%06d.mes%c", MailDir, Msg->number, 0); if (DeletetoRecycleBin) DeletetoRecycle(MsgFile); else DeleteFile(MsgFile); MsgnotoMsg[Msg->number] = NULL; free(Msg); Removed++; } else { NewMsgHddrPtr[++i] = Msg; if (memcmp(Msg->fbbs, zeros, NBMASK) != 0) { if (FirstMessageIndextoForward == 0) FirstMessageIndextoForward = i; } } } NumberofMessages = i; NewMsgHddrPtr[0]->number = i; if (FirstMessageIndextoForward == 0) FirstMessageIndextoForward = NumberofMessages; free(MsgHddrPtr); MsgHddrPtr = NewMsgHddrPtr; FreeSemaphore(&MsgNoSemaphore); FreeSemaphore(&AllocSemaphore); SaveMessageDatabase(); return TRUE; }