Mercurial > sdl-ios-xcode
view src/video/x11/SDL_x11image.c @ 1584:b786d9c15e42
Fixed bug #61
Date: Mon, 24 Feb 2003 13:35:11 +0800
From: "Leonidas"
Subject: [SDL] Re: Trigger mouse wheel event -- not in X-environment
I have looked into the codes for the IMPS/2 mouse wheel mode of fbcon driver.
But I found something weird.
Here's the original codes to set a mouse device into IMPS/2 mode in libSDL.
In the file src/video/fbcon/SDL_fbevents.c
In function static int set_imps2_mode(int fd)
...
Uint8 set_imps2[] = {0xf3, 200, 0xf3, 100, 0xf3, 80};
Uint8 reset = 0xff;
fd_set fdset;
struct timeval tv;
int retval = 0;
// Set mouse device fd into IMPS/2 mode
if ( write(fd, &set_imps2, sizeof(set_imps2)) == sizeof(set_imps2) ) {
// ??? then RESET it..???
if (write(fd, &reset, sizeof (reset)) == sizeof (reset) ) {
retval = 1;
}
}
...........
Since it sets IMPS/2 mode then reset it, so you will never get a mouse into
IMPS/2 mode to use its wheel.
What I did to make the wheel usable is remove the RESET codes.
....
if ( write(fd, &set_imps2, sizeof(set_imps2)) == sizeof(set_imps2) ) {
/*
if (write(fd, &reset, sizeof (reset)) == sizeof (reset) ) {
}
*/
retval = 1;
}
....
And in FB_OpenMouse(_THIS)
Make the device /dev/psaux to be setted into imps2 mode such that it can be
detected its a imps/2 mouse or not.
(my mouse device is on ps2, but the codes only set /dev/input/mice device
originally)
Then I have done, I can use the mouse wheel when SDL uses frame buff driver.
I dont exactly know I did right or wrong, I just change it for my usuage.
Correct me please, if I did something wrong.
Best regards,
Li Tsung Lin
IAP Product Dept. Engineer
EeRise Corp. (Image Processing System, Computer Vision System)
Hsin Tien, Taipei Hsien, Taiwan, R.O.C.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Wed, 22 Mar 2006 07:22:40 +0000 |
parents | 3ba88cb7eb1b |
children | e49147870aac c121d94672cb a1b03ba2fcd0 |
line wrap: on
line source
/* SDL - Simple DirectMedia Layer Copyright (C) 1997-2006 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Sam Lantinga slouken@libsdl.org */ #include "SDL_config.h" #include <stdio.h> #include <unistd.h> #include "SDL_endian.h" #include "../../events/SDL_events_c.h" #include "SDL_x11image_c.h" #ifndef NO_SHARED_MEMORY /* Shared memory error handler routine */ static int shm_error; static int (*X_handler)(Display *, XErrorEvent *) = NULL; static int shm_errhandler(Display *d, XErrorEvent *e) { if ( e->error_code == BadAccess ) { shm_error = True; return(0); } else return(X_handler(d,e)); } static void try_mitshm(_THIS, SDL_Surface *screen) { /* Dynamic X11 may not have SHM entry points on this box. */ if ((use_mitshm) && (!SDL_X11_HAVE_SHM)) use_mitshm = 0; if(!use_mitshm) return; shminfo.shmid = shmget(IPC_PRIVATE, screen->h*screen->pitch, IPC_CREAT | 0777); if ( shminfo.shmid >= 0 ) { shminfo.shmaddr = (char *)shmat(shminfo.shmid, 0, 0); shminfo.readOnly = False; if ( shminfo.shmaddr != (char *)-1 ) { shm_error = False; X_handler = XSetErrorHandler(shm_errhandler); XShmAttach(SDL_Display, &shminfo); XSync(SDL_Display, True); XSetErrorHandler(X_handler); if ( shm_error ) shmdt(shminfo.shmaddr); } else { shm_error = True; } shmctl(shminfo.shmid, IPC_RMID, NULL); } else { shm_error = True; } if ( shm_error ) use_mitshm = 0; if ( use_mitshm ) screen->pixels = shminfo.shmaddr; } #endif /* ! NO_SHARED_MEMORY */ /* Various screen update functions available */ static void X11_NormalUpdate(_THIS, int numrects, SDL_Rect *rects); static void X11_MITSHMUpdate(_THIS, int numrects, SDL_Rect *rects); int X11_SetupImage(_THIS, SDL_Surface *screen) { #ifndef NO_SHARED_MEMORY try_mitshm(this, screen); if(use_mitshm) { SDL_Ximage = XShmCreateImage(SDL_Display, SDL_Visual, this->hidden->depth, ZPixmap, shminfo.shmaddr, &shminfo, screen->w, screen->h); if(!SDL_Ximage) { XShmDetach(SDL_Display, &shminfo); XSync(SDL_Display, False); shmdt(shminfo.shmaddr); screen->pixels = NULL; goto error; } this->UpdateRects = X11_MITSHMUpdate; } if(!use_mitshm) #endif /* not NO_SHARED_MEMORY */ { int bpp; screen->pixels = SDL_malloc(screen->h*screen->pitch); if ( screen->pixels == NULL ) { SDL_OutOfMemory(); return -1; } bpp = screen->format->BytesPerPixel; SDL_Ximage = XCreateImage(SDL_Display, SDL_Visual, this->hidden->depth, ZPixmap, 0, (char *)screen->pixels, screen->w, screen->h, 32, 0); if ( SDL_Ximage == NULL ) goto error; /* XPutImage will convert byte sex automatically */ SDL_Ximage->byte_order = (SDL_BYTEORDER == SDL_BIG_ENDIAN) ? MSBFirst : LSBFirst; this->UpdateRects = X11_NormalUpdate; } screen->pitch = SDL_Ximage->bytes_per_line; return(0); error: SDL_SetError("Couldn't create XImage"); return 1; } void X11_DestroyImage(_THIS, SDL_Surface *screen) { if ( SDL_Ximage ) { XDestroyImage(SDL_Ximage); #ifndef NO_SHARED_MEMORY if ( use_mitshm ) { XShmDetach(SDL_Display, &shminfo); XSync(SDL_Display, False); shmdt(shminfo.shmaddr); } #endif /* ! NO_SHARED_MEMORY */ SDL_Ximage = NULL; } if ( screen ) { screen->pixels = NULL; } } /* Determine the number of CPUs in the system */ static int num_CPU(void) { static int num_cpus = 0; if(!num_cpus) { #if defined(__LINUX__) char line[BUFSIZ]; FILE *pstat = fopen("/proc/stat", "r"); if ( pstat ) { while ( fgets(line, sizeof(line), pstat) ) { if (SDL_memcmp(line, "cpu", 3) == 0 && line[3] != ' ') { ++num_cpus; } } fclose(pstat); } #elif defined(__IRIX__) num_cpus = sysconf(_SC_NPROC_ONLN); #elif defined(_SC_NPROCESSORS_ONLN) /* number of processors online (SVR4.0MP compliant machines) */ num_cpus = sysconf(_SC_NPROCESSORS_ONLN); #elif defined(_SC_NPROCESSORS_CONF) /* number of processors configured (SVR4.0MP compliant machines) */ num_cpus = sysconf(_SC_NPROCESSORS_CONF); #endif if ( num_cpus <= 0 ) { num_cpus = 1; } } return num_cpus; } int X11_ResizeImage(_THIS, SDL_Surface *screen, Uint32 flags) { int retval; X11_DestroyImage(this, screen); if ( flags & SDL_OPENGL ) { /* No image when using GL */ retval = 0; } else { retval = X11_SetupImage(this, screen); /* We support asynchronous blitting on the display */ if ( flags & SDL_ASYNCBLIT ) { /* This is actually slower on single-CPU systems, probably because of CPU contention between the X server and the application. Note: Is this still true with XFree86 4.0? */ if ( num_CPU() > 1 ) { screen->flags |= SDL_ASYNCBLIT; } } } return(retval); } /* We don't actually allow hardware surfaces other than the main one */ int X11_AllocHWSurface(_THIS, SDL_Surface *surface) { return(-1); } void X11_FreeHWSurface(_THIS, SDL_Surface *surface) { return; } int X11_LockHWSurface(_THIS, SDL_Surface *surface) { if ( (surface == SDL_VideoSurface) && blit_queued ) { XSync(GFX_Display, False); blit_queued = 0; } return(0); } void X11_UnlockHWSurface(_THIS, SDL_Surface *surface) { return; } int X11_FlipHWSurface(_THIS, SDL_Surface *surface) { return(0); } static void X11_NormalUpdate(_THIS, int numrects, SDL_Rect *rects) { int i; for (i = 0; i < numrects; ++i) { if ( rects[i].w == 0 || rects[i].h == 0 ) { /* Clipped? */ continue; } XPutImage(GFX_Display, SDL_Window, SDL_GC, SDL_Ximage, rects[i].x, rects[i].y, rects[i].x, rects[i].y, rects[i].w, rects[i].h); } if ( SDL_VideoSurface->flags & SDL_ASYNCBLIT ) { XFlush(GFX_Display); blit_queued = 1; } else { XSync(GFX_Display, False); } } static void X11_MITSHMUpdate(_THIS, int numrects, SDL_Rect *rects) { #ifndef NO_SHARED_MEMORY int i; for ( i=0; i<numrects; ++i ) { if ( rects[i].w == 0 || rects[i].h == 0 ) { /* Clipped? */ continue; } XShmPutImage(GFX_Display, SDL_Window, SDL_GC, SDL_Ximage, rects[i].x, rects[i].y, rects[i].x, rects[i].y, rects[i].w, rects[i].h, False); } if ( SDL_VideoSurface->flags & SDL_ASYNCBLIT ) { XFlush(GFX_Display); blit_queued = 1; } else { XSync(GFX_Display, False); } #endif /* ! NO_SHARED_MEMORY */ } /* There's a problem with the automatic refreshing of the display. Even though the XVideo code uses the GFX_Display to update the video memory, it appears that updating the window asynchronously from a different thread will cause "blackouts" of the window. This is a sort of a hacked workaround for the problem. */ static int enable_autorefresh = 1; void X11_DisableAutoRefresh(_THIS) { --enable_autorefresh; } void X11_EnableAutoRefresh(_THIS) { ++enable_autorefresh; } void X11_RefreshDisplay(_THIS) { /* Don't refresh a display that doesn't have an image (like GL) Instead, post an expose event so the application can refresh. */ if ( ! SDL_Ximage || (enable_autorefresh <= 0) ) { SDL_PrivateExpose(); return; } #ifndef NO_SHARED_MEMORY if ( this->UpdateRects == X11_MITSHMUpdate ) { XShmPutImage(SDL_Display, SDL_Window, SDL_GC, SDL_Ximage, 0, 0, 0, 0, this->screen->w, this->screen->h, False); } else #endif /* ! NO_SHARED_MEMORY */ { XPutImage(SDL_Display, SDL_Window, SDL_GC, SDL_Ximage, 0, 0, 0, 0, this->screen->w, this->screen->h); } XSync(SDL_Display, False); }