123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516 |
- #include <rtthread.h>
- #include <stdio.h>
- #ifdef _WIN32
- #include <sdl.h>
- #else
- #include <SDL/SDL.h>
- #endif
- #include <rtdevice.h>
- #include <rtgui/driver.h>
- #define SDL_SCREEN_WIDTH 480
- #define SDL_SCREEN_HEIGHT 320
- extern void rt_hw_exit(void);
- #define SDL_SCREEN_FORMAT SDL_PIXELFORMAT_RGB565
- struct sdlfb_device
- {
- struct rt_device parent;
- SDL_Renderer *renderer; /* window renderer */
- SDL_Surface *surface; /* screen surface */
- 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;
- }
- int sdlfb_info(int *format, int *bpp)
- {
- int bit_pp; /* texture bits per pixel */
- Uint32 Rmask, Gmask, Bmask, Amask; /* masks for pixel format passed into OpenGL */
- /* Grab info about format that will be passed into OpenGL */
- SDL_PixelFormatEnumToMasks(SDL_SCREEN_FORMAT, &bit_pp, &Rmask, &Gmask,
- &Bmask, &Amask);
- *bpp = bit_pp;
- switch (SDL_SCREEN_FORMAT)
- {
- case SDL_PIXELFORMAT_RGB565:
- *format = RTGRAPHIC_PIXEL_FORMAT_RGB565;
- break;
- case SDL_PIXELFORMAT_RGB888:
- *format = RTGRAPHIC_PIXEL_FORMAT_RGB888;
- break;
- case SDL_PIXELFORMAT_ARGB8888:
- *format = RTGRAPHIC_PIXEL_FORMAT_ARGB888;
- break;
- case SDL_PIXELFORMAT_ABGR8888:
- *format = RTGRAPHIC_PIXEL_FORMAT_ABGR888;
- }
- return 0;
- }
- static rt_mutex_t sdllock;
- static rt_err_t sdlfb_control(rt_device_t dev, int cmd, void *args)
- {
- struct sdlfb_device *device;
- rt_mutex_take(sdllock, RT_WAITING_FOREVER);
- device = (struct sdlfb_device *)dev;
- RT_ASSERT(device != RT_NULL);
- switch (cmd)
- {
- case RTGRAPHIC_CTRL_GET_INFO:
- {
- int format, bpp;
- struct rt_device_graphic_info *info;
- sdlfb_info(&format, &bpp);
- info = (struct rt_device_graphic_info *) args;
- info->bits_per_pixel = bpp;
- info->pixel_format = format;
- info->framebuffer = (rt_uint8_t*)device->surface->pixels;
- info->width = device->width;
- info->height = device->height;
- }
- break;
- case RTGRAPHIC_CTRL_RECT_UPDATE:
- {
- SDL_Texture * texture;
- struct rt_device_rect_info *rect;
- SDL_Rect _rect = { 0, 0, SDL_SCREEN_WIDTH, SDL_SCREEN_HEIGHT };
- rect = (struct rt_device_rect_info *)args;
- SDL_RenderClear(_device.renderer);
- texture = SDL_CreateTextureFromSurface(_device.renderer, _device.surface);
- SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
- SDL_RenderCopy(_device.renderer, texture, NULL, &_rect);
- SDL_RenderPresent(_device.renderer);
- SDL_DestroyTexture(texture);
- }
- break;
- case RTGRAPHIC_CTRL_SET_MODE:
- {
- break;
- }
- break;
- }
- rt_mutex_release(sdllock);
- return RT_EOK;
- }
- Uint16 pixels[16 * 16] = { // ...or with raw pixel data:
- 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff,
- 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff,
- 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff,
- 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff,
- 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff,
- 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff,
- 0x0fff, 0x0aab, 0x0789, 0x0bcc, 0x0eee, 0x09aa, 0x099a, 0x0ddd,
- 0x0fff, 0x0eee, 0x0899, 0x0fff, 0x0fff, 0x1fff, 0x0dde, 0x0dee,
- 0x0fff, 0xabbc, 0xf779, 0x8cdd, 0x3fff, 0x9bbc, 0xaaab, 0x6fff,
- 0x0fff, 0x3fff, 0xbaab, 0x0fff, 0x0fff, 0x6689, 0x6fff, 0x0dee,
- 0xe678, 0xf134, 0x8abb, 0xf235, 0xf678, 0xf013, 0xf568, 0xf001,
- 0xd889, 0x7abc, 0xf001, 0x0fff, 0x0fff, 0x0bcc, 0x9124, 0x5fff,
- 0xf124, 0xf356, 0x3eee, 0x0fff, 0x7bbc, 0xf124, 0x0789, 0x2fff,
- 0xf002, 0xd789, 0xf024, 0x0fff, 0x0fff, 0x0002, 0x0134, 0xd79a,
- 0x1fff, 0xf023, 0xf000, 0xf124, 0xc99a, 0xf024, 0x0567, 0x0fff,
- 0xf002, 0xe678, 0xf013, 0x0fff, 0x0ddd, 0x0fff, 0x0fff, 0xb689,
- 0x8abb, 0x0fff, 0x0fff, 0xf001, 0xf235, 0xf013, 0x0fff, 0xd789,
- 0xf002, 0x9899, 0xf001, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0xe789,
- 0xf023, 0xf000, 0xf001, 0xe456, 0x8bcc, 0xf013, 0xf002, 0xf012,
- 0x1767, 0x5aaa, 0xf013, 0xf001, 0xf000, 0x0fff, 0x7fff, 0xf124,
- 0x0fff, 0x089a, 0x0578, 0x0fff, 0x089a, 0x0013, 0x0245, 0x0eff,
- 0x0223, 0x0dde, 0x0135, 0x0789, 0x0ddd, 0xbbbc, 0xf346, 0x0467,
- 0x0fff, 0x4eee, 0x3ddd, 0x0edd, 0x0dee, 0x0fff, 0x0fff, 0x0dee,
- 0x0def, 0x08ab, 0x0fff, 0x7fff, 0xfabc, 0xf356, 0x0457, 0x0467,
- 0x0fff, 0x0bcd, 0x4bde, 0x9bcc, 0x8dee, 0x8eff, 0x8fff, 0x9fff,
- 0xadee, 0xeccd, 0xf689, 0xc357, 0x2356, 0x0356, 0x0467, 0x0467,
- 0x0fff, 0x0ccd, 0x0bdd, 0x0cdd, 0x0aaa, 0x2234, 0x4135, 0x4346,
- 0x5356, 0x2246, 0x0346, 0x0356, 0x0467, 0x0356, 0x0467, 0x0467,
- 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff,
- 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff,
- 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff,
- 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff
- };
- static void sdlfb_hw_init(void)
- {
- SDL_Window *win;
- if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 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;
- {
- int bpp; /* texture bits per pixel */
- Uint32 Rmask, Gmask, Bmask, Amask; /* masks for pixel format passed into OpenGL */
- /* Grab info about format that will be passed into OpenGL */
- SDL_PixelFormatEnumToMasks(SDL_SCREEN_FORMAT, &bpp, &Rmask, &Gmask,
- &Bmask, &Amask);
- _device.surface = SDL_CreateRGBSurface(0, SDL_SCREEN_WIDTH, SDL_SCREEN_HEIGHT,
- bpp, Rmask, Gmask, Bmask, Amask);
- }
- win = SDL_CreateWindow("RT-Thread/Persimmon",
- SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
- SDL_SCREEN_WIDTH, SDL_SCREEN_HEIGHT, SDL_WINDOW_OPENGL);
- if (win == NULL)
- {
- fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError());
- exit(1);
- }
- /* set the icon of Window */
- {
- SDL_Surface *surface;
- surface = SDL_CreateRGBSurfaceFrom(pixels, 16, 16, 16, 16 * 2, 0x0f00, 0x00f0, 0x000f, 0xf000);
- SDL_SetWindowIcon(win, surface);
- }
- _device.renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED);
- 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 state = 0;
- rt_device_t device;
- int timeout = 1000000;
- int last_x = -1, last_y = -1;
- int motion_x, motion_y;
- int motion_button = 0;
- int motion_tick = 50;
- int mouse_id = 1;
-
- #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)
- {
- if (motion_button & RTGUI_MOUSE_BUTTON_DOWN)
- {
- timeout = motion_tick - SDL_GetTicks();
- }
- else
- {
- timeout = 1000 * 1000;
- }
- int tick = SDL_GetTicks();
- SDL_WaitEventTimeout(&event, timeout);
- if (SDL_GetTicks() >= motion_tick && (motion_button & RTGUI_MOUSE_BUTTON_DOWN)) /* whether timeout */
- {
- /* sendout motion event */
- struct rtgui_event_mouse emouse;
- emouse.parent.type = RTGUI_EVENT_MOUSE_MOTION;
- emouse.parent.sender = RT_NULL;
- emouse.wid = RT_NULL;
- emouse.id = mouse_id;
- emouse.ts = rt_tick_get();
- if ((motion_x > 0 && motion_x < SDL_SCREEN_WIDTH) &&
- (motion_y > 0 && motion_y < SDL_SCREEN_HEIGHT))
- {
- emouse.x = motion_x;
- emouse.y = motion_y;
- /* init mouse button */
- emouse.button = motion_button;
- /* send event to server */
- rtgui_server_post_event(&emouse.parent, sizeof(struct rtgui_event_mouse));
- }
- /* reset motion tick */
- motion_tick = 50 + SDL_GetTicks();
- }
- switch (event.type)
- {
- case SDL_MOUSEMOTION:
- {
- /* save to (x,y) in the motion */
- motion_x = ((SDL_MouseMotionEvent *)&event)->x;
- motion_y = ((SDL_MouseMotionEvent *)&event)->y;
- }
- break;
- case SDL_MOUSEBUTTONDOWN:
- case SDL_MOUSEBUTTONUP:
- {
- int x, y;
- struct rtgui_event_mouse emouse;
- SDL_MouseButtonEvent *mb;
- emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON;
- emouse.parent.sender = RT_NULL;
- emouse.wid = RT_NULL;
- if (event.type == SDL_MOUSEBUTTONDOWN && state == 0)
- mouse_id = rt_tick_get();
- emouse.id = mouse_id;
- emouse.ts = rt_tick_get();
- mb = (SDL_MouseButtonEvent *)&event;
- x = mb->x;
- y = mb->y;
- if ((x > 0 && x < SDL_SCREEN_WIDTH) &&
- (y > 0 && y < SDL_SCREEN_HEIGHT))
- {
- emouse.x = x;
- emouse.y = 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;
- motion_button = emouse.button;
- /* set motion timeout tick */
- motion_tick = 50 + SDL_GetTicks();
- if (state == 0)
- {
- /* send event to server */
- rtgui_server_post_event(&emouse.parent, sizeof(struct rtgui_event_mouse));
- last_x = -1; last_y = -1;
- state = 1;
- }
- }
- else
- {
- emouse.button |= RTGUI_MOUSE_BUTTON_UP;
- motion_button = 0;
- if (state == 1)
- {
- /* send event to server */
- rtgui_server_post_event(&emouse.parent, sizeof(struct rtgui_event_mouse));
- last_x = -1; last_y = -1;
- state = 0;
- }
- }
- }
- }
- 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
- }
|