[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
correction : Improved X11 performance for xlinrad wit MIT-SHM
- Subject: correction : Improved X11 performance for xlinrad wit MIT-SHM
- From: Pierre Vanhoucke <skynet.be; pierre.vanhoucke@xxxxxxxxxxxxxxxx>
- Date: Sat, 25 Jul 2009 15:35:40 +0200
Hi Leif,
During the compilation tests for standard X11 processing without
MIT-SHM, I found a few bugs related to the SHM_INSTALLED switch.
I corrected xmain.c and xvar.c ( see attachment ) and now everything
compiles fine when I force SHM_INSTALLED to 0 in lconf.h.
If SHM_INSTALLED is 0 I also added a message to inform the user of the
missing SHM libraries.
However there is still a problem in configure with the SHM_INSTALLED
switch:
When I remove the x11proto-xext-dev package, the SHM_INSTALLED switch is
wrongly set to 1 and the Makefile contains a reference to -LXext which
is not there.
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
printf("\nThe libraries for MIT-SHM are not installed in this system.\n");
printf("Install the packages libxext-dev and x11proto-xext-dev\n");
printf("to enable MIT-SHM.\n");
printf("Then run ./configure and after that make xlinrad.\n\n");
#endif
#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");
}
#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);
}
#if SHM_INSTALLED == 1
else
{
XShmPutImage (xdis, xwin, xgc, ximage, 0, 0, 0, 0, screen_width, screen_height, FALSE);
}
#endif
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;
#endif
int X11_accesstype;
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;
LINRADDARNIL