📄 xynth.c
字号:
/*************************************************************************** begin : Thu Jan 22 2004 copyright : (C) 2004 - 2005 by Alper Akcan email : distchx@yahoo.com ***************************************************************************//*************************************************************************** * * * This program 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. * * * ***************************************************************************/#include "cfg.h"#ifdef GRDRV_XYNTH#include "links.h"#include "bits.h"#include <ctype.h>#include <xynth.h>//#define DEBUGF printf#define DEBUGF#define MIN(a, b) ((a) < (b) ? (a) : (b))#define MAX(a, b) ((a) > (b) ? (a) : (b))extern struct graphics_driver xynth_driver;typedef struct lxynth_device_s { char *title; s_rect_t update; s_surface_t *surface;} lxynth_device_t;typedef struct lxynth_eventq_s { s_list_t *list; s_thread_mutex_t *mut;} lxynth_eventq_t;typedef struct lxynth_gd_s { s_list_t *list; s_thread_mutex_t *mut; struct graphics_device *active;} lxynth_gd_t;typedef struct lxynth_root_s { int timerid; int running; s_thread_t *tid; s_window_t *window; lxynth_eventq_t *eventq; lxynth_gd_t *gd;} lxynth_root_t;static lxynth_root_t *lxynth_root = NULL;static void lxynth_set_title (struct graphics_device *dev, unsigned char *title);static void lxynth_surface_register_update (void *dev){ lxynth_device_t *wd; if (lxynth_root->running == 0) return; s_thread_mutex_lock(lxynth_root->gd->mut); if (lxynth_root->gd->active != dev) { s_thread_mutex_unlock(lxynth_root->gd->mut); return; } wd = (lxynth_device_t *) ((struct graphics_device *) dev)->driver_data; s_putboxpart(lxynth_root->window->surface, wd->update.x, wd->update.y, wd->update.w, wd->update.h, wd->surface->width, wd->surface->height, wd->surface->vbuf, wd->update.x, wd->update.y); wd->update = (s_rect_t) {-1, -1, -1, -1}; s_thread_mutex_unlock(lxynth_root->gd->mut);}static void lxynth_surface_update (struct graphics_device *dev, int x, int y, int w, int h){ s_rect_t rect; lxynth_device_t *wd; wd = (lxynth_device_t *) dev->driver_data; rect = wd->update; if (rect.x >= 0) { wd->update.x = MIN(rect.x, x); } else { wd->update.x = x; } if (rect.y >= 0) { wd->update.y = MIN(rect.y, y); } else { wd->update.y = y; } if (rect.w >= 0) { wd->update.w = MAX(rect.x + rect.w, x + w) - wd->update.x; } else { wd->update.w = w; } if (rect.h >= 0) { wd->update.h = MAX(rect.y + rect.h, y + h) - wd->update.y; } else { wd->update.h = h; } register_bottom_half(lxynth_surface_register_update, dev);}static void lxynth_event_parse_mouse (s_event_t *event){ int x; int y; int flag = 0; x = event->mouse->x - lxynth_root->window->surface->buf.x; y = event->mouse->y - lxynth_root->window->surface->buf.y; if ((x < 0) || (x > lxynth_root->window->surface->buf.w) || (y < 0) || (y > lxynth_root->window->surface->buf.h)) { return; } switch (event->mouse->b) { case 1: flag = B_RIGHT; break; case 2: flag = B_MIDDLE; break; case 4: flag = B_LEFT; break; } if (event->type & MOUSE_PRESSED) { flag |= B_DOWN; if (event->mouse->b == MOUSE_WHEELXBUTTON_U) { flag = B_MOVE | B_WHEELUP; } else if (event->mouse->b == MOUSE_WHEELXBUTTON_D) { flag = B_MOVE | B_WHEELDOWN; } else if (event->mouse->b == MOUSE_WHEELYBUTTON_U) { flag = B_MOVE | B_WHEELLEFT; } else if (event->mouse->b == MOUSE_WHEELYBUTTON_D) { flag = B_MOVE | B_WHEELRIGHT; } } else if (event->type & (MOUSE_RELEASED | MOUSE_CLICKED)) { flag |= B_UP; } else { if (event->mouse->buttons) { flag |= B_DRAG; } else { flag |= B_MOVE; } } lxynth_root->gd->active->mouse_handler(lxynth_root->gd->active, x, y, flag);}static void lxynth_event_parse_keybd (s_event_t *event){ int k = 0; int flag = 0; if (!(event->type & KEYBD_PRESSED)) { return; } switch (event->keybd->keycode) { case S_KEYCODE_RETURN: k = KBD_ENTER; break; case S_KEYCODE_DELETE: k = KBD_BS; break; case S_KEYCODE_TAB: k = KBD_TAB; break; case S_KEYCODE_ESCAPE: k = KBD_ESC; break; case S_KEYCODE_UP: k = KBD_UP; break; case S_KEYCODE_DOWN: k = KBD_DOWN; break; case S_KEYCODE_LEFT: k = KBD_LEFT; break; case S_KEYCODE_RIGHT: k = KBD_RIGHT; break; case S_KEYCODE_INSERT: k = KBD_INS; break; case S_KEYCODE_REMOVE: k = KBD_DEL; break; case S_KEYCODE_HOME: k = KBD_HOME; break; case S_KEYCODE_END: k = KBD_END; break; case S_KEYCODE_PAGEUP: k = KBD_PAGE_UP;break; case S_KEYCODE_PAGEDOWN:k = KBD_PAGE_DOWN;break; case S_KEYCODE_F1: k = KBD_F1; break; case S_KEYCODE_F2: k = KBD_F2; break; case S_KEYCODE_F3: k = KBD_F3; break; case S_KEYCODE_F4: k = KBD_F4; break; case S_KEYCODE_F5: k = KBD_F5; break; case S_KEYCODE_F6: k = KBD_F6; break; case S_KEYCODE_F7: k = KBD_F7; break; case S_KEYCODE_F8: k = KBD_F8; break; case S_KEYCODE_F9: k = KBD_F9; break; case S_KEYCODE_F10: k = KBD_F10; break; case S_KEYCODE_F11: k = KBD_F11; break; case S_KEYCODE_F12: k = KBD_F12; break; default: k = event->keybd->ascii; if (!isprint(k)) { return; } break; } if (event->keybd->flag & (KEYCODE_CTRLF)) { flag |= KBD_CTRL; } if (event->keybd->flag & (KEYCODE_SHIFTF)) { } if (event->keybd->flag & (KEYCODE_ALTF | KEYCODE_ALTGRF)) { flag |= KBD_ALT; }#define KEYBD_HOOK0 \ int acc = 0;\ int pos = 0;\ struct graphics_device *gd;\ s_thread_mutex_lock(lxynth_root->gd->mut);\ while (!s_list_eol(lxynth_root->gd->list, pos)) {\ gd = (struct graphics_device *) s_list_get(lxynth_root->gd->list, pos);\ if (gd == lxynth_root->gd->active) {\#define KEYBD_HOOK1 \ }\ pos++;\ }\ s_thread_mutex_unlock(lxynth_root->gd->mut);\ if (acc) {\ char *title;\ struct rect r;\ r.x1 = 0;\ r.y1 = 0;\ r.x2 = lxynth_root->window->surface->buf.w;\ r.y2 = lxynth_root->window->surface->buf.h;\ title = strdup(((lxynth_device_t *) lxynth_root->gd->active->driver_data)->title);\ lxynth_set_title(lxynth_root->gd->active, title);\ lxynth_root->gd->active->resize_handler(lxynth_root->gd->active);\ lxynth_root->gd->active->redraw_handler(lxynth_root->gd->active, &r);\ s_free(title);\ } if ((flag == KBD_CTRL) && (event->keybd->ascii == 'w')) { KEYBD_HOOK0; if (lxynth_root->gd->list->nb_elt > 1) { s_list_remove(lxynth_root->gd->list, pos); lxynth_root->gd->active = (struct graphics_device *) s_list_get(lxynth_root->gd->list, 0); acc = 1; break; } KEYBD_HOOK1; if (acc) { gd->keyboard_handler(gd, KBD_CLOSE, 0); } } else if ((flag == KBD_CTRL) && (k == KBD_LEFT)) { KEYBD_HOOK0; if (pos >= 1) { lxynth_root->gd->active = (struct graphics_device *) s_list_get(lxynth_root->gd->list, pos - 1); acc = 1; break; } KEYBD_HOOK1; } else if ((flag == KBD_CTRL) && (k == KBD_RIGHT)) { KEYBD_HOOK0; if ((pos + 1) < lxynth_root->gd->list->nb_elt) { lxynth_root->gd->active = (struct graphics_device *) s_list_get(lxynth_root->gd->list, pos + 1); acc = 1; break; } KEYBD_HOOK1; } else { lxynth_root->gd->active->keyboard_handler(lxynth_root->gd->active, k, flag); }}static void lxynth_event_parse_expos (s_event_t *event){ if (event->expose->change & (EXPOSE_CHNGW | EXPOSE_CHNGH)) { int pos = 0; s_thread_mutex_lock(lxynth_root->gd->mut); while (!s_list_eol(lxynth_root->gd->list, pos)) { struct graphics_device *gd = (struct graphics_device *) s_list_get(lxynth_root->gd->list, pos); lxynth_device_t *wd = gd->driver_data; gd->size.x2 = lxynth_root->window->surface->buf.w; gd->size.y2 = lxynth_root->window->surface->buf.h; wd->surface->width = lxynth_root->window->surface->buf.w; wd->surface->height = lxynth_root->window->surface->buf.h; s_free(wd->surface->vbuf); wd->surface->vbuf = (char *) s_malloc(wd->surface->width * wd->surface->height * wd->surface->bytesperpixel); pos++; } s_thread_mutex_unlock(lxynth_root->gd->mut); lxynth_root->gd->active->resize_handler(lxynth_root->gd->active); }}static void lxynth_timer (void *arg){ int x = 0; int y = 0; int k = 0; int flag = 0; s_event_t *event; s_thread_mutex_lock(lxynth_root->eventq->mut); while (!s_list_eol(lxynth_root->eventq->list, 0)) { event = (s_event_t *) s_list_get(lxynth_root->eventq->list, 0); s_list_remove(lxynth_root->eventq->list, 0); switch (event->type & EVENT_MASK) { case QUIT_EVENT: break; case MOUSE_EVENT: lxynth_event_parse_mouse(event); break; case KEYBD_EVENT: lxynth_event_parse_keybd(event); break; case EXPOSE_EVENT: lxynth_event_parse_expos(event); break; } s_event_uninit(event); } s_thread_mutex_unlock(lxynth_root->eventq->mut); if (lxynth_root->running) { lxynth_root->timerid = install_timer(20, lxynth_timer, NULL); }}static void lxynth_atevent (s_window_t *window, s_event_t *event){ s_event_t *e; if (lxynth_root == NULL) { return; } switch (event->type & EVENT_MASK) { case QUIT_EVENT: case MOUSE_EVENT: case KEYBD_EVENT: case EXPOSE_EVENT: if (!s_event_init(&e)) { e->type = event->type; memcpy(e->mouse, event->mouse, sizeof(s_mouse_t)); memcpy(e->keybd, event->keybd, sizeof(s_keybd_t)); memcpy(e->expose, event->expose, sizeof(s_expose_t)); s_thread_mutex_lock(lxynth_root->eventq->mut); s_list_add(lxynth_root->eventq->list, e, -1); s_thread_mutex_unlock(lxynth_root->eventq->mut); } break; default: break; }}static void lxynth_atexit (s_window_t *window){ if (lxynth_root == NULL) { return; } if (lxynth_root->running) { struct graphics_device *gd = lxynth_root->gd->active; s_thread_mutex_lock(lxynth_root->gd->mut); lxynth_root->running = 0; lxynth_root->gd->active = NULL; s_thread_mutex_unlock(lxynth_root->gd->mut); gd->keyboard_handler(gd, KBD_CLOSE, 0); }}static unsigned char * lxynth_init_driver (unsigned char *param, unsigned char *display){ int bpp; int Bpp; DEBUGF ("%s (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__); lxynth_root = (lxynth_root_t *) s_malloc(sizeof(lxynth_root_t)); lxynth_root->eventq = (lxynth_eventq_t *) s_malloc(sizeof(lxynth_eventq_t)); lxynth_root->eventq->list = (s_list_t *) s_malloc(sizeof(s_list_t)); s_list_init(lxynth_root->eventq->list); s_thread_mutex_init(&(lxynth_root->eventq->mut)); lxynth_root->gd = (lxynth_gd_t *) s_malloc(sizeof(lxynth_gd_t)); lxynth_root->gd->list = (s_list_t *) s_malloc(sizeof(s_list_t)); s_list_init(lxynth_root->gd->list); s_thread_mutex_init(&(lxynth_root->gd->mut)); lxynth_root->gd->active = NULL; s_client_init(&(lxynth_root->window)); s_window_new(lxynth_root->window, WINDOW_MAIN, NULL); s_window_set_coor(lxynth_root->window, NO_FORM, 50, 50, 600, 500); bpp = lxynth_root->window->surface->bitsperpixel; Bpp = lxynth_root->window->surface->bytesperpixel; if (bpp == 32) { bpp = 24; } xynth_driver.depth = (bpp << 3) | Bpp; s_window_show(lxynth_root->window); lxynth_root->tid = s_thread_create(s_client_main, lxynth_root->window); s_client_atevent(lxynth_root->window, lxynth_atevent); s_client_atexit(lxynth_root->window, lxynth_atexit); lxynth_root->running = 1; install_timer(20, lxynth_timer, NULL); return NULL;}static struct graphics_device * lxynth_init_device (void){ char *vbuf; lxynth_device_t *wd; struct graphics_device *gd; DEBUGF ("%s (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__); wd = (lxynth_device_t *) s_malloc(sizeof(lxynth_device_t)); wd->update = (s_rect_t) {-1, -1, -1, -1}; gd = (struct graphics_device *) s_malloc(sizeof(struct graphics_device)); wd->title = NULL; wd->surface = (s_surface_t *) s_malloc(sizeof(s_surface_t)); vbuf = (char *) s_malloc(lxynth_root->window->surface->buf.w * lxynth_root->window->surface->buf.h * lxynth_root->window->surface->bytesperpixel); s_getsurfacevirtual(wd->surface, lxynth_root->window->surface->buf.w , lxynth_root->window->surface->buf.h, lxynth_root->window->surface->bitsperpixel, vbuf); gd->size.x1 = 0; gd->size.x2 = wd->surface->width; gd->size.y1 = 0; gd->size.y2 = wd->surface->height; gd->clip.x1 = 0; gd->clip.x2 = gd->size.x2; gd->clip.y1 = 0; gd->clip.y2 = gd->size.y2; gd->drv = &xynth_driver; gd->driver_data = wd; gd->user_data = NULL; s_thread_mutex_lock(lxynth_root->gd->mut); s_list_add(lxynth_root->gd->list, gd, -1); lxynth_root->gd->active = gd; s_thread_mutex_unlock(lxynth_root->gd->mut); return gd;}static void lxynth_shutdown_device (struct graphics_device *dev){ int acc = 0; int pos = 0; lxynth_device_t *wd; struct graphics_device *gd; DEBUGF ("%s (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__); s_thread_mutex_lock(lxynth_root->gd->mut); while (!s_list_eol(lxynth_root->gd->list, pos)) { gd = (struct graphics_device *) s_list_get(lxynth_root->gd->list, pos);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -