[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Next version : Improved X11 performance for xlinrad wit MIT-SHM
- Subject: Re: Next version : Improved X11 performance for xlinrad wit MIT-SHM
- From: Pierre Vanhoucke <skynet.be; pierre.vanhoucke@xxxxxxxxxxxxxxxx>
- Date: Fri, 24 Jul 2009 21:57:36 +0200
Hi Leif,
On Fri, 2009-07-24 at 14:47 +0200, Leif Asbrink wrote:
> OK. I have packed the current version in the attached file. Please start
> from that to make it easier to merge the code you make with the changes I
> make myself.
>
I made the following modifications:
1. All MIT-SHM code is enclosed between #if SHM_INSTALLED == 1 and
#endif statements to avoid compilation errors when the MIT-SHM libraries
are not available.
2. In xmain.c at line 118, I modified the content of the message:
It is possible that the X11 server does not support MIT-SHM calls
because the MIT-SHM option in the server was not enabled.
In my opinion the lack of support for MIT-SHM calls by the X11 server
is not related to the availability of the packages libxext-dev and
x11proto-xext-dev on the linux system.
What do you think?
73
Pierre
// For help on X11 give command: "man X Interface"
// Event masks and event definitions are in /usr/X11R6/include/X11/X.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <X11/Xlib.h>
#include <ctype.h>
#include <semaphore.h>
#include <unistd.h>
#include <pthread.h>
#include <X11/cursorfont.h>
#include <X11/Xutil.h>
#include "globdef.h"
#include "thrdef.h"
#include "uidef.h"
#include "screendef.h"
#include "vernr.h"
#include "options.h"
#include "keyboard_def.h"
#include "lconf.h"
#include "xdef.h"
#include "ldef.h"
#if SHM_INSTALLED == 1
#include <X11/extensions/XShm.h>
#include <sys/ipc.h>
#include <sys/shm.h>
extern XShmSegmentInfo *shminfo;
int ShmMajor,ShmMinor;
Bool ShmPixmaps;
#endif
extern GC xgc;
extern XImage *ximage;
extern Display *xdis;
extern Window xwin;
extern Colormap lir_colormap;
int newcomer_escflag;
typedef struct {
unsigned short int red;
unsigned short int green;
unsigned short int blue;
unsigned int pixel;
short int flag;
float total;
}PIXINFO;
// We want to know about the user clicking on the close window button
Atom wm_delete_window;
int main(int argc, char **argv)
{
int id,il,kd,kl;
int bitmap_pad;
float t1,t2;
PIXINFO *defpix, *lirpix;
float *pixdiff;
PIXINFO tmppix;
Colormap default_colormap;
char *hostname;
Visual *visual;
int i, k, m, screen_num;
Cursor cross_cursor;
unsigned short int *ipalette;
XColor xco;
for(i=0; i<MAX_LIRSEM; i++)lirsem_flag[i]=0;
XInitThreads();
if(DUMPFILE)
{
dmp = fopen("dmp", "w");
DEB"\n******************************\n");
}
else
{
dmp=NULL;
}
expose_event_done=FALSE;
first_mempix=0x7fffffff;
last_mempix=0;
shift_key_status=0;
i=argc;
os_flag=OS_FLAG_X;
init_os_independent_globals();
newcomer_escflag=FALSE;
serport=-1;
keyboard_buffer_ptr=0;
keyboard_buffer_used=0;
keyboard_buffer=malloc(KEYBOARD_BUFFER_SIZE*sizeof(int));
if (argv[1] == NULL)
{
hostname = NULL;
}
else
{
hostname = argv[1];
}
xdis = XOpenDisplay(hostname);
if (xdis == NULL)
{
fprintf(stderr, "\nCan't open display: %s\n", hostname);
return(10);
}
X11_accesstype=X11_STANDARD;
#if SHM_INSTALLED == 1
// test if the X11 server supports MIT-SHM
if(XShmQueryVersion(xdis,&ShmMajor,&ShmMinor,&ShmPixmaps))
{
X11_accesstype=X11_MIT_SHM;
printf("\nThe X11 server supports MIT-SHM\n");
}
else
{
printf("\nThe X11 server does not support MIT-SHM \n");
printf("Check your X11 configuration with the xdpyinfo command \n");
printf("and try to enable MIT-SHM by adding following lines\n");
printf("to the /etc/X11/xorg.conf file :\n\n");
printf("Section ""Extensions"" \n");
printf(" Option ""MIT-SHM"" ""enable"" \n");
printf("EndSection \n\n");
// printf("Suggest install packages libxext-dev and x11proto-xext-dev\n");
// printf("Then ./configure and after that make xlinrad");
}
#endif
visual=DefaultVisual(xdis, 0);
ui_setup();
screen_num = DefaultScreen(xdis);
screen_width = ui.screen_width_factor*DisplayWidth(xdis, screen_num)/100;
screen_width &= -4;
screen_height = ui.screen_height_factor*DisplayHeight(xdis, screen_num)/100;
screen_totpix=screen_width*(screen_height+1);
// *****************************************************************
// Set the variables Linrad uses to access the screen.
init_font(ui.font_scale);
if(lir_errcod != 0)goto exitmain;
xwin=XCreateSimpleWindow(xdis, RootWindow(xdis, 0),
0, 0, screen_width, screen_height, 1, 0, 0);
// We want to know about the user clicking on the close window button
wm_delete_window = XInternAtom(xdis, "WM_DELETE_WINDOW", 0);
XSetWMProtocols(xdis,xwin, &wm_delete_window, 1);
cross_cursor = XCreateFontCursor(xdis, XC_diamond_cross);
// attach the icon cursor to our window
XDefineCursor(xdis, xwin, cross_cursor);
xgc=DefaultGC(xdis, 0);
color_depth = DefaultDepth(xdis, screen_num );
if(visual->class!=TrueColor && color_depth != 8)
{
printf("Unknown color type\n");
exit(1);
}
bitmap_pad=color_depth;
switch (color_depth)
{
case 24:
bitmap_pad=32;
mempix_char=(unsigned char *)malloc((screen_totpix+1)*4);
for(i=0; i<(screen_totpix+1)*4;i++)mempix_char[i]=0;
// ******************************************************************
// Rearrange the palette. It was designed for svgalib under Linux
for(i=0; i<3*256; i++)
{
svga_palette[i]<<=2;
if(svga_palette[i] != 0) svga_palette[i]|=3;
}
break;
case 16:
mempix_shi=(unsigned short int*)malloc((screen_totpix+1)*sizeof(unsigned short int));
mempix_char=(void*)mempix_shi;
for(i=0; i<screen_totpix+1; i++)mempix_shi[i]=0;
// ******************************************************************
ipalette=(void*)(&svga_palette[0]);
for(i=0; i<256; i++)
{
k=svga_palette[3*i+2];
k&=0xfffe;
k<<=5;
k|=svga_palette[3*i+1];
k&=0xfffe;
k<<=6;
k|=svga_palette[3*i ];
k>>=1;
ipalette[i]=k;
}
break;
case 8:
mempix_char=(unsigned char*)malloc((screen_totpix+1)+256);
defpix=(PIXINFO*)malloc(sizeof(PIXINFO)*256);
lirpix=(PIXINFO*)malloc(sizeof(PIXINFO)*256);
pixdiff=(float*)malloc(256*256*sizeof(float));
xpalette=&mempix_char[screen_totpix+1];
for(i=0; i<(screen_totpix+1)+256; i++)mempix_char[i]=0;
lir_colormap=XCreateColormap(xdis, xwin, visual, AllocAll);
default_colormap = DefaultColormap(xdis, screen_num);
// Store the default colormap in defpix
for(id=0; id<256; id++)
{
xco.pixel=id;
k=XQueryColor (xdis,default_colormap,&xco);
defpix[id].red=xco.red;
defpix[id].green=xco.green;
defpix[id].blue=xco.blue;
defpix[id].flag=0;
defpix[id].pixel=id;
defpix[id].total= ( (float)((unsigned int)defpix[id].red)*
(unsigned int)defpix[id].red+
(float)((unsigned int)defpix[id].green)*
(unsigned int)defpix[id].green+
(float)((unsigned int)defpix[id].blue)*
(unsigned int)defpix[id].blue);
}
// svga_palette uses the six lowest bits for the colour intensities.
// shift left by 10 to move our data to occupy the six highest bits.
// Store the svgalib palette.
for(il=0; il<MAX_SVGA_PALETTE; il++)
{
lirpix[il].red=svga_palette[3*il+2]<<2;
lirpix[il].green=svga_palette[3*il+1]<<2;
lirpix[il].blue=svga_palette[3*il ]<<2;
if(lirpix[il].red != 0)lirpix[il].red|=3;
if(lirpix[il].green != 0)lirpix[il].green|=3;
if(lirpix[il].blue != 0)lirpix[il].blue|=3;
lirpix[il].red<<=8;
lirpix[il].green<<=8;
lirpix[il].blue<<=8;
lirpix[il].pixel=il;
lirpix[il].flag=1;
lirpix[il].total= ( (float)((unsigned int)lirpix[il].red)*
(unsigned int)lirpix[il].red+
(float)((unsigned int)lirpix[il].green)*
(unsigned int)lirpix[il].green+
(float)((unsigned int)lirpix[il].blue)*
(unsigned int)lirpix[il].blue);
}
for(il=MAX_SVGA_PALETTE; il<256; il++)
{
lirpix[il].red=0;
lirpix[il].green=0;
lirpix[il].blue=0;
lirpix[il].pixel=il;
lirpix[il].flag=0;
}
#define M 0.00000001
#define N 0x100
// Sort lirpix in order of ascending total intensity.
for(il=0; il<MAX_SVGA_PALETTE-1; il++)
{
t1=0;
m=il;
for(kl=il; kl<MAX_SVGA_PALETTE; kl++)
{
if(lirpix[kl].total > t1)
{
t1=lirpix[kl].total;
m=kl;
}
}
tmppix=lirpix[il];
lirpix[il]=lirpix[m];
lirpix[m]=tmppix;
}
// Compute the similarity between lirpix and defpix and store in a matrix.
for(il=0; il<MAX_SVGA_PALETTE; il++)
{
for(id=0; id<256; id++)
{
t2=pow((float)(int)(((unsigned int)lirpix[il].red-
(unsigned int)defpix[id].red)),2.0)+
pow((float)(int)(((unsigned int)lirpix[il].green-
(unsigned int)defpix[id].green)),2.0)+
pow((float)(int)(((unsigned int)lirpix[il].blue-
(unsigned int)defpix[id].blue)),2.0);
pixdiff[id+il*256]=t2;
}
}
// Reorder the default colormap for the diagonal elements
// of pixdiff (up to MAX_SVGA_PALETTE-1) to become as small
// as possible when stepping in the ascending order that
// lirpix currently is sorted in.
for(il=0; il<MAX_SVGA_PALETTE; il++)
{
t1=BIG;
kd=0;
for(id=0; id<256; id++)
{
if(pixdiff[id+il*256] < t1)
{
t1=pixdiff[id+il*256];
kd=id;
}
}
tmppix=defpix[il];
defpix[il]=defpix[kd];
defpix[kd]=tmppix;
for(kl=0; kl<MAX_SVGA_PALETTE; kl++)
{
t1=pixdiff[kd+kl*256];
pixdiff[kd+kl*256]=pixdiff[il+kl*256];
pixdiff[il+kl*256]=t1;
}
}
for(i=0; i<MAX_SVGA_PALETTE; i++)
{
xco.pixel=defpix[i].pixel;
xco.red=lirpix[i].red;
xco.green=lirpix[i].green;
xco.blue=lirpix[i].blue;
xco.flags=DoRed|DoGreen|DoBlue;
xco.pad=0;
k=XStoreColor(xdis, lir_colormap, &xco);
if(k==0)
{
printf("\nPalette failed\n");
goto exitmain;
}
xpalette[lirpix[i].pixel]=xco.pixel;
}
for(i=MAX_SVGA_PALETTE; i<256; i++)
{
xco.pixel=defpix[i].pixel;
xco.red=defpix[i].red;
xco.green=defpix[i].green;
xco.blue=defpix[i].blue;
xco.flags=DoRed|DoGreen|DoBlue;
xco.pad=0;
k=XStoreColor(xdis, lir_colormap, &xco);
if(k==0)
{
printf("\nPalette failed\n");
goto exitmain;
}
xpalette[i]=lirpix[i].pixel;
}
XSetWindowColormap(xdis, xwin, lir_colormap);
free(defpix);
free(lirpix);
free(pixdiff);
break;
default:
printf("\nUnknown color depth: %d\n",color_depth);
goto exitmain;
}
if(X11_accesstype==X11_STANDARD)
{
ximage=XCreateImage(xdis, visual, color_depth, ZPixmap, 0,
(char*)(mempix_char), screen_width, screen_height, bitmap_pad, 0);
}
#if SHM_INSTALLED == 1
else
{
shminfo=(XShmSegmentInfo *)malloc(sizeof(XShmSegmentInfo));
memset(shminfo,0, sizeof(XShmSegmentInfo));
ximage =XShmCreateImage(xdis, visual, color_depth, ZPixmap,NULL,
shminfo, screen_width, screen_height );
shminfo->shmid=shmget(IPC_PRIVATE,
ximage->bytes_per_line*
ximage->height,IPC_CREAT|0777);
shminfo->shmaddr = ximage->data = shmat (shminfo->shmid, 0, 0);
// replace address in mempix_char and mempix_shi by shared memory address
switch (color_depth)
{
case 24:
free(mempix_char);
mempix_char=(unsigned char *)(ximage->data);
break;
case 16:
free(mempix_char);
mempix_char=(unsigned char *)(ximage->data);
mempix_shi=(void *)(ximage->data);
break;
case 8:
free(mempix_char);
mempix_char=(unsigned char *)(ximage->data);
defpix=(PIXINFO*)malloc(sizeof(PIXINFO)*256);
lirpix=(PIXINFO*)malloc(sizeof(PIXINFO)*256);
pixdiff=(float*)malloc(256*256*sizeof(float));
xpalette=&mempix_char[screen_totpix+1];
for(i=0; i<(screen_totpix+1)+256; i++)mempix_char[i]=0;
lir_colormap=XCreateColormap(xdis, xwin, visual, AllocAll);
default_colormap = DefaultColormap(xdis, screen_num);
// Store the default colormap in defpix
for(id=0; id<256; id++)
{
xco.pixel=id;
k=XQueryColor (xdis,default_colormap,&xco);
defpix[id].red=xco.red;
defpix[id].green=xco.green;
defpix[id].blue=xco.blue;
defpix[id].flag=0;
defpix[id].pixel=id;
defpix[id].total= ( (float)((unsigned int)defpix[id].red)*
(unsigned int)defpix[id].red+
(float)((unsigned int)defpix[id].green)*
(unsigned int)defpix[id].green+
(float)((unsigned int)defpix[id].blue)*
(unsigned int)defpix[id].blue);
}
// svga_palette uses the six lowest bits for the colour intensities.
// shift left by 10 to move our data to occupy the six highest bits.
// Store the svgalib palette.
for(il=0; il<MAX_SVGA_PALETTE; il++)
{
lirpix[il].red=svga_palette[3*il+2]<<2;
lirpix[il].green=svga_palette[3*il+1]<<2;
lirpix[il].blue=svga_palette[3*il ]<<2;
if(lirpix[il].red != 0)lirpix[il].red|=3;
if(lirpix[il].green != 0)lirpix[il].green|=3;
if(lirpix[il].blue != 0)lirpix[il].blue|=3;
lirpix[il].red<<=8;
lirpix[il].green<<=8;
lirpix[il].blue<<=8;
lirpix[il].pixel=il;
lirpix[il].flag=1;
lirpix[il].total= ( (float)((unsigned int)lirpix[il].red)*
(unsigned int)lirpix[il].red+
(float)((unsigned int)lirpix[il].green)*
(unsigned int)lirpix[il].green+
(float)((unsigned int)lirpix[il].blue)*
(unsigned int)lirpix[il].blue);
}
for(il=MAX_SVGA_PALETTE; il<256; il++)
{
lirpix[il].red=0;
lirpix[il].green=0;
lirpix[il].blue=0;
lirpix[il].pixel=il;
lirpix[il].flag=0;
}
#define M 0.00000001
#define N 0x100
// Sort lirpix in order of ascending total intensity.
for(il=0; il<MAX_SVGA_PALETTE-1; il++)
{
t1=0;
m=il;
for(kl=il; kl<MAX_SVGA_PALETTE; kl++)
{
if(lirpix[kl].total > t1)
{
t1=lirpix[kl].total;
m=kl;
}
}
tmppix=lirpix[il];
lirpix[il]=lirpix[m];
lirpix[m]=tmppix;
}
// Compute the similarity between lirpix and defpix and store in a matrix.
for(il=0; il<MAX_SVGA_PALETTE; il++)
{
for(id=0; id<256; id++)
{
t2=pow((float)(int)(((unsigned int)lirpix[il].red-
(unsigned int)defpix[id].red)),2.0)+
pow((float)(int)(((unsigned int)lirpix[il].green-
(unsigned int)defpix[id].green)),2.0)+
pow((float)(int)(((unsigned int)lirpix[il].blue-
(unsigned int)defpix[id].blue)),2.0);
pixdiff[id+il*256]=t2;
}
}
// Reorder the default colormap for the diagonal elements
// of pixdiff (up to MAX_SVGA_PALETTE-1) to become as small
// as possible when stepping in the ascending order that
// lirpix currently is sorted in.
for(il=0; il<MAX_SVGA_PALETTE; il++)
{
t1=BIG;
kd=0;
for(id=0; id<256; id++)
{
if(pixdiff[id+il*256] < t1)
{
t1=pixdiff[id+il*256];
kd=id;
}
}
tmppix=defpix[il];
defpix[il]=defpix[kd];
defpix[kd]=tmppix;
for(kl=0; kl<MAX_SVGA_PALETTE; kl++)
{
t1=pixdiff[kd+kl*256];
pixdiff[kd+kl*256]=pixdiff[il+kl*256];
pixdiff[il+kl*256]=t1;
}
}
for(i=0; i<MAX_SVGA_PALETTE; i++)
{
xco.pixel=defpix[i].pixel;
xco.red=lirpix[i].red;
xco.green=lirpix[i].green;
xco.blue=lirpix[i].blue;
xco.flags=DoRed|DoGreen|DoBlue;
xco.pad=0;
k=XStoreColor(xdis, lir_colormap, &xco);
if(k==0)
{
printf("\nPalette failed\n");
goto exitmain;
}
xpalette[lirpix[i].pixel]=xco.pixel;
}
for(i=MAX_SVGA_PALETTE; i<256; i++)
{
xco.pixel=defpix[i].pixel;
xco.red=defpix[i].red;
xco.green=defpix[i].green;
xco.blue=defpix[i].blue;
xco.flags=DoRed|DoGreen|DoBlue;
xco.pad=0;
k=XStoreColor(xdis, lir_colormap, &xco);
if(k==0)
{
printf("\nPalette failed\n");
goto exitmain;
}
xpalette[i]=lirpix[i].pixel;
}
XSetWindowColormap(xdis, xwin, lir_colormap);
free(defpix);
free(lirpix);
free(pixdiff);
break;
}
shminfo->readOnly = False;
XShmAttach(xdis,shminfo);
}
#endif
XInitImage(ximage);
XSelectInput(xdis, xwin,
ButtonPressMask|
ExposureMask|
KeyPressMask|
KeyReleaseMask|
ButtonReleaseMask|
PointerMotionMask);
XMapWindow(xdis, xwin);
// Create a thread that will close the entire process in a controlled way
// in case lirerr() is called or the ESC key is pressed.
sem_init(&sem_kill_all,0,0);
pthread_create(&thread_identifier_kill_all,NULL,(void*)thread_kill_all, NULL);
i=check_mmx();
mmx_present=i&1;
if(mmx_present != 0)simd_present=i/2; else simd_present=0;
lir_status=LIR_OK;
lir_sem_init(SEM_KEYBOARD);
process_event_flag=TRUE;
pthread_create(&thread_identifier_process_event,NULL,
(void*)thread_process_event, NULL);
while(expose_event_done == FALSE)
{
lir_sleep(1000);
}
lir_sem_init(SEM_MOUSE);
pthread_create(&thread_identifier_mouse,NULL, (void*)thread_mouse, NULL);
// Create a thread for the main menu.
users_open_devices();
if(kill_all_flag) goto skipmenu;
pthread_create(&thread_identifier_main_menu,NULL,
(void*)thread_main_menu, NULL);
pthread_join(thread_identifier_main_menu,0);
skipmenu:;
sem_post(&sem_kill_all);
pthread_join(thread_identifier_kill_all,0);
lir_remove_mouse_thread();
pthread_join(thread_identifier_mouse,0);
show_errmsg(1);
lir_refresh_screen();
XSync(xdis,True);
process_event_flag=FALSE;
pthread_join(thread_identifier_process_event,0);
XFreeCursor(xdis, cross_cursor);
if(X11_accesstype==X11_STANDARD)
{
free(mempix_char);
}
#if SHM_INSTALLED == 1
else
{
XShmDetach(xdis,shminfo);
shmdt(shminfo->shmaddr);
shmctl(shminfo->shmid,IPC_RMID,NULL);
free(shminfo);
}
#endif
exitmain:;
users_close_devices();
lir_close_serport();
free(vga_font);
XCloseDisplay(xdis);
free(keyboard_buffer);
if(dmp!=NULL)fclose(dmp);
return lir_errcod;
}
void thread_process_event(void)
{
int chr;
int cc;
XEvent ev;
char key_buff[16];
int count, m;
KeySym ks;
int mbutton_state;
mbutton_state=0;
while(process_event_flag)
{
XNextEvent(xdis, &ev);
switch(ev.type)
{
// We want to know about the user clicking on the close window button
case ClientMessage:
if ( ev.xclient.data.l[0] == (int)(wm_delete_window) )
{
printf ( "Shutting down now!!!\n" );
chr = X_ESC_SYM;
sem_post(&sem_kill_all);
store_in_kbdbuf(0);
return;
}
break;
case Expose:
if(X11_accesstype==X11_STANDARD)
{
XPutImage(xdis, xwin, xgc, ximage,0,0,0,0, screen_width, screen_height);
}
else
{
XShmPutImage (xdis, xwin, xgc, ximage, 0, 0, 0, 0, screen_width, screen_height, FALSE);
}
if(color_depth==8)XInstallColormap(xdis, lir_colormap);
expose_event_done=TRUE;
break;
case ButtonPress:
if ( (ev.xbutton.button == Button1) != 0)
{
new_lbutton_state=1;
goto mousepost;
}
if ( (ev.xbutton.button == Button3) != 0)
{
new_rbutton_state=1;
goto mousepost;
}
if ( (ev.xbutton.button == Button2) != 0)
{
mbutton_state=1;
}
if(mbutton_state==0)
{
if ( (ev.xbutton.button == Button5) != 0)
{
step_rx_frequency(1);
}
if ( (ev.xbutton.button == Button4) != 0)
{
step_rx_frequency(-1);
}
}
else
{
m=bg.wheel_stepn;
if ( (ev.xbutton.button == Button5) != 0)
{
m++;
if(m>30)m=30;
}
if ( (ev.xbutton.button == Button4) != 0)
{
m=bg.wheel_stepn;
m--;
if(m<-30)m=-30;
if(genparm[AFC_ENABLE]==0 && m<0)m=0;
}
bg.wheel_stepn=m;
sc[SC_SHOW_WHEEL]++;
make_modepar_file(GRAPHTYPE_BG);
}
break;
case ButtonRelease:
if ( (ev.xbutton.button == Button1) != 0)
{
new_lbutton_state=0;
goto mousepost;
}
if ( (ev.xbutton.button == Button3) != 0)
{
new_rbutton_state=0;
goto mousepost;
}
if ( (ev.xbutton.button == Button2) != 0)
{
mbutton_state=0;
}
break;
case MotionNotify:
new_mouse_x= ev.xbutton.x;
if(new_mouse_x < 0)new_mouse_x=0;
if(new_mouse_x >= screen_width)new_mouse_x=screen_width-1;
new_mouse_y= ev.xbutton.y;
if(new_mouse_y < 0)new_mouse_y=0;
if(new_mouse_y >= screen_height)new_mouse_y=screen_height-1;
mousepost:;
lir_sem_post(SEM_MOUSE);
break;
case KeyPress:
chr = XKeycodeToKeysym(xdis, ev.xkey.keycode, 0);
if(newcomer_escflag)
{
cc=toupper(chr);
if(cc=='Y')goto escexit;
if(cc!='N')break;
newcomer_escpress(1);
newcomer_escflag=FALSE;
break;
}
if(chr == X_ESC_SYM)
{
// The ESC key was pressed.
if(ui.newcomer_mode != 0)
{
newcomer_escpress(0);
newcomer_escflag=TRUE;
break;
}
escexit:;
sem_post(&sem_kill_all);
store_in_kbdbuf(0);
return;
}
if(chr == X_SHIFT_SYM_L || chr == X_SHIFT_SYM_R)
{
shift_key_status=1;
break;
}
// Get ASCII codes from Dec 32 to Dec 127
count = XLookupString((XKeyEvent *)&ev, key_buff, 2, &ks,NULL);
if ((count == 1) && ((int)key_buff[0]>31) )
{
store_in_kbdbuf((int)key_buff[0]);
break;
}
cc=0;
if(chr >= X_F1_SYM && chr <= X_F12_SYM)
{
if(chr <= X_F10_SYM)
{
if(shift_key_status == 0)
{
cc=F1_KEY+chr-X_F1_SYM;
}
else
{
cc=SHIFT_F1_KEY+chr-X_F1_SYM;
if(chr > X_F2_SYM)cc++;
if(chr >= X_F9_SYM)cc=0;
}
}
else
{
if(shift_key_status == 0)
{
cc=F11_KEY+chr-X_F11_SYM;
}
}
if(cc != 0)store_in_kbdbuf(cc);
break;
}
switch (chr)
{
case X_UP_SYM:
cc=ARROW_UP_KEY;
break;
case X_DWN_SYM:
cc=ARROW_DOWN_KEY;
break;
case X_RIGHT_SYM:
cc=ARROW_RIGHT_KEY;
break;
case X_BACKDEL_SYM:
case X_LEFT_SYM:
cc=ARROW_LEFT_KEY;
break;
case X_HOME_SYM:
cc=HOME_KEY;
break;
case X_INSERT_SYM:
cc=INSERT_KEY;
break;
case X_DELETE_SYM:
cc=DELETE_KEY;
break;
case X_END_SYM:
cc=END_KEY;
break;
case X_PGUP_SYM:
cc=PAGE_UP_KEY;
break;
case X_PGDN_SYM:
cc=PAGE_DOWN_KEY;
break;
case X_PAUSE_SYM:
cc=PAUSE_KEY;
break;
case X_ENTER_SYM:
cc=10;
break;
}
if(cc != 0)store_in_kbdbuf(cc);
break;
case KeyRelease:
chr=XKeycodeToKeysym(xdis, ev.xkey.keycode, 0);
if(chr == X_SHIFT_SYM_L || chr == X_SHIFT_SYM_R)
{
shift_key_status=0;
}
break;
}
}
}
void ui_setup(void)
{
FILE *file;
int i, j, k;
int xxprint;
char s[10];
char chr;
int *uiparm;
char *parinfo;
uiparm=(int*)(&ui);
parinfo=NULL;
xxprint=investigate_cpu();
file = fopen(userint_filename, "rb");
if (file == NULL)
{
print_procerr(xxprint);
printf("\n\nSetup file %s missing.",userint_filename);
full_setup:;
for(i=0; i<MAX_UIPARM; i++) uiparm[i]=0;
printf("\nUse W to create a new %s file after setup.\n\n",userint_filename);
printf(
"Press S for setup routines in normal mode or press N for NEWCOMER mode");
printf("\nAny other key to exit. (You might want to manually edit %s)",
userint_filename);
printf("\nThen press enter\n\n=>");
while(fgets(s,8,stdin)==NULL);
chr=toupper(s[0]);
if(chr != 'S' && chr != 'N') exit(0);
if(chr == 'N')
{
ui.newcomer_mode=1;
}
else
{
ui.newcomer_mode=0;
}
x_global_uiparms(0);
ui.rx_input_mode=-1;
ui.tx_dadev_no=-1;
ui.rx_dadev_no=-1;
uiparm_change_flag=TRUE;
}
else
{
if(parinfo==NULL)
{
parinfo=malloc(4096);
if(parinfo==NULL)
{
lirerr(1078);
return;
}
}
for(i=0; i<4096; i++) parinfo[i]=0;
i=fread(parinfo,1,4095,file);
fclose(file);
file=NULL;
if(i >= 4095)
{
goto go_full_setup;
}
k=0;
for(i=0; i<MAX_UIPARM; i++)
{
while(parinfo[k]==' ' ||
parinfo[k]== '\n' )k++;
j=0;
while(parinfo[k]== uiparm_text[i][j] && k<4096)
{
k++;
j++;
}
if(uiparm_text[i][j] != 0)goto go_full_setup;
while(parinfo[k]!='[' && k<4096)k++;
sscanf(&parinfo[k],"[%d]",&uiparm[i]);
while(parinfo[k]!='\n')k++;
}
if( ui.font_scale < 1 ||
ui.font_scale > 5 ||
ui.check != UI_VERNR ||
ui.screen_width_factor < 33 ||
ui.screen_width_factor > 100 ||
ui.screen_height_factor <33 ||
ui.screen_height_factor > 100 ||
ui.newcomer_mode <0 ||
ui.newcomer_mode >1)
{
go_full_setup:;
printf("\n\nSetup file %s has errors",userint_filename);
goto full_setup;
}
uiparm_change_flag=FALSE;
free(parinfo);
}
}
#include <pthread.h>
#include <semaphore.h>
#include <X11/cursorfont.h>
#include <X11/Xutil.h>
#include "globdef.h"
#include "thrdef.h"
#include "lconf.h"
#include "xdef.h"
#include "ldef.h"
#if SHM_INSTALLED == 1
#include <X11/extensions/XShm.h>
#include <sys/ipc.h>
#include <sys/shm.h>
XShmSegmentInfo *shminfo;
int X11_accesstype;
#endif
pthread_t thread_identifier_process_event;
unsigned char *mempix_char;
unsigned short int *mempix_shi;
int first_mempix;
int last_mempix;
int process_event_flag;
int expose_event_done;
int shift_key_status;
int color_depth;
unsigned char *xpalette;
GC xgc;
XImage *ximage;
Display *xdis;
Window xwin;
Colormap lir_colormap;
#include <semaphore.h>
#include <pthread.h>
#include <ctype.h>
#include <X11/cursorfont.h>
#include <X11/Xutil.h>
#include "globdef.h"
#include "thrdef.h"
#include "uidef.h"
#include "screendef.h"
#include "lconf.h"
#include "xdef.h"
#include "keyboard_def.h"
#include "vernr.h"
#if SHM_INSTALLED == 1
#include <X11/extensions/XShm.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#endif
extern GC xgc;
extern XImage *ximage;
extern Display *xdis;
extern Window xwin;
extern Colormap lir_colormap;
typedef struct {
unsigned short int red;
unsigned short int green;
unsigned short int blue;
unsigned int pixel;
short int flag;
float total;
}PIXINFO;
void lir_set_title(char *s)
{
char *window_name;
char wn[80];
XTextProperty window_title_property;
// Set the name of our window
// This is the string to be translated into a property.
// translate the given string into an X property.
if(X11_accesstype==X11_STANDARD)
{
sprintf(wn,"%s %s",PROGRAM_NAME,s);
}
else
{
sprintf(wn,"MIT SHM %s %s",PROGRAM_NAME,s);
}
window_name=wn;
XStringListToTextProperty(&window_name, 1, &window_title_property);
XSetWMName(xdis, xwin, &window_title_property);
XFree(window_title_property.value);
}
void x_global_uiparms(int wn)
{
char s[80],ss[10];
int line;
line=0;
if(ui.vga_mode==0)ui.vga_mode=12;
if(ui.mouse_speed <=0 || ui.mouse_speed> 120)ui.mouse_speed=8;
if(ui.vga_mode < 10 || ui.vga_mode > 256)ui.vga_mode=10;
ui.process_priority=1;
clear_screen();
if(ui.newcomer_mode != 0)
{
ui.font_scale=2;
ui.parport=0;
ui.parport_pin=0;
}
else
{
sprintf(s,"Font scale (1 to 5):");
if(wn==0)
{
fntc:;
printf("\n%s\n=>",s);
while(fgets(ss,8,stdin)==NULL);
lir_inkey=toupper(ss[0]);
if(lir_inkey < '1' || lir_inkey > '5')goto fntc;
ui.font_scale=lir_inkey-'0';
}
else
{
lir_text(0,2,s);
ui.font_scale=lir_get_integer(21,2,2,1,5);
if(kill_all_flag) return;
}
sprintf(s,"Parport address (lpt1=888, none=0):");
parport_gtnum:;
if(wn==0)
{
printf("\n%s\n=>",s);
while(fgets(ss,8,stdin)==NULL);
sscanf(ss,"%d", &ui.parport);
if(ui.parport < 0)goto parport_gtnum;
}
else
{
clear_lines(3,3);
lir_text(0,3,s);
ui.parport=lir_get_integer(36,3,5,0,99999);
if(kill_all_flag) return;
}
if(ui.parport != 0)
{
sprintf (s,"Parport read pin (ACK=10):");
gtpin:;
if(wn==0)
{
printf("\n%s\n=>",s);
while(fgets(ss,8,stdin)==NULL);
sscanf(ss,"%d", &ui.parport_pin);
}
else
{
clear_lines(4,4);
lir_text(0,4,s);
ui.parport_pin=lir_get_integer(27,4,2,10,15);
if(kill_all_flag) return;
}
if( ui.parport_pin ==14 ||
ui.parport_pin > 15 ||
ui.parport_pin < 10) goto gtpin;
}
else
{
ui.parport_pin=0;
}
}
sprintf(s,"Percentage of screen width to use(33 to 100):");
parport_wfac:;
if(wn==0)
{
printf("\n%s\n=>",s);
while(fgets(ss,8,stdin)==NULL);
sscanf(ss,"%d", &ui.screen_width_factor);
if(ui.screen_width_factor < 33 ||
ui.screen_width_factor > 100)goto parport_wfac;
}
else
{
clear_lines(5,5);
lir_text(0,5,s);
ui.screen_width_factor=lir_get_integer(47,5,3,33,100);
if(kill_all_flag) return;
}
sprintf(s,"Percentage of screen height to use (33 to 100):");
parport_hfac:;
if(wn==0)
{
printf("\n%s\n=>",s);
while(fgets(ss,8,stdin)==NULL);
sscanf(ss,"%d", &ui.screen_height_factor);
if(ui.screen_height_factor < 33 ||
ui.screen_height_factor > 100)goto parport_hfac;
printf("\n\nLinrad will now open another window.");
printf("\nMinimize this window and click on the new window to continue.");
printf(
"\n\nDo not forget to save your parameters with 'W' in the main menu");
fflush(NULL);
}
else
{
clear_lines(6,6);
lir_text(0,6,s);
ui.screen_height_factor=lir_get_integer(49,6,3,33,100);
if(kill_all_flag) return;
if(ui.newcomer_mode != 0)
{
clear_screen();
lir_text(0,4,"You are now in newcomer mode.");
lir_text(0,6,"Press 'Y' to change to normal mode or 'N' to");
lir_text(0,7,"stay in newcomer mode.");
ask_newco:;
await_processed_keyboard();
if(lir_inkey == 'N')goto stay_newco;
if(lir_inkey != 'Y')goto ask_newco;
ui.newcomer_mode=0;
}
stay_newco:;
lir_text(0,8,"Save the new parameters with W in the main menu");
lir_text(0,9,"Then restart Linrad for changes to take effect.");
lir_text(10,11,press_any_key);
await_keyboard();
}
}
void lin_global_uiparms(int wn)
{
int i;
i=wn;
}
// *********************************************************
// Graphics for X11
// *********************************************************
void lir_getpalettecolor(int j, int *r, int *g, int *b)
{
int k;
unsigned short int *ipalette;
switch (color_depth)
{
case 24:
b[0]=(int)(svga_palette[3*j ])>>2;
g[0]=(int)(svga_palette[3*j+1])>>2;
r[0]=(int)(svga_palette[3*j+2])>>2;
break;
case 16:
ipalette=(void*)(&svga_palette[0]);
k=ipalette[j];
k<<=1;
b[0]=k&0x3f;
k>>=6;
g[0]=k&0x3f;
k>>=5;
r[0]=k;
break;
case 8:
b[0]=(int)(svga_palette[3*j ]);
g[0]=(int)(svga_palette[3*j+1]);
r[0]=(int)(svga_palette[3*j+2]);
break;
}
}
void lir_fillbox(int x, int y,int w, int h, unsigned char c)
{
int i, j, k;
unsigned short int *ipalette;
k=(x+y*screen_width);
if(k<0 || k+(h-1)*screen_width+w > screen_totpix)
{
lirerr(1213);
return;
}
if(first_mempix > k)first_mempix=k;
switch (color_depth)
{
case 24:
for(j=0; j<h; j++)
{
for(i=0; i<w; i++)
{
mempix_char[4*(k+i) ]=svga_palette[3*c ];
mempix_char[4*(k+i)+1]=svga_palette[3*c+1];
mempix_char[4*(k+i)+2]=svga_palette[3*c+2];
}
k+=screen_width;
}
break;
case 16:
ipalette=(void*)(&svga_palette[0]);
for(j=0; j<h; j++)
{
for(i=0; i<w; i++)
{
mempix_shi[k+i]=ipalette[c];
}
k+=screen_width;
}
break;
case 8:
for(j=0; j<h; j++)
{
for(i=0; i<w; i++)
{
mempix_char[k+i]=xpalette[c];
}
k+=screen_width;
}
break;
}
k-=screen_width-w;
if(last_mempix < k)last_mempix=k;
}
void lir_getbox(int x, int y, int w, int h, void* dp)
{
unsigned char *savmem;
int i, j, k, m;
unsigned char c,c1,c2,c3;
unsigned short int *ipalette;
k=x+y*screen_width;
savmem=(unsigned char*)dp;
m=0;
c=0;
c1=0;
c2=0;
switch (color_depth)
{
case 24:
for(j=0; j<h; j++)
{
for(i=0; i<w; i++)
{
if(svga_palette[3*c ] == mempix_char[4*(k+i) ] &&
svga_palette[3*c+1] == mempix_char[4*(k+i)+1] &&
svga_palette[3*c+2] == mempix_char[4*(k+i)+2])goto store_24;
if(svga_palette[3*c1 ] == mempix_char[4*(k+i) ] &&
svga_palette[3*c1+1] == mempix_char[4*(k+i)+1] &&
svga_palette[3*c1+2] == mempix_char[4*(k+i)+2])
{
c3=c;
c=c1;
c1=c;
goto store_24;
}
if(svga_palette[3*c2 ] == mempix_char[4*(k+i) ] &&
svga_palette[3*c2+1] == mempix_char[4*(k+i)+1] &&
svga_palette[3*c2+2] == mempix_char[4*(k+i)+2])
{
c3=c;
c=c2;
c1=c;
c2=c3;
goto store_24;
}
c2=c1;
c1=c;
while(svga_palette[3*c ] != mempix_char[4*(k+i) ] ||
svga_palette[3*c+1] != mempix_char[4*(k+i)+1] ||
svga_palette[3*c+2] != mempix_char[4*(k+i)+2])
{
c++;
if(c>=MAX_SVGA_PALETTE)c=0;
if(c==c1)
{
lirerr(1248);
return;
}
}
store_24:;
savmem[m]=c;
m++;
}
k+=screen_width;
}
break;
case 16:
ipalette=(void*)(&svga_palette[0]);
for(j=0; j<h; j++)
{
for(i=0; i<w; i++)
{
if(ipalette[c] == mempix_shi[(k+i)]) goto store_16;
if(ipalette[c1] == mempix_shi[(k+i)])
{
c3=c;
c=c1;
c1=c;
goto store_16;
}
if(ipalette[c2] == mempix_shi[(k+i)])
{
c3=c;
c=c2;
c1=c;
c2=c3;
goto store_16;
}
c2=c1;
c1=c;
while(ipalette[c] != mempix_shi[(k+i)])
{
c++;
if(c>=MAX_SVGA_PALETTE)c=0;
if(c==c1)
{
lirerr(1248);
return;
}
}
store_16:;
savmem[m]=c;
m++;
}
k+=screen_width;
}
break;
case 8:
for(j=0; j<h; j++)
{
for(i=0; i<w; i++)
{
if(xpalette[c] == mempix_char[(k+i)]) goto store_8;
if(xpalette[c1] == mempix_char[(k+i)])
{
c3=c;
c=c1;
c1=c;
goto store_8;
}
if(xpalette[c2] == mempix_char[(k+i)])
{
c3=c;
c=c2;
c1=c;
c2=c3;
goto store_8;
}
c2=c1;
c1=c;
while(xpalette[c] != mempix_char[(k+i)])
{
c++;
if(c>=MAX_SVGA_PALETTE)c=0;
if(c==c1)
{
lirerr(1248);
return;
}
}
store_8:;
savmem[m]=c;
m++;
}
k+=screen_width;
}
break;
}
}
void lir_putbox(int x, int y, int w, int h, void* dp)
{
unsigned char *savmem;
int i, j, k, m;
unsigned short int *ipalette;
k=(x+y*screen_width);
if(k<0 || k+(h-1)*screen_width+w-1 >= screen_totpix)
{
lirerr(1213);
return;
}
if(first_mempix > k)first_mempix=k;
m=0;
savmem=(unsigned char*)dp;
switch (color_depth)
{
case 24:
for(j=0; j<h; j++)
{
for(i=0; i<w; i++)
{
mempix_char[4*(k+i) ]=svga_palette[3*savmem[m] ];
mempix_char[4*(k+i)+1]=svga_palette[3*savmem[m]+1];
mempix_char[4*(k+i)+2]=svga_palette[3*savmem[m]+2];
m++;
}
k+=screen_width;
}
break;
case 16:
ipalette=(void*)(&svga_palette[0]);
for(j=0; j<h; j++)
{
for(i=0; i<w; i++)
{
mempix_shi[k+i]=ipalette[savmem[m]];
m++;
}
k+=screen_width;
}
break;
case 8:
for(j=0; j<h; j++)
{
for(i=0; i<w; i++)
{
mempix_char[k+i]=xpalette[savmem[m]];
m++;
}
k+=screen_width;
}
}
if(last_mempix < k)last_mempix=k;
}
void lir_hline(int x1, int y, int x2, unsigned char c)
{
int i, ia, ib;
unsigned short int *ipalette;
ia=y*screen_width;
if(x1 <= x2)
{
ib=ia+x2;
ia+=x1;
}
else
{
ib=ia+x1;
ia+=x2;
}
if(ia < 0 || ib >= screen_totpix)
{
lirerr(1214);
return;
}
switch (color_depth)
{
case 24:
for(i=ia; i<=ib; i++)
{
mempix_char[4*i ]=svga_palette[3*c ];
mempix_char[4*i+1]=svga_palette[3*c+1];
mempix_char[4*i+2]=svga_palette[3*c+2];
}
break;
case 16:
ipalette=(void*)(&svga_palette[0]);
for(i=ia; i<=ib; i++)
{
mempix_shi[i]=ipalette[c];
}
break;
case 8:
for(i=ia; i<=ib; i++)
{
mempix_char[i]=xpalette[c];
}
break;
}
if(first_mempix > ia)first_mempix=ia;
if(last_mempix < ib)last_mempix=ib;
}
void lir_line(int x1, int yy1, int x2,int y2, unsigned char c)
{
int ia;
int i,j,k;
int xd, yd;
float t1,t2,delt;
unsigned short int *ipalette;
if(x1 < 0)x1=0;
if(x1 >= screen_width)x1=screen_width-1;
if(x2 < 0)x2=0;
if(x2 >= screen_width)x2=screen_width-1;
if(yy1 < 0)yy1=0;
if(yy1 >= screen_height)yy1=screen_height-1;
if(y2 < 0)y2=0;
if(y2 >= screen_height)y2=screen_height-1;
xd=x2-x1;
yd=y2-yy1;
if(yd==0)
{
if(xd==0)
{
lir_setpixel(x1,yy1,c);
}
else
{
lir_hline(x1,yy1,x2,c);
}
return;
}
if(abs(xd)>=abs(yd))
{
if(xd>=0)
{
k=1;
}
else
{
k=-1;
}
if(yd >= 0)
{
delt=0.5;
}
else
{
delt=-0.5;
}
t1=yy1;
t2=(float)(yd)/abs(xd);
i=x1-k;
switch (color_depth)
{
case 24:
while(i!=x2)
{
i+=k;
j=t1+delt;
ia=i+j*(screen_width);
mempix_char[4*ia ]=svga_palette[3*c ];
mempix_char[4*ia+1]=svga_palette[3*c+1];
mempix_char[4*ia+2]=svga_palette[3*c+2];
if(first_mempix > ia)first_mempix=ia;
if(last_mempix < ia)last_mempix=ia;
t1+=t2;
}
break;
case 16:
ipalette=(void*)(&svga_palette[0]);
while(i!=x2)
{
i+=k;
j=t1+delt;
ia=i+j*(screen_width);
mempix_shi[ia ]=ipalette[c ];
if(first_mempix > ia)first_mempix=ia;
if(last_mempix < ia)last_mempix=ia;
t1+=t2;
}
break;
case 8:
while(i!=x2)
{
i+=k;
j=t1+delt;
ia=i+j*(screen_width);
mempix_char[ia ]=xpalette[c ];
if(first_mempix > ia)first_mempix=ia;
if(last_mempix < ia)last_mempix=ia;
t1+=t2;
}
break;
}
}
else
{
if(yd>=0)
{
k=1;
}
else
{
k=-1;
}
if(xd >= 0)
{
delt=0.5;
}
else
{
delt=-0.5;
}
t1=x1;
t2=(float)(xd)/abs(yd);
i=yy1-k;
switch (color_depth)
{
case 24:
while(i!=y2)
{
i+=k;
j=t1+delt;
ia=j+i*(screen_width);
mempix_char[4*ia ]=svga_palette[3*c ];
mempix_char[4*ia+1]=svga_palette[3*c+1];
mempix_char[4*ia+2]=svga_palette[3*c+2];
if(first_mempix > ia)first_mempix=ia;
if(last_mempix < ia)last_mempix=ia;
t1+=t2;
}
break;
case 16:
ipalette=(void*)(&svga_palette[0]);
while(i!=y2)
{
i+=k;
j=t1+delt;
ia=j+i*(screen_width);
mempix_shi[ia ]=ipalette[c ];
if(first_mempix > ia)first_mempix=ia;
if(last_mempix < ia)last_mempix=ia;
t1+=t2;
}
break;
case 8:
while(i!=y2)
{
i+=k;
j=t1+delt;
ia=j+i*(screen_width);
mempix_char[ia ]=xpalette[c ];
if(first_mempix > ia)first_mempix=ia;
if(last_mempix < ia)last_mempix=ia;
t1+=t2;
}
break;
}
}
}
void lir_setpixel(int x, int y, unsigned char c)
{
int ia;
unsigned short int *ipalette;
ia=x+y*screen_width;
if(ia < 0 || ia >= screen_totpix)
{
DEB"\nwrite: x=%d y=%d",x,y);
lirerr(1210);
return;
}
switch (color_depth)
{
case 24:
mempix_char[4*ia ]=svga_palette[3*c ];
mempix_char[4*ia+1]=svga_palette[3*c+1];
mempix_char[4*ia+2]=svga_palette[3*c+2];
break;
case 16:
ipalette=(void*)(&svga_palette[0]);
mempix_shi[ia]=ipalette[c];
break;
case 8:
mempix_char[ia]=xpalette[c];
break;
}
if(first_mempix > ia)first_mempix=ia;
if(last_mempix < ia)last_mempix=ia;
}
void clear_screen(void)
{
int i, k;
switch (color_depth)
{
case 24:
k=4*screen_width*screen_height;
for(i=0; i<k; i+=4)
{
mempix_char[i]=0;
mempix_char[i+1]=0;
mempix_char[i+2]=0;
mempix_char[i+3]=255;
}
break;
case 16:
k=screen_width*screen_height;
for(i=0; i<k; i++)
{
mempix_shi[i]=0;
}
break;
case 8:
k=screen_width*screen_height;
for(i=0; i<k; i++)
{
mempix_char[i]=xpalette[0];
}
}
first_mempix=0;
last_mempix=screen_totpix-1;
lir_refresh_screen();
}
void lir_refresh_screen(void)
{
int l1, h, h1, n;
if(last_mempix >= first_mempix )
{
l1=first_mempix/screen_width;
h=last_mempix/screen_width-l1+1;
if(h>screen_height)h=screen_height;
first_mempix=0x7fffffff;
last_mempix=0;
while(h>0)
{
n=(5*h)/screen_height;
if(n > 1)
{
h1=h/n;
}
else
{
h1=h;
}
if(X11_accesstype==X11_STANDARD)
{
XPutImage(xdis, xwin, xgc, ximage, 0, l1, 0, l1, screen_width, h1);
}
#if SHM_INSTALLED == 1
else
{
XShmPutImage(xdis, xwin, xgc, ximage, 0, l1, 0, l1, screen_width, h1,FALSE);
}
#endif
l1+=h1;
h-=h1;
if(h > 0)lir_sched_yield();
}
XFlush(xdis);
}
}
void thread_mouse(void)
{
wxmouse();
}
LINRADDARNIL