Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Copyright 2008,2010 Vincent Sanders <vince@simtec.co.uk>
  3.  *
  4.  * Framebuffer windowing toolkit core.
  5.  *
  6.  * This file is part of NetSurf, http://www.netsurf-browser.org/
  7.  *
  8.  * NetSurf is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation; version 2 of the License.
  11.  *
  12.  * NetSurf is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  * GNU General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU General Public License
  18.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  19.  */
  20.  
  21. #include <sys/types.h>
  22. #include <assert.h>
  23. #include <stdint.h>
  24. #include <string.h>
  25. #include <stdbool.h>
  26. #include <stdarg.h>
  27.  
  28. #include <libnsfb.h>
  29. #include <libnsfb_plot.h>
  30. #include <libnsfb_plot_util.h>
  31. #include <libnsfb_event.h>
  32. #include <libnsfb_cursor.h>
  33.  
  34. #include "utils/utils.h"
  35. #include "utils/log.h"
  36. #include "css/css.h"
  37. #include "desktop/browser.h"
  38. #include "desktop/plotters.h"
  39.  
  40. #include "framebuffer/gui.h"
  41. #include "framebuffer/fbtk.h"
  42. #include "framebuffer/image_data.h"
  43.  
  44. #include "widget.h"
  45.  
  46. #ifdef FBTK_LOGGING
  47.  
  48. /* tree dump debug, also example of depth first tree walk */
  49. static void
  50. dump_tk_tree(fbtk_widget_t *widget)
  51. {
  52.         widget = fbtk_get_root_widget(widget);
  53.         int indent = 0;
  54.  
  55.         while (widget != NULL) {
  56.                 LOG(("%*s%p", indent, "", widget));
  57.                 if (widget->first_child != NULL) {
  58.                         widget = widget->first_child;
  59.                         indent += 6;
  60.                 } else if (widget->next != NULL) {
  61.                         widget = widget->next;
  62.                 } else {
  63.                         while ((widget->parent != NULL) &&
  64.                                (widget->parent->next == NULL)) {
  65.                                 widget = widget->parent;
  66.                                 indent -= 6;
  67.                         }
  68.                         if (widget->parent != NULL) {
  69.                                 indent -= 6;
  70.                                 widget = widget->parent->next;
  71.                         } else {
  72.                                 widget = NULL;
  73.                         }
  74.                 }
  75.         }
  76. }
  77.  
  78. #endif
  79.  
  80. /* exported function documented in fbtk.h */
  81. void
  82. fbtk_request_redraw(fbtk_widget_t *widget)
  83. {
  84.         fbtk_widget_t *cwidget;
  85.         fbtk_widget_t *pwidget;
  86.  
  87.         assert(widget != NULL);
  88.  
  89.         /* if widget not mapped do not try to redraw it */
  90.         pwidget = widget;
  91.         while (pwidget != NULL) {
  92.                 if (pwidget->mapped == false)
  93.                         return;
  94.                 pwidget = pwidget->parent;
  95.         }
  96.  
  97.         widget->redraw.needed = true;
  98.         widget->redraw.x = 0;
  99.         widget->redraw.y = 0;
  100.         widget->redraw.width = widget->width;
  101.         widget->redraw.height = widget->height;
  102.  
  103.         LOG(("redrawing %p %d,%d %d,%d",
  104.              widget,
  105.              widget->redraw.x,
  106.              widget->redraw.y,
  107.              widget->redraw.width,
  108.              widget->redraw.height));
  109.  
  110.         cwidget = widget->last_child;
  111.         while (cwidget != NULL) {
  112.                 fbtk_request_redraw(cwidget);
  113.                 cwidget = cwidget->prev;
  114.         }
  115.  
  116.         while (widget->parent != NULL) {
  117.                 widget = widget->parent;
  118.                 widget->redraw.child = true;
  119.         }
  120. }
  121.  
  122.  
  123.  
  124. /* exported function documented in fbtk.h */
  125. int
  126. fbtk_set_mapping(fbtk_widget_t *widget, bool map)
  127. {
  128.         LOG(("setting mapping on %p to %d", widget, map));
  129.         widget->mapped = map;
  130.         if (map) {
  131.                 fbtk_request_redraw(widget);
  132.         } else {
  133.                 fbtk_request_redraw(widget->parent);
  134.         }
  135.         return 0;
  136. }
  137.  
  138. /** swap the widget given with the next sibling.
  139.  *
  140.  * Swap a sibling widget with the next deepest in the hierachy
  141.  */
  142. static void
  143. swap_siblings(fbtk_widget_t *lw)
  144. {
  145.         fbtk_widget_t *rw; /* the widget to swap lw with */
  146.         fbtk_widget_t *before;
  147.         fbtk_widget_t *after;
  148.  
  149.         rw = lw->next;
  150.         LOG(("Swapping %p with %p", lw, rw));
  151.         before = lw->prev;
  152.         after = rw->next;
  153.  
  154.         if (before == NULL) {
  155.                 /* left widget is currently the first child */
  156.                 lw->parent->first_child = rw;
  157.         } else {
  158.                 before->next = rw;
  159.         }
  160.         rw->prev = before;
  161.         rw->next = lw;
  162.  
  163.         if (after == NULL) {
  164.                 /* right widget is currently the last child */
  165.                 rw->parent->last_child = lw;
  166.         } else {
  167.                 after->prev = lw;
  168.         }
  169.         lw->next = after;
  170.         lw->prev = rw;
  171. }
  172.  
  173.  
  174.  
  175. /* exported function documented in fbtk.h */
  176. int
  177. fbtk_set_zorder(fbtk_widget_t *widget, int z)
  178. {
  179.         while (z != 0) {
  180.                 if (z < 0) {
  181.                         if (widget->prev == NULL)
  182.                                 break; /* cannot go any shallower */
  183.  
  184.                         /* swap with previous entry */
  185.                         swap_siblings(widget->prev);
  186.  
  187.                         z++;
  188.                 } else {
  189.                         if (widget->next == NULL)
  190.                                 break; /* cannot go any deeper */
  191.  
  192.                         /* swap with subsequent entry */
  193.                         swap_siblings(widget);
  194.  
  195.                         z--;
  196.                 }
  197.         }
  198.  
  199.         return z;
  200. }
  201.  
  202.  
  203. /* exported function documented in fbtk.h */
  204. bool
  205. fbtk_set_pos_and_size(fbtk_widget_t *widget,
  206.                       int x, int y,
  207.                       int width, int height)
  208. {
  209.         if ((widget->x != x) ||
  210.             (widget->y != y) ||
  211.             (widget->width != width) ||
  212.             (widget->height != height)) {
  213.                 widget->x = x;
  214.                 widget->y = y;
  215.                 widget->width = width;
  216.                 widget->height = height;
  217.                 /* @todo This should limit the redrawn area to the sum
  218.                  * of the old and new widget dimensions, not redraw the lot.
  219.                  */
  220.                 fbtk_request_redraw(widget->parent);
  221.                 return true;
  222.         }
  223.         return false;
  224. }
  225.  
  226.  
  227. /* exported function docuemnted in fbtk.h */
  228. void
  229. fbtk_set_caret(fbtk_widget_t *widget, bool set,
  230.                 int x, int y, int height,
  231.                 void (*remove_caret)(fbtk_widget_t *widget))
  232. {
  233.         fbtk_widget_t *root;
  234.  
  235.         assert(widget != NULL);
  236.         root = fbtk_get_root_widget(widget);
  237.  
  238.         if (root->u.root.caret.owner != NULL &&
  239.                         root->u.root.caret.remove_cb != NULL)
  240.                 root->u.root.caret.remove_cb(widget);
  241.  
  242.         if (set) {
  243.                 assert(remove_caret != NULL);
  244.  
  245.                 root->u.root.caret.owner = widget;
  246.                 root->u.root.caret.x = x;
  247.                 root->u.root.caret.y = y;
  248.                 root->u.root.caret.height = height;
  249.                 root->u.root.caret.remove_cb = remove_caret;
  250.  
  251.         } else {
  252.                 root->u.root.caret.owner = NULL;
  253.                 root->u.root.caret.remove_cb = NULL;
  254.         }
  255. }
  256.  
  257. /* exported function documented in fbtk.h */
  258. int
  259. fbtk_destroy_widget(fbtk_widget_t *widget)
  260. {
  261.         fbtk_widget_t *parent;
  262.         int ret = 0;
  263.  
  264.         ret = fbtk_post_callback(widget, FBTK_CBT_DESTROY);
  265.  
  266.         while (widget->first_child != NULL) {
  267.                 fbtk_destroy_widget(widget->first_child);
  268.         }
  269.  
  270.         parent = widget->parent;
  271.         if (parent != NULL) {
  272.  
  273.                 /* unlink from siblings */
  274.                 if (widget->prev != NULL) {
  275.                         widget->prev->next = widget->next;
  276.                 } else {
  277.                         /* must be the first widget, unlink from parent */
  278.                         parent->first_child = widget->next;
  279.                 }
  280.                 if (widget->next != NULL) {
  281.                         widget->next->prev = widget->prev;
  282.                 } else {
  283.                         /* must be the last widget, unlink from parent */
  284.                         parent->last_child = widget->prev;
  285.                 }
  286.  
  287.                 free(widget);
  288.         }
  289.  
  290.         return ret;
  291. }
  292.  
  293. /* region coverage flags. */
  294. enum {
  295.         POINT_LEFTOF_REGION = 1,
  296.         POINT_RIGHTOF_REGION = 2,
  297.         POINT_ABOVE_REGION = 4,
  298.         POINT_BELOW_REGION = 8,
  299. };
  300.  
  301. /* Computes where a point lies in respect to an area. */
  302. #define REGION(x,y,cx1,cx2,cy1,cy2)                     \
  303.         (( (y) > (cy2) ? POINT_BELOW_REGION : 0) |      \
  304.          ( (y) < (cy1) ? POINT_ABOVE_REGION : 0) |      \
  305.          ( (x) > (cx2) ? POINT_RIGHTOF_REGION : 0) |    \
  306.          ( (x) < (cx1) ? POINT_LEFTOF_REGION : 0) )
  307.  
  308. /* swap two integers */
  309. #define SWAP(a, b) do { int t; t=(a); (a)=(b); (b)=t;  } while(0)
  310.  
  311. /* exported function documented in fbtk.h */
  312. bool
  313. fbtk_clip_rect(const bbox_t *  clip, bbox_t *  box)
  314. {
  315.         uint8_t region1;
  316.         uint8_t region2;
  317.  
  318.         /* ensure co-ordinates are in ascending order */
  319.         if (box->x1 < box->x0)
  320.                 SWAP(box->x0, box->x1);
  321.         if (box->y1 < box->y0)
  322.                 SWAP(box->y0, box->y1);
  323.  
  324.         region1 = REGION(box->x0, box->y0, clip->x0, clip->x1 - 1, clip->y0, clip->y1 - 1);
  325.         region2 = REGION(box->x1, box->y1, clip->x0, clip->x1 - 1, clip->y0, clip->y1 - 1);
  326.  
  327.         /* area lies entirely outside the clipping rectangle */
  328.         if ((region1 | region2) && (region1 & region2))
  329.                 return false;
  330.  
  331.         if (box->x0 < clip->x0)
  332.                 box->x0 = clip->x0;
  333.         if (box->x0 > clip->x1)
  334.                 box->x0 = clip->x1;
  335.  
  336.         if (box->x1 < clip->x0)
  337.                 box->x1 = clip->x0;
  338.         if (box->x1 > clip->x1)
  339.                 box->x1 = clip->x1;
  340.  
  341.         if (box->y0 < clip->y0)
  342.                 box->y0 = clip->y0;
  343.         if (box->y0 > clip->y1)
  344.                 box->y0 = clip->y1;
  345.  
  346.         if (box->y1 < clip->y0)
  347.                 box->y1 = clip->y0;
  348.         if (box->y1 > clip->y1)
  349.                 box->y1 = clip->y1;
  350.  
  351.         return true;
  352. }
  353.  
  354. /* exported function documented in fbtk.h */
  355. bool
  356. fbtk_clip_to_widget(fbtk_widget_t *widget, bbox_t *  box)
  357. {
  358.         bbox_t wbox;
  359.         wbox.x0 = 0;
  360.         wbox.y0 = 0;
  361.         wbox.x1 = widget->width;
  362.         wbox.y1 = widget->height;
  363.         return fbtk_clip_rect(&wbox, box);
  364. }
  365.  
  366.  
  367.  
  368. /* internally exported function documented in widget.h */
  369. int
  370. fbtk_set_ptr(fbtk_widget_t *widget, fbtk_callback_info *cbi)
  371. {
  372.         fbtk_widget_t *root = fbtk_get_root_widget(widget);
  373.         struct fbtk_bitmap *bm = cbi->context;
  374.  
  375.         nsfb_cursor_set(root->u.root.fb,
  376.                         (nsfb_colour_t *)bm->pixdata,
  377.                         bm->width,
  378.                         bm->height,
  379.                         bm->width,
  380.                         bm->hot_x,
  381.                         bm->hot_y);
  382.  
  383.         return 0;
  384. }
  385.  
  386.  
  387.  
  388. /* internally exported function documented in widget.h */
  389. fbtk_widget_t *
  390. fbtk_get_root_widget(fbtk_widget_t *widget)
  391. {
  392.         while (widget->parent != NULL)
  393.                 widget = widget->parent;
  394.  
  395.         /* check root widget was found */
  396.         if (widget->type != FB_WIDGET_TYPE_ROOT) {
  397.                 LOG(("Widget with null parent that is not the root widget!"));
  398.                 return NULL;
  399.         }
  400.  
  401.         return widget;
  402. }
  403.  
  404.  
  405. /* exported function documented in fbtk.h */
  406. int
  407. fbtk_get_absx(fbtk_widget_t *widget)
  408. {
  409.         int x = widget->x;
  410.  
  411.         while (widget->parent != NULL) {
  412.                 widget = widget->parent;
  413.                 x += widget->x;
  414.         }
  415.  
  416.         return x;
  417. }
  418.  
  419. /* exported function documented in fbtk.h */
  420. int
  421. fbtk_get_absy(fbtk_widget_t *widget)
  422. {
  423.         int y = widget->y;
  424.  
  425.         while (widget->parent != NULL) {
  426.                 widget = widget->parent;
  427.                 y += widget->y;
  428.         }
  429.  
  430.         return y;
  431. }
  432.  
  433. /* exported function documented in fbtk.h */
  434. int
  435. fbtk_get_height(fbtk_widget_t *widget)
  436. {
  437.         return widget->height;
  438. }
  439.  
  440. /* exported function documented in fbtk.h */
  441. int
  442. fbtk_get_width(fbtk_widget_t *widget)
  443. {
  444.         return widget->width;
  445. }
  446.  
  447. /* exported function documented in fbtk.h */
  448. bool
  449. fbtk_get_bbox(fbtk_widget_t *widget, nsfb_bbox_t *bbox)
  450. {
  451.         bbox->x0 = widget->x;
  452.         bbox->y0 = widget->y;
  453.         bbox->x1 = widget->x + widget->width;
  454.         bbox->y1 = widget->y + widget->height;
  455.  
  456.         widget = widget->parent;
  457.         while (widget != NULL) {
  458.                 bbox->x0 += widget->x;
  459.                 bbox->y0 += widget->y;
  460.                 bbox->x1 += widget->x;
  461.                 bbox->y1 += widget->y;
  462.                 widget = widget->parent;
  463.         }
  464.  
  465.         return true;
  466. }
  467.  
  468. bool
  469. fbtk_get_caret(fbtk_widget_t *widget, int *x, int *y, int *height)
  470. {
  471.         fbtk_widget_t *root = fbtk_get_root_widget(widget);
  472.  
  473.         if (root->u.root.caret.owner == widget) {
  474.                 *x = root->u.root.caret.x;
  475.                 *y = root->u.root.caret.y;
  476.                 *height = root->u.root.caret.height;
  477.  
  478.                 return true;
  479.  
  480.         } else {
  481.                 *x = 0;
  482.                 *y = 0;
  483.                 *height = 0;
  484.  
  485.                 return false;
  486.         }
  487. }
  488.  
  489. /* exported function documented in fbtk.h */
  490. fbtk_widget_t *
  491. fbtk_get_widget_at(fbtk_widget_t *nwid, int x, int y)
  492. {
  493.         fbtk_widget_t *widget = NULL; /* found widget */
  494.  
  495.         /* require the root widget to start */
  496.         nwid = fbtk_get_root_widget(nwid);
  497.  
  498.         while (nwid != NULL) {
  499.                 if ((nwid->mapped) &&
  500.                     (x >= nwid->x) &&
  501.                     (y >= nwid->y) &&
  502.                     (x < (nwid->x + nwid->width)) &&
  503.                     (y < (nwid->y + nwid->height))) {
  504.                         widget = nwid;
  505.                         x -= nwid->x;
  506.                         y -= nwid->y;
  507.                         nwid = nwid->first_child;
  508.                 } else {
  509.                         nwid = nwid->next;
  510.                 }
  511.         }
  512.  
  513.         return widget;
  514. }
  515.  
  516.  
  517.  
  518.  
  519. /* internally exported function documented in widget.h */
  520. fbtk_widget_t *
  521. fbtk_widget_new(fbtk_widget_t *parent,
  522.                 enum fbtk_widgettype_e type,
  523.                 int x,
  524.                 int y,
  525.                 int width,
  526.                 int height)
  527. {
  528.         LOG(("New widget..."));
  529.  
  530.         fbtk_widget_t *neww; /* new widget */
  531.  
  532.         if (parent == NULL)
  533.         {LOG(("parent null..."));
  534.                 return NULL;}
  535.  
  536.         LOG(("calloc..."));
  537.         neww = calloc(1, sizeof(fbtk_widget_t));
  538.         if (neww == NULL)
  539.                 return NULL;
  540.  
  541.         LOG(("super!..."));
  542.         LOG(("creating %p %d,%d %d,%d", neww, x, y, width, height));
  543.  
  544.         /* make new window fit inside parent */
  545.         if (width == 0) {
  546.                 width = parent->width - x;
  547.         } else if (width < 0) {
  548.                 width = parent->width + width - x;
  549.         }
  550.         if ((width + x) > parent->width) {
  551.                 width = parent->width - x;
  552.         }
  553.  
  554.         if (height == 0) {
  555.                 height = parent->height - y;
  556.         } else if (height < 0) {
  557.                 height = parent->height + height - y;
  558.         }
  559.         if ((height + y) > parent->height) {
  560.                 height = parent->height - y;
  561.         }
  562.  
  563.  
  564.         LOG(("using %p %d,%d %d,%d", neww, x, y, width, height));
  565.         /* set values */
  566.         neww->type = type;
  567.         neww->x = x;
  568.         neww->y = y;
  569.         neww->width = width;
  570.         neww->height = height;
  571.  
  572.         /* insert into widget heiarchy */
  573.  
  574.         LOG(("into hierarchy..."));
  575.         neww->parent = parent;
  576.  
  577.         if (parent->first_child == NULL) {
  578.                 /* no child widgets yet */
  579.                 LOG(("no childs yet..."));
  580.                 parent->last_child = neww;
  581.         } else {
  582.                 /* add new widget to front of sibling chain */
  583.                 neww->next = parent->first_child;
  584.                 neww->next->prev = neww;
  585.                 LOG(("n front of sibling..."));
  586.         }
  587.         parent->first_child = neww;
  588.  
  589.  
  590.         LOG(("Widget OK..."));
  591.         return neww;
  592. }
  593.  
  594. /* exported function documented in fbtk.h */
  595. bool
  596. fbtk_get_redraw_pending(fbtk_widget_t *widget)
  597. {
  598.         fbtk_widget_t *root;
  599.  
  600.         /* ensure we have the root widget */
  601.         root = fbtk_get_root_widget(widget);
  602.  
  603.         return root->redraw.needed | root->redraw.child;
  604. }
  605.  
  606. /** Perform a depth-first tree-walk, calling the redraw callback of the widgets in turn.
  607.  *
  608.  * This function makes no decisions of its own and simply walks the
  609.  * widget tree depth first calling widgets redraw callbacks if flagged
  610.  * to do so.
  611.  * The tree search is optimised with a flag to indicate wether the
  612.  * children of a node should be considered.
  613.  */
  614.  #include <menuet/os.h>
  615.  
  616. static int
  617. do_redraw(nsfb_t *nsfb, fbtk_widget_t *widget)
  618. {
  619.         nsfb_bbox_t plot_ctx;
  620.         fbtk_widget_t *cwidget; /* child widget */
  621.  
  622.  
  623.         LOG(("DO REDRAW"));
  624.         //__menuet__debug_out("\n***********\nDO REDRAW\n********\n");
  625.         /* check if the widget requires redrawing */
  626.         if (widget->redraw.needed == true) {
  627.                 plot_ctx.x0 = fbtk_get_absx(widget) + widget->redraw.x;
  628.                 plot_ctx.y0 = fbtk_get_absy(widget) + widget->redraw.y;
  629.                 plot_ctx.x1 = plot_ctx.x0 + widget->redraw.width;
  630.                 plot_ctx.y1 = plot_ctx.y0 + widget->redraw.height;
  631.  
  632.                 LOG(("clipping %p %d,%d %d,%d",
  633.                      widget, plot_ctx.x0, plot_ctx.y0,
  634.                      plot_ctx.x1, plot_ctx.y1));
  635.                 if (nsfb_plot_set_clip(nsfb, &plot_ctx) == true) {
  636.                        
  637.         LOG(("POST CALLBACK"));
  638.         //__menuet__debug_out("\n***********\nPOST CALLBACK\n********\n");
  639.                        
  640.                         fbtk_post_callback(widget, FBTK_CBT_REDRAW);
  641.                 }
  642.                 widget->redraw.needed = false;
  643.         }
  644.  
  645.        
  646.         LOG(("DO CHILD"));
  647.         //__menuet__debug_out("\n***********\nDO CHILD\n********\n");
  648.  
  649.         /* walk the widgets children if child flag is set */
  650.         if (widget->redraw.child) {
  651.                 LOG(("DO CHILD 2"));
  652.         //__menuet__debug_out("\n***********\nDO CHILD 2\n********\n");
  653.                 cwidget = widget->last_child;
  654.                 while (cwidget != NULL) {
  655.                                 LOG(("DO CHILD 3 ZZZ"));
  656.         //__menuet__debug_out("\n***********\nDO CHILD 3 ZZZ\n********\n");
  657.                         do_redraw(nsfb, cwidget);
  658.                         cwidget = cwidget->prev;
  659.                 }
  660.                         LOG(("DO CHILD 4"));
  661.         //__menuet__debug_out("\n***********\nDO CHILD 4\n********\n");
  662.                 widget->redraw.child = false;
  663.         }
  664.  
  665.  
  666.         LOG(("SUP"));
  667.         //__menuet__debug_out("\n***********\nFIN REDRAW\n********\n");
  668.  
  669.         return 1;
  670. }
  671.  
  672. /* exported function documented in fbtk.h */
  673. int
  674. fbtk_redraw(fbtk_widget_t *widget)
  675. {
  676.         fbtk_widget_t *root;
  677.  
  678.         /* ensure we have the root widget */
  679.         root = fbtk_get_root_widget(widget);
  680.  
  681.         return do_redraw(root->u.root.fb, root);
  682. }
  683.  
  684. /* exported function documented in fbtk.h */
  685. fbtk_callback
  686. fbtk_get_handler(fbtk_widget_t *widget, fbtk_callback_type cbt)
  687. {
  688.         if ((cbt <= FBTK_CBT_START) || (cbt >= FBTK_CBT_END)) {
  689.                 /* type out of range, no way to report error so return NULL */
  690.                 return NULL;
  691.         }
  692.  
  693.         return widget->callback[cbt];
  694. }
  695.  
  696. /* exported function documented in fbtk.h */
  697. fbtk_callback
  698. fbtk_set_handler(fbtk_widget_t *widget,
  699.                  fbtk_callback_type cbt,
  700.                  fbtk_callback cb,
  701.                  void *context)
  702. {
  703.         fbtk_callback prevcb;
  704.  
  705.         if ((cbt <= FBTK_CBT_START) || (cbt >= FBTK_CBT_END)) {
  706.                 /* type out of range, no way to report error so return NULL */
  707.                 return NULL;
  708.         }
  709.  
  710.         prevcb = widget->callback[cbt];
  711.  
  712.         widget->callback[cbt] = cb;
  713.         widget->callback_context[cbt] = context;
  714.  
  715.         return prevcb;
  716. }
  717.  
  718. /* exported function docuemnted in fbtk.h */
  719. int
  720. fbtk_post_callback(fbtk_widget_t *widget, fbtk_callback_type cbt, ...)
  721. {
  722.        
  723.         LOG(("DO POST CALLBACK"));
  724.         //__menuet__debug_out("\n***********\nDO POST CALLBACK\n********\n");
  725.        
  726.         fbtk_callback_info cbi;
  727.         int ret = 0;
  728.         va_list ap;
  729.  
  730.         if (widget == NULL)
  731.                 return -1;
  732.         /* if the widget is not mapped do not attempt to post any
  733.          * events to it
  734.          */
  735.         if (widget->mapped == false)
  736.                 return ret;
  737.  
  738.         LOG(("DO POST CALLBACK 2"));
  739.         //__menuet__debug_out("\n***********\nDO POST CALLBACK 2\n********\n");
  740.  
  741.         if (widget->callback[cbt] != NULL) {
  742.                 cbi.type = cbt;
  743.                 cbi.context = widget->callback_context[cbt];
  744.  
  745.         LOG(("DO POST CALLBACK 3 - VA"));
  746.         //__menuet__debug_out("\n***********\nDO POST CALLBACK 3 - VA\n********\n");
  747.        
  748.                 va_start(ap, cbt);
  749.  
  750.                 switch (cbt) {
  751.                 case FBTK_CBT_SCROLLX:
  752.                         //__menuet__debug_out("\n***********\n scroll x - VA\n********\n");
  753.                         cbi.x = va_arg(ap,int);
  754.                         break;
  755.  
  756.                 case FBTK_CBT_SCROLLY:
  757.                         //__menuet__debug_out("\n***********\n scroll y - VA\n********\n");
  758.                         cbi.y = va_arg(ap,int);
  759.                         break;
  760.  
  761.                 case FBTK_CBT_CLICK:
  762.                         //__menuet__debug_out("\n***********\n click - VA\n********\n");
  763.                         cbi.event = va_arg(ap, void *);
  764.                         cbi.x = va_arg(ap, int);
  765.                         cbi.y = va_arg(ap, int);
  766.                         break;
  767.  
  768.                 case FBTK_CBT_INPUT:
  769.                         //__menuet__debug_out("\n***********\n input - VA\n********\n");
  770.                         cbi.event = va_arg(ap, void *);
  771.                         break;
  772.  
  773.                 case FBTK_CBT_POINTERMOVE:
  774.                         //__menuet__debug_out("\n***********\n mouse move - VA\n********\n");
  775.                         cbi.x = va_arg(ap, int);
  776.                         cbi.y = va_arg(ap, int);
  777.                         break;
  778.  
  779.                 case FBTK_CBT_REDRAW:
  780.                 //__menuet__debug_out("\n***********\n red - VA\n********\n");
  781.                         break;
  782.  
  783.                 case FBTK_CBT_USER:
  784.                 //__menuet__debug_out("\n***********\n user - VA\n********\n");
  785.                         break;
  786.  
  787.                 case FBTK_CBT_STRIP_FOCUS:
  788.                 //__menuet__debug_out("\n***********\n focus - VA\n********\n");
  789.                         break;
  790.  
  791.                 default:
  792.                 //__menuet__debug_out("\n***********\n wtf - VA\n********\n");
  793.                         break;
  794.                 }
  795.                
  796.                 LOG(("DO POST CALLBACK free"));
  797.         //__menuet__debug_out("\n***********\nDO POST CALLBACK free\n********\n");
  798.                 va_end(ap);
  799.  
  800.                
  801.                 LOG(("DO CALLBACK YEAH"));
  802.         //__menuet__debug_out("\n***********\nWTF IS THIS\n********\n");
  803.         char zupa[64];
  804.        
  805.         sprintf (zupa, "ADDRESS of callback is %x \n",(widget->callback[cbt]));
  806.         //__menuet__debug_out(zupa);
  807.         LOG(("ADDRESS of callback is %x \n",(widget->callback[cbt])));
  808.        
  809.                 ret = (widget->callback[cbt])(widget, &cbi);
  810.                         LOG(("DO CALLBACK YEAH 2"));
  811.         //__menuet__debug_out("\n***********\nWTF IS THIS!!!12121\n********\n");
  812.         }
  813.  
  814. LOG(("DO POST CALLBACK OK"));
  815.         //__menuet__debug_out("\n***********\nDO POST CALLBACK OK\n********\n");
  816.         return ret;
  817. }
  818.  
  819. /* exported function docuemnted in fbtk.h */
  820. void
  821. fbtk_set_focus(fbtk_widget_t *widget)
  822. {
  823.         fbtk_widget_t *root;
  824.  
  825.         /* ensure we have the root widget */
  826.         root = fbtk_get_root_widget(widget);
  827.  
  828.         if (root->u.root.input != NULL &&
  829.                         root->u.root.input != widget) {
  830.                 /* inform previous holder of focus that it's being stripped
  831.                  * of focus */
  832.                 fbtk_post_callback(root->u.root.input, FBTK_CBT_STRIP_FOCUS);
  833.         }
  834.  
  835.         root->u.root.input = widget;
  836. }
  837.  
  838.  
  839.  
  840. /* exported function docuemnted in fbtk.h */
  841. nsfb_t *
  842. fbtk_get_nsfb(fbtk_widget_t *widget)
  843. {
  844.         fbtk_widget_t *root;
  845.  
  846.         /* ensure we have the root widget */
  847.         root = fbtk_get_root_widget(widget);
  848.  
  849.         return root->u.root.fb;
  850. }
  851.  
  852. /* exported function docuemnted in fbtk.h */
  853. fbtk_widget_t *
  854. fbtk_init(nsfb_t *fb)
  855. {
  856.         fbtk_widget_t *root;
  857.  
  858.         /* create and configure root widget */
  859.         root = calloc(1, sizeof(fbtk_widget_t));
  860.         if (root == NULL)
  861.                 return NULL;
  862.  
  863.         root->type = FB_WIDGET_TYPE_ROOT;
  864.         root->u.root.fb = fb;
  865.         root->u.root.caret.owner = NULL;
  866.  
  867.         nsfb_get_geometry(fb, &root->width, &root->height, NULL);
  868.  
  869.         root->mapped = true;
  870.  
  871.         return root;
  872. }
  873.  
  874. /*
  875.  * Local Variables:
  876.  * c-basic-offset:8
  877.  * End:
  878.  */
  879.