Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator) (05/07/90)
Submitted-by: Richard Frost <rfrost@spam.ua.OZ.AU> Posting-number: Volume 90, Issue 164 Archive-name: applications/nv-2.32/part03 #!/bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 3 (of 6)." # Contents: Display.c NewsViewer/NV.pw.uu Select.c # Wrapped by tadguy@xanth on Sun May 6 18:08:55 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'Display.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Display.c'\" else echo shar: Extracting \"'Display.c'\" \(18075 characters\) sed "s/^X//" >'Display.c' <<'END_OF_FILE' X/* ======================================================================= */ X/* */ X/* PROGRAM: News View */ X/* */ X/* VERSION: 2.32 */ X/* */ X/* */ X/* FILENAME: Display.c */ X/* */ X/* DESCRIPTION: This module is a collection of routines that deal with */ X/* updating the display. */ X/* */ X/* AUTHOR: Copyright 1990 Richard Frost */ X/* */ X/* DATE: 22nd April 1990 */ X/* */ X/* ======================================================================= */ X X X#include "Defs.h" X#include "Globals.h" X#include "ShutDown.h" X#include "DefViewer.h" X#include "WindData.h" X#include "Gadgets.h" X#include "Select.h" X X X#define WINDOW_TITLE "News View: Version 2.32 By Richard Frost and Robert Wozniak" X#define SCREEN_TITLE "News View: Yet another product from 4.00 AM Hacks Inc." X X X/* Remove the line below to enable jump scrolling which involves X the clearing of the entire screen when a new screen of text is X displayed rather than clearing a line at a time and redrawing X text on top of it. X*/ X X#define NO_JUMP X XSHORT Reg_LEFT, X Reg_TOP, X Reg_RIGHT, X Reg_BOTTOM, X X Text_LEFT, X X Wind_Rows, X Wind_Cols, X Wind_FirstItem, /* # of first Item in window */ X X ArrowOffset=0, /* Y offset in pixels from the top of a character pos X where to start to draw the selector */ X X ItemsDisplayed=0, X MaxFirstItem=0; /* This is the Wind_FirstItem of the LAST allowable X window. It is the maximum value that Wind_FirstItem X can have. X */ X XUBYTE SubjColour=1, X SizeColour=0, X BgndColour=2; X XUWORD Text_Xsize, X Text_Ysize, X Text_Baseline; X Xstruct RastPort *Rp; X Xextern struct Window *OpenWindow(); Xextern BOOL GetScreenData(); X X X /* Useful macros: 1) ROW(n) obtains y pixel coord of bottom of row n, X 2) COL(n) obtains x pixel coord of right of col n X */ X X#define TEXT_OFFSET 1 X X#define ROW(n) (Reg_TOP + TEXT_OFFSET + (n)*Text_Ysize) X#define COL(n) (Text_LEFT + (n)*Text_Xsize) X X X X/* ======================================================================= */ X/* DrawArrow */ X/* ======================================================================= */ X/* Draw the arrow next to the current news item. */ X XPUBLIC VOID DrawArrow() X{ X DrawBorder(Rp,&Arrow,Reg_LEFT+2,Reg_TOP+(CurrentItem-Wind_FirstItem)*Text_Ysize+ArrowOffset); X} X X XPUBLIC VOID EraseArrow() X{ X DrawBorder(Rp,&BlankArrow,Reg_LEFT+2,Reg_TOP+(CurrentItem-Wind_FirstItem)*Text_Ysize+ArrowOffset); X} X X X/* ======================================================================= */ X/* SetGlobalVars */ X/* ======================================================================= */ X X/* Initialize all global variables, these are values that rarely change */ X XPUBLIC VOID SetGlobalVars() X{ X Rp = NV_Window->RPort; X X Text_Xsize = Rp->Font->tf_XSize; X Text_Ysize = Rp->Font->tf_YSize; X Text_Baseline = Rp->Font->tf_Baseline; X X X /* These values below are always relative to the upper left corner X of the window, and will not change with change in window size */ X X Text_LEFT = NV_Window->BorderLeft+Text_Xsize+4; X Reg_LEFT = NV_Window->BorderLeft-2; X Reg_TOP = NV_Window->BorderTop-1; X X Wind_FirstItem = 0; X X ArrowOffset = (Text_Ysize-7)/2; X X if (ArrowOffset <0) X ArrowOffset = -ArrowOffset; X} X X X/* ======================================================================== */ X/* SetWindowVars */ X/* ======================================================================== */ X XPUBLIC VOID SetWindowVars() X{ X register SHORT wid1,wid2,hgt; X static SHORT prev_windrows=10000; /* The previous number of rows X of text in the window */ X X wid1 = NV_Window->Width - NV_Window->BorderRight - Reg_LEFT; X wid2 = NV_Window->Width - NV_Window->BorderRight - Text_LEFT; X X hgt = NV_Window->Height - NV_Window->BorderBottom - NV_Window->BorderTop; X X Reg_RIGHT = Reg_LEFT + wid1 - 1; /* Calculate the max X coord of the region */ X Reg_BOTTOM = Reg_TOP + hgt; /* Calculate the max Y coord of region */ X X Wind_Cols = wid2 / Text_Xsize; X Wind_Rows = (hgt-TEXT_OFFSET) / Text_Ysize; X X /* Here we will ADJUST the variable "Wind_FirstItem" so that when a user X resizes the window from SMALL to LARGE, the larger window will have the X extra text row-space FILLED WITH TEXT (ie. there will be NO GAPS). X X OR, "Wind_FirstItem" will be set to zero as the window must be large enough X to see ALL the available news items!! X X The static variable "prev_windrows" stores the previous window size X (# rows of text). X X The algorithm is: X X If (Wind_Rows > prev_windrows) X { X addedrows = Wind_Rows-prev_windrows X Wind_FirstItem -= addedrows scroll the text down X if (Wind_FirstItem < 0) not enough text to scroll X Wind_FirstItem == 0 X } X X prev_windrows = Wind_Rows X X */ X X if (Wind_Rows > prev_windrows) /* Window is BIGGER than BEFORE! */ X { X Wind_FirstItem -= (Wind_Rows-prev_windrows); X if (Wind_FirstItem < 0) Wind_FirstItem = 0; X } X X prev_windrows = Wind_Rows; X X if (NumItems > Wind_Rows) X MaxFirstItem = NumItems - Wind_Rows; X else X MaxFirstItem = 0; X X SetDrMd(Rp,JAM2); X X} X X X/* ======================================================================== */ X/* MakeWindow */ X/* ======================================================================== */ XPUBLIC VOID MakeWindow() X{ X X register SHORT deltaX,deltaY, X deltaWid,deltaHgt; X X register struct Window *w; X X struct Screen WBscrn; X BOOL gotdata; X X X /* Find out the Screen Width & Height of the Workbench screen! */ X /* EVERYONE SHOULD OPEN WINDOWS LIKE THIS!!!!!!!!!!!!!!!!!!!! */ X X if (gotdata=GetScreenData(&WBscrn,sizeof(struct Screen),WBENCHSCREEN,NULL)) X { X NewWindowStructure1.TopEdge = WBscrn.TopEdge + WBscrn.BarHeight+2; X NewWindowStructure1.LeftEdge = WBscrn.LeftEdge; X NewWindowStructure1.Width = WBscrn.Width; X NewWindowStructure1.Height = WBscrn.Height - WBscrn.BarHeight-2; X } X X if ( (NV_Window = OpenWindow(&NewWindowStructure1)) == NULL) X ShutDown("Could not open the window!",FALSE); X X /* Set up the Menus! */ X X SetMenuStrip(NV_Window,&MenuList1); X X if (gotdata == FALSE) /* Resize to full size! */ X { X w = NV_Window; X X deltaX = w->WScreen->LeftEdge - w->LeftEdge; X deltaY = w->WScreen->TopEdge - w->TopEdge + 12; X deltaHgt = w->WScreen->Height - w->Height - 12; X deltaWid = w->WScreen->Width - w->Width; X X MoveWindow(w,deltaX,deltaY); X SizeWindow(w,deltaWid,deltaHgt); X } X X /* THE DEFINES FOR THESE 2 STRING ARGUMENTS BELOW ARE AT THE TOP X OF THIS SOURCE FILE X */ X X SetWindowTitles(NV_Window,WINDOW_TITLE,SCREEN_TITLE); X X} X X/* ======================================================================== */ X/* ClearWindow */ X/* ======================================================================== */ X XPUBLIC VOID ClearWindow() /* Completely erase ALL characters in the current window */ X{ X SetAPen(Rp,BgndColour); X RectFill(Rp,Reg_LEFT,Reg_TOP,Reg_RIGHT,Reg_BOTTOM); X} X X/* ======================================================================== */ X/* ClearRow */ X/* ======================================================================== */ X XPUBLIC VOID ClearRow(row) /* Erase ALL characters in a row */ XSHORT row; X{ X register SHORT tmp = Reg_TOP+TEXT_OFFSET+row*Text_Ysize; X X SetAPen(Rp,BgndColour); X RectFill(Rp,Reg_LEFT,tmp,Reg_RIGHT,tmp+Text_Ysize-1); X} X X X/* ======================================================================== */ X/* ClearFirstRow */ X/* ======================================================================== */ X XPUBLIC VOID ClearFirstRow() /* Erase ALL characters in the 1st row */ X{ X register SHORT tmp = Reg_TOP+TEXT_OFFSET; X X SetAPen(Rp,BgndColour); X RectFill(Rp,Reg_LEFT,tmp,Reg_RIGHT,tmp+Text_Ysize-1); X} X X/* ======================================================================== */ X/* ClearLastRow */ X/* ======================================================================== */ X XPUBLIC VOID ClearLastRow() /* Erase ALL characters in the LAST row */ X{ X register SHORT tmp = Reg_TOP+TEXT_OFFSET+Wind_Rows*Text_Ysize-1; X X SetAPen(Rp,BgndColour); X RectFill(Rp,Reg_LEFT,tmp,Reg_RIGHT,tmp+Text_Ysize-1); X} X X/* ======================================================================== */ X/* DrawItem */ X/* ======================================================================== */ X X/* This routine will display data corresponding to a news item pointed to by X "iptr". The types of data displayed is controlled by the global variables X "ShowNames" and "ShowSizes". The Subject string is always displayed but X is rendered in a colour dependent on whether the item has been read or not, X this is determined using by the "Status" feild of the ITEM structure. X*/ X XPUBLIC DrawItem(iptr) XITEM *iptr; X{ X char Buffer[8]; X register USHORT len, X colsleft; /* Number of window cols left X in which to display text */ X#define LOTS_OF_SPACES " " X X X SetBPen(Rp,BgndColour); /* Black Bgnd */ X colsleft = Wind_Cols; X X /* I KNOW Intuition clips Text() calls for you but X I WANT TO KNOW WHEN IT DOES SO for speedier window redraws ! */ X X if (ShowSizes) X { X SetAPen(Rp,SizeColour); /* Blue Fgnd */ X X/* sprintf(Buffer,"%5d ",iptr->FileBytes); X len = strlen(Buffer); X*/ X X len = iptr->fsize_len; X X if (len < colsleft) /* See if we had to clip text */ X { X Text(Rp,iptr->Filesize,len); X colsleft -= len; /* less space now to print in */ X } X else X { X Text(Rp,iptr->Filesize,colsleft); /* We did, thus JUMP OUT here! */ X return; /* NO MORE text can be displayed */ X } X X } X X X SetAPen(Rp,SubjColour); /* White Fgnd */ X X if (ShowNames) /* Print the filename of the newsitem?? */ X { X/* sprintf(Buffer,"%4s: ",iptr->Filename); X len = strlen(Buffer); X*/ X len = iptr->fname_len; X X if (len < colsleft) X { X Text(Rp,iptr->PrintedFilename,len); X colsleft -= len; X } X else X { X Text(Rp,iptr->PrintedFilename,colsleft); X return; X } X } X X /* Print the SUBJECT TITLE ALWAYS! */ X /* Change pen colour to ORANGE if item is READ */ X X /* NOTE: CHANGE THIS LATER ON, make a choice of this X colour intelligent! (ie != Bgnd col or Subj Col!! X */ X X X if (iptr->Status == READ) X SetAPen(Rp,(UBYTE) 3); /* Orange Fgnd */ X X/* len = strlen(iptr->Subject); */ X X len = iptr->fsubj_len; X X if (len < colsleft) X { X Text(Rp,iptr->Subject,len); X colsleft -= len; X } X else X { X Text(Rp,iptr->Subject,colsleft); /* not enough space for whole string */ X return; /* BAIL OUT!! */ X } X X#ifdef NO_JUMP X /* Fill rest of the space in with spaces, NO MORE FLASHY FLASHY redraws! */ X Text(Rp,LOTS_OF_SPACES,colsleft); X#endif X X} X X X/* ======================================================================== */ X/* RedrawWindow */ X/* ======================================================================== */ X X/* Redraw each menu item & clip if neccesary */ X XPUBLIC VOID RedrawWindow() X{ X X register SHORT i,ypos, X last_item; /* The number of the LAST item displayed */ X X /* ---------------------------------*/ X /* VARIABLE INPUT: Wind_FirstItem */ X /* ---------------------------------*/ X X /* This routine attempts to draw from item "Wind_FirstItem", which is the X number of the news item corresponding to the FIRST DISPLAYED ITEM at the X top of the window, to the last item that is DISPLAYABLE. X X An item cannot be displayed if: X X The item does not exist. This is when "Wind_FirstItem+Wind_Rows-1" is an X index value to the array "ItemList" (size NumItems) being larger than the X array's size. X NOTE: "NumItems-1" is the index of the LAST item in the array "ItemList". X */ X X X X /* See if we can draw Wind_rows rows of text */ X X last_item = Wind_FirstItem + Wind_Rows-1; X X if (last_item > NumItems-1) /* If there is not enough text left to do so ..*/ X last_item = NumItems-1; /* then stop with the last item in "ItemList" */ X X X /* Ypos of the FIRST DISPLAYED item */ X ypos = Reg_TOP + TEXT_OFFSET + Text_Baseline; X X ItemsDisplayed=0; X X#ifndef NO_JUMP X ClearWindow(); X#endif X X for(i= Wind_FirstItem; i <= last_item ;i++) X { X Move(Rp,Text_LEFT,ypos); /* Start text up against LEFT side of window */ X X DrawItem(ItemList[i]); X X ItemsDisplayed++; X ypos += Text_Ysize; /* Advance to next row */ X } X X} X X/* ======================================================================== */ X/* SyncDisplay */ X/* ======================================================================== */ X/* Call CentreOnItem() only if the current item is not visible. */ X XPUBLIC VOID SyncDisplay() X{ X register SHORT last_item; X X X /* calculate the last item displayed & see if Current item X is still visble. */ X X last_item = Wind_FirstItem + Wind_Rows-1; X if (last_item > NumItems-1) X last_item = NumItems-1; X X if (CurrentItem >= Wind_FirstItem && CurrentItem <= last_item) X { X RedrawWindow(); /* Current item is still visible ! */ X } X else X { X CentreOnItem(CurrentItem); X } X} X X X/* ======================================================================== */ X/* RedrawRow */ X/* ======================================================================== */ X X/* Redraw a given row (0=firstrow) and show its State accordingly as X either READ or UNREAD */ X X/* WARNING: NO CLIPPING is applied to this routine so make sure that there IS X an item on row "row"!!!!! X*/ X XPUBLIC VOID RedrawRow(row) XSHORT row; X{ X SetAPen(Rp,SubjColour); X SetBPen(Rp,BgndColour); X SetDrMd(Rp,JAM2); X X /* get into position! */ X Move(Rp,Text_LEFT,TEXT_OFFSET+Reg_TOP+Text_Baseline+row*Text_Ysize); X DrawItem(ItemList[Wind_FirstItem+row]); X} X X X/* ======================================================================== */ X/* ScrollDown */ X/* ======================================================================== */ X/* Scroll the window DOWN 1 row */ X XPUBLIC VOID ScrollDown(setpos) XSHORT setpos; X{ X VOID SetKnobPos(); X register SHORT last_item; X X if (Wind_FirstItem < MaxFirstItem) X { X Wind_FirstItem++; X /* SCROLL THE BITMAP UP BY ONE TEXT ROW */ X /* This leaves a gap in the LAST row that must be filled IF possible */ X X ScrollRaster(Rp,0,Text_Ysize,Text_LEFT,Reg_TOP+TEXT_OFFSET,Reg_RIGHT,ROW(Wind_Rows)-1); X X last_item = Wind_FirstItem + Wind_Rows-1; X X if (last_item <= NumItems-1) /* If there is an item in the last row */ X RedrawRow(Wind_Rows-1); /* then draw it.*/ X else X ItemsDisplayed--; /* else 1 less item was displayed */ X X if (setpos == UPDATESLIDER) X SetKnobPos(); X X } X X} X X/* ======================================================================== */ X/* ScrollUp */ X/* ======================================================================== */ X/* Scroll the window UP 1 row */ X XPUBLIC VOID ScrollUp(setpos) XSHORT setpos; X{ X VOID SetKnobPos(); X register SHORT last_item; /* The item # for item that occurs on the LAST row */ X X if (Wind_FirstItem > 0) X { X Wind_FirstItem--; X X /* Scroll the BITMAP DOWN 1 ROW */ X ScrollRaster(Rp,0,-Text_Ysize,Text_LEFT,Reg_TOP+TEXT_OFFSET,Reg_RIGHT,ROW(Wind_Rows)-1); X X RedrawRow(0); /* FIll the gap left in the first row with text */ X /* WE CAN ALWAYS DO THIS */ X last_item = Wind_FirstItem + Wind_Rows-1; X X if (last_item > NumItems-1) /* If no item exists on last row */ X ItemsDisplayed++; /* then 1 more has been displayed */ X X if (setpos == UPDATESLIDER) X SetKnobPos(); X X } X} X X X/* ======================================================================== */ X/* UnreadAll */ X/* ======================================================================== */ X/* Unread ALL items!! */ X XPUBLIC VOID UnreadAll() X{ X register SHORT i; X X for (i=0 ; i < NumItems; i++) X ItemList[i]->Status = UNREAD; X X RedrawWindow(); X} END_OF_FILE if test 18075 -ne `wc -c <'Display.c'`; then echo shar: \"'Display.c'\" unpacked with wrong size! fi # end of 'Display.c' fi if test -f 'NewsViewer/NV.pw.uu' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'NewsViewer/NV.pw.uu'\" else echo shar: Extracting \"'NewsViewer/NV.pw.uu'\" \(10239 characters\) sed "s/^X//" >'NewsViewer/NV.pw.uu' <<'END_OF_FILE' Xbegin 666 NV.pw XM4&]W97)7:6YD;W=S('8R+C4@+"`@:6UP;W)T960@8GD@455!4E1%6"!C<F%C1 XM:RUT96-H;F]L;V=I97,@,3DX."`@("`@("`@("`@```#]`````D@`0#_````6 XM`0`````!``````YD9C$Z3E9'861S,BYH```````````!``(0+P`$$WH`9``ZA XM_____P`C=.`````````````````````````````*`/A*`````````0```0``! XM`#T">P!?``4`!?____\````^3F5W<R!6:65W.B`@5F5R<VEO;B`R+C-A("!"K XM>2!2:6-H87)D($9R;W-T(&%N9"!2;V)E<G0@5V]Z;FEA:P``(R#8``+_]``VN XM``P`#@"#``$`^&I@`/AR2````````````````````"!R,/____\#```%`",@; XMO````````````#<````W``T````-````````````-@`,``(``<2X`P``````( XM````P/________P`________\`#_SY___\_P`/QGG___S_``_/.?SSWS\`#_% XM^9QGD,/P`/_MG\9CS_``_^>>$[3)\`#_YZ?C&/'P`/_'Q@8QP_``_X\/____O XM\`"`````````````````````````````#``\/W___[_\`#N>?___/_P`/XY\) XM/O(/_``_AGN<;S_\`#^2>#^?/_P`/YAY[TLW_``_G%P<YX_\`#^^/_____P`: XM/'_______`!________\````````-@`,``(``>[``P``````````P/______: XM__P`````````#``"@(```$`,``Q"BJJJ2JP`!"$511E17``*T(PBD(*L``4IP XM%41!15P`"L**$I2(K``%)2:@B%%<``K#0@(@@JP`!H4%55557``?_______\P XM````````````________\`#]?W___[_P`/N_?___O_``_][^OO:O\`#_KWO=L XM;W_P`/_6^K^_O_``_[U][VMW\`#_WMU?=Z_P`/^^O_____``_7______\`#@T XM``````````````@`"`"#`/AI2`#X:P@`^'!``/AX4`#X=+@`^(5P````"4YE< XM>'1)=&5M``````$``````0`````*3F5X=%])=&5M``````$``````0``(R(0K XM`#C_]``V``P`#@"#``$`(9,H`"&4$````````````````````"&7:/____\#_ XM```%`",A%````````````#<````W``T````-````````````-@`,``(``>^(A XM`P``````````P/________P`________\`#__Y_____P`/Q@S_____``^.?,P XMY\\Y\`#_YYT$9SSP`/__#C_!D/``_^`\?A*C\`#_Y_S[X\?P`/_G\/P'#_``2 XM_X?_____\```````````````````````````````#``\`'_____\`#N?/___) XM__P`/Y\S'#SW_``_GV+[F./\`#^`\?@^;_P`/Y_S^>]?_``_G_/\'S_\`#^?S XM______P`/W_______`#________\````````-@`,``(``?!0`P``````````L XMP/________P`````````#``"JH`````,``0@155555P`",*(HHHHK``%)94$3 XM10A<``K5"BJ`D*P`!2`45!"A7``*PJBJHD*L``4E4%0%!5P`"H*JJJJJK``?S XM_______\````````````________\`#]57_____P`/O?O_____``_[]W77WWK XM\`#_WVK[NO?P`/^J]?U_;_``_]_[^^]?\`#_O_?]7[_P`/_?______``_W__F XM____\`#@``````````````@`"`"#`"!98`#XBQ``(%I8`"!;L``@<8``('Z0( XM````"5!R979)=&5M``````$``````0`````*4')E=E])=&5M``````$`````- XM`0``(R1P`'C_]`!```P`#@"#``$`(9F0`"+!*````````````````````"+!Y XM>/____\#```%`",B3````````````$$```!!``T````-`````/_V````6``," XM``(``A2@`P`````````!(/______________`/_/_________\_\`/_/__Y_M XM__^?_\_\`/_/\8,___X?_\_\`/_/XY\_/,YYS\_\`/_/_YXQG69YS\_\`/_/Z XM__Q_#F99S\_\`/_/_[#X3$<ZS\_\`/_/_YGOCXXLS\_\`/_/_XR0'!APS\_\< XM`/_/_A,?_/__C\_\```````````````````````````````````P````````" XM`#`#`#_S\`'___Q___/_`#_S[GS___G___/_`#_S_GSP\SGG/_/_`#_S_GWN^ XM8IG'/_/_`#_S_@/@\9GF/_/_`#_S_D_GL[CE/_/_`#_S_F?P<'GS/_/_`#_S4 XM_G-_\___/_/_`#_S_?S_\__X?_/_`/______________```"````0``,``(`< XM`A7(`P``````````P/__________``````````,`JJ```!```P40(5550557' XM"BB2HHBC!*L%46$)4D:85PJJ@U"D(12K!5$$A$10J%<*J(JHJ*+$JP50B0%!` XM!0A7"J$@JHJJJ*L?_________P``````````__________S_55___^___/[OU XMW___O__\__?O7W?>^_S_[][VK;UW_/_U?J];WNO\_^[_>[NO5_S_]W]75]\[H XM_/_O=_^___?\_]_?_W__U_S@``````````````@`"`"#`"&=H``A2+@`(9%@B XM`"+#H``ADM@`(K*(````"DYE>'1297!L>0`````!``````$`````"TYE>'1?L XM4F5P;'D``````0`````!```C)/``QO_T`#L`#``.`(,``0`BT#@`(O]`````B XM````````````````(R3(_____P,```4`(R2L````````````/````#P`#0``+ XM``T````````````[``P``@`"&Q@#``````````#`_________^#_________@ XM@/__\Y___S^`_XP#'___/X#_G/^<Y^?/@/_\_YT&$P^`__\_GCW#/X#_S#_,Y XM?#,C@/_,_XS_X\.`__C_&/X'#X#_\?______@```````````````````````: XM````````8#^`#G___O_@/W/____\_^`_\_YS'!@_X#_S_&+Y[/_@/\#^<?X\$ XM_^`_L_XS^\S?X#_S_G/\'C_@/_?______^`_#_______X/_________@````W XM```[``P``@`"&^`#``````````#`_________^``````````8`!54(```(!@' XM!8@!%556%6`*A*L(HJ5*X`585I4$$@5@"I4K&BE!*N`%2!2$5"(A8`J$JPBJ7 XMHT+@!5A5$%0%!6`*H*JJJJJJX!_________@``````````#_________@/^J\ XMKW___W^`_W?____]_X#_^_[W75J_@/_W_6K[[?^`_^K^]?Z^_X#_M_][^]W?! XM@/_[_O?]7K^`__?______X#_7_______@.``````````````"``(`(,`(L9XF XM`"++Z``BT.@`(O]@`"+3(``BV7`````*1FER<W1)=&5M``````$``````0``3 XM```+1FER<W1?271E;0`````!``````$``",IX`$!__0`-@`,``X`@P`!`",/J XMB``C)4@````````````````````C)6C_____`P``!0`C)2P````````````WW XM````-P`-````#0```````````#8`#``"``(<J`,``````````,#________\4 XM`/________``__/____/\`#_P____\_P`/_/__/Y\_``_\_^,X3#\`#_S_YSG XM<,_P`/_/_KD,R?``_X_G$?CQ\`#_\\8S@</P`/\/C_____``````````````! XM``````````````````P`/X____^__``_/____S_\`#\__@\&#_P`/S_]SGL_G XM_``_/_F/CS_\`#\_^4;S-_P`/W_<[P>/_``^#[_____\`#_P?_____P`____S XM_____````````#8`#``"``(=<`,``````````,#________\``````````P`1 XM`%````!`#``%@555545<``I*JJ*I4JP`!855((2!7``*2JI24$JL``6%5*D(. XMB5P`"@JA$*C0K``%4401`4%<``H*BJJJJJP`'________````````````/__S XM______``_Z____^_\`#_?____[_P`/^__U]6K_``_W_^WWM_\`#_O_VOK[_P. XM`/]_^U;W=_``___>[U>O\`#^K[_____P`/_U?_____``X``````````````(/ XM``@`@P`C)9``(N=0`",B:``C):@`(R7``",ET`````E,87-T271E;0`````!F XM``````$`````"DQA<W1?271E;0`````!``````$``",OB`$W__0`H``,``\`/ XM@P`!`",J.``````````````````````````C*EC_____`P``!0`C*AP`````; XM``````"A````H0`-````#0```````````*``#``"``(>.`,``````````>#_% XM___________________________/_______________________Q_\___\__U XM_S__/G/___________'_S_X8#___/_\_(________S__\?_/_GG_//?/^9XSA XM\\_G\\Y_/__Q_\__^?&>0P_YS',9S_,9T'\___'_S__Y_QF//__,\_%DX_'C? XM_S__\?_/__GX3M,G_^CYA.M'A,?_/\/Q_\__^G^,8\?_\?'X\8_XS_\\/_'_- XMS__\>!C'#__SXX'C'X&/_P/_\?_/_^#______^/_________/__Q````````] XM``````````````````$````````````````````````````P````````````Q XM```````````./_/^`#___O_\_<________\___X_\_WG___\__CX________P XM_\/__C_S_^?P^\@_]GW/#S_?#S'_^#_^/_/_Y^YQO/__.X[F/X[F+___@_X_L XM\__GX/Y\__\[S@^;W@\?___X?C_S_^?GO2S?_Y?&>]2^>S_____^/_/_Y?!S" XMGC__S\\'SG\'/_____X_\__#_______/_____________C_S____________K XM___________^__________________________X````(``L`@``C)>``(RL@* XM`",K,``C*T``(RM0`",K8`````$``````0`````!``````$``````0`````!> XM```C,.C_ZO_I`!4`"P`>`!,``0`C*W``(R_@````````````````````(S!0Q XM_____P,```4`(R_$````````````%@```!8`#`````P````````````5``L`^ XM`@``&,`#``````````!8___P`/__X`#_\^``__/@`/_^(`#__&``__C@`/_QD XMX`#_X^``_^?@`.````````@`#__X``^?^``/G_@`"/_X``Q_^``./_@`#Q_X/ XM``^?^``/W_@`'__X````````%0`+``(``<6``P``````````6,``"`#"JK@`1 XMQ5%8`,*BN`#%5!@`PJ@X`,506`#"H+@`Q4%8`,*BN`#/__@`/__P`#__X``_O XMO^``/]_@`#K_X``]?^``/K_@`#]?X``_O^``/]_@`#`````````(`!@`$P`C/ XM,'@`(S"0`",PH``C,+``(S#(`",PV`````M$;W=N0G5T=&]N``````$`````G XM`0`````,1$]73E]"55143TX``````0`````!```C6YC_ZO_>`!4`"P`>`!,`O XM`0`C,4``(SE0````````````````````(T=0_____P,```4`(S$D````````W XM````%@```!8`#`````P````````````5``L``@`"("`#``````````!8___PQ XM`/_GX`#_X^``__'@`/_XX`#__&``__X@`/_SX`#_\^``___@`.````````@`1 XM#]_X``^?^``/'_@`#C_X``Q_^``(__@`#Y_X``^?^``/__@`'__X````````A XM%0`+``(``C`H`P``````````6,``"`#%15@`PJ*X`,516`#"J+@`Q518`,*J* XM.`#%45@`PJ*X`,556`#/__@`/__P`#__X``_W^``/[_@`#]_X``^_^``/?_@Y XM`#^_X``_W^``/__@`#`````````(`!@`$P`C1W@`(S%@`"-1<``C48``(UMX! XM`"-;B`````E5<$)U='1O;@`````!``````$`````"E507T)55%1/3@`````!] XM``````$``"-JF/_J``H`%O_3`%``$P`#`"-;\``````````````````C7!``D XM```C7##_____`P``!0`C6]0````````````7````%P`S````,P``````````9 XM``X`+@`````````````````````!!?__``#_____````"@!0`!L`(VHH`"-JS XM0``C:E``(VI@`"-J>``C:H@````+5F5R=%-L:61E<@`````!``````$`````U XM#%9%4E1?4TQ)1$52``````$``````0```````=G_]?YF``H`*`*#``0`(VK$O XM`````````````````"-T&````"-T2/____\#```%`"-JU````````````.(`5 XM``#B``L````+```````````````41&5F875L=``@("`@("`@("`@(``````*[ XM`"@"@P`C='``(W2(`"-TF``C=*@`(W3``"-TT`````I3=')I;F='860`````, XM`0`````!``````M3=')I;F=?1V%D``````$``````0``(W4``P```````%``< XM"@`C=1``(W78````"%!R;VIE8W0``"-UN``C=<@`40`C=3``````$```````: XM``````4``@,`!``!``$```!0``H```````````````51=6ET``````$``"-UK XM^`,``%````!0``H`(W80`".+H`````E3971T:6YG<P``(W98`"-V>````"-V1 XM,``C=H@0```C=[@`````!0`"`P`$``$``0```*``"@``````````````%$-LP XM:6-K(%-E;&5C="`@("`@(+L``````0``(W;0`"-VX#0Q`"-VJ``C=O`````"& XM!0(#`0`6``$`D?_[`',`"@``````````````!U-I;F=L90`````!```C=Q``^ XM(W<@/#(`(W>0``````````$%`@,!`!8``0"1``4`<P`*```````````````'/ XM1&]U8FQE``````$``"-X```C>"`````C=]@`(W@P,```(WXX``````4``@,`" XM!``!``$`#P"@``H``````````````!13=6)J96-T("`@($-O;&]U<B"[````R XM``$``"-X>``C?/`D```C>%``(WT`````#@4!````%``!`)'_\0!.``H`````4 XM``````````@@("`@("`@``````$``"-]2``C?5@L```C?2``(WUH````#04!0 XM`0$`%``!`)'_^P!.``H```````````````@@("`@("`@``````$``"-]L``C6 XM?<`D```C?8@`(WW0````"P4!`@(`%``!`)$`!0!.``H```````````````@@Y XM("`@("`@``````$``"-^&``C?B@D```C??``````````!P4!`P,`%``!`)$`P XM#P!.``H```````````````@@("`@("`@``````$``"-^@``C?J`````C?E@`K XM(WZP$```(X!0``````4``@,`!``!``$`&0"@``H``````````````!1)=&5M* XM(%-I>F4@($-O;&]U<B"[``````$``"-^^``C?P@L```C?M``(W\8````#@4!Y XM````%``!`)'_\0!.``H```````````````@@("`@("`@``````$``"-_8``C\ XM?W`D```C?S@`(W^`````#04!`0$`%``!`)'_^P!.``H```````````````@@$ XM("`@("`@``````$``"-_R``C?]@D```C?Z``(W_H````"P4!`@(`%``!`)$`0 XM!0!.``H```````````````@@("`@("`@``````$``".`,``C@$`D```C@`@`+ XM````````!P4!`P,`%``!`)$`#P!.``H```````````````@@("`@("`@````( XM``$``".`F``C@+@````C@'``(X#($```(X)H``````4``@,`!``!``$`(P"@% XM``H``````````````!1"86-K9W)O=6YD($-O;&]U<B"[``````$``".!$``CE XM@2`D```C@.@`(X$P````!@4!````%``!`)'_\0!.``H```````````````@@& XM("`@("`@``````$``".!>``C@8@D```C@5``(X&8````#04!`0$`%``!`)'_7 XM^P!.``H```````````````@@("`@("`@``````$``".!X``C@?`L```C@;@`< XM(X(`````"P4!`@(`%``!`)$`!0!.``H```````````````@@("`@("`@````E XM``$``"."2``C@E@D```C@B``````````!P4!`P,`%``!`)$`#P!.``H`````T XM``````````@@("`@("`@``````$``"."L``CBK`````C@H@`(XK`$```````% XM``````4``@,`!``!``$`,@"@``H``````````````!1396%R8V@@:7,@8V%SI XM92`N+B"[``````$``".+"``CBR`T10`CBN``(XLP`````@4"`P$`%@`!`)'_9 XM^P"6``H```````````````I396YS:71I=F4``````0``(XMX`".+D#Q)`".+W XM4``````````!!0(#`0`6``$`D0`%`)8`"@``````````````#$EN<V5N<VET" XM:79E``````$``".+P`,``*D```!7````(XO8`"/1``````M.97=S($ET96USZ XM```C'#``(ODH````(XOX`"//2!```"/0&`````$%`@,!``0``0`!````KP`*X XM```````````````64VAO=R!.97=S($ET96T@+BX@(""[``````$``"//D``C@ XMSZ`03@`CSV@`(\^P`````04"`P$`!``!`(G_^P!:``H```````````````9.5 XM86UE<P`````!```CS_@`(]`($%,`(\_0``````````(%`@,!``0``0")``4`1 XM6@`*```````````````&4VEZ97,``````0``(O\H`",<"!!&`"/0.``````0: XM```CT(@`````!0(#`0`$``$``0`*`*\`"@``````````````#E-T<FEN9R!3' XM96%R8V@``````0``(OJH`"+Y.!!5`"/0J``````0````````````!0(#`0`$Z XM``$``0`>`*\`"@``````````````$55N<F5A9"!!3$P@271E;7,``````0``E XM(]$@`P`!$0```&<````CT3@`(]&H````#4AI<W1O<GD@1FEL90``(]&``"/1? XMF!```"/16``````0````````````!0(#`0`$``$``0```'H`"@``````````9 XM````#U5P9&%T92!(:7-T;W)Y``````$``"/1R`,``8D````O````(]'8````) XM``````9!8F]U=```(](@`"/2.````"/1^``````0````````````!0(#`0`$. XK``$``0```(P`"@``````````````$$%B;W5T($YE=W,@5FEE=P`````!```$@ X`` Xend Xsize 7288 END_OF_FILE if test 10239 -ne `wc -c <'NewsViewer/NV.pw.uu'`; then echo shar: \"'NewsViewer/NV.pw.uu'\" unpacked with wrong size! fi # end of 'NewsViewer/NV.pw.uu' fi if test -f 'Select.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Select.c'\" else echo shar: Extracting \"'Select.c'\" \(15072 characters\) sed "s/^X//" >'Select.c' <<'END_OF_FILE' X/* ======================================================================= */ X/* */ X/* PROGRAM: News View */ X/* */ X/* VERSION: 2.3a */ X/* */ X/* */ X/* FILENAME: Select.c */ X/* */ X/* DESCRIPTION: This module is a collection of routines that handle */ X/* the selection of items in the window uisng the mouse. */ X/* */ X/* AUTHOR: Copyright 1990 Richard Frost */ X/* */ X/* DATE: 22nd April 1990 */ X/* */ X/* ======================================================================= */ X#include "Defs.h" X#include "Globals.h" X#include "Winddata.h" X#include "Request.h" X#include "Display.h" X X /* Variables to keep track of what the current item is */ X XSHORT CurrentRow = 0, /* # of Current Row the arrow is on */ X PreviousRow = 0, X CurrentItem = 0, X PreviousItem = 0; X X /* REPLY VARIABLES */ X#define WORD_LEN 30 XSHORT NumKeywords=0; XUBYTE keyword[3][WORD_LEN+1]; /* 3 keywords thanks! */ X X X/* ======================================================================= */ X/* GoReadItem */ X/* ======================================================================= */ X X/* Execute the TEXT READER and give it the filename */ X XPUBLIC VOID GoReadItem(item) XSHORT item; X{ X VOID RedrawRow(); X X if (StringGadSInfo.Buffer[0] != '\0') X { X if (strcmp(StringGadSInfo.Buffer,"Default") == 0) X { X if (ViewNewsItem(ItemList[item]->Filename,ItemList[item]->Subject) == TRUE) X { X ItemList[item]->Status = READ; X RedrawRow(item-Wind_FirstItem); X } X else X ErrorMsg("Couldn't use the Default Viewer on that item!"); X } X else X if (ExternalReadItem(item,StringGadSInfo.Buffer) == FALSE) X { X ErrorMsg("Couldn't use YOUR text viewer, so I'll try mine!"); X if (ViewNewsItem(ItemList[item]->Filename,ItemList[item]->Subject) == TRUE) X { X ItemList[item]->Status = READ; X RedrawRow(item-Wind_FirstItem); X } X else X ErrorMsg("Couldn't use my Default Viewer either!"); X } X else X { X ItemList[item]->Status = READ; X RedrawRow(item-Wind_FirstItem); X } X } X} X X X/* ======================================================================= */ X/* SelectMouse */ X/* ======================================================================= */ X XPUBLIC VOID SelectMouse(CurrentRow,CurrentSecs,CurrentMicros) XSHORT CurrentRow; XLONG CurrentSecs,CurrentMicros; X{ X static LONG StartSecs, X StartMicros; X static SHORT StartRow, X ClickNum=1; X X SHORT ChosenItem; X X BOOL DoubleClick(); X VOID SetCurrentItem(); X X X if (ClickSelect == 1) /* If a selection is ONE mouse click ... */ X { X ClickNum = 1; X ChosenItem = Wind_FirstItem+CurrentRow; X EraseArrow(); X SetCurrentItem(ChosenItem); X DrawArrow(); X GoReadItem(ChosenItem); X } X else X { X if (ClickNum == 1) /* first click */ X { X ClickNum++; /* Keep track of clicks */ X StartSecs = CurrentSecs; /* Store "DoubleClick" params */ X StartMicros = CurrentMicros; X StartRow = CurrentRow; X } X else X { X if (CurrentRow == StartRow) X { X /* Okay, we hit on the SAME row as before, lets X check if the double click was OK! X */ X X if (DoubleClick(StartSecs,StartMicros,CurrentSecs,CurrentMicros)) X { X ChosenItem = Wind_FirstItem+CurrentRow; X EraseArrow(); X SetCurrentItem(ChosenItem); X DrawArrow(); X GoReadItem(ChosenItem); X } X else X ClickNum = 1; /* double click no good, start again! */ X } X else X { X /* User moved rows on the second click!!, arrgh! X Make this NEW row as the FIRST row clicked on. X */ X X StartSecs = CurrentSecs; /* Store "DoubleClick" params */ X StartMicros = CurrentMicros; X StartRow = CurrentRow; X ClickNum = 2; /* Reset click counter */ X } X } X } X} X X X/* ======================================================================== */ X/* TouchedItem */ X/* ======================================================================== */ XPUBLIC BOOL TouchedItem(selrow) XSHORT *selrow; X{ X *selrow = (NV_Window->MouseY - Reg_TOP)/Text_Ysize; X X /* Test to see if an item is X 1: within window row limits X 2: the one the mouse pointer touched X */ X X if (*selrow < Wind_Rows) X { X if ((Wind_FirstItem + *selrow) < NumItems) X return TRUE; X } X X return FALSE; X} X X X/* ======================================================================== */ X/* SetCurrentItem */ X/* ======================================================================== */ X/* Make item x the current item, this routine will save the previous X current item so PrevItem will work. This is also used when the X MOUSE selects an item. X*/ X XPUBLIC VOID SetCurrentItem(x) XSHORT x; X{ X PreviousItem = CurrentItem; X CurrentItem = x; X X PreviousRow = CurrentRow; X CurrentRow = x-Wind_FirstItem; X} X X X/* ======================================================================== */ X/* GetPrevItem */ X/* ======================================================================== */ X/* Return the item that was JUST READ */ X XPUBLIC SHORT GetPrevItem() X{ X return PreviousItem; X} X X X/* ======================================================================== */ X/* GetNextItem */ X/* ======================================================================== */ X/* Return the next item to read THAT IS UNREAD <= make this an option? */ X XPUBLIC SHORT GetNextItem() X{ X /* Search for the next ITEM with status UNREAD */ X register SHORT i,cnt; X X i = CurrentItem; X cnt = 0; X X while (cnt <= NumItems) X { X if (ItemList[i]->Status == UNREAD) X return i; X X cnt++; X i++; X i %= NumItems; /* Allow Wrap around! */ X X } X X DisplayBeep(NULL); /* NO MORE ITEMS TO READ !!!! */ X return i; X} X X X X/* ======================================================================== */ X/* */ X/* Reply Functions */ X/* */ X/* ======================================================================== */ X X/* This routine will search for the next WORD in the string STR X and will return a pointer to where the search ended so that X NextWord() could be called again with the return pointer X as the new STR argument to find the next word. X X NextWord() returns 0 when NO word is found. X X The found word is stored in the char array "WORD". X X NOTE: Ensure the WORD array is defined as WORD[WORD_LEN+1] AT LEAST! X X NOTE: NEXT WORD WILL REJECT the WORD "re:" "RE:" etc. X*/ X X X/* ======================================================================== */ X/* NextWord */ X/* ======================================================================== */ X XPRIVATE UBYTE *NextWord(str,word) /* Retreive the NEXT word (skip white space) */ XUBYTE *str; XUBYTE *word; X{ X X register UBYTE *ch = str; X register UBYTE *cp = word; X register SHORT len = 0; X register UBYTE R,E; X register SHORT WordNotFound=1; X X X while (WordNotFound) X { X WordNotFound = 0; X X /* SKIP COLONS skip whitespace: TABS & SPACES */ X while (*ch && (*ch == ' ' || *ch == '\t')) X ch++; X X /* Copy the word over ! STOP AT SPACES, TABS AND X ":" <= used to trap Re:'s as 'Re:hhshsh' becomes 'Re' and 'hshsh' X */ X X while (*ch && *ch != ' ' && *ch != '\t') X { X if (*ch == ':') /* check for a RE: */ X { X if (len >=2 ) /* enough room to back up ?*/ X { X R = tolower(*(ch-2)); /* get 2 chars before the colon */ X E = tolower(*(ch-1)); X X if (R == 'r' && E =='e') /* are they a RE? */ X { X len = 0; /* if so, reset the found word */ X cp = word; X ch++; /* Advance over the colon char */ X WordNotFound = 1; /* We want another word! */ X continue; /* BACK to the while loop! */ X } X } X } X X if (len < WORD_LEN) X { X *cp++ = *ch++; X len++; X } X else X { X ch++; X#ifdef LOUD X printf("\nNo keyword space left!\n"); X#endif X } X } X }; X X if (len == 0) /* Did NOT copy a word into the buffer! */ X return 0; /* return ABORT code! */ X else X { X *cp = '\0'; /* NULL terminate the copied word */ X return ch; /* return where we got up to */ X } X X} X X X/* =================================================================== */ X/* This routine will set the Array of 3 strings to the keywords found X in the current line and will return the NUMBER of keywords found. X*/ X XPRIVATE SHORT GetSearchStrings(line) XUBYTE *line; X{ X UBYTE *NextWord(); X X register UBYTE *pos=line,*kywd; X register SHORT numfound=0; X X while (*pos && numfound < 3) X { X kywd = keyword[numfound]; /* get start addr of keyword str */ X X if (pos = NextWord(pos,kywd)) X numfound++; /* If Got a word .. */ X else break; X } X X return numfound; X} X X/* =================================================================== */ X/* Do the first chars of the string STR contain the key? */ X XPRIVATE BOOL SubStr(k,str) XUBYTE *k,*str; X{ X register UBYTE *ch=str; X register UBYTE *key=k; X X while (*key && *ch) /* Step both arrays for each successful match */ X if (tolower(*key) == tolower(*ch)) X { X#ifdef VLOUD X printf("KEY = [%c] STR = [%c]\n",tolower(*key),tolower(*ch)); X#endif X key++; ch++; X } X else X break; /* Failed match!, stop stepping */ X X if (*key) /* All of key matched? */ X return FALSE; X else /* Yes, we are pointing to the NULL of the keyword! */ X return TRUE; X} X X/* =================================================================== */ X/* Is the STRING STR a reply with respect to the 3 keyword search X strings? X X A return of TRUE occurs ONLY when the 3 search keywords are X matched IN ORDER with no bad matches in between. X X If a BAD match occurs then the search continues with the search X keyword reset to the FIRST search keyword. X X*/ X XUBYTE word[WORD_LEN+1]; X XPRIVATE BOOL IsReply(str) XUBYTE *str; X{ X UBYTE *NextWord(); X X register UBYTE *pos=str,*kywd; X register SHORT kwdmatches=0; X X#ifdef LOUD X printf("\nANALYSING LINE[%s]\n",str); X#endif X X while (*pos && kwdmatches != NumKeywords) X { X if (pos = NextWord(pos,word)) /* If Got a word .. */ X { X X#ifdef LOUD X printf("Got the word [%s]\n",word); X#endif X if (SubStr(keyword[kwdmatches],word)) /* a match ?! */ X { X X#ifdef LOUD X printf("Matched keyword [%s]!\n",keyword[kwdmatches]); X#endif X kwdmatches++; X } X else X kwdmatches = 0; /* No, reset to FIRST search token */ X } X else break; X } X X if (kwdmatches == NumKeywords) X return TRUE; X else X return FALSE; X} X X X/* ======================================================================== */ X/* GetNextReply */ X/* ======================================================================== */ X/* Return the next item to read that is a reply to the current Item. */ X XPUBLIC SHORT GetNextReply() X{ X /* Search for the next ITEM that has the same inital 3 keywords of the X "Subject:" field of the CURRENT ITEM. X */ X X BOOL IsReply(); X SHORT GetSearchStrings(); X X register SHORT i, /* Current item to be searched */ X cnt; /* Number of items searched thru */ X X#ifdef LOUD X int j; X#endif X X X X i = CurrentItem; X cnt = 0; X X if (NumItems > 1) /* Cant have a reply if 1 item only!! */ X { X X#ifdef LOUD X printf("Current Item = %d\n",i); X printf("NumItems = %d\n",NumItems); X#endif X X /* Get all the keywords to search! */ X NumKeywords = GetSearchStrings(ItemList[i++]->Subject); X X#ifdef LOUD X for(j=0; j < NumKeywords; j++) X printf("Search Keyword %d is [%s]\n",j,keyword[j]); X#endif X X X while (cnt < NumItems-1) X { X i %= NumItems; /* Allow Wrap around! */ X X if (IsReply(ItemList[i]->Subject)) X return i; X i++; X cnt++; X } X } X X DisplayBeep(NULL); /* NO MORE ITEMS TO READ !!!! */ X return i; X} X X/* ======================================================================== */ X/* CentreOnItem */ X/* ======================================================================== */ X/* Centre the screen about item x ... used in NEXT & PREV calculations.*/ X XPUBLIC VOID CentreOnItem(x) XSHORT x; X{ X register SHORT CentreRow=0; X X if (x < Wind_FirstItem) /* We want to jump UP to item x */ X { X if (Wind_Rows % 2) CentreRow = Wind_Rows/2; X else CentreRow = Wind_Rows/2 - 1; X X if (x >= CentreRow) X { X Wind_FirstItem = x - CentreRow; X } X else X { X Wind_FirstItem = 0; X } X X SetCurrentItem(x); X RedrawWindow(); X SetKnobPos(); X } X else /* We want to jump DOWN to item x */ X if (x > (Wind_FirstItem+Wind_Rows -1)) X { X if (Wind_Rows % 2) CentreRow = Wind_Rows/2; X else CentreRow = Wind_Rows/2 - 1; X X if (x < (NumItems - CentreRow)) /* <= Equiv. to (x <= (NI-CR-1) ) */ X { X Wind_FirstItem = x - CentreRow; X } X else X { X Wind_FirstItem = MaxFirstItem; X } X X SetCurrentItem(x); X RedrawWindow(); X SetKnobPos(); X } X else /* The item is displayed in the window!, so lets move to it */ X { X SetCurrentItem(x); X } X} END_OF_FILE if test 15072 -ne `wc -c <'Select.c'`; then echo shar: \"'Select.c'\" unpacked with wrong size! fi # end of 'Select.c' fi echo shar: End of archive 3 \(of 6\). cp /dev/null ark3isdone MISSING="" for I in 1 2 3 4 5 6 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 6 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Mail submissions (sources or binaries) to <amiga@cs.odu.edu>. Mail comments to the moderator at <amiga-request@cs.odu.edu>. Post requests for sources, and general discussion to comp.sys.amiga.