/* GEMFSLIB.C 5/14/84 - 07/16/85 Lee Lorenzen */ /* * Copyright 1999, Caldera Thin Clients, Inc. * This software is licenced under the GNU Public License. * Please see LICENSE.TXT for further information. * * Historical Copyright * ------------------------------------------------------------- * GEM Application Environment Services Version 3.0 * Serial No. XXXX-0000-654321 All Rights Reserved * Copyright (C) 1986 Digital Research Inc. * ------------------------------------------------------------- */ #include #include #include #include #include #include #include #include #define NM_NAMES (F9NAME-F1NAME+1) #define NAME_OFFSET F1NAME /* in DOS.C */ EXTERN WORD dos_create(); EXTERN WORD dos_open(); EXTERN LONG dos_lseek(); EXTERN LONG dos_alloc(); EXTERN WORD dos_read(); EXTERN WORD dos_write(); EXTERN WORD dos_close(); EXTERN BYTE *scasb(); /* in RSLIB.C */ EXTERN WORD rs_obfix(); EXTERN WORD gl_wchar; EXTERN WORD gl_hchar; EXTERN GRECT gl_rcenter; EXTERN WORD gl_wbox; EXTERN WORD gl_hbox; EXTERN WORD DOS_ERR; EXTERN LONG ad_sysglo; EXTERN LONG ad_armice; EXTERN LONG ad_hgmice; EXTERN TEDINFO edblk; EXTERN LONG ad_dta; EXTERN LONG ad_path; EXTERN BYTE gl_dta[128]; EXTERN UWORD gl_bvdisk; EXTERN THEGLO D; GLOBAL BYTE gl_fsobj[4] = {FTITLE, FILEBOX, SCRLBAR, 0x0}; GLOBAL LONG ad_fstree; GLOBAL LONG ad_fsnames; GLOBAL LONG ad_fsdta; GLOBAL GRECT gl_rfs; GLOBAL LONG ad_tmp1; GLOBAL BYTE gl_tmp1[LEN_FSNAME]; GLOBAL LONG ad_tmp2; GLOBAL BYTE gl_tmp2[LEN_FSNAME]; GLOBAL WORD gl_shdrive; /* * Routine to back off the end of a file string. */ BYTE *fs_back(pstr, pend) REG BYTE *pstr; REG BYTE *pend; { /* back off to last */ /* slash */ while ( (*pend != ':') && (*pend != '\\') && (pend != pstr) ) pend--; /* if a : then insert */ /* a backslash */ if (*pend == ':') { pend++; ins_char(pend, 0, '\\', 64); } return(pend); } /* * Routine to back up a path and return the pointer to the beginning * of the file specification part */ BYTE *fs_pspec(pstr, pend) REG BYTE *pstr; REG BYTE *pend; { pend = fs_back(pstr, pend); if (*pend == '\\') pend++; else { strcpy("A:\\*.*", pstr); pstr[0] += (BYTE) dos_gdrv(); pend = pstr + 3; } return(pend); } /* * Routine to compare based on type and then on name if its a file * else, just based on name */ WORD fs_comp() { WORD chk; if ( (gl_tmp1[0] == ' ') && (gl_tmp2[0] == ' ') ) { chk = strchk( scasb(&gl_tmp1[0], '.'), scasb(&gl_tmp2[0], '.') ); if ( chk ) return( chk ); } return ( strchk(&gl_tmp1[0], &gl_tmp2[0]) ); } WORD fs_add(thefile, fs_index) WORD thefile; WORD fs_index; { WORD len; len = LSTCPY(ad_fsnames + (LONG) fs_index, ad_fsdta - (LONG) 1); D.g_fslist[thefile] = (BYTE *) fs_index; fs_index += len + 2; return(fs_index); } /* * Make a particular path the active path. This involves * reading its directory, initializing a file list, and filling * out the information in the path node. Then sort the files. */ WORD fs_active(ppath, pspec, pcount) LONG ppath; BYTE *pspec; WORD *pcount; { WORD ret, thefile, len; WORD err_code, fs_index; REG WORD i, j, gap, drv; BYTE *temp; gsx_mfset(ad_hgmice); thefile = 0; fs_index = 0; len = 0; if (gl_shdrive) { strcpy("\007 A:", &gl_dta[29]); for(i=0; i<16; i++) { if ( (gl_bvdisk >> i) & 0x0001 ) { gl_dta[31] = 'A' + (15 - i); fs_index = fs_add(thefile, fs_index); thefile++; } } } else { dos_sdta(ad_dta); ret = dos_sfirst(ppath, F_SUBDIR); while ( ret ) { /* if it is a real file */ /* or directory then */ /* save it and set */ /* first byte to tell */ /* which */ if (gl_dta[30] != '.') { gl_dta[29] = (gl_dta[21] & F_SUBDIR) ? 0x07 : ' '; if ( (gl_dta[29] == 0x07) || (wildcmp(pspec, &gl_dta[30])) ) { fs_index = fs_add(thefile, fs_index); thefile++; } } ret = dos_snext(); if (thefile >= NM_FILES) { ret = FALSE; sound(TRUE, 660, 4); } } } *pcount = thefile; /* sort files using shell*/ /* sort on page 108 of */ /* K&R C Prog. Lang. */ for(gap = thefile/2; gap > 0; gap /= 2) { for(i = gap; i < thefile; i++) { for (j = i-gap; j >= 0; j -= gap) { LSTCPY(ad_tmp1, ad_fsnames + (LONG) D.g_fslist[j]); LSTCPY(ad_tmp2, ad_fsnames + (LONG) D.g_fslist[j+gap]); if ( fs_comp() <= 0 ) break; temp = D.g_fslist[j]; D.g_fslist[j] = D.g_fslist[j+gap]; D.g_fslist[j+gap] = temp; } } } gsx_mfset( ad_armice ); return(TRUE); } /* * Routine to adjust the scroll counters by one in either * direction, being careful not to overrun or underrun the * tail and heads of the list */ WORD fs_1scroll(curr, count, touchob) REG WORD curr, count, touchob; { REG WORD newcurr; newcurr = (touchob == FUPAROW) ? (curr - 1) : (curr + 1); if (newcurr < 0) newcurr++; if ( (count - newcurr) < NM_NAMES ) newcurr--; return( (count > NM_NAMES) ? newcurr : curr ); } /* * Routine to take the filenames that will appear in the window, * based on the current scrolled position, and point at them * with the sub-tree of G_STRINGs that makes up the window box. */ VOID fs_format(tree, currtop, count) REG LONG tree; WORD currtop; WORD count; { REG WORD i, cnt; REG WORD y, h, th; LONG adtext, tlen; /* build in real text */ /* strings */ cnt = min(NM_NAMES, count - currtop); for(i=0; i NM_NAMES) { h = mul_div(NM_NAMES, h, count); h = max(gl_hbox/2, h); /* min size elevator */ y = mul_div(currtop, th-h, count-NM_NAMES); } LWSET(OB_Y(FSVELEV), y); LWSET(OB_HEIGHT(FSVELEV), h); } /* * Routine to select or deselect a file name in the scrollable * list. */ VOID fs_sel(sel, state) WORD sel; WORD state; { if (sel) ob_change(ad_fstree, F1NAME + sel - 1, state, TRUE); } /* * Routine to handle scrolling the directory window a certain number * of file names. */ WORD fs_nscroll(tree, psel, curr, count, touchob, n) REG LONG tree; REG WORD *psel; WORD curr, count, touchob, n; { REG WORD i, newcurr, diffcurr; WORD sy, dy, neg; GRECT r[2]; /* single scroll n times*/ newcurr = curr; for (i=0; i= 0) touchob = FUPAROW; else { touchob = FDNAROW; value = -value; } break; case F1NAME: case F2NAME: case F3NAME: case F4NAME: case F5NAME: case F6NAME: case F7NAME: case F8NAME: case F9NAME: fnum = touchob - F1NAME + 1; if ( fnum <= count ) { if ( (sel) && (sel != fnum) ) fs_sel(sel, NORMAL); if ( sel != fnum) { sel = fnum; fs_sel(sel, SELECTED); } /* get string and see */ /* if file or folder */ fs_sget(tree, touchob, ad_tmp1); if (gl_tmp1[0] == ' ') { /* copy to selection */ newname = TRUE; if (dclkret) cont = FALSE; } else { if (gl_shdrive) { /* prepend in drive name*/ if (locstr[1] == ':') locstr[0] = gl_tmp1[2]; } else { /* append in folder name*/ pstr = fs_pspec(&locstr[0], &locstr[fpath_len]); strcpy(pstr - 1, &gl_tmp2[0]); unfmt_str(&gl_tmp1[1], pstr); strcat(&gl_tmp2[0], pstr); } firsttime = TRUE; } gl_shdrive = FALSE; } break; case FCLSBOX: pspec = pstr = fs_back(&locstr[0], &locstr[fpath_len]); if (*pstr-- == '\\') { firsttime = TRUE; if (*pstr != ':') { pstr = fs_back(&locstr[0], pstr); if (*pstr == '\\') strcpy(pspec, pstr); } else { if (gl_bvdisk) gl_shdrive = TRUE; } } break; case FTITLE: firsttime = TRUE; break; } if (firsttime) { LSTCPY(ad_fpath, ad_locstr); D.g_dir[0] = NULL; gl_tmp1[1] = NULL; newname = TRUE; } if (newname) { LSTCPY(ad_fname, ad_tmp1 + 1); ob_draw(tree, FSSELECT, MAX_DEPTH); if (!cont) ob_change(tree, FSOK, SELECTED, TRUE); newname = FALSE; } if (value) curr = fs_nscroll(tree, &sel, curr, count, touchob, value); } /* return path and */ /* file name to app */ LSTCPY(pipath, ad_fpath); LSTCPY(ad_tmp1, ad_fname); unfmt_str(&gl_tmp1[0], &gl_tmp2[0]); LSTCPY(pisel, ad_tmp2); /* start the redraw */ fm_dial(FMD_FINISH, &gl_rcenter, &gl_rfs); /* return exit button */ *pbutton = inf_what(tree, FSOK, FSCANCEL); #if SINGLAPP dos_free(ad_fsnames); #endif return( TRUE ); }