Frank Kotler wrote:
> Herbert Kleebauer wrote:
> > If I ever get past my lazy period, I will convert your X code
>
> *Your* X code, you mean. "Our" X code, tops. If I get past my lazy
> period, I'm going to get back to that...
> > to C so you can do graphics in a C program without any graphics
> > library.
>
> Before you waste your time, explain to me how this would be "better".
Ok, at least now I converted "Annie's flying hearts" as an example
for your/our X code to C. Because it is a 1:1 translation of the
assembler code, I omitted the comments to get a more compact source.
Therefore maybe it is necessary to read the commented assembly source
annie.asm (NASM) or annie.mac (Lindela) to understand the C version.
I know, this is somehow pervert, because normally it is the the other
way. But I also had to look at the compiler generated assembly code:
it worked without optimization, but with -O3 it didn't. The problem
was the inline assembly, needed an additional "volatile" and "memory".
On my Linux it now works, but I'm not sure if also a "cc" is necessary.
The funny thing is, the C version is faster than the assembly version.
Compile it with gcc -O3 -o annie annie.c , no libraries required.
Press any key or mouse button to exit. Hope there are not too many
bugs left.
#include <stdio.h>
#define abs(x) (((x) >=0) ? (x) : (- (x)))
void exit();
void x_send();
int x_receive_raw();
int x_receive();
void display();
void annie();
void init_color();
unsigned int eax, x_handle, id_next, id_incr;
int screen[320*200];
int color[64];
#define BUF_SIZE 1024
char buf[BUF_SIZE]; int buf_rest=0; char* buf_ptr;
int mes_size; char *mes_ptr;
char fname[300];
char prot_name[256], prot_data[256]; int prot_name_size=0,
prot_data_size=0;
FILE *fp=NULL;
/**************************************************************************/
const char sockaddr_un[]=
{1,0,'/','t','m','p','/','.','X','1','1','-','u','n','i','x','/','X','0'};
/**************************************************************************/
/************************* Connection Setup
******************************/
volatile struct {char a[2]; short b[2],s1n,s1d,c;}
send1={0x6c,0,11,0,0,0,0};
/**************************************************************************/
/************************* Create Window
*********************************/
volatile struct {char a[2]; short b; int s2a,s2b; short c[2],s2x,s2y,d[2];
int e[3]; char f[4]; int g;}
//send2={1,0,sizeof(send2)/4,0,0,0,0,640,400,0,0,0,0xa02,255,1,0,0,0,0x05};
send2={1,0,sizeof(send2)/4,0,0,0,0,640,400,0,0,0,0xa02,0,1,0,0,0,0x05};
/**************************************************************************/
/************************* Map Window
***********************************/
volatile struct {char a[2]; short b; int s3a;}
send3={8,0,sizeof(send3)/4,0};
/**************************************************************************/
/************************* Create GC
************************************/
volatile struct {char a[2]; short b; int s4b,s4a; int c[4];}
send4={55,0,sizeof(send4)/4,0,0,1+4+8,3,0xffffff,0x0080ff};
/**************************************************************************/
/************************* Put Image
*************************************/
volatile struct {char a[2]; short b; int s5a,s5b; short c[2],s5x,s5y;
char d[2]; short e;}
send5={72,2,sizeof(send5)/4+320*10*4/4,0,0,320,200/20,0,0,0,24,0};
/**************************************************************************/
/************************* Set Input Focus
******************************/
volatile struct {char a[2]; short b; int s6a,c;}
send6={42,0,sizeof(send6)/4,0,0};
/**************************************************************************/
/**************************************************************************/
/************************* main
*****************************************/
/**************************************************************************/
int main(nargs,args) int nargs; char **args;
{char *p, *q;
int i,j,k,n=nargs+1;
/************************* read .Xauthority
*****************************/
while ((p=args[n++]) != NULL)
{if (*(int*)p != ('H'+('O'<<8) +('M'<<16) +('E'<<24)) ) continue;
if (p[4] != '=' || p[5] == 0) continue;
p=p+5; q=fname;
for (i=0; i<256; i++) if ( (*q++ = *p++) == 0) break;
if (*(--q)) exit(0);
p="/.Xauthority"; while ((*q++ = *p++));
fp=fopen(fname,"rb");
break;
}
if (fp != NULL)
{while ( (i=getc(fp),j=getc(fp)) != EOF)
{if ( ((j<<8)+i) != 1)
{for (k=0; k<4; k++)
{i=getc(fp); i = (i<<8) + getc(fp);
for (j=0; j<i; j++) if (getc(fp) == EOF) break;
}
}
else
{for (k=0; k<2; k++)
{i=getc(fp); i = (i<<8) + getc(fp);
for (j=0; j<i; j++) if (getc(fp) == EOF) break;
}
i=getc(fp); prot_name_size = (i<<8) + getc(fp);
if (prot_name_size > 256) exit(0); p=prot_name;
for (i=0; i<prot_name_size; i++) *p++=getc(fp);
i=getc(fp); prot_data_size = (i<<8) + getc(fp);
if (prot_data_size > 256) exit(0); p=prot_data;
for (i=0; i<prot_data_size; i++) *p++=getc(fp);
break;
}
}
fclose(fp);
}
/**************************************************************************/
/************************* get socket handle
****************************/
const int gsh[] = {1,1,0};
asm volatile ("int $0x80":"=a" (x_handle): "0" (102), "b" (1), "c"
(&gsh));
if (x_handle>=-4095) exit(0);
/**************************************************************************/
/*********************** connect socket to tmp/.X11-unix/X0
***************/
const int cst[]={x_handle, (int) &sockaddr_un,sizeof(sockaddr_un)};
/* with -O3 but without volatile, cst[1/2] is intialized after the int 80
*/
asm volatile ("int $0x80":"=a" (eax): "0" (102), "b" (3), "c" (&cst));
if (eax>=-4095) exit(0);
/**************************************************************************/
/************* make socket read non blocking ***************/
asm volatile ("int $0x80":"=a" (eax): "0" (55), "b" (x_handle), "c" (3));
if (eax>=-4095) exit(0);
asm volatile
("int $0x80":"=a" (eax):"0" (55),"b" (x_handle),"c" (4),"d"
(eax|0x800));
if (eax>=-4095) exit(0);
/**************************************************************************/
/***************************** send connect message
**********************/
send1.s1n=prot_name_size;
send1.s1d=prot_data_size;
x_send((char*)&send1, sizeof(send1));
if (prot_name_size) x_send(prot_name,(prot_name_size+3)&0xfffffffc);
if (prot_data_size) x_send(prot_data,(prot_data_size+3)&0xfffffffc);
buf_ptr=buf; buf_rest=0;
n=8;
for (k=0; k<2; k++)
{while (buf_rest < n)
{i=x_receive_raw(buf_ptr,BUF_SIZE-buf_rest);
buf_rest += i; buf_ptr += i;
if ( (buf_ptr != buf) && buf[0] != 1) exit(0);
}
n= 4 * (*(short*)(buf+6)) + 8;
}
buf_ptr=buf; buf_rest=0;
/**************************************************************************/
/***************************** calculate id's
****************************/
id_next = *(int*)(buf+12); n = *(int*)(buf+16);
id_incr = n & (-n);
send2.s2a=id_next; send3.s3a=id_next; send4.s4a=id_next;
send5.s5a=id_next; send6.s6a=id_next;
id_next += id_incr; send4.s4b=id_next; send5.s5b=id_next;
id_next += id_incr;
/**************************************************************************/
/***************************** get root window id
************************/
n = (((*(short*)(buf+24)) + 43) & -4) + ((*(unsigned char*)(buf+29)) *8);
send2.s2b = *(int*)(buf+n);
*(int*)(&send2.s2x) = i = *(int*)(buf+n+20);
*(int*)(&send5.s5x) = ((i - ((200<<16)+320))/2) & 0xffff7fff;
/**************************************************************************/
/***************************** send CreatWindow request
*******************/
x_send((char*)&send2, sizeof(send2));
/***************************** send MapWindow request
*********************/
x_send((char*)&send3, sizeof(send3));
/***************************** send CreatDC request
***********************/
x_send((char*)&send4, sizeof(send4));
/***************************** send SetInputFocust
************************/
x_send((char*)&send6, sizeof(send6));
/**************************************************************************/
init_color();
/***************************** main loop
*********************************/
while (1)
{annie();
display();
if (x_receive() !=0 )
if (*mes_ptr == 0 || *mes_ptr == 2 || *mes_ptr == 4) exit(0);
}
}
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/***************************** display
***********************************/
void display()
{int i;
char *p;
p=(char*)screen;
for (i=0; i<20; i++)
{x_send((char*)&send5, sizeof(send5));
x_send(p, 320*10*4); send5.s5y += 10; p += 320*10*4;
}
send5.s5y -= 20*10;
}
/**************************************************************************/
/******************** Annie's code to draw a heart
***********************/
void annie()
{static int annie1;
unsigned int i;
int n, k,x,y;
annie1++;
for (i=0; i<320*200; i++)
{y=((int)(i/320))-120; x= abs(((int)(i%320))-160);
n=(y*y+(x+y)*(x+y));
if ( (k=n+y*y) != 0 ) n=600000/k;
screen[i]=color[((n+annie1)>>2)&0x3f];
}
}
/**************************************************************************/
/******************** initialize 64 VGA colors
***************************/
void init_color()
{int i, x=0, y=0, z=0;
for (i=0; i<64; i++)
{color[i]=x+y+z;
x=(x+0x000010)&0x0000ff;
y=(y+0x000800)&0x00ff00;
z=(z+0x040000)&0xff0000;
}
}
/**************************************************************************/
/******************** send message to X server
****************************/
void x_send(p,n) char *p; int n;
{while (n)
{eax=-11;
const int par[]={x_handle, (int)p, n, 0};
while (eax == -11)
asm volatile ("int $0x80":"=a" (eax): "0" (102), "b" (9), "c"
(&par));
if (eax>=-4095) exit(0);
n -= eax; p += eax;
}
}
/**************************************************************************/
/*********************** receive ONE message from X server
***************/
int x_receive()
{int n;
while (1)
{if (buf_rest >= 32)
{n=32;
if (*buf_ptr == 1) n += (*(int*)(buf_ptr+4))*4;
if (buf_rest >= n)
{mes_ptr=buf_ptr; mes_size=n;
buf_ptr += n; buf_rest -= n; return 1;
}
}
if (buf_ptr != buf )
{for (n=0; n<buf_rest; n++) buf[n] = *buf_ptr++;
buf_ptr=buf;
}
if ((n=x_receive_raw(buf+buf_rest,BUF_SIZE-buf_rest)) == 0) return 0;
buf_rest += n;
}
}
/**************************************************************************/
/************************ read data from X server
************************/
int x_receive_raw(p,n) char *p; int n;
{const int par[]={x_handle, (int)p, n, 0};
/* with -O3 but without "memory", modif. of buf[0] is not recognized !!!
*/
asm volatile
("int $0x80":"=a" (eax): "0" (102), "b" (10), "c" (&par):"memory");
if (eax == -11) return 0;
if (eax>=-4095) exit(0);
if (eax == 0) exit(0);
return eax;
}
/**************************************************************************/


|