// Copyright (c) <2012> // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, // merge, publish, distribute, sublicense, and/or sell copies of // the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE // OR OTHER DEALINGS IN THE SOFTWARE. // for Linux/svgalib. // We set up the screen and mouse here and then we start // the version independent main menu thread and the keyboard thread. // We return here with lir_status=LIR_NEW_SCREEN in case the user // wants a different screen resolution or LIR_UIPARMS if the // user wants to change other system parameters. //#define UNINIT_MEMDATA 0x57 #define UNINIT_MEMDATA 0 #define MAX_MOUSE_CURSIZE 50 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* to use KG_SHIFT and so on */ #include "globdef.h" #include "lconf.h" #include "conf.h" #include "rusage.h" #include "thrdef.h" #include "fdef.h" #include "uidef.h" #include "screendef.h" #include "vernr.h" #include "options.h" #include "keyboard_def.h" typedef struct { unsigned short int red; unsigned short int green; unsigned short int blue;unsigned int pixel; short int flag; float total; }PIXINFO; struct termios termios_pp; int terminal_flag; int gpm_fd; struct fb_cmap *fb_palette; int mouse_wheel_flag; int main(int argc, char *argv[]) { int i,ir,j,k; int xxprint; char *parinfo; FILE *file; int *uiparm; (void) *argv; (void) argc; setlocale(LC_ALL,"POSIX"); #if UNINIT_MEMDATA != 0 { parinfo=(char*)(&uninit_mem_begin); k=&uninit_mem_end-parinfo; for(i=0; i= 4095) { goto go_full_setup; } k=0; for(i=0; i OPERATOR_SKIL_EXPERT || ui.soundcard_radio < SOUNDCARD_RADIO_UNDEFINED || ui.soundcard_radio >= MAX_SOUNDCARD_RADIO) { go_full_setup:; printf("\n\nSetup file %s has errors",userint_filename); parinfo=chk_free(parinfo); goto full_setup; } graphics_init(); init_font(ui.font_scale); if(lir_errcod != 0)goto exitmain; uiparm_change_flag=FALSE; } //extio_error=load_extio_library(); users_open_devices(); if(kill_all_flag) goto exitmain; pthread_create(&thread_identifier_main_menu,NULL, (void*)thread_main_menu, NULL); file=freopen( "stderr.log", "w", stderr ); usleep(50000); lir_inkey=0; pthread_join(thread_identifier_main_menu,0); exitmain:; //unload_extio_library(); if(terminal_flag) { clear_keyboard(); tcsetattr(0, TCSANOW, &termios_pp); } if(gpm_fd>=0) close(gpm_fd); printf( "\e[?25h" ); // restore cursor visibility users_close_devices(); lir_close_serport(); pthread_cancel(thread_identifier_mouse); pthread_join(thread_identifier_mouse,0); lir_sleep(20000); pthread_cancel(thread_identifier_keyboard); pthread_join(thread_identifier_keyboard,0); show_errmsg(0); skip:; printf("\nLeaving %s\n",PROGRAM_NAME); if(dmp!=NULL)fclose(dmp); munmap(mempix_char, framebuffer_screensize); if(framebuffer_handle)close(framebuffer_handle); if(fb_palette)free(fb_palette); return lir_errcod; } void graphics_init(void) { int i, k; unsigned short int *ipalette; struct fb_var_screeninfo vinfo; struct fb_fix_screeninfo finfo; short unsigned int red[MAX_SVGA_PALETTE]; short unsigned int green[MAX_SVGA_PALETTE]; short unsigned int blue[MAX_SVGA_PALETTE]; short unsigned int transp[MAX_SVGA_PALETTE]; struct sockaddr_un addr; struct MouseCaps caps; struct termios termios_p; framebuffer_screensize=0; framebuffer_handle = open("/dev/fb0", O_RDWR); if (!framebuffer_handle) { lirerr(1349); return; } if (ioctl(framebuffer_handle, FBIOGET_VSCREENINFO, &vinfo)) { lirerr(1351); return; } color_depth=vinfo.bits_per_pixel; framebuffer_screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8; mempix_char = mmap(0, framebuffer_screensize, PROT_READ | PROT_WRITE, MAP_SHARED, framebuffer_handle, 0); #if IA64 == 0 if ((int)mempix_char == -1) #else if ((long int)mempix_char == -1) #endif { lirerr(1355); return; } color_depth=vinfo.bits_per_pixel; printf("color_depth=%d",color_depth); tcgetattr(0, &termios_pp); memcpy(&termios_p, &termios_pp, sizeof(termios_p)); terminal_flag=TRUE; termios_p.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); termios_p.c_oflag &= ~OPOST; termios_p.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); termios_p.c_cflag &= ~(CSIZE | PARENB); termios_p.c_cflag |= CS8; tcsetattr(0, TCSANOW, &termios_p); printf( "\e[?25l\n " ); // hide the cursor // Open gpmctl. This will hide the gpm cursor. gpm_fd=socket(AF_UNIX,SOCK_STREAM,0); if(gpm_fd >= 0) { memset(&addr,0,sizeof(addr)); addr.sun_family=AF_UNIX; strcpy(addr.sun_path, GPMCTL); i=sizeof(addr.sun_family)+strlen(GPMCTL); if(connect(gpm_fd,(struct sockaddr *)(&addr),i)<0 ) { close(gpm_fd); gpm_fd=open(GPMCTL,O_RDWR); } } screen_width=vinfo.xres; screen_height=vinfo.yres; screen_totpix=screen_width*screen_height; i=vga_getmousetype(); if(i == MOUSE_NONE) { lirerr(1354); return; } mouse_init("/dev/mouse",i,MOUSE_DEFAULTSAMPLERATE); mouse_setdefaulteventhandler(); mouse_setxrange(0, screen_width-1); mouse_setyrange(0, screen_height-1); mouse_setwrap(MOUSE_NOWRAP); lir_status=LIR_OK; // Set up mouse and system parameters in case it has not been done already. mouse_cursize=screen_height/80; if(mouse_cursize > MAX_MOUSE_CURSIZE)mouse_cursize=MAX_MOUSE_CURSIZE; if(ui.mouse_speed < 1)ui.mouse_speed=1; if(ui.mouse_speed > 999)ui.mouse_speed=999; mouse_setscale(ui.mouse_speed); mouse_x=screen_width/2; mouse_y=screen_height/2; new_mouse_x=screen_width/2; new_mouse_y=screen_height/2; mouse_setposition( mouse_x, mouse_y); if(mouse_getcaps(&caps)) { // Failed! Old library version... Check the mouse type. i=vga_getmousetype() & MOUSE_TYPE_MASK; if(i == MOUSE_INTELLIMOUSE || i==MOUSE_IMPS2) { mouse_wheel_flag=1; } else { mouse_wheel_flag=0; } } else { // If this is a mouse_wheel_flag mouse, interpret rx as a wheel mouse_wheel_flag = ((caps.info & MOUSE_INFO_WHEEL) != 0); } if(mouse_wheel_flag) { mouse_setrange_6d(0,0, 0,0, 0, 0, -180,180, 0,0, 0,0, MOUSE_RXDIM); } if(screen_width < 640 || screen_height < 480) { lirerr(1242); return; } switch (color_depth) { case 32: case 24: for(i=0; i>=1; ipalette[i]=(short unsigned int)k; } break; case 8: if (ioctl(framebuffer_handle, FBIOGET_FSCREENINFO, &finfo)) { lirerr(1350); return; } fb_palette=malloc(256*sizeof(fb_palette)); if(finfo.visual == FB_VISUAL_DIRECTCOLOR) { if (ioctl(framebuffer_handle, FBIOGETCMAP , &fb_palette)) { free(fb_palette); lirerr(1352); return; } } fb_palette->start=0; fb_palette->len=MAX_SVGA_PALETTE; for(i=0; ired=red; fb_palette->green=green; fb_palette->blue=blue; fb_palette->transp=transp; vinfo.activate=FB_ACTIVATE_ALL|FB_CHANGE_CMAP_VBL; ioctl(framebuffer_handle, FBIOPUT_VSCREENINFO, &vinfo); i=ioctl(framebuffer_handle, FBIOPUTCMAP , &fb_palette); printf("\nioctl FBIOPUTCMAP returned %d\n",i); /* defpix=(PIXINFO*)malloc(sizeof(PIXINFO)*256); lirpix=(PIXINFO*)malloc(sizeof(PIXINFO)*256); pixdiff=(float*)malloc(256*256*sizeof(float)); 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=(long unsigned int)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=(unsigned int)id; defpix[id].total=(float)defpix[id].red*(float)defpix[id].red+ (float)defpix[id].green*(float)defpix[id].green+ (float)defpix[id].blue*(float)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 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= 65 && c <= 68) { c+=ARROW_UP_KEY-65; goto fkn_key_ok; } if(c >= 49 && c <= 54) { i=force_getchar(); // These keys have to be followed by 126 // HOME=49 // INSERT=50 // DELETE=51 // END=52 // PAGE_UP=53 // PAGE_DOWN=54 if(i == 126) { c+=HOME_KEY-49; goto fkn_key_ok; } k=force_getchar(); if(k == 126) { if(c == 49) { // F6=55 // F7=56 // F8=57 if(i >= 55 && i <= 57) { c=i+F6_KEY-55; goto fkn_key_ok; } } if(c == 50) { // F9=48 // F10=49 // F10_PAD=50 // F11=51 // F12=52 // SHIFT_F1=53 // SHIFT_F2=54 // SHIFT_F2_PAD=55 // SHIFT_F3=56 // SHIFT_F4=57 if(i >= 48 && i <= 57) { c=i+F9_KEY-48; goto fkn_key_ok; } } if(c == 51) { // SHIFT_F5=49 // SHIFT_F6=50 // SHIFT_F7=51 // SHIFT_F8=52 if(i >= 49 && i <= 52) { c=i+SHIFT_F5_KEY-49; goto fkn_key_ok; } } } sprintf(s,"ESC sequence):[27][91][%d][%d][%d]",c,i,k); goto skip; } // PAUSE = 80 if(c == 80) { c=PAUSE_KEY; goto fkn_key_ok; } if(c == 91) { c=force_getchar(); // F1=65 // F2=66 // F3=67 // F4=68 // F5=69 if(c >= 65 && c <= 69) { c+=F1_KEY-65; goto fkn_key_ok; } sprintf(s,"ESC sequence:[27][91][91][%d]",c); goto skip; } sprintf(s,"ESC sequence:[27][91][%d]",c); goto skip; } // ESC followed by something else than 91 (should never occur) sprintf(s,"ESC sequence:[27][%d]",c); skip:; lir_text(1,5,s); c=force_getchar(); if(c != -1) { i=0; while(s[i]!=0 && i<70)i++; sprintf(&s[i],"[%d]",c); goto skip; } if(c == -1) goto next; fkn_key_ok:; keyboard_buffer[keyboard_buffer_ptr]=c; } } keyboard_buffer_ptr=(keyboard_buffer_ptr+1)&(KEYBOARD_BUFFER_SIZE-1); lir_sleep(10000); lir_set_event(EVENT_KEYBOARD); next:; } } void thread_mouse(void) { int i, m, button, rx; pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,&i); while(TRUE) { // ********************************************** // Wait for svgalib to report a mouse event mouse_waitforupdate(); // We do nothing unless mouse_flag is set. if(mouse_flag != 0) { button= mouse_getbutton(); mouse_getposition_6d(&new_mouse_x, &new_mouse_y, NULL, &rx, NULL, NULL); if(rx!=0) { if (button & MOUSE_MIDDLEBUTTON) { m=bg.wheel_stepn; if(rx > 0) { m++; if(m>30)m=30; } else { 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); } else { if(rx > 0) { step_rx_frequency(1); } else { step_rx_frequency(-1); } } } if (button & MOUSE_LEFTBUTTON) { new_lbutton_state=1; } else { new_lbutton_state=0; } if (button & MOUSE_RIGHTBUTTON) { new_rbutton_state=1; } else { new_rbutton_state=0; } if( thread_status_flag[THREAD_SCREEN] == THRFLAG_SEM_WAIT || thread_status_flag[THREAD_SCREEN] == THRFLAG_ACTIVE || thread_status_flag[THREAD_SCREEN] == THRFLAG_IDLE) { if( new_mouse_x!=mouse_x || new_mouse_y!=mouse_y) { lir_set_event(EVENT_SCREEN); } check_mouse_actions(); } } } }