diff options
author | Anas Nashif <anas.nashif@intel.com> | 2012-12-07 02:53:31 -0800 |
---|---|---|
committer | Anas Nashif <anas.nashif@intel.com> | 2012-12-07 02:53:31 -0800 |
commit | cbb6286cb92020dd7ae88798ed831ed76fd2130e (patch) | |
tree | 782a01c00d5e064aa67ea3f9241a8ef1de1060c6 /atheos.cpp | |
download | links-cbb6286cb92020dd7ae88798ed831ed76fd2130e.tar.gz links-cbb6286cb92020dd7ae88798ed831ed76fd2130e.tar.bz2 links-cbb6286cb92020dd7ae88798ed831ed76fd2130e.zip |
Imported Upstream version 2.6upstream/2.6upstream
Diffstat (limited to 'atheos.cpp')
-rw-r--r-- | atheos.cpp | 647 |
1 files changed, 647 insertions, 0 deletions
diff --git a/atheos.cpp b/atheos.cpp new file mode 100644 index 0000000..7bc4adc --- /dev/null +++ b/atheos.cpp @@ -0,0 +1,647 @@ +#include "cfg.h" + +#ifdef GRDRV_ATHEOS + +#include <atheos/threads.h> +#include <gui/view.h> +#include <gui/window.h> +#include <gui/desktop.h> +#include <gui/bitmap.h> +#include <util/locker.h> +#include <util/application.h> +#include <string> + +using namespace std; + +extern "C" { +#include "links.h" +} + +#define WINDOW_TITLE_SIZE 16 +#define TOP_PANEL_SIZE 32 +#define NEW_WINDOW_X_ADD 16 +#define NEW_WINDOW_Y_ADD 16 +#define NEW_WINDOW_X_MIN 8 +#define NEW_WINDOW_Y_MIN 8 + +#ifdef debug +#undef debug +#endif +#ifdef debug2 +#undef debug2 +#endif +#define debug(x) +#define debug2(x) + +extern struct graphics_driver atheos_driver; + +using namespace os; + +class LinksApplication : public Application { + public: + LinksApplication():Application("application/x-vnd.links"){} + virtual bool OkToQuit(){return false;} +}; + +class LinksView; + +class LinksWindow : public Window { + public: + LinksWindow(Rect r); + ~LinksWindow(); + virtual void FrameSized(const Point &d); + virtual bool OkToQuit(); + int resized; + LinksView *view; +}; + +class LinksView : public View { + public: + LinksView(LinksWindow *w); + ~LinksView(); + virtual void Paint(const Rect &r); + virtual void MouseDown(const Point &p, uint32 b); + virtual void MouseUp(const Point &p, uint32 b, Message *m); + virtual void MouseMove(const Point &p, int c, uint32 b, Message *m); + virtual void KeyDown(const char *s, const char *rs, uint32 q); + virtual void WheelMove(const point &d); + LinksWindow *win; + struct graphics_device *dev; + void d_flush(); + int flushing; + int last_x, last_y; +}; + +#define lv(dev) ((LinksView *)(dev)->driver_data) + +#define lock_dev(dev) do { if (lv(dev)->win->Lock()) return; } while (0) +#define lock_dev0(dev) do { if (lv(dev)->win->Lock()) return 0; } while (0) +#define unlock_dev(dev) do { lv(dev)->win->Unlock(); } while (0) + +LinksApplication *ath_links_app; +Locker *ath_lock = NULL; + +int msg_pipe[2]; + +thread_id ath_app_thread_id; + +#define rpipe (msg_pipe[0]) +#define wpipe (msg_pipe[1]) + +#define small_color (sizeof(Color32_s) <= sizeof(long)) +#define get_color32(c, rgb) Color32_s c((rgb >> 16) & 255, (rgb >> 8) & 255, rgb & 255, 255) + +color_space ath_cs_desktop, ath_cs_bmp; + +int ath_x_size, ath_y_size; +int ath_y_panel; + +int ath_win_x_size, ath_win_y_size; +int ath_win_x_pos, ath_win_y_pos; + +LinksWindow::LinksWindow(Rect r):Window(r, "links_wnd", "Links") +{ + debug2("LINKSWINDOW\n"); + resized = 0; + view = NULL; +} + +LinksWindow::~LinksWindow() +{ + view = NULL; + debug2("~LINKSWINDOW\n"); +} + +void LinksWindow::FrameSized(const Point &d) +{ + resized = 1; +} + +bool LinksWindow::OkToQuit() +{ + ath_lock->Lock(); + Lock(); + if (view) if (view->dev) view->dev->keyboard_handler(view->dev, KBD_CTRL_C, 0); + Unlock(); + ath_lock->Unlock(); + write(wpipe, " ", 1); + /*debug2("key: :%s: :%s: %d %d\n", s, rs, q, c);*/ + return false; +} + +void do_flush(void *p_dev) +{ + struct graphics_device *dev = (struct graphics_device *)p_dev; + LinksView *v = lv(dev); + v->win->Lock(); + v->win->Flush(); + v->win->Unlock(); + v->flushing = 0; +} + +LinksView::LinksView(LinksWindow *w):View(w->GetBounds(), "Links", CF_FOLLOW_ALL, WID_WILL_DRAW | WID_FULL_UPDATE_ON_RESIZE) +{ + debug2("LINKSVIEW\n"); + (win = w)->AddChild(this); + w->SetFocusChild(this); + w->view = this; + flushing = 0; + last_x = last_y = 0; +} + +LinksView::~LinksView() +{ + win->view = NULL; + debug2("~LINKSVIEW\n"); +} + +void LinksView::d_flush() +{ + if (flushing) return; + register_bottom_half(do_flush, this->dev); + flushing = 1; +} + +#undef select + +int ath_select(int n, fd_set *r, fd_set *w, fd_set *e, struct timeval *t) +{ + int v; + if (ath_lock) ath_lock->Unlock(); + v = select(n, r, w, e, t); + if (ath_lock) { + ath_lock->Lock(); + check_bottom_halves(); + } + return v; +} + +void ath_get_event(void *dummy) +{ + char dummy_buffer[256]; + read(rpipe, dummy_buffer, 256); + debug2("GETE\n"); +} + +void ath_get_size(struct graphics_device *dev) +{ + Rect r = lv(dev)->GetBounds(); + dev->size.x1 = dev->size.y1 = 0; + dev->size.x2 = (int)r.Width() + 1; + dev->size.y2 = (int)r.Height() + 1; +} + +void LinksView::Paint(const Rect &r) +{ + struct rect rr; + win->Unlock(); + ath_lock->Lock(); + win->Lock(); + rr.x1 = (int)r.left; + rr.x2 = (int)r.right + 1; + rr.y1 = (int)r.top; + rr.y2 = (int)r.bottom + 1; + /*debug2("paint: %d %d %d %d\n", rr.x1, rr.x2, rr.y1, rr.y2);*/ + if (dev) { + if (!win->resized) dev->redraw_handler(dev, &rr); + else { + ath_get_size(dev); + win->resized = 0; + dev->resize_handler(dev); + } + } + check_bottom_halves(); + ath_lock->Unlock(); + write(wpipe, " ", 1); +} + + +void LinksView::MouseDown(const Point &p, uint32 b) +{ + win->Unlock(); + ath_lock->Lock(); + win->Lock(); + if (dev) dev->mouse_handler(dev, last_x = (int)p.x, last_y = (int)p.y, B_DOWN | (b == 2 ? B_RIGHT : b == 3 ? B_MIDDLE : B_LEFT)); + ath_lock->Unlock(); + write(wpipe, " ", 1); +} + +void LinksView::MouseUp(const Point &p, uint32 b, Message *m) +{ + win->Unlock(); + ath_lock->Lock(); + win->Lock(); + if (dev) dev->mouse_handler(dev, last_x = (int)p.x, last_y = (int)p.y, B_UP | (b == 2 ? B_RIGHT : b == 3 ? B_MIDDLE : B_LEFT)); + ath_lock->Unlock(); + write(wpipe, " ", 1); +} + +void LinksView::MouseMove(const Point &p, int c, uint32 b, Message *m) +{ + win->Unlock(); + ath_lock->Lock(); + win->Lock(); + if (dev) dev->mouse_handler(dev, last_x = (int)p.x, last_y = (int)p.y, !b ? B_MOVE : B_DRAG | (b & 1 ? B_LEFT : b & 2 ? B_RIGHT : b & 4 ? B_MIDDLE : B_LEFT)); + ath_lock->Unlock(); + write(wpipe, " ", 1); +} + +void LinksView::WheelMove(const point &d) +{ + win->Unlock(); + ath_lock->Lock(); + win->Lock(); + if (d.y) if (dev) dev->mouse_handler(dev, last_x, last_y, B_MOVE | (d.y > 0 ? B_WHEELDOWN : B_WHEELUP)); + if (d.x) if (dev) dev->mouse_handler(dev, last_x, last_y, B_MOVE | (d.x < 0 ? B_WHEELLEFT : B_WHEELRIGHT)); + ath_lock->Unlock(); + write(wpipe, " ", 1); +} + +void LinksView::KeyDown(const char *s, const char *rs, uint32 q) +{ + int c; + unsigned char *ss = q & (QUAL_CTRL | QUAL_ALT) ? (unsigned char *)rs : (unsigned char *)s; + win->Unlock(); + ath_lock->Lock(); + win->Lock(); + GET_UTF_8(ss, c); + switch (c) { + case VK_BACKSPACE: c = KBD_BS; break; + case VK_ENTER: c = KBD_ENTER; break; + case VK_SPACE: c = ' '; break; + case VK_TAB: c = KBD_TAB; break; + case VK_ESCAPE: c = KBD_ESC; break; + case VK_LEFT_ARROW: c = KBD_LEFT; break; + case VK_RIGHT_ARROW: c = KBD_RIGHT; break; + case VK_UP_ARROW: c = KBD_UP; break; + case VK_DOWN_ARROW: c = KBD_DOWN; break; + case VK_INSERT: c = KBD_INS; break; + case VK_DELETE: c = KBD_DEL; break; + case VK_HOME: c = KBD_HOME; break; + case VK_END: c = KBD_END; break; + case VK_PAGE_UP: c = KBD_PAGE_UP; break; + case VK_PAGE_DOWN: c = KBD_PAGE_DOWN; break; + default: if (c < 32) c = 0; + else q &= ~QUAL_SHIFT; + break; + } + if (c) if (dev) dev->keyboard_handler(dev, c, (q & QUAL_SHIFT ? KBD_SHIFT : 0) | (q & QUAL_CTRL ? KBD_CTRL : 0) | (q & QUAL_ALT ? KBD_ALT : 0)); + ath_lock->Unlock(); + write(wpipe, " ", 1); + /*debug2("key: :%s: :%s: %d %d\n", s, rs, q, c);*/ +} + +unsigned char *ath_get_driver_param(void) +{ + return NULL; +} + +uint32 ath_app_thread(void *p) +{ + ath_links_app->Run(); + delete ath_links_app; + return 0; +} + +unsigned char *ath_init_driver(unsigned char *param, unsigned char *display) +{ + Desktop *d; + ath_links_app = new LinksApplication(); + if (!ath_links_app) { + return stracpy((unsigned char *)"Unable to allocate Application object.\n"); + } + ath_lock = new Locker("links_sem", false, false); + if (!ath_lock || ath_lock->Lock()) { + delete ath_links_app; + return stracpy((unsigned char *)"Could not create lock.\n"); + } + if (c_pipe(msg_pipe)) { + delete ath_lock; ath_lock = NULL; + delete ath_links_app; + return stracpy((unsigned char *)"Could not create pipe.\n"); + } + fcntl(rpipe, F_SETFL, O_NONBLOCK); + fcntl(wpipe, F_SETFL, O_NONBLOCK); + set_handlers(rpipe, ath_get_event, NULL, NULL, NULL); + ath_app_thread_id = spawn_thread("links_app", (void *)ath_app_thread, 0, 0, NULL); + resume_thread(ath_app_thread_id); + if ((d = new Desktop)) { + ath_cs_desktop = d->GetColorSpace(); + ath_x_size = d->GetResolution().x; + ath_y_size = d->GetResolution().y; + delete d; + } else { + ath_cs_desktop = CS_NO_COLOR_SPACE; + ath_x_size = 640; + ath_y_size = 480; + } + ath_y_panel = WINDOW_TITLE_SIZE; +#ifdef __SYLLABLE__ + ath_y_panel += TOP_PANEL_SIZE; +#endif + if (ath_y_panel > ath_y_size) ath_y_panel = 0; + ath_win_y_size = (ath_y_size - ath_y_panel) * 9 / 10; + ath_win_x_size = ath_win_y_size; + /* + debug2("%d %d\n", ath_x_size, ath_y_size); + debug2("%d %d\n", ath_win_x_size, ath_win_y_size); + */ + ath_win_y_pos = (ath_y_size - ath_y_panel - ath_win_y_size) / 2 + ath_y_panel; + ath_win_x_pos = ath_x_size - ath_win_x_size - ath_win_y_pos; + if (/*ath_cs_desktop == CS_RGB32 ||*/ ath_cs_desktop == CS_RGB24 || ath_cs_desktop == CS_RGB16 || ath_cs_desktop == CS_RGB15) + ath_cs_bmp = ath_cs_desktop; + else if (ath_cs_desktop == CS_RGB32 || ath_cs_desktop == CS_RGBA32) ath_cs_bmp = CS_RGB24; + else ath_cs_bmp = CS_RGB15; + switch (ath_cs_bmp) { + case CS_RGB24: + atheos_driver.depth = 0xc3; + break; + case CS_RGB16: + atheos_driver.depth = 0x82; + break; + case CS_RGB15: + atheos_driver.depth = 0x7a; + break; + default: + internal((unsigned char *)"unknown depth"); + } + return NULL; +} + +void ath_shutdown_driver() +{ + debug((unsigned char *)"D"); + close(rpipe); + close(wpipe); + set_handlers(rpipe, NULL, NULL, NULL, NULL); + ath_lock->Unlock(); + debug((unsigned char *)"DD"); + ath_links_app->PostMessage(M_TERMINATE); + debug((unsigned char *)"E"); + /*delete ath_lock; ath_lock = NULL;*/ + debug((unsigned char *)"F"); +} + +struct graphics_device *ath_init_device() +{ + LinksView *view; + LinksWindow *win; + struct graphics_device *dev = (struct graphics_device *)mem_calloc(sizeof(struct graphics_device)); + if (!dev) return NULL; + debug((unsigned char *)"1"); + retry: + win = new LinksWindow(Rect(ath_win_x_pos, ath_win_y_pos, ath_win_x_pos + ath_win_x_size, ath_win_y_pos + ath_win_y_size)); + debug((unsigned char *)"2"); + if (!win) { + if (out_of_memory(NULL, 0)) + goto retry; + mem_free(dev); + return NULL; + } + debug((unsigned char *)"3"); + retry2: + view = new LinksView(win); + if (!view) { + if (out_of_memory(NULL, 0)) + goto retry2; + delete win; + mem_free(dev); + return NULL; + } + view->dev = dev; + dev->driver_data = view; + ath_get_size(dev); + memcpy(&dev->clip, &dev->size, sizeof(struct rect)); + debug((unsigned char *)"4"); + win->Show(); + win->MakeFocus(); + debug((unsigned char *)"5"); + + ath_win_x_pos += NEW_WINDOW_X_ADD; + ath_win_y_pos += NEW_WINDOW_Y_ADD; + if (ath_win_x_pos + ath_win_x_size > ath_x_size - NEW_WINDOW_X_MIN) + ath_win_x_pos = NEW_WINDOW_X_MIN; + if (ath_win_y_pos + ath_win_y_size > ath_y_size - NEW_WINDOW_Y_MIN) + ath_win_y_pos = ath_y_panel + NEW_WINDOW_Y_MIN; + + return dev; +} + +void ath_shutdown_device(struct graphics_device *dev) +{ + LinksWindow *win = lv(dev)->win; + unregister_bottom_half(do_flush, dev); + lv(dev)->dev = NULL; + win->PostMessage(M_TERMINATE); + mem_free(dev); +} + +void ath_set_title(struct graphics_device *dev, unsigned char *title) +{ + LinksWindow *win = lv(dev)->win; + lock_dev(dev); + win->SetTitle(string((char *)title)); + lv(dev)->d_flush(); + unlock_dev(dev); +} + +int ath_get_empty_bitmap(struct bitmap *bmp) +{ + debug2("bmp\n"); + Bitmap *b; + retry: + b = new Bitmap(bmp->x, bmp->y, ath_cs_bmp, Bitmap::SHARE_FRAMEBUFFER); + if (!b) { + if (out_of_memory(NULL, 0)) + goto retry; + bmp->data = NULL; + bmp->flags = NULL; + return -1; + } + bmp->data = b->LockRaster(); + bmp->skip = b->GetBytesPerRow(); + bmp->flags = b; + return 0; +} + +void ath_register_bitmap(struct bitmap *bmp) +{ + Bitmap *b = (Bitmap *)bmp->flags; + if (!b) return; + b->UnlockRaster(); +} + +void *ath_prepare_strip(struct bitmap *bmp, int top, int lines) +{ + debug2("preps\n"); + Bitmap *b = (Bitmap *)bmp->flags; + if (!b) return NULL; + bmp->data = b->LockRaster(); + bmp->skip = b->GetBytesPerRow(); + return ((char *)bmp->data) + bmp->skip * top; +} + +void ath_commit_strip(struct bitmap *bmp, int top, int lines) +{ + Bitmap *b = (Bitmap *)bmp->flags; + if (!b) return; + b->UnlockRaster(); +} + +void ath_unregister_bitmap(struct bitmap *bmp) +{ + debug2("unb\n"); + Bitmap *b = (Bitmap *)bmp->flags; + if (!b) return; + delete b; +} + +void ath_draw_bitmap(struct graphics_device *dev, struct bitmap *bmp, int x, int y) +{ + debug2("drawb\n"); + Bitmap *b = (Bitmap *)bmp->flags; + if (!b) return; + lock_dev(dev); + lv(dev)->DrawBitmap(b, b->GetBounds(), Rect(x, y, x + bmp->x - 1, y + bmp->y - 1)); + lv(dev)->d_flush(); + unlock_dev(dev); +} + +#if 0 +void ath_draw_bitmaps(struct graphics_device *dev, struct bitmap **bmp, int n, int x, int y) +{ + LinksView *lvv = lv(dev); + lock_dev(dev); + while (n--) { + Bitmap *b = (Bitmap *)(*bmp)->flags; + lvv->DrawBitmap(b, b->GetBounds(), Rect(x, y, x + (*bmp)->x, y + (*bmp)->y)); + x += (*bmp)->x; + bmp++; + } + lv(dev)->d_flush(); + unlock_dev(dev); +} +#endif + +long ath_get_color(int rgb) +{ + if (small_color) { + get_color32(c, rgb); + return *(long *)(void *)&c; + } else return rgb & 0xffffff; +} + +void ath_fill_area(struct graphics_device *dev, int x1, int y1, int x2, int y2, long color) +{ + debug2("fill\n"); + if (x1 >= x2 || y1 >= y2) return; + lock_dev(dev); + if (small_color) + lv(dev)->FillRect(Rect(x1, y1, x2 - 1, y2 - 1), *(Color32_s *)(void *)&color); + else + lv(dev)->FillRect(Rect(x1, y1, x2 - 1, y2 - 1), get_color32(, color)); + lv(dev)->d_flush(); + unlock_dev(dev); +} + +void ath_draw_hline(struct graphics_device *dev, int x1, int y, int x2, long color) +{ + debug2("hline\n"); + if (x1 >= x2) return; + lock_dev(dev); + if (small_color) + lv(dev)->SetFgColor(*(Color32_s *)(void *)&color); + else + lv(dev)->SetFgColor(get_color32(, color)); + lv(dev)->DrawLine(Point(IPoint(x1, y)), Point(IPoint(x2 - 1, y))); + lv(dev)->d_flush(); + unlock_dev(dev); +} + +void ath_draw_vline(struct graphics_device *dev, int x, int y1, int y2, long color) +{ + debug2("vline\n"); + if (y1 >= y2) return; + lock_dev(dev); + if (small_color) + lv(dev)->SetFgColor(*(Color32_s *)(void *)&color); + else + lv(dev)->SetFgColor(get_color32(, color)); + lv(dev)->DrawLine(Point(IPoint(x, y1)), Point(IPoint(x, y2 - 1))); + lv(dev)->d_flush(); + unlock_dev(dev); +} + +int ath_hscroll(struct graphics_device *dev, struct rect_set **ignore, int sc) +{ + debug2("hscroll\n"); + if (dev->clip.x1 >= dev->clip.x2 || dev->clip.y1 >= dev->clip.y2) return 0; + if (sc <= dev->clip.x1 - dev->clip.x2) return 1; + if (sc >= dev->clip.x2 - dev->clip.x1) return 1; + lock_dev0(dev); + if (sc > 0) lv(dev)->ScrollRect(Rect(dev->clip.x1, dev->clip.y1, dev->clip.x2 - sc - 1, dev->clip.y2 - 1), Rect(dev->clip.x1 + sc, dev->clip.y1, dev->clip.x2 - 1, dev->clip.y2 - 1)); + else lv(dev)->ScrollRect(Rect(dev->clip.x1 - sc, dev->clip.y1, dev->clip.x2 - 1, dev->clip.y2 - 1), Rect(dev->clip.x1, dev->clip.y1, dev->clip.x2 + sc - 1, dev->clip.y2 - 1)); + lv(dev)->d_flush(); + unlock_dev(dev); + return 1; +} + +int ath_vscroll(struct graphics_device *dev, struct rect_set **ignore, int sc) +{ + debug2("vscroll\n"); + if (!sc || dev->clip.x1 >= dev->clip.x2 || dev->clip.y1 >= dev->clip.y2) return 0; + if (sc <= dev->clip.y1 - dev->clip.y2) return 1; + if (sc >= dev->clip.y2 - dev->clip.y1) return 1; + lock_dev0(dev); + if (sc > 0) lv(dev)->ScrollRect(Rect(dev->clip.x1, dev->clip.y1, dev->clip.x2 - 1, dev->clip.y2 - sc - 1), Rect(dev->clip.x1, dev->clip.y1 + sc, dev->clip.x2 - 1, dev->clip.y2 - 1)); + else lv(dev)->ScrollRect(Rect(dev->clip.x1, dev->clip.y1 - sc, dev->clip.x2 - 1, dev->clip.y2 - 1), Rect(dev->clip.x1, dev->clip.y1, dev->clip.x2 - 1, dev->clip.y2 + sc - 1)); + lv(dev)->d_flush(); + unlock_dev(dev); + return 1; +} + +void ath_set_clip_area(struct graphics_device *dev, struct rect *r) +{ + debug2("setc\n"); + memcpy(&dev->clip, r, sizeof(struct rect)); + lock_dev(dev); + lv(dev)->SetDrawingRegion(Region(IRect(r->x1, r->y1, r->x2 - 1, r->y2 - 1))); + unlock_dev(dev); +} + +struct graphics_driver atheos_driver = { + (unsigned char *)"atheos", + ath_init_driver, + ath_init_device, + ath_shutdown_device, + ath_shutdown_driver, + ath_get_driver_param, + ath_get_empty_bitmap, + /*ath_get_filled_bitmap,*/ + ath_register_bitmap, + ath_prepare_strip, + ath_commit_strip, + ath_unregister_bitmap, + ath_draw_bitmap, + /*ath_draw_bitmaps,*/ + ath_get_color, + ath_fill_area, + ath_draw_hline, + ath_draw_vline, + ath_hscroll, + ath_vscroll, + ath_set_clip_area, + dummy_block, + dummy_unblock, + ath_set_title, + NULL, /* exec */ + NULL, /* set_clipboard_text */ + NULL, /* get_clipboard_text */ + 0, /* depth */ + 0, 0, /* size */ + GD_NO_OS_SHELL, /* flags */ + 0, /* codepage */ + NULL, /* shell */ +}; + +#endif |