123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372 |
- #include <rtthread.h>
- #ifdef _WIN32
- #include <sdl.h>
- #else
- #include <SDL/SDL.h>
- #endif
- #include <rtdevice.h>
- #include <rtgui/driver.h>
- #define SDL_SCREEN_WIDTH 800
- #define SDL_SCREEN_HEIGHT 480
- extern void rt_hw_exit(void);
- struct sdlfb_device
- {
- struct rt_device parent;
- SDL_Surface *screen;
- rt_uint16_t width;
- rt_uint16_t height;
- };
- struct sdlfb_device _device;
- /* common device interface */
- static rt_err_t sdlfb_init(rt_device_t dev)
- {
- return RT_EOK;
- }
- static rt_err_t sdlfb_open(rt_device_t dev, rt_uint16_t oflag)
- {
- return RT_EOK;
- }
- static rt_err_t sdlfb_close(rt_device_t dev)
- {
- SDL_Quit();
- return RT_EOK;
- }
- static rt_mutex_t sdllock;
- static rt_err_t sdlfb_control(rt_device_t dev, rt_uint8_t cmd, void *args)
- {
- struct sdlfb_device *device;
- rt_mutex_take(sdllock, RT_WAITING_FOREVER);
- device = (struct sdlfb_device *)dev;
- RT_ASSERT(device != RT_NULL);
- RT_ASSERT(device->screen != RT_NULL);
- switch (cmd)
- {
- case RTGRAPHIC_CTRL_GET_INFO:
- {
- struct rt_device_graphic_info *info;
- info = (struct rt_device_graphic_info *) args;
- info->bits_per_pixel = 16;
- info->pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB565;
- info->framebuffer = device->screen->pixels;
- info->width = device->screen->w;
- info->height = device->screen->h;
- }
- break;
- case RTGRAPHIC_CTRL_RECT_UPDATE:
- {
- struct rt_device_rect_info *rect;
- rect = (struct rt_device_rect_info *)args;
- /* SDL_UpdateRect(_device.screen, rect->x, rect->y, rect->x + rect->w, rect->y + rect->h); */
- SDL_UpdateRect(_device.screen, 0, 0, device->width, device->height);
- }
- break;
- case RTGRAPHIC_CTRL_SET_MODE:
- {
- #if 0
- struct rt_device_rect_info *rect;
- rect = (struct rt_device_rect_info *)args;
- if ((_device.width == rect->width) && (_device.height == rect->height)) return -RT_ERROR;
- _device.width = rect->width;
- _device.height = rect->height;
- if (_device.screen != RT_NULL)
- {
- SDL_FreeSurface(_device.screen);
- /* re-create screen surface */
- _device.screen = SDL_SetVideoMode(_device.width, _device.height, 16, SDL_SWSURFACE | SDL_DOUBLEBUF);
- if (_device.screen == NULL)
- {
- fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError());
- exit(1);
- }
- SDL_WM_SetCaption("RT-Thread/GUI Simulator", NULL);
- }
- #endif
- }
- break;
- }
- rt_mutex_release(sdllock);
- return RT_EOK;
- }
- static void sdlfb_hw_init(void)
- {
- /* set video driver for VC++ debug */
- //_putenv("SDL_VIDEODRIVER=windib");
- //if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_AUDIO) < 0)
- if (SDL_Init(SDL_INIT_VIDEO) < 0)
- {
- fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
- exit(1);
- }
- _device.parent.init = sdlfb_init;
- _device.parent.open = sdlfb_open;
- _device.parent.close = sdlfb_close;
- _device.parent.read = RT_NULL;
- _device.parent.write = RT_NULL;
- _device.parent.control = sdlfb_control;
- _device.width = SDL_SCREEN_WIDTH;
- _device.height = SDL_SCREEN_HEIGHT;
- _device.screen = SDL_SetVideoMode(_device.width, _device.height, 16, SDL_SWSURFACE | SDL_DOUBLEBUF);
- if (_device.screen == NULL)
- {
- fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError());
- exit(1);
- }
- SDL_WM_SetCaption("RT-Thread/GUI Simulator", NULL);
- rt_device_register(RT_DEVICE(&_device), "sdl", RT_DEVICE_FLAG_RDWR);
- sdllock = rt_mutex_create("fb", RT_IPC_FLAG_FIFO);
- }
- #ifdef _WIN32
- #include <windows.h>
- #include <mmsystem.h>
- #else
- #include <pthread.h>
- #include <signal.h>
- #endif
- #include <stdio.h>
- #include <rtgui/event.h>
- #include <rtgui/kbddef.h>
- #include <rtgui/rtgui_server.h>
- #include <rtgui/rtgui_system.h>
- #ifdef _WIN32
- static HANDLE sdl_ok_event = NULL;
- static DWORD WINAPI sdl_loop(LPVOID lpParam)
- #else
- static pthread_mutex_t sdl_ok_mutex;
- static pthread_cond_t sdl_ok_event;
- static void *sdl_loop(void *lpParam)
- #endif
- {
- int quit = 0;
- SDL_Event event;
- int button_state = 0;
- rt_device_t device;
- #ifndef _WIN32
- sigset_t sigmask, oldmask;
- /* set the getchar without buffer */
- sigfillset(&sigmask);
- pthread_sigmask(SIG_BLOCK, &sigmask, &oldmask);
- pthread_mutex_lock(&sdl_ok_mutex);
- #endif
- sdlfb_hw_init();
- device = rt_device_find("sdl");
- RT_ASSERT(device);
- rtgui_graphic_set_device(device);
- #ifdef _WIN32
- SetEvent(sdl_ok_event);
- #else
- pthread_cond_signal(&sdl_ok_event);
- pthread_mutex_unlock(&sdl_ok_mutex);
- #endif
- /* handle SDL event */
- while (!quit)
- {
- SDL_WaitEvent(&event);
- switch (event.type)
- {
- case SDL_MOUSEMOTION:
- {
- struct rtgui_event_mouse emouse;
- emouse.parent.type = RTGUI_EVENT_MOUSE_MOTION;
- emouse.parent.sender = RT_NULL;
- emouse.wid = RT_NULL;
- emouse.x = ((SDL_MouseMotionEvent *)&event)->x;
- emouse.y = ((SDL_MouseMotionEvent *)&event)->y;
- /* init mouse button */
- emouse.button = button_state;
- /* send event to server */
- rtgui_server_post_event(&emouse.parent, sizeof(struct rtgui_event_mouse));
- }
- break;
- case SDL_MOUSEBUTTONDOWN:
- case SDL_MOUSEBUTTONUP:
- {
- struct rtgui_event_mouse emouse;
- SDL_MouseButtonEvent *mb;
- emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON;
- emouse.parent.sender = RT_NULL;
- emouse.wid = RT_NULL;
- mb = (SDL_MouseButtonEvent *)&event;
- emouse.x = mb->x;
- emouse.y = mb->y;
- /* init mouse button */
- emouse.button = 0;
- /* set emouse button */
- if (mb->button & (1 << (SDL_BUTTON_LEFT - 1)))
- {
- emouse.button |= RTGUI_MOUSE_BUTTON_LEFT;
- }
- else if (mb->button & (1 << (SDL_BUTTON_RIGHT - 1)))
- {
- emouse.button |= RTGUI_MOUSE_BUTTON_RIGHT;
- }
- else if (mb->button & (1 << (SDL_BUTTON_MIDDLE - 1)))
- {
- emouse.button |= RTGUI_MOUSE_BUTTON_MIDDLE;
- }
- if (mb->type == SDL_MOUSEBUTTONDOWN)
- {
- emouse.button |= RTGUI_MOUSE_BUTTON_DOWN;
- button_state = emouse.button;
- }
- else
- {
- emouse.button |= RTGUI_MOUSE_BUTTON_UP;
- button_state = 0;
- }
- /* send event to server */
- rtgui_server_post_event(&emouse.parent, sizeof(struct rtgui_event_mouse));
- }
- break;
- case SDL_KEYUP:
- {
- struct rtgui_event_kbd ekbd;
- ekbd.parent.type = RTGUI_EVENT_KBD;
- ekbd.parent.sender = RT_NULL;
- ekbd.type = RTGUI_KEYUP;
- ekbd.wid = RT_NULL;
- ekbd.mod = event.key.keysym.mod;
- ekbd.key = event.key.keysym.sym;
- /* FIXME: unicode */
- ekbd.unicode = 0;
- /* send event to server */
- rtgui_server_post_event(&ekbd.parent, sizeof(struct rtgui_event_kbd));
- }
- break;
- case SDL_KEYDOWN:
- {
- struct rtgui_event_kbd ekbd;
- ekbd.parent.type = RTGUI_EVENT_KBD;
- ekbd.parent.sender = RT_NULL;
- ekbd.type = RTGUI_KEYDOWN;
- ekbd.wid = RT_NULL;
- ekbd.mod = event.key.keysym.mod;
- ekbd.key = event.key.keysym.sym;
- /* FIXME: unicode */
- ekbd.unicode = 0;
- /* send event to server */
- rtgui_server_post_event(&ekbd.parent, sizeof(struct rtgui_event_kbd));
- }
- break;
- case SDL_QUIT:
- SDL_Quit();
- quit = 1;
- break;
- default:
- break;
- }
- if (quit)
- {
- exit(1);
- break;
- }
-
- }
- rt_hw_exit();
- return 0;
- }
- /* start sdl thread */
- void rt_hw_sdl_start(void)
- {
- #ifdef _WIN32
- HANDLE thread;
- DWORD thread_id;
- sdl_ok_event = CreateEvent(NULL,
- FALSE,
- FALSE,
- NULL);
- if (sdl_ok_event == NULL)
- {
- printf("error, create SDL event failed\n");
- exit(-1);
- }
- /* create thread that loop sdl event */
- thread = CreateThread(NULL,
- 0,
- (LPTHREAD_START_ROUTINE)sdl_loop,
- 0,
- CREATE_SUSPENDED,
- &thread_id);
- if (thread == NULL)
- {
- //Display Error Message
- return;
- }
- ResumeThread(thread);
- /* wait until SDL LCD device is registered and seted */
- WaitForSingleObject(sdl_ok_event, INFINITE);
- #else
- /* Linux */
- pthread_t pid;
- int res;
- pthread_mutex_init(&sdl_ok_mutex, NULL);
- pthread_cond_init(&sdl_ok_event, NULL);
- res = pthread_create(&pid, NULL, &sdl_loop, NULL);
- if (res)
- {
- printf("pthread create sdl thread faild, <%d>\n", res);
- exit(EXIT_FAILURE);
- }
- pthread_mutex_lock(&sdl_ok_mutex);
- pthread_cond_wait(&sdl_ok_event, &sdl_ok_mutex);
- pthread_mutex_destroy(&sdl_ok_mutex);
- pthread_cond_destroy(&sdl_ok_event);
- #endif
- }
|