Subversion Repositories Kolibri OS

Rev

Rev 3622 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright 2013 SoUrcerer sourcerer@bk.ru
  3.  *
  4.  * This file is part of libnsfb, http://www.netsurf-browser.org/
  5.  * Licenced under the MIT License,
  6.  *                http://www.opensource.org/licenses/mit-license.php
  7.  */
  8.  
  9. #include <stdbool.h>
  10. #include <stdlib.h>
  11.  
  12. #include "libnsfb.h"
  13. #include "libnsfb_event.h"
  14. #include "libnsfb_plot.h"
  15. #include "libnsfb_plot_util.h"
  16.  
  17. #include "nsfb.h"
  18. #include "surface.h"
  19. #include "palette.h"
  20. #include "plot.h"
  21. #include "cursor.h"
  22.  
  23.  
  24. #include <menuet/os.h>
  25.  
  26.  
  27.  
  28. unsigned char * pixels;
  29.  
  30.  inline void f65(unsigned x, unsigned y, unsigned w, unsigned h, char *d)
  31. {
  32. asm("pusha");
  33. asm ("nop"::"D"(0), "c"(w*65536+h), "d"(x*65536+y), "b"(d));
  34. asm ("xor %eax, %eax");
  35. asm ("movl %eax, %ebp");
  36. asm ("pushl $32");
  37. asm ("popl %esi");
  38. asm ("int $0x40"::"a"(65));
  39. asm("popa");
  40. }
  41.  
  42.  
  43. unsigned kol_mouse_posw()
  44. {
  45. unsigned error;
  46. asm volatile ("int $0x40":"=a"(error):"a"(37), "b"(1));
  47. return error;
  48. }
  49.  
  50.  
  51. unsigned kol_mouse_btn()
  52. {
  53. unsigned error;
  54. asm volatile ("int $0x40":"=a"(error):"a"(37), "b"(2));
  55. return error;
  56. }
  57.  
  58. unsigned kol_scancodes()
  59. {
  60. unsigned error;
  61. asm volatile ("int $0x40":"=a"(error):"a"(66), "b"(1), "c"(1));
  62. return error;
  63. }
  64.  
  65.  
  66. void kolibri_redraw(nsfb_t *nsfb){
  67.        
  68.  
  69.  f65(0,0, nsfb->width, nsfb->height, pixels);
  70.  
  71. }
  72.  
  73.  
  74. unsigned kol_skin_h()
  75. {
  76. unsigned error;
  77. asm volatile ("int $0x40":"=a"(error):"a"(48), "b"(4));
  78. return error;
  79. }
  80.  
  81. unsigned kol_area(char *data)
  82. {
  83. unsigned error;
  84. asm volatile ("int $0x40":"=a"(error):"a"(9), "b"(data), "c"(0xffffffff));
  85. return error;
  86. }
  87.  
  88.  
  89. void kolibri_window_redraw(nsfb_t *nsfb){
  90.        
  91.  __menuet__window_redraw(1);
  92.  __menuet__define_window(100,100,nsfb->width+9,nsfb->height+kol_skin_h(),0x34000080,0x800000FF,"Netsurf");
  93.  //__menuet__write_text(3,3,0xFFFFFF,"Netsurf",7);
  94. //__menuet__debug_out("f65 is mighty!\n");
  95.  
  96. //here put image pixels! it's 32bpp
  97.  f65(0,0, nsfb->width, nsfb->height, pixels);
  98.  __menuet__window_redraw(2);
  99.  
  100.  
  101.  
  102. }
  103.  
  104.  
  105.  
  106. static bool
  107. kolibricopy(nsfb_t *nsfb, nsfb_bbox_t *srcbox, nsfb_bbox_t *dstbox)
  108. {
  109.    
  110.     char *pixels = nsfb->surface_priv;
  111.     nsfb_bbox_t allbox;
  112.     struct nsfb_cursor_s *cursor = nsfb->cursor;
  113.  
  114.     nsfb_plot_add_rect(srcbox, dstbox, &allbox);
  115.  
  116.         int x,y,w,h;
  117.     x = srcbox->x0;
  118.     y = srcbox->y0;
  119.     w = srcbox->x1 - srcbox->x0;
  120.     h = srcbox->y1 - srcbox->y0;
  121.    
  122.     int tx, ty, tw, th;
  123.    
  124.     tx = dstbox->x0;
  125.     ty = dstbox->y0;
  126.     tw = dstbox->x1 - dstbox->x0;
  127.     th = dstbox->y1 - dstbox->y0;
  128.    
  129.    // char pst[255];
  130.   //  sprintf (pst, "Src %d,%d %dx%d Dst %d,%d %dx%d \n", x,y,w,h,tx,ty,tw,th);
  131.    // __menuet__debug_out(pst);
  132.    
  133.     int px, py, pp;
  134.    
  135.  
  136.    
  137.     for (px=x; px<w; px++)
  138.                 for (py=y;py<h;py++)
  139.                         for (pp=0; pp<4; pp++) {
  140.                                
  141.                                 pixels[4*(px+tx)*nsfb->width+4*(py+ty)+pp]=pixels[4*px*nsfb->width+4*py+pp];
  142.                                
  143.                                
  144.                         }
  145.    
  146.    
  147.    
  148.    
  149.         kolibri_redraw(nsfb);
  150.  
  151.     return true;
  152.  
  153. }
  154.  
  155. static int kolibri_set_geometry(nsfb_t *nsfb, int width, int height,
  156.         enum nsfb_format_e format)
  157. {
  158.     if (nsfb->surface_priv != NULL)
  159.         return -1; /* fail if surface already initialised */
  160.  
  161.     nsfb->width = width;
  162.     nsfb->height = height;
  163.     nsfb->format = format;
  164.        
  165.         pixels=(char *)malloc(width*height*4);
  166.        
  167.     /* select default sw plotters for format */
  168.     select_plotters(nsfb);
  169.  
  170.     //nsfb->plotter_fns->copy = kolibricopy;
  171.  
  172.     return 0;
  173. }
  174. unsigned pz, pb;
  175.  
  176. static int kolibri_initialise(nsfb_t *nsfb)
  177. {
  178.     enum nsfb_format_e fmt;
  179.  
  180.         kol_scancodes();
  181.  
  182. pz=0;
  183. pb=0;
  184.  
  185. __menuet__debug_out("Start UI\n");
  186.  
  187.     if (nsfb->surface_priv != NULL)
  188.         return -1;
  189.  
  190.     /* sanity checked depth. */
  191.     if ((nsfb->bpp != 32) ) {
  192.                
  193.                 __menuet__debug_out("Wrong bpp\n");
  194.         return -1; }
  195.  
  196.        
  197.                 fmt = NSFB_FMT_XRGB8888;
  198.    
  199.     /* If we didn't get what we asked for, reselect plotters */
  200.     if (nsfb->format != fmt) {
  201.         nsfb->format = fmt;
  202.  
  203.         if (kolibri_set_geometry(nsfb, nsfb->width, nsfb->height,
  204.                 nsfb->format) != 0) {
  205.                                        
  206.                                         __menuet__debug_out("can't set geometry\n");
  207.             return -1;
  208.         }
  209.     }
  210.  
  211.     nsfb->surface_priv = pixels;
  212.  
  213.     nsfb->ptr = pixels;
  214.     nsfb->linelen = (nsfb->width * nsfb->bpp) / 8;
  215.    
  216.     __menuet__debug_out("Redraw\n");
  217.     kolibri_redraw(nsfb);
  218.    
  219.     __menuet__set_bitfield_for_wanted_events(EVENT_REDRAW|EVENT_KEY|EVENT_BUTTON|EVENT_MOUSE_CHANGE);
  220.  
  221.     return 0;
  222. }
  223.  
  224.  
  225.  
  226. static int kolibri_finalise(nsfb_t *nsfb)
  227. {
  228.     nsfb=nsfb;
  229.     __menuet__sys_exit();
  230.     return 0;
  231. }
  232.  
  233.  
  234.  
  235. int isup(int scan){
  236.         return (scan&0x80)>>7;
  237. }
  238.  
  239. int scan2key(int scan){
  240.         int keycode=(scan&0x0FF7F);
  241.         /* MAIN KB - NUMS */
  242.         if (keycode == 0x02) return NSFB_KEY_1;
  243.         if (keycode == 0x03) return NSFB_KEY_2;
  244.         if (keycode == 0x04) return NSFB_KEY_3;
  245.         if (keycode == 0x05) return NSFB_KEY_4;
  246.         if (keycode == 0x06) return NSFB_KEY_5;
  247.         if (keycode == 0x07) return NSFB_KEY_6;
  248.         if (keycode == 0x08) return NSFB_KEY_7;
  249.         if (keycode == 0x09) return NSFB_KEY_8;
  250.         if (keycode == 0x0A) return NSFB_KEY_9;
  251.         if (keycode == 0x0B) return NSFB_KEY_0;
  252.        
  253.         if (keycode == 0x10) return NSFB_KEY_q;
  254.         if (keycode == 0x11) return NSFB_KEY_w;
  255.         if (keycode == 0x12) return NSFB_KEY_e;
  256.         if (keycode == 0x13) return NSFB_KEY_r;
  257.         if (keycode == 0x14) return NSFB_KEY_t;
  258.         if (keycode == 0x15) return NSFB_KEY_y;
  259.         if (keycode == 0x16) return NSFB_KEY_u;
  260.         if (keycode == 0x17) return NSFB_KEY_i;
  261.         if (keycode == 0x18) return NSFB_KEY_o;
  262.         if (keycode == 0x19) return NSFB_KEY_p;
  263.         if (keycode == 0x1A) return NSFB_KEY_LEFTBRACKET;
  264.         if (keycode == 0x1B) return NSFB_KEY_RIGHTBRACKET;
  265.        
  266.         if (keycode == 0x1E) return NSFB_KEY_a;
  267.         if (keycode == 0x1F) return NSFB_KEY_s;
  268.         if (keycode == 0x20) return NSFB_KEY_d;
  269.         if (keycode == 0x21) return NSFB_KEY_f;
  270.         if (keycode == 0x22) return NSFB_KEY_g;
  271.         if (keycode == 0x23) return NSFB_KEY_h;
  272.         if (keycode == 0x24) return NSFB_KEY_j;
  273.         if (keycode == 0x25) return NSFB_KEY_k;
  274.         if (keycode == 0x26) return NSFB_KEY_l;
  275.        
  276.         if (keycode == 0x2C) return NSFB_KEY_z;
  277.         if (keycode == 0x2D) return NSFB_KEY_x;
  278.         if (keycode == 0x2E) return NSFB_KEY_c;
  279.         if (keycode == 0x2F) return NSFB_KEY_v;
  280.         if (keycode == 0x30) return NSFB_KEY_b;
  281.         if (keycode == 0x31) return NSFB_KEY_n;
  282.         if (keycode == 0x32) return NSFB_KEY_m;
  283.        
  284.         if (keycode == 0x27) return NSFB_KEY_SEMICOLON;
  285.         if (keycode == 0x28) return NSFB_KEY_QUOTEDBL;
  286.         if (keycode == 0x2B) return NSFB_KEY_BACKSLASH;
  287.         if (keycode == 0x33) return NSFB_KEY_COMMA;
  288.         if (keycode == 0x34) return NSFB_KEY_PERIOD;
  289.         if (keycode == 0x35) return NSFB_KEY_SLASH;
  290.         if (keycode == 0x0C) return NSFB_KEY_MINUS;
  291.         if (keycode == 0x0D) return NSFB_KEY_EQUALS;
  292.        
  293.         if (keycode == 0x0E) return NSFB_KEY_BACKSPACE;
  294.         if (keycode == 0xE053) return NSFB_KEY_DELETE;
  295.         if (keycode == 0x2A) return NSFB_KEY_LSHIFT;
  296.         if (keycode == 0x36) return NSFB_KEY_RSHIFT;
  297.        
  298.         if (keycode == 0x1C) return NSFB_KEY_RETURN;
  299.        
  300.         if (keycode == 0xE04B) return NSFB_KEY_LEFT;
  301.         if (keycode == 0xE04D) return NSFB_KEY_RIGHT;
  302.         if (keycode == 0xE048) return NSFB_KEY_UP;
  303.         if (keycode == 0xE050) return NSFB_KEY_DOWN;
  304.        
  305.         if (keycode == 0x3F) return NSFB_KEY_F5;
  306.        
  307.         if (keycode == 0x39) return NSFB_KEY_SPACE;
  308.         if (keycode == 0x01) return NSFB_KEY_ESCAPE;
  309.        
  310.         if (keycode == 0x38) return NSFB_KEY_LALT;
  311.         if (keycode == 0x1D) return NSFB_KEY_LCTRL;
  312.         if (keycode == 0xE038) return NSFB_KEY_RALT;
  313.         if (keycode == 0xE01D) return NSFB_KEY_RCTRL;
  314.        
  315.        
  316.         if (keycode == 0xE047) return NSFB_KEY_HOME;
  317.         if (keycode == 0xE04F) return NSFB_KEY_END;
  318.         if (keycode == 0xE049) return NSFB_KEY_PAGEUP;
  319.         if (keycode == 0xE051) return NSFB_KEY_PAGEDOWN;
  320.        
  321.         return NSFB_KEY_UNKNOWN;
  322.        
  323. }
  324.  
  325. int ispowerkey(int scan){
  326.         return (scan&0xE000)>>15;
  327. }
  328.  
  329.  
  330. static bool kolibri_input(nsfb_t *nsfb, nsfb_event_t *event, int timeout)
  331. {
  332.     int got_event;
  333.     static int scanfull=0;
  334.  
  335.     nsfb = nsfb; /* unused */
  336.  
  337.        
  338.        got_event = __menuet__check_for_event();
  339.  
  340.     if (got_event == 0) {
  341.         return false;
  342.     }
  343.  
  344.     event->type = NSFB_EVENT_NONE;
  345.  
  346.          if (got_event==1) { //key pressed
  347.     kolibri_window_redraw(nsfb);
  348.        
  349.         }
  350.  
  351.     if (got_event==2) { //key pressed
  352.     int scanz = __menuet__getkey();
  353.    
  354.     //char dbs[64];
  355.    
  356.     //__menuet__debug_out("KEY PRESSED\n");
  357.    
  358.    // sprintf (dbs, "FULLKEY BEFORE: F:%x\n", scanfull);
  359.         //__menuet__debug_out(dbs);
  360.        
  361.         if (scanz==0xE0) {
  362.                 scanfull=0xE000;
  363.                 return true;
  364.         } else {
  365.                 scanfull=scanfull+scanz;
  366.         }
  367.        
  368.     //sprintf (dbs, "FULLKEY AFTER: F:%x\n", scanfull);
  369.         //__menuet__debug_out(dbs);
  370.    
  371.    
  372.         if (isup(scanfull)==1) {
  373.         event->type = NSFB_EVENT_KEY_UP;} else {
  374.         event->type = NSFB_EVENT_KEY_DOWN;}
  375.                
  376.         event->value.keycode = scan2key(scanfull);
  377.        
  378.         //sprintf (dbs, "KEY: %x F:%x %d %d\n", scanz, scanfull, isup(scanz), scan2key(scanz));
  379.         //__menuet__debug_out(dbs);
  380.        
  381.         scanfull=0;
  382.        
  383.         return true;
  384.  
  385.         }
  386.        
  387.         if (got_event==3) { //key pressed
  388.     if (__menuet__get_button_id()==1) kolibri_finalise(nsfb);
  389.         return true;
  390.         }
  391.        
  392.         if (got_event==6) { //key pressed
  393.         unsigned z=kol_mouse_posw();
  394.         unsigned b=kol_mouse_btn();
  395.                
  396.                
  397.                 if (pz!=z) {
  398.                         event->type = NSFB_EVENT_MOVE_ABSOLUTE;
  399.                         event->value.vector.x = (z&0xffff0000)>>16; //sdlevent.motion.x;
  400.                         event->value.vector.y = z&0xffff; //sdlevent.motion.y;
  401.                         event->value.vector.z = 0;
  402.                         pz=z;
  403.                         return true;
  404.                 }
  405.                
  406.                
  407.                 if (pb!=b) {
  408.                         unsigned t=b&1;
  409.                         if (t==0) {
  410.                                 event->type = NSFB_EVENT_KEY_UP;
  411.                             event->value.keycode = NSFB_KEY_MOUSE_1;
  412.                         } else {
  413.                                 event->type = NSFB_EVENT_KEY_DOWN;
  414.                             event->value.keycode = NSFB_KEY_MOUSE_1;
  415.                         }
  416.                         pb=b;          
  417.                         return true;
  418.                 }
  419.                
  420.         }
  421.  
  422.     /*
  423.  
  424.     case SDL_MOUSEBUTTONDOWN:
  425.         event->type = NSFB_EVENT_KEY_DOWN;
  426.  
  427.         switch (sdlevent.button.button) {
  428.  
  429.         case SDL_BUTTON_LEFT:
  430.             event->value.keycode = NSFB_KEY_MOUSE_1;
  431.             break;
  432.  
  433.         case SDL_BUTTON_MIDDLE:
  434.             event->value.keycode = NSFB_KEY_MOUSE_2;
  435.             break;
  436.  
  437.         case SDL_BUTTON_RIGHT:
  438.             event->value.keycode = NSFB_KEY_MOUSE_3;
  439.             break;
  440.  
  441.         }
  442.         break;
  443.  
  444.     case SDL_MOUSEBUTTONUP:
  445.         event->type = NSFB_EVENT_KEY_UP;
  446.  
  447.         switch (sdlevent.button.button) {
  448.  
  449.         case SDL_BUTTON_LEFT:
  450.             event->value.keycode = NSFB_KEY_MOUSE_1;
  451.             break;
  452.  
  453.         case SDL_BUTTON_MIDDLE:
  454.             event->value.keycode = NSFB_KEY_MOUSE_2;
  455.             break;
  456.  
  457.         case SDL_BUTTON_RIGHT:
  458.             event->value.keycode = NSFB_KEY_MOUSE_3;
  459.             break;
  460.  
  461.         }
  462.         break;
  463.  
  464.     case SDL_MOUSEMOTION:
  465.         event->type = NSFB_EVENT_MOVE_ABSOLUTE;
  466.         event->value.vector.x = sdlevent.motion.x;
  467.         event->value.vector.y = sdlevent.motion.y;
  468.         event->value.vector.z = 0;
  469.         break;
  470.  
  471.     case SDL_QUIT:
  472.         event->type = NSFB_EVENT_CONTROL;
  473.         event->value.controlcode = NSFB_CONTROL_QUIT;
  474.         break;
  475.  
  476.     case SDL_USEREVENT:
  477.         event->type = NSFB_EVENT_CONTROL;
  478.         event->value.controlcode = NSFB_CONTROL_TIMEOUT;
  479.         break;
  480.  
  481.     }
  482.         */
  483.     return true;
  484. }
  485.  
  486.  
  487. static int kolibri_claim(nsfb_t *nsfb, nsfb_bbox_t *box)
  488. {
  489.         /*
  490.     if ((cursor != NULL) &&
  491.         (cursor->plotted == true) &&
  492.         (nsfb_plot_bbox_intersect(box, &cursor->loc))) {
  493.         nsfb_cursor_clear(nsfb, cursor);
  494.     } */
  495.         return 0; //stub yet
  496. }
  497.  
  498. static int kolibri_cursor(nsfb_t *nsfb, struct nsfb_cursor_s *cursor)
  499. {
  500.         return true; //stub yet
  501. }
  502.  
  503.  
  504.  
  505. static int kolibri_update(nsfb_t *nsfb, nsfb_bbox_t *box)
  506. {
  507.     /*SDL_Surface *sdl_screen = nsfb->surface_priv;
  508.     struct nsfb_cursor_s *cursor = nsfb->cursor;
  509.  
  510.     if ((cursor != NULL) &&
  511.         (cursor->plotted == false)) {
  512.         nsfb_cursor_plot(nsfb, cursor);
  513.     }
  514.  
  515.     SDL_UpdateRect(sdl_screen,
  516.                    box->x0,
  517.                    box->y0,
  518.                    box->x1 - box->x0,
  519.                    box->y1 - box->y0);
  520.   */
  521.  
  522.   //Ask for window redraw here!
  523.  
  524.         kolibri_redraw(nsfb);
  525.     return 0;
  526. }
  527.  
  528. const nsfb_surface_rtns_t kolibri_rtns = {
  529.     .initialise = kolibri_initialise,
  530.     .finalise = kolibri_finalise,
  531.     .input = kolibri_input,
  532.     .claim = kolibri_claim,
  533.     .update = kolibri_update,
  534.     .cursor = kolibri_cursor,
  535.     .geometry = kolibri_set_geometry,
  536. };
  537.  
  538. NSFB_SURFACE_DEF(kolibri, NSFB_SURFACE_KOLIBRI, &kolibri_rtns)
  539.  
  540. /*
  541.  * Local variables:
  542.  *  c-basic-offset: 4
  543.  *  tab-width: 8
  544.  * End:
  545.  */
  546.