English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Language > Coders. C/C++

 
 
Thread Tools
Old 01 August 2017, 12:34   #1
chocsplease
Registered User
 
Join Date: Dec 2016
Location: london
Posts: 178
Question [Solved] Problems trying to output text to a simple window

Hello all,

I am trying to output text to a window and have run into a number of issues.

I had assumed that the Amiga would be nice and if I set up a window with drag bars and resize etc gadgets it would take care of text that was larger than the size of the window.

It looks like I was wrong.

I am defining my window thus
Code:
int open_window(int scrnwidth,int scrnheight)
{
    int topleftx=0,toplefty=0;
    int width=200,height=200;
    int tempw=0,temph=0;
/*calculate 1 quarter of screen width*/

    if (mywindow)
        return 0; /*opened already*/

    tempw=scrnwidth/4;

/*calculate 1 5th screen height*/

    temph=scrnheight/5;

    topleftx=tempw;
    toplefty=temph;

    width=scrnwidth-(tempw*2);
    height=scrnheight-(temph*2);

    mywindow = OpenWindowTags(NULL, WA_Left, topleftx, WA_Top, toplefty, WA_Width,width, WA_Height,height,\
        WA_IDCMP,IDCMP_CLOSEWINDOW, WA_Flags, WFLG_SIZEGADGET | WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET | WFLG_ACTIVATE,\
        WA_Title, "Info64", WA_PubScreenName, "WorkBench", TAG_DONE);

    if (mywindow)
    {
        myIText.FrontPen    = myTEXTPEN;
                myIText.BackPen     = myBACKGROUNDPEN;
                myIText.DrawMode    = JAM2;
                myIText.LeftEdge    = MYTEXT_LEFT;
                myIText.TopEdge     = MYTEXT_TOP;
                myIText.ITextFont   = &myTextAttr;
                myIText.IText       = "Hello, World.  ;-)";
                myIText.NextText    = NULL;
        mywindowrastport=mywindow->RPort;
        return 0;
    }
    else
        return 1;
}
You'll see that I am also setting up a structure to output some text in the same function. myIText is a global defined as - struct IntuiText myIText;

Later on in the code I replace my simple hello world text with what I want to display -

Code:
if (mywindow)
    {
        sprintf(buffer,"%s%s       %s%s    %s%s       %s%s       %s%s   %s%s  %s%s     %s%s%s\n",messages[9],tabs_ptr[0],\
            messages[10],tabs_ptr[1],messages[11],tabs_ptr[2],messages[12],\
            tabs_ptr[3],messages[13],tabs_ptr[4],messages[14],tabs_ptr[5],messages[15],\
            tabs_ptr[6],messages[16],tabs_ptr[7],messages[17]);
        myIText.IText = buffer;
        PrintIText(mywindow->RPort,&myIText,10,10);
    }
buffer is simply a char array 500 long.

However this text is larger than the window so I had assumed that the Amiga would only display what it could and keep the rest hidden 'somewhere' for when the window was resized.

Nope doesn't do that.

Instead it dumps out the text and overwrites the right most edge of the window.

I've obviously missed something fundamental here but I am struggling to find out what.

Is there a way of confining text output in the way I have described? I don't really want to attach a console to the window, which is the only way I have discovered so far.

Here's hoping, and as always many many thanks in advance.

Last edited by chocsplease; 24 September 2017 at 14:38. Reason: Solved
chocsplease is offline  
Old 01 August 2017, 14:32   #2
Cylon
Registered User
 
Join Date: Oct 2014
Location: Europe
Posts: 471
Easy way is to use GimmeZeroZero (GZZ) flags on your window, which results in a different Rastport for the window's borders - the system (Intuition) will handle clipping at the edges, or,
you install your own clipping regions.
Third option:
you determine the pixel width of the text and cut the string accordingly.

Last edited by Cylon; 02 August 2017 at 02:00.
Cylon is offline  
Old 03 August 2017, 16:31   #3
chocsplease
Registered User
 
Join Date: Dec 2016
Location: london
Posts: 178
Quote:
Originally Posted by Cylon View Post
Easy way is to use GimmeZeroZero (GZZ) flags on your window, which results in a different Rastport for the window's borders - the system (Intuition) will handle clipping at the edges, or,
you install your own clipping regions.
Third option:
you determine the pixel width of the text and cut the string accordingly.
Many thanks for the reply - I'll check out the gzz option. I have been working on the 3rd, and wrote a function to count the number of chars I was going to output in preparation. Thing is it doesn't work

This is the code
Code:
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <proto/dos.h>   
#include <proto/exec.h>  



long count_chars(char *format, ...) /* variable number of args*/
{
    va_list valist;
    unsigned int i,longcount=0,spcfound=1,nosign=0,ok=0,ii=0,error=0;
    long count=0;
    long long number;
/*    char *format;*/
    char letter1,letter2,letter3;
    char* string;

    va_start(valist,format);

/*    if (num<1)/
    {
        error=-2;
        va_end(valist);
        return error;    
    }*/

    /*format=(char*)va_arg(valist,char);*/ /*get format string*/

    if (strlen(format)==0) /*if dud format string*/
    {
        va_end(valist); /*free memory*/
        return -3;    /*quit*/
    }

    printf("format is %d long\n",strlen(format));

    /*now parse format string, counting normal chars and calulating size of numbers*/

    for (i=0;i<strlen(format);i++)
    {

        printf("i=%d char=%c\n",i,(char)format[i]);

        if (CheckSignal (SIGBREAKF_CTRL_C))
        { 
            printf("*BREAK main loop*\n");
            break;
        }
                    

        letter1=(char)format[i];
        if (letter1 !='%')
        {
            if (letter1==' ')
                spcfound=1;

            if (spcfound==1)    /*normal character ie not in format% <something>*/
                count++;
        }
        else if ((i+1) <(strlen(format)))
        {
            letter2=(char)format[i+1];
            spcfound=0;        /*now we hunt for a space or %*/
    
            if (letter2=='%') /*want to output a percent sign*/
            {
                count++;    /*just add to count*/
                i++;        /*inc place*/
                spcfound=1;    /*now looking for a space*/
            }
            else if (letter2=='u')    /*signifies unsigned so set flag*/
            {
                nosign=1;
                i++;
            }
            
            else if (letter2=='l')    /*long integer so add to longcount*/
            {
                longcount++;
                i++;
            }

            else if ((letter2=='d') ||(letter2=='x'))    /*work out number of chars in dec or hex number*/
            {
                ok=0;
                i++;
                if (nosign)
                {
                    if (longcount==0)
                    {
                        ok=1;
                        number=va_arg(valist,unsigned int);
                    }
                    if (longcount==1)
                    {
                        ok=1;
                        number=va_arg(valist,unsigned long int);
                    }
                    if (longcount==2)
                    {
                        ok=1;
                        number=va_arg(valist,unsigned long long int);
                    }
                    if (longcount>2)
                    {
                        error=-1;    /*formatting error too many l's*/
                        break;
                    }
                
        
                    if (ok)        /* have something in number*/
                    {
                        while (number!=0)
                        {
                            printf("unsigned  number %d\n",number);
                            if (CheckSignal (SIGBREAKF_CTRL_C))
                            { 
                                printf("*BREAK unsigned loop*\n");
                                break;
                            }
    
                            if (letter2=='d')
                                number=number/10;
                            else
                                number=number/16;

                            count++;
                        }
                    }
                    longcount=0;    /*clear count of l's*/
                                
                }
                else     /*signed*/
                {
                    printf("signed longcount=%d\n",longcount);
                    if (longcount==0)
                    {
                        ok=1;
                        printf("int\n");
                        number=va_arg(valist, int);
                    }
                    if (longcount==1)
                    {
                        ok=1;
                        printf("long int\n");

                        number=(long long int)va_arg(valist, long int);
                    }
                    if (longcount==2)
                    {
                        ok=1;
                        printf("long long int\n");

                        number=(long long int)va_arg(valist, long long int);
                    }
                    if (longcount>2)
                    {
                        error=-1;    /*formatting error too many l's*/
                        break;
                    }
                
                    if(ok)
                    {
                        printf("number starts %d\n",number);
                        if (number<0)    /*negetive number so allow for sign*/
                            count++;
                        while (number!=0)
                        {
                            printf("signed number %d\n",number);

                            if (CheckSignal (SIGBREAKF_CTRL_C))
                            { 
                                printf("*BREAK signed loop*\n");
                                break;
                            }
                    
                            if (letter2=='d')
                                number=number/10;
                            else
                                number=number/16;
                            
                            count++;
                        }

                    }
                    longcount=0;    /*clear count of l's*/
                }
            }    /*end of if (letter1=='d')*/
            
            else if(letter2=='s') /*string*/
            {
                string =va_arg(valist,char*);
                count=count+strlen(string);
            }
        }
        else    /* % at end of string - dud format*/
        {
            printf("dud string\n");
            error=-1;
            break;
        }
    }    /* end for*/

    va_end(valist);    /*clear va memory*/

printf("error=%d\n",error);

    if (error!=0)
        return error;

    return count;
}

int main()
{
    int num1=-500;
    unsigned int num2 =45;
    long int num3 = -5087654;
    unsigned long int num4 = 3637363783;
    long long int num5= -82344826482342;
    unsigned long long int num6 =88268966344;

    long result=0;

    result=count_chars("This is a test %d",num1);

    printf("The number of chars is %d\n",result);
return 0;
}
What I am trying to do is parse a format string like "this is a number %d" in the 1st argument have the actual number, or numbers in subsequent arguments and spit out the total number of characters.

However the line -

number=va_arg(valist, int);

is always setting number to -1. I have tried casting as - number=(long long int)va_arg(valist, int); but this also returns -1.

I'm using this page - https://en.wikibooks.org/wiki/C%2B%2...nctions/va_arg

for my inspiration, but this is C++ and appears to be defining the vars used to pull the arguments out on the fly (eg -
int d = va_arg( argptr, int ); )

Once
again I am stuck. What really baffles me is the loop -

Code:
while (number!=0)                         
{ 
       printf("signed number %d\n",number);                              
       if (CheckSignal (SIGBREAKF_CTRL_C))                             
       {                                  
              printf("*BREAK signed loop*\n");                                 
             break;                             
       }                                                  
       if (letter2=='d')                                 
             number=number/10;                             
       else                                 
             number=number/16;                                                          
       count++;                         
}
Actually works and loops 3 times for the number -500. Even though number is printf-ing as -1 and changing the %d to %ld in my printfs has no effect it still spits out -1.

Can anyone see where I am going wrong?
chocsplease is offline  
Old 03 August 2017, 17:10   #4
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
what exactly are you trying to do?

sprintf should return the 'number of chars' that went into the buffer. If it didn't/doesn't, you can always return strlen(buffer)
alkis is offline  
Old 03 August 2017, 19:06   #5
Cylon
Registered User
 
Join Date: Oct 2014
Location: Europe
Posts: 471
No no, just use TextLength() and if the returned amount of pixels is to high then eat a few chars from the end.
Cylon is offline  
Old 03 August 2017, 20:04   #6
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
Let me try again, what does the function count_chars() supposed to do?
It returns a long. What is the long supposed to represent?
alkis is offline  
Old 08 August 2017, 12:09   #7
chocsplease
Registered User
 
Join Date: Dec 2016
Location: london
Posts: 178
Many thanks for the replies, I'll look into TextLength.

Quote:
Originally Posted by alkis View Post
Let me try again, what does the function count_chars() supposed to do?
It returns a long. What is the long supposed to represent?
count_chars takes a format string, similar to that used in printf and counts all the characters plus any from numbers and additional strings.

If you give it "Test number %d test string %s",number,string it will count the chars in the text (25) and then work out the number of digits in number and then add the length of string to the result before returning the result.

So if number is 50 and string is "Hello" the total would be 32.

There is some very simple format checking and the function will return a negative number if it has hit a problem.

I think I've stumbled on what's going wrong - its to do with the way my version of gcc handles long longs , or rather does not.

64 bit maths is implemented (you can add, subtract etc long longs) as are shifts (<< and >>) and boolean ops ( x &y and x | y work). But printf breaks if you give it a long long. printf ("%lld",number) just returns %lld and printf("%ld",number) returns -1 if the number is a long long. I can cast the number to a long and then printf works.

The other issue is that va_arg() can't handle long longs so I have had to break these into two longs and shift the high bytes after they have been retrieved by va_arg().

I did think about just using sprintf, but this requires a buffer and I do not know the maximum size the resulting string is going to be.
chocsplease is offline  
Old 08 August 2017, 15:45   #8
mark_k
Registered User
 
Join Date: Aug 2004
Location:
Posts: 3,343
How about using fprintf() instead of sprintf()?

It's kind of a hack, but can you open NIL: then call fprintf() outputting to NIL: to discard the output since you're just interested in the return value?
mark_k is offline  
Old 12 August 2017, 13:09   #9
chocsplease
Registered User
 
Join Date: Dec 2016
Location: london
Posts: 178
Quote:
Originally Posted by mark_k View Post
How about using fprintf() instead of sprintf()?

It's kind of a hack, but can you open NIL: then call fprintf() outputting to NIL: to discard the output since you're just interested in the return value?
Many thanks for the suggestion, it may be a hack(ish) but it works. the only problem I have is that the resulting executable is 7.7K for something that is tiny. So I tried to 'Amigaise' it - this is my code.

Code:
#include <proto/dos.h>
#include <proto/exec.h>
#include <ctype.h>
int main()
{
    BPTR *fh;
    long result;
    int number =57;
    fh = Open("NIL:", MODE_NEWFILE);
    if (fh) /*if file opened*/
    {
        result=VFPrintf(fh,"This is a test %ld",(long)number);
        Close(fh);
    }

    Printf("the result is %ld\n",result);
}
I have a problem
  • I am getting a warning on the VFPrintf line (Initialisation makes integer for a pointer without a cast)
The executable is 2.2 k and it works, but I've had problems finding info on VFPrintf so suspect I've got the args wrong, can someone point out where?


Many thanks.

Last edited by chocsplease; 12 August 2017 at 13:17.
chocsplease is offline  
Old 12 August 2017, 19:12   #10
a/b
Registered User
 
Join Date: Jun 2016
Location: europe
Posts: 1,039
You generally don't use v-printf style functions with individual arguments, you use them with a variable length argument list. Something like:
Code:
int some_function(int first, const char* format, ...)  // variable number of arguments
{
va_list list;
va_start(list,format); // format is the last non-variable argument
vfprintf(stdout,format,list);
va_end(list);
}
You should use fprintf instead.
a/b is offline  
Old 13 August 2017, 14:33   #11
mark_k
Registered User
 
Join Date: Aug 2004
Location:
Posts: 3,343
Quote:
Originally Posted by chocsplease View Post
Many thanks for the suggestion, it may be a hack(ish) but it works. the only problem I have is that the resulting executable is 7.7K for something that is tiny. So I tried to 'Amigaise' it - this is my code.
...
I have a problem
  • I am getting a warning on the VFPrintf line (Initialisation makes integer for a pointer without a cast)
The executable is 2.2 k and it works, but I've had problems finding info on VFPrintf so suspect I've got the args wrong, can someone point out where?
I think you're almost there. Check the VFPrintf autodoc.

VFPrintf takes a fixed number of arguments (3). The third argument is a pointer to an array of formatting values. That's unlike the C fprintf() function which takes a variable number of arguments. However as mentioned in the autodoc you can use FPrintf which does take a variable number of arguments. You'll need to link your program with amiga.lib if you don't already. So do something like
Code:
result=FPrintf(fh,"This is a test %ld",(long)number);

Another alternative, which is cleaner in a sense because you don't need to open a file, would be to use the Exec function RawDoFmt(). With that, you could pass &result for the 4th argument (PutChData). Your PutChProc function would look like this:
Code:
PutChProc:  addq.l #1,(A3)
            rts
mark_k is offline  
Old 13 August 2017, 14:48   #12
mark_k
Registered User
 
Join Date: Aug 2004
Location:
Posts: 3,343
No guarantee this is correct. In fact it probably isn't...
Code:
long result = 0;
long PutChProc = 0x52934E75;   /* 68000 opcodes for addq.l #1,(A3) then rts */
RawDoFmt("This is a test %ld", &number, &PutChProc, &result);

Last edited by mark_k; 13 August 2017 at 14:56.
mark_k is offline  
Old 13 August 2017, 15:05   #13
mark_k
Registered User
 
Join Date: Aug 2004
Location:
Posts: 3,343
Another idea... If you wanted to write portable code, it looks like using snprintf() could be neater than fprintf() with NIL: (and of course NIL: is Amiga-specific).
Code:
char dummy = 0;
result = snprintf(&dummy, 1, "This is a test %ld", number);
mark_k is offline  
Old 13 August 2017, 15:46   #14
chocsplease
Registered User
 
Join Date: Dec 2016
Location: london
Posts: 178
Many thanks for the replies.

I wanted to try and keep the executable small, and using fprintf (with fopen, fclose etc) gave one that was over 10k. The Amiga version I posted gave 2.9k however I had completely missed the existence of FPrintf which is exactly what I need.

I tried using VFPrintf with va_start etc, but for some reason it would only output the basic text, 0 for any number and nothing at all for strings. No idea why.

I'm writing for the Amiga so thankfully portability is not an issue.

Many thanks once again.
chocsplease is offline  
Old 23 August 2017, 12:57   #15
chocsplease
Registered User
 
Join Date: Dec 2016
Location: london
Posts: 178
OOOkay,

I am (I think) almost there.
  • I now have a linked list of the text, line by line I want to display.
  • I know the length (in characters of each line)
  • I know the width and height of the window I want to put the text in.
  • I know the width etc of the font I'm using
What I cannot find is how to use Textlength (or whatever) to find the number of pixels each line will use, my idea is to take this divide it by the number of chars, to give an average, leave a bit of leeway and then work put how many chars will fit per line into the window and I guess how many lines.


Can someone point me at the right command to use, or better still a code chunk to learn from? I confess that the limited stuff I have found on the net has left me somewhat confused.


Thanks in advance.
chocsplease is offline  
Old 29 August 2017, 02:31   #16
chocsplease
Registered User
 
Join Date: Dec 2016
Location: london
Posts: 178
Hi All,

Well almost there but not quite. I am having an odd problem when lining up columns in a window. I am basically outputting an updated version of the info command but things are not quite lining up correctly.

This is the output straight to the shell window:

Code:
Unit       DOS    Size       Used       Free   Full  Errors     Status        Name
SMBFS0:    DOS0   488Gb      223Gb      264Gb   45%     0       Read & Write  PCbackup
PC0:       MSD0   720Kb       11Kb      709Kb    1%     0       Read only     EMPTY
CF0:       No disk in drive
RAM:       DOS0   686Kb      686Kb      121Mb    0%     0       Read & Write  Ram Disk
DH0:       PFS3    94Mb       93Mb      654Kb   99%     0       Read & Write  WB
DF0:       PC Disk
CC0:       No disk in drive
DF1:       DOS0   837Kb      789Kb       48Kb   94%     0       Read & Write  EdWordPro_2
DH1:       PFS3  3471Mb     3353Mb      117Mb   96%     0       Read & Write  Games
DH2:       PFS3  3567Mb     3487Mb       80Mb   97%     0       Read & Write  Apps

Available Volumes:
PCbackup    Mounted
EMPTY       Mounted
Ram Disk    Mounted
Apps        Mounted
Games       Mounted
EdWordPro_2 Mounted
In order to get this onto a window I am building a linked list with this structure
Code:
struct window_keeper
{
	struct window_keeper *next;
	char* line;
	int body;
	int linetype;
	unsigned int lineno;
};
*next points to the next line
line is the line of text eg -DH2: PFS3 3567Mb 3487Mb 80Mb 97% 0 Read & Write Apps
body is unused at pres
linetype is 1 for the 1st heading, 2 for the device list, 3 for the Volumes heading and 4 for the volumes list
lineno is the line's number starting at 1.

This structure is the var winhead in the below code.

This is the code I am using to output to the window.
Code:
int write_win()
{
/*	struct textattr TextAttr;*/
	long win_width=0,win_height=0;
	long line_len=0,doscol=0,currentdoscol;
	long numpix=0, avpix=0, fitchar=0,tempfitchar=0;
	struct window_keeper *currentline=NULL;
	unsigned char *buffer;	/*used for lines*/
	unsigned char *buffer_part; /*used for colours*/
	unsigned int charpos=0, percentpos=0;
int zz=0;


	win_width=mywindow->Width-mywindow->BorderRight;
	win_height=mywindow->Height-mywindow->BorderBottom;

	/*dirty way to find how may chars will fit into window*/

	myIText.IText="M";
	numpix=IntuiTextLength(&myIText);

	fitchar=(win_width/numpix) -4; /* -4 for safety*/

	printf("number of pix %d width %d max=%d\n",numpix,win_width,fitchar);


	if (fitchar==0) /*cant get any so give up*/
		return 0;

	if (winhead)	/*if we have something*/
	{

		if (currentline==NULL)
			currentline=winhead;
	}
	else
		return 0; /*nothing saved!*/

	buffer=malloc((maxlinelen+1)*sizeof(char)); /*make memory buffers for line plus null char*/
	buffer_part=malloc((maxlinelen+1)*sizeof(char));


	while ((currentline) && ((10*currentline->lineno)<win_height)) /*now dump saved text rough attempt stopping at end of data or window*/
	{

/*		printf("BUFFER is %d\n",&buffer);
		printf("Line -%s-\n",currentline->line);	*/
		if (fitchar>strlen(currentline->line))
		{
			
			memcpy(buffer, (char *)currentline->line, strlen(currentline->line));
			(char)buffer[strlen(currentline->line)]='\0';	/*teminate string*/
		}
		else
		{	

			memcpy(buffer, (char *)currentline->line,fitchar );
			(char)buffer[fitchar]='\0';	/*terminate string*/
		}

		switch (currentline->linetype)
		{
			case 1:
				myIText.FrontPen = white;
				doscol=finddoscol(buffer);
				break;

			case 2:
				charpos=findchar(buffer,':');
				currentdoscol=finddoscol(buffer);
				if (charpos!=-1)
				{
					
					myIText.FrontPen = white;
					leftstr(buffer_part,currentline->line,charpos);
					myIText.IText=buffer_part;
					PrintIText(mywindow->RPort,&myIText,10,10*currentline->lineno);

					/*now the rest*/

					/*but can it fit?*/

					tempfitchar=(win_width/numpix) -4;/* - (strlen(buffer_part)); -4 for safety*/
					
					if (tempfitchar>0)
					{
						myIText.FrontPen = black;
						midstr(buffer,currentline->line,currentdoscol,tempfitchar-(currentdoscol));




						/*now look for %*/
						
						percentpos=findchar(currentline->line,'%');
						if (percentpos!=-1)
						{
							percentpos=percentpos-3;
							/*dump up to percent*/

							midstr(buffer_part,currentline->line,currentdoscol,percentpos);
							myIText.IText=buffer_part;

					printf("doscol=%d currentdoscol=%d buffer-%s-\n",doscol,currentdoscol,buffer_part);

							PrintIText(mywindow->RPort,&myIText,10+(10*(doscol-3)),10*currentline->lineno);  /*<<<<< why do I have to subtract 3????*/

							/*colour for percent*/
							myIText.FrontPen = white;
							midstr(buffer_part,currentline->line,percentpos,percentpos+3);
							myIText.IText=buffer_part;

							printf("PERCENT BUFFER -%s- %d\n",buffer_part,percentpos);

							[B]PrintIText(mywindow->RPort,&myIText,10+(10*(percentpos-9)),10*currentline->lineno); /*<<<<<< no idea why i need to subtract 9*/[/B]
	
							myIText.FrontPen = black;
							/*set up to print remainder - do we need to check size?*/

							midstr(buffer,currentline->line,percentpos+4,tempfitchar);
							myIText.IText=buffer;

							charpos=percentpos+3;

							PrintIText(mywindow->RPort,&myIText,10+(10*(charpos-9)),10*currentline->lineno);


						}
						else
						{
							/*now print out*/
						
							myIText.IText=buffer;
							PrintIText(mywindow->RPort,&myIText,10+(10*charpos),10*currentline->lineno);
						}
					}
				}
				else /* cant find so dump*/
				{
					myIText.FrontPen = black;
					myIText.IText=buffer;

					PrintIText(mywindow->RPort,&myIText,10,10*currentline->lineno);
				}
				break;

			case 3:
				myIText.FrontPen = white;
				break;

			default:
				myIText.FrontPen = black;
				break;
		}

		if (currentline->linetype!=2)
		{
			myIText.IText=buffer;

			PrintIText(mywindow->RPort,&myIText,10,10*currentline->lineno);
		}

		currentline=currentline->next;

	}
	free(buffer);	/*clear the buffers*/
	free(buffer_part);

			printf("waiting press space\n");
				zz=0;
				while ((zz!=32) && (zz!='a'))
				{
					zz=getchar();
					if (zz=='a')
						return 1;
					putchar(zz);
				}

return 0;
}
This takes the info from the linked list in a while loop and using a couple of buffers (I need these as I do not know how long the lines could be) outputs the header, device name and percentage used in white and the rest of the text in black.
The 4 functions, findchar, midstr, leftstr and finddoscol are below:
Code:
int findchar(char string[], char letter)
{
	int result=-1;
	int i=0;
	while (string[i]!='\0')
	{
		if (string[i]==letter)
			result=i;
		i++;
	}
	return result;
}

int midstr(char str1[], char str2[],int start,int last)
{
	int count,count2;
	count=start;count2=0;
	if (last!=NULL)
	{
		while ((str2[count]!='\0') && (count<=last))
		{
			str1[count2]=str2[count];
			count++;
			count2++;
		}
	}
	else
	{
		while ((str2[count]!='\0'))
		{
			str1[count2]=str2[count];
			count++;
			count2++;
		}
		
	}
	str1[count2]='\0';
	return count2;
}

int leftstr(char str1[],char str2[],int last)
{
	return midstr(str1,str2,0,last);
}

long finddoscol(char str[])
{
	int i=0;

	while((str[i]!='\0') && (str[i]!=' '))
		i++;

	if (str[i]=='\0')
		return i;

	while ((str[i]==' ') && (str[i]!='\0'))
		i++;

	return i;
}
The problem lines in write_win are marked, and below for clarity..
.
.
myIText.IText=buffer_part;

printf("doscol=%d currentdoscol=%d buffer-%s-\n",doscol,currentdoscol,buffer_part);

PrintIText(mywindow->RPort,&myIText,10+(10*(doscol-3)),10*currentline->lineno); /*<<<<< why do I have to subtract 3????*/

/*colour for percent*/
.
.

and
.
.
myIText.IText=buffer_part;

printf("PERCENT BUFFER -%s- %d\n",buffer_part,percentpos);

PrintIText(mywindow->RPort,&myIText,10+(10*(percentpos-9)),10*currentline->lineno); /*<<<<<< no idea why i need to subtract 9*/

myIText.FrontPen = black;
/*set up to print remainder - do we need to check size?*/
.
.
.
If I don't subtract 3 and 9 then the dos columns are 3 chars to the right of the header and the errors, status etc are 9 chars to the right of their cols.

Sorry this is such a long post, but could someone suggest where I have gone wrong? The values for doscol and currentdoscol are correct at 11, but the dos column etc is outputting starting 140 pixels from the left of the window (10+(currentdoscol*10)) should be 110! (I'm counting as the 1st char being 0)

I have no idea why
chocsplease is offline  
Old 29 August 2017, 20:28   #17
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
I still don't get what you are trying to do!

Are you doing all this to avoid clipping? So, that PrintIText doesn't (over)write on window borders?

if that's the case all you need to do is

Code:
    struct Region *reg;
    struct Region *oldreg;
    struct Rectangle rect;
    
    rect.MinX = myWindow->BorderLeft;
    rect.MinY = myWindow->BorderTop;
    rect.MaxX = myWindow->Width-myWindow->BorderRight-1;
    rect.MaxY = myWindow->Height-myWindow->BorderBottom-1;
    if (reg = NewRegion()) {
      OrRectRegion(reg, &rect);
      oldreg = InstallClipRegion(myWindow->WLayer, reg);
    }
and then you can use PrintIText and not worry about the borders.


full example code follows:
Code:
#include <intuition/intuition.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/exec.h>
#include <proto/gadtools.h>
#include <proto/layers.h>

#include <stdio.h>

int main(int argc, char *argv[])
{
  struct Window *myWindow;
  int closewin = FALSE;       /* Flag used to end program */
  struct IntuiMessage *msg;   /* Structure to store Intuition message data */
  ULONG msgClass;             /* Class value */
  /* For printing in Window */
  UBYTE result[255];
  struct IntuiText WinText = {1, 0, JAM1, 0, 0, NULL, &result[0], NULL};
  int x,y;

  if (myWindow = OpenWindowTags(NULL,
                           WA_Left,   100,
                           WA_Top,    100,
                           WA_Width,  100,
                           WA_Height, 100,
                           WA_MaxWidth, 600,
                           WA_MaxHeight, 400,
                           WA_Activate, TRUE,
                           WA_IDCMP,  IDCMP_CLOSEWINDOW | IDCMP_MOUSEMOVE | IDCMP_NEWSIZE,
                           WA_Flags,  WFLG_SMART_REFRESH | WFLG_SIZEGADGET | WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET    | WFLG_ACTIVATE | WFLG_REPORTMOUSE,
                           TAG_END))
  {
    struct Region *reg;
    struct Region *oldreg;
    struct Rectangle rect;
    
    rect.MinX = myWindow->BorderLeft;
    rect.MinY = myWindow->BorderTop;
    rect.MaxX = myWindow->Width-myWindow->BorderRight-1;
    rect.MaxY = myWindow->Height-myWindow->BorderBottom-1;
    if (reg = NewRegion()) {
      OrRectRegion(reg, &rect);
      oldreg = InstallClipRegion(myWindow->WLayer, reg);
    }    
    while (closewin == FALSE) { /* Run program until window is closed */
      Wait(1L << myWindow->UserPort->mp_SigBit);     /* Wait for an event! */
      msg = GT_GetIMsg(myWindow->UserPort);
      msgClass = msg->Class;
      GT_ReplyIMsg(msg);

      switch (msgClass) {
        case IDCMP_CLOSEWINDOW: /* Close window? */
          closewin = TRUE;
          break;
        case IDCMP_MOUSEMOVE: /* Mouse moved? */
          x = msg->MouseX;
          y = msg->MouseY;
          /* Print selection in window */
          sprintf(result, "X-coord: %d Y-coord: %d", x, y);
          SetRast(myWindow->RPort, 0);
          PrintIText(myWindow->RPort, &WinText, x, y);

          break;
        case IDCMP_NEWSIZE:
          if (reg) {
            InstallClipRegion(myWindow->WLayer, oldreg);
            DisposeRegion(reg);

            rect.MinX = myWindow->BorderLeft;
            rect.MinY = myWindow->BorderTop;
            rect.MaxX = myWindow->Width-myWindow->BorderRight-1;
            rect.MaxY = myWindow->Height-myWindow->BorderBottom-1;
            if (reg = NewRegion()) {
              OrRectRegion(reg, &rect);
              oldreg = InstallClipRegion(myWindow->WLayer, reg);
            }
          }
          break;
        }
    }
    if (reg) {
      InstallClipRegion(myWindow->WLayer, oldreg);
      DisposeRegion(reg);
    }
    CloseWindow(myWindow);
  }
  return 0;
}
alkis is offline  
Old 31 August 2017, 12:52   #18
chocsplease
Registered User
 
Join Date: Dec 2016
Location: london
Posts: 178
Quote:
Originally Posted by alkis View Post
I still don't get what you are trying to do!

Are you doing all this to avoid clipping? So, that PrintIText doesn't (over)write on window borders?
<snip>

Well not just that but it is my current problem .

I had no idea that you could set up a clip region like this, though it will take me a while to read though and understand the code you've so kindly posted.

Will this also work with SetRast(&rastPort, 0);? I'm hoping to use this to clear the window when someone swaps a disk.

Many thanks once again for such a great reply.

<edit>

Having looked at your code I'm a bit confused about the very last part ....

Code:
 if (reg) {
      InstallClipRegion(myWindow->WLayer, oldreg);
      DisposeRegion(reg);
    }
It looks like you are creating a new region just before you close the window? Or have I got the loops wrong? Could you explain this bit please?

Many thanks.

Last edited by chocsplease; 31 August 2017 at 13:25.
chocsplease is offline  
Old 31 August 2017, 18:23   #19
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
Yes, it will work with clearing the window, my example code actually does that in the MOUSEMOVE case.

Now, about the last part. Actually there I install the oldregion (oldreg always hold the region that was installed before any new clipregion is installed. So, think of it as 'restoring the old clip region'.

Reading the documentation might clear things better http://amigadev.elowar.com/read/ADCD.../node0399.html

PS: Also note, that whenever the size of the window changes, I dispose the new clip region, restore the old clip region, change the rect to the new window width and height and install a new clip region.
alkis is offline  
Old 01 September 2017, 00:09   #20
chocsplease
Registered User
 
Join Date: Dec 2016
Location: london
Posts: 178
Hi,

Many thanks for the explanation, I'll read the link.

At the moment my code sort of works but somehow kills Intuition, or I suspect it does.

Everything is fine the 1st time through and the window displays the correct info and clips correctly.

However the Amiga freezes solid as soon as I try and move the window or resize it. It never gets to the message handler (I've checked with printfs) and its not a Guru, it just locks.

I'm not at all sure how to debug this. This is the code I use to open the window, maybe there is something in this?

Code:
int open_window(int scrnwidth,int scrnheight)
{
    int topleftx=0,toplefty=0;
    int width=200,height=200;
    int tempw=0,temph=0;

    unsigned long maxchars=0;

    struct TextFont *font;
    UWORD font_width=0;

/*calculate 1 quarter of screen width*/

    if (mywindow)
        return 0; /*opened already*/

    tempw=scrnwidth/4;

/*calculate 1 5th screen height*/

    temph=scrnheight/5;

    topleftx=tempw;
    toplefty=temph;

    width=scrnwidth-(tempw*2);
    height=scrnheight-(temph*2);

    mywindow = OpenWindowTags(NULL, WA_Left, topleftx, WA_Top, toplefty,\
         WA_InnerWidth, width,  WA_InnerHeight, height,\
        WA_MinWidth,90,WA_MinHeight, 40, WA_MaxWidth, scrnwidth-20, WA_MaxHeight, scrnheight-20,\
        WA_IDCMP,IDCMP_CLOSEWINDOW  | IDCMP_DISKINSERTED | IDCMP_DISKREMOVED | IDCMP_NEWSIZE | IDCMP_REFRESHWINDOW,\
        WA_Flags, WFLG_SIZEGADGET | WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET | WFLG_ACTIVATE,\
        WA_Title, (ULONG)"Info64", WA_PubScreenName, (ULONG)"WorkBench", TAG_DONE);

    if (mywindow)
    {
        myIText.FrontPen    = myTEXTPEN;
                myIText.BackPen     = myBACKGROUNDPEN;
                myIText.DrawMode    = JAM2;
                myIText.LeftEdge    = MYTEXT_LEFT;
                myIText.TopEdge     = MYTEXT_TOP;
                myIText.ITextFont   = &myTextAttr;
                myIText.IText       = "Hello, World.  ;-)";
                myIText.NextText    = NULL;
        mywindowrastport=mywindow->RPort;

        oldwin_width=mywindow->Width;
        oldwin_height=mywindow->Height;

        /*open line buffers*/

        font=mywindow->RPort->Font;
        font_width=font->tf_XSize;

        maxchars=(scrnwidth/font_width)+1;

        win_buffer=malloc((maxchars+2)*sizeof(char)); /*make memory buffers for line plus null char*/
        win_buffer_part=malloc((maxchars+2)*sizeof(char));
        win_buffer_len=maxchars;

        win_rect.MinX = mywindow->BorderLeft;
        win_rect.MinY = mywindow->BorderTop;
        win_rect.MaxX = mywindow->Width-mywindow->BorderRight-1;
        win_rect.MaxY = mywindow->Height-mywindow->BorderBottom-1;
        if (win_reg = NewRegion()) 
            {
            OrRectRegion(win_reg, &win_rect);
            win_oldreg = InstallClipRegion(mywindow->WLayer, win_reg);
        }    
        return 0;
    }
    else
        return 1;
}
Here's hoping anyway
chocsplease is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
Trying the get bold, italic and coloured text out to the shell window. chocsplease Coders. C/C++ 16 22 June 2017 14:58
Simple and ugly text wrapping routine rockersuke Coders. AMOS 7 21 November 2014 22:31
How can I do I/O redirection to a simple console window? Leffmann Coders. System 5 26 October 2014 23:42
Searching for a simple Text Editor Morbane request.Apps 2 01 January 2012 01:05
Standard output window Rixa support.Apps 5 17 January 2008 23:36

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 15:00.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.09976 seconds with 15 queries