libnslog: branch master updated. 2fcc7c75ca46072af79de8ec78e966556206f038
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/libnslog.git/shortlog/2fcc7c75ca46072af79d...
...commit http://git.netsurf-browser.org/libnslog.git/commit/2fcc7c75ca46072af79de8...
...tree http://git.netsurf-browser.org/libnslog.git/tree/2fcc7c75ca46072af79de8ec...
The branch, master has been updated
via 2fcc7c75ca46072af79de8ec78e966556206f038 (commit)
from 73860cdc8625b4f8443cb8531019d6f57f8b59ce (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/libnslog.git/commit/?id=2fcc7c75ca46072af7...
commit 2fcc7c75ca46072af79de8ec78e966556206f038
Author: Daniel Silverstone <dsilvers(a)digital-scurf.org>
Commit: Daniel Silverstone <dsilvers(a)digital-scurf.org>
A commented example for the docs
diff --git a/docs/examples.md b/docs/examples.md
new file mode 100644
index 0000000..fbd6763
--- /dev/null
+++ b/docs/examples.md
@@ -0,0 +1,203 @@
+Example of libnslog in use
+==========================
+
+Since some people work better from an example, the following is an example of
+both a library using libnslog, and a client application using that library.
+
+The source is only inlined here, and not directly tested, but it should be
+moderately complete and thus functional. It was taken, in part, from the test
+suite so that you can be reasonably confident it works.
+
+The library
+===========
+
+First we need a public header:
+
+```{.c}
+ /* Example Library Header, include/libexample.h */
+
+ #ifndef LIBEXAMPLE_H
+ #define LIBEXAMPLE_H
+
+ #include "nslog/nslog.h"
+
+ /* All logging in libexample comes underneath this category */
+ NSLOG_DECLARE_CATEGORY(libexample);
+
+ /* This function does what the library does */
+ extern void example_do_stuff(void);
+
+ #endif
+```
+
+Next we need a private header, because libexample has some more categories...
+
+```{.c}
+ /* Example Library Header, src/hidden.h */
+
+ #ifndef LIBEXAMPLE__HIDDEN_H
+ #define LIBEXAMPLE__HIDDEN_H
+
+ #include "libexample.h"
+
+ /* When logging some stuff, we use this subcategory */
+ NSLOG_DECLARE_CATEGORY(interesting);
+
+ /* And when logging some other stuff, we use this subcategory */
+ NSLOG_DECLARE_CATEGORY(boring);
+
+ void libexample__hidden_func();
+
+ #endif
+```
+
+Finally let's have some libexample code:
+
+```{.c}
+ /* Example Library source, src/libexample.c */
+
+ #include "hidden.h"
+
+ /* First up, lets realise the main category */
+ NSLOG_DEFINE_CATEGORY(libexample, "The example library for nslog");
+
+ void example_do_stuff(void)
+ {
+ /* Despite not having realised the categories here, we can use them */
+ NSLOG(interesting, INFO, "Did you know? Categories can be realised anywhere!");
+ libexample__hidden_func();
+ /* We can also log with the main category, despite it having subs */
+ NSLOG(libexample, INFO, "All done, good bye %s", "Mr Bond");
+ }
+```
+
+And because functionality may be spread among files:
+
+```{.c}
+ /* Example Library source, src/hidden.c */
+
+ #include "hidden.h"
+
+ /* Lets define the subcategories, even though the main is elsewhere */
+ NSLOG_DEFINE_SUBCATEGORY(libexample, interesting, "Interesting things");
+ NSLOG_DEFINE_SUBCATEGORY(libexample, boring, "Boring stuff");
+
+ void libexample__hidden_func(void)
+ {
+ /* And here we can log with the main or sub categories at our leisure */
+ NSLOG(libexample, INFO, "Yay, top level stuff");
+ NSLOG(boring, DEBUG, "Boring debug number: %d", 18);
+ }
+```
+
+The above, compiled together with libnslog's headers, will result in a library.
+
+The client application
+======================
+
+Since it's easy enough to do, we'll show a client application in a single file.
+It ought to be well enough commented to be of use...
+
+```{.c}
+ /* Example client application, main.c */
+
+ /* We use nslog */
+ #include "nslog/nslog.h"
+
+ /* As the client, we only get to see the public API of our library */
+ #include "libexample.h"
+
+ /* And we're using printf and friends */
+ #include <stdio.h>
+ #include <stdarg.h>
+
+ /* All client applications *MUST* have a render function.
+ * Ours is deliberately obnoxious in order to make things clear.
+ */
+ static void
+ exampleapp__render_function(void *_ctx, nslog_entry_context_t *ctx,
+ const char *fmt, va_list args)
+ {
+ UNUSED(_ctx);
+ /* All the metadata about the log entry */
+ fprintf(stderr,
+ "EXAMPLE LOG MESSAGE:\n"
+ "Category name: %.*s\n",
+ "Category description: %s\n",
+ "Logging level: %s\n",
+ "Source location: %.*s (line %d function %.*s)\n",
+ ctx->category->namelen, ctx->category->name, ctx->category->description,
+ nslog_level_name(ctx->level),
+ ctx->filenamelen, ctx->filename, ctx->lineno, ctx->funcnamelen, ctx->funcname);
+ /* The log entry itself */
+ vfprintf(stderr, fmt, args);
+ /* Log entries aren't newline terminated, let's put a couple here for clarity */
+ fprintf(stderr, "\n\n");
+ }
+
+ /* All that's left is to cause code to run... */
+ int
+ main(int argc, char **argv)
+ {
+ UNUSED(argc);
+ UNUSED(argv);
+
+ /* One beauty of libnslog is that it allows logging before the client
+ * is nominally ready...
+ */
+ example_do_stuff();
+
+ /* To make the client ready, we need to register our callback */
+ if (nslog_set_render_callback(exampleapp__render_function, NULL) != NSLOG_NO_ERROR) {
+ fprintf(stderr, "Unable to set render callback\n");
+ return 1;
+ }
+
+ /* Next we can uncork the log. This causes all previously logged
+ * messages to make their way out of our render function
+ */
+ fprintf(stderr, "Before uncork...\n");
+ if (nslog_uncork() != NSLOG_NO_ERROR) {
+ fprintf(stderr, "Unable to uncork!\n");
+ return 2;
+ }
+ fprintf(stderr, "After uncork.\n");
+
+ /* And of course, we can log again... */
+ example_do_stuff();
+
+ /* We can set a filter, and since nslog knows all the categories, we
+ * are permitted to set filters on categories we can't directly access
+ * ourselves.
+ */
+ nslog_filter_t *filter;
+ if (nslog_filter_from_text("cat:libexample/interesting", &filter) != NSLOG_NO_ERROR) {
+ fprintf(stderr, "Giving up, unable to parse filter.\n");
+ return 3;
+ }
+
+ /* We need to set that filter as the active filter to engage it */
+ if (nslog_filter_set_active(filter, NULL) != NSLOG_NO_ERROR) {
+ fprintf(stderr, "Unable to set active filter, stopping.\n");
+ return 4;
+ }
+
+ /* We don't need to hold on to our filter handle any longer */
+ filter = nslog_filter_unref(filter);
+
+ /* This time, only "interesting" log messages come through */
+ example_do_stuff();
+
+ /* We can remove the filter... */
+ if (nslog_filter_set_active(NULL, NULL) != NSLOG_NO_ERROR) {
+ fprintf(stderr, "Unable to clear active filter, stopping.\n");
+ return 4;
+ }
+
+ /* Finally, all log messages come through once more */
+ example_do_stuff();
+
+ /* and we're done */
+ return 0;
+ }
+```
diff --git a/docs/mainpage.md b/docs/mainpage.md
index 1d29aee..d0ed00b 100644
--- a/docs/mainpage.md
+++ b/docs/mainpage.md
@@ -17,6 +17,8 @@ libraries can verify the log messages sent. If a library might produce a lot
of logging then it must implement a client in its test drivers or it might run
out of RAM while running tests.
+If you're not into prose, [here is a commented example](md_docs_examples.html).
+
How to log stuff
----------------
-----------------------------------------------------------------------
Summary of changes:
docs/examples.md | 203 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
docs/mainpage.md | 2 +
2 files changed, 205 insertions(+)
create mode 100644 docs/examples.md
diff --git a/docs/examples.md b/docs/examples.md
new file mode 100644
index 0000000..fbd6763
--- /dev/null
+++ b/docs/examples.md
@@ -0,0 +1,203 @@
+Example of libnslog in use
+==========================
+
+Since some people work better from an example, the following is an example of
+both a library using libnslog, and a client application using that library.
+
+The source is only inlined here, and not directly tested, but it should be
+moderately complete and thus functional. It was taken, in part, from the test
+suite so that you can be reasonably confident it works.
+
+The library
+===========
+
+First we need a public header:
+
+```{.c}
+ /* Example Library Header, include/libexample.h */
+
+ #ifndef LIBEXAMPLE_H
+ #define LIBEXAMPLE_H
+
+ #include "nslog/nslog.h"
+
+ /* All logging in libexample comes underneath this category */
+ NSLOG_DECLARE_CATEGORY(libexample);
+
+ /* This function does what the library does */
+ extern void example_do_stuff(void);
+
+ #endif
+```
+
+Next we need a private header, because libexample has some more categories...
+
+```{.c}
+ /* Example Library Header, src/hidden.h */
+
+ #ifndef LIBEXAMPLE__HIDDEN_H
+ #define LIBEXAMPLE__HIDDEN_H
+
+ #include "libexample.h"
+
+ /* When logging some stuff, we use this subcategory */
+ NSLOG_DECLARE_CATEGORY(interesting);
+
+ /* And when logging some other stuff, we use this subcategory */
+ NSLOG_DECLARE_CATEGORY(boring);
+
+ void libexample__hidden_func();
+
+ #endif
+```
+
+Finally let's have some libexample code:
+
+```{.c}
+ /* Example Library source, src/libexample.c */
+
+ #include "hidden.h"
+
+ /* First up, lets realise the main category */
+ NSLOG_DEFINE_CATEGORY(libexample, "The example library for nslog");
+
+ void example_do_stuff(void)
+ {
+ /* Despite not having realised the categories here, we can use them */
+ NSLOG(interesting, INFO, "Did you know? Categories can be realised anywhere!");
+ libexample__hidden_func();
+ /* We can also log with the main category, despite it having subs */
+ NSLOG(libexample, INFO, "All done, good bye %s", "Mr Bond");
+ }
+```
+
+And because functionality may be spread among files:
+
+```{.c}
+ /* Example Library source, src/hidden.c */
+
+ #include "hidden.h"
+
+ /* Lets define the subcategories, even though the main is elsewhere */
+ NSLOG_DEFINE_SUBCATEGORY(libexample, interesting, "Interesting things");
+ NSLOG_DEFINE_SUBCATEGORY(libexample, boring, "Boring stuff");
+
+ void libexample__hidden_func(void)
+ {
+ /* And here we can log with the main or sub categories at our leisure */
+ NSLOG(libexample, INFO, "Yay, top level stuff");
+ NSLOG(boring, DEBUG, "Boring debug number: %d", 18);
+ }
+```
+
+The above, compiled together with libnslog's headers, will result in a library.
+
+The client application
+======================
+
+Since it's easy enough to do, we'll show a client application in a single file.
+It ought to be well enough commented to be of use...
+
+```{.c}
+ /* Example client application, main.c */
+
+ /* We use nslog */
+ #include "nslog/nslog.h"
+
+ /* As the client, we only get to see the public API of our library */
+ #include "libexample.h"
+
+ /* And we're using printf and friends */
+ #include <stdio.h>
+ #include <stdarg.h>
+
+ /* All client applications *MUST* have a render function.
+ * Ours is deliberately obnoxious in order to make things clear.
+ */
+ static void
+ exampleapp__render_function(void *_ctx, nslog_entry_context_t *ctx,
+ const char *fmt, va_list args)
+ {
+ UNUSED(_ctx);
+ /* All the metadata about the log entry */
+ fprintf(stderr,
+ "EXAMPLE LOG MESSAGE:\n"
+ "Category name: %.*s\n",
+ "Category description: %s\n",
+ "Logging level: %s\n",
+ "Source location: %.*s (line %d function %.*s)\n",
+ ctx->category->namelen, ctx->category->name, ctx->category->description,
+ nslog_level_name(ctx->level),
+ ctx->filenamelen, ctx->filename, ctx->lineno, ctx->funcnamelen, ctx->funcname);
+ /* The log entry itself */
+ vfprintf(stderr, fmt, args);
+ /* Log entries aren't newline terminated, let's put a couple here for clarity */
+ fprintf(stderr, "\n\n");
+ }
+
+ /* All that's left is to cause code to run... */
+ int
+ main(int argc, char **argv)
+ {
+ UNUSED(argc);
+ UNUSED(argv);
+
+ /* One beauty of libnslog is that it allows logging before the client
+ * is nominally ready...
+ */
+ example_do_stuff();
+
+ /* To make the client ready, we need to register our callback */
+ if (nslog_set_render_callback(exampleapp__render_function, NULL) != NSLOG_NO_ERROR) {
+ fprintf(stderr, "Unable to set render callback\n");
+ return 1;
+ }
+
+ /* Next we can uncork the log. This causes all previously logged
+ * messages to make their way out of our render function
+ */
+ fprintf(stderr, "Before uncork...\n");
+ if (nslog_uncork() != NSLOG_NO_ERROR) {
+ fprintf(stderr, "Unable to uncork!\n");
+ return 2;
+ }
+ fprintf(stderr, "After uncork.\n");
+
+ /* And of course, we can log again... */
+ example_do_stuff();
+
+ /* We can set a filter, and since nslog knows all the categories, we
+ * are permitted to set filters on categories we can't directly access
+ * ourselves.
+ */
+ nslog_filter_t *filter;
+ if (nslog_filter_from_text("cat:libexample/interesting", &filter) != NSLOG_NO_ERROR) {
+ fprintf(stderr, "Giving up, unable to parse filter.\n");
+ return 3;
+ }
+
+ /* We need to set that filter as the active filter to engage it */
+ if (nslog_filter_set_active(filter, NULL) != NSLOG_NO_ERROR) {
+ fprintf(stderr, "Unable to set active filter, stopping.\n");
+ return 4;
+ }
+
+ /* We don't need to hold on to our filter handle any longer */
+ filter = nslog_filter_unref(filter);
+
+ /* This time, only "interesting" log messages come through */
+ example_do_stuff();
+
+ /* We can remove the filter... */
+ if (nslog_filter_set_active(NULL, NULL) != NSLOG_NO_ERROR) {
+ fprintf(stderr, "Unable to clear active filter, stopping.\n");
+ return 4;
+ }
+
+ /* Finally, all log messages come through once more */
+ example_do_stuff();
+
+ /* and we're done */
+ return 0;
+ }
+```
diff --git a/docs/mainpage.md b/docs/mainpage.md
index 1d29aee..d0ed00b 100644
--- a/docs/mainpage.md
+++ b/docs/mainpage.md
@@ -17,6 +17,8 @@ libraries can verify the log messages sent. If a library might produce a lot
of logging then it must implement a client in its test drivers or it might run
out of RAM while running tests.
+If you're not into prose, [here is a commented example](md_docs_examples.html).
+
How to log stuff
----------------
--
NetSurf Parametric Logging Library
5 years, 9 months
netsurf: branch master updated. release/3.6-491-g8c29c67
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/8c29c675c4301c90f5038...
...commit http://git.netsurf-browser.org/netsurf.git/commit/8c29c675c4301c90f5038a2...
...tree http://git.netsurf-browser.org/netsurf.git/tree/8c29c675c4301c90f5038a27a...
The branch, master has been updated
via 8c29c675c4301c90f5038a27aa31fa640f47e5aa (commit)
from a661fdf83bf63907a7a8ccc6d2ba0e67dd5ea902 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=8c29c675c4301c90f50...
commit 8c29c675c4301c90f5038a27aa31fa640f47e5aa
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
clean up atari treeview code, stop it including headers it does not need
diff --git a/frontends/atari/treeview.c b/frontends/atari/treeview.c
index a72d268..abc1fa7 100644
--- a/frontends/atari/treeview.c
+++ b/frontends/atari/treeview.c
@@ -16,21 +16,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <sys/types.h>
-#include <string.h>
-
#include "assert.h"
-#include "cflib.h"
-#include "netsurf/inttypes.h"
-#include "utils/nsoption.h"
#include "utils/log.h"
#include "utils/messages.h"
-#include "utils/utils.h"
-#include "netsurf/plotters.h"
-#include "netsurf/mouse.h"
+#include "netsurf/inttypes.h"
#include "netsurf/core_window.h"
-#include "desktop/treeview.h"
+#include "netsurf/plotters.h"
#include "atari/gui.h"
#include "atari/plot/plot.h"
@@ -40,29 +32,6 @@
#include "atari/res/netsurf.rsh"
-/**
- * Declare Core Window Callbacks:
- */
-
-nserror atari_treeview_invalidate_area(struct core_window *cw, const struct rect *r);
-void atari_treeview_update_size(struct core_window *cw, int width, int height);
-void atari_treeview_scroll_visible(struct core_window *cw,
- const struct rect *r);
-void atari_treeview_get_window_dimensions(struct core_window *cw,
- int *width, int *height);
- // TODO: implement drag status!
-void atari_treeview_drag_status(struct core_window *cw,
- core_window_drag_status ds);
-
-static struct core_window_callback_table cw_t = {
- .invalidate = atari_treeview_invalidate_area,
- .update_size = atari_treeview_update_size,
- .scroll_visible = atari_treeview_scroll_visible,
- .get_window_dimensions = atari_treeview_get_window_dimensions,
- .drag_status = atari_treeview_drag_status
-};
-
-
struct atari_treeview_window {
struct atari_treeview_window * prev_open;
struct atari_treeview_window * next_open;
@@ -80,23 +49,12 @@ struct atari_treeview_window {
static struct atari_treeview_window * treeviews_open;
-/* native GUI event handlers: */
-static void on_mbutton_event(struct core_window *cw, EVMULT_OUT *ev_out,
- short msg[8]);
-static void on_keybd_event(struct core_window *cw, EVMULT_OUT *ev_out,
- short msg[8]);
-static void on_redraw_event(struct core_window *cw, EVMULT_OUT *ev_out,
- short msg[8]);
-
-/* static utils: */
-//static void atari_treeview_dump_info(struct atari_treeview_window *tv, char *s);
-
/**
* Schedule a redraw of the treeview content
*
*/
-static void atari_treeview_redraw_grect_request(struct core_window *cw,
- GRECT *area)
+static void
+atari_treeview_redraw_grect_request(struct core_window *cw, GRECT *area)
{
struct atari_treeview_window *tv = (struct atari_treeview_window *)cw;
if (cw != NULL) {
@@ -114,264 +72,77 @@ static void atari_treeview_redraw_grect_request(struct core_window *cw,
int oldy1 = tv->rdw_area.g_y + tv->rdw_area.g_h;
tv->rdw_area.g_x = MIN(tv->rdw_area.g_x, area->g_x);
tv->rdw_area.g_y = MIN(tv->rdw_area.g_y, area->g_y);
- tv->rdw_area.g_w = ( oldx1 > newx1 ) ? oldx1 - tv->rdw_area.g_x : newx1 - tv->rdw_area.g_x;
- tv->rdw_area.g_h = ( oldy1 > newy1 ) ? oldy1 - tv->rdw_area.g_y : newy1 - tv->rdw_area.g_y;
- }
- //dbg_grect("atari_treeview_request_redraw_grect", &tv->rdw_area);
- }
-}
-
-
-void atari_treeview_get_grect(struct core_window *cw, enum treeview_area_e mode,
- GRECT *dest)
-{
- struct atari_treeview_window *tv = (struct atari_treeview_window *)cw;
+ if ( oldx1 > newx1 ) {
+ tv->rdw_area.g_w = oldx1 - tv->rdw_area.g_x;
+ } else {
+ tv->rdw_area.g_w = newx1 - tv->rdw_area.g_x;
+ }
- if (mode == TREEVIEW_AREA_CONTENT) {
- gemtk_wm_get_grect(tv->window, GEMTK_WM_AREA_CONTENT, dest);
- }
- else if (mode == TREEVIEW_AREA_TOOLBAR) {
- gemtk_wm_get_grect(tv->window, GEMTK_WM_AREA_TOOLBAR, dest);
+ if ( oldy1 > newy1 ) {
+ tv->rdw_area.g_h = oldy1 - tv->rdw_area.g_y;
+ } else {
+ tv->rdw_area.g_h = newy1 - tv->rdw_area.g_y;
+ }
+ }
+ //dbg_grect("atari_treeview_request_redraw_grect", &tv->rdw_area);
}
}
-GUIWIN * atari_treeview_get_gemtk_window(struct core_window *cw)
-{
- struct atari_treeview_window *tv = (struct atari_treeview_window *)cw;
- return(tv->window);
-}
-/*
-static void atari_treeview_dump_info(struct atari_treeview_window *tv,
- char * title)
+#ifdef ATARI_TREEVIEW_DUMP
+static void
+atari_treeview_dump_info(struct atari_treeview_window *tv, char * title)
{
printf("Treeview Dump (%s)\n", title);
printf("=================================\n");
gemtk_wm_dump_window_info(atari_treeview_get_gemtk_window((struct core_window *)tv));
GEMTK_DBG_GRECT("Redraw Area: \n", &tv->rdw_area)
- dbg_grect("Redraw Area2: \n", &tv->rdw_area);
+ dbg_grect("Redraw Area2: \n", &tv->rdw_area);
printf("Extent: x: %d, y: %d\n", tv->extent.x, tv->extent.y);
}
-*/
+#endif
-static bool atari_treeview_is_iconified(struct core_window *cw){
- struct atari_treeview_window *tv = (struct atari_treeview_window *)cw;
+static bool atari_treeview_is_iconified(struct core_window *cw)
+{
+ struct atari_treeview_window *tv = (struct atari_treeview_window *)cw;
- return((gemtk_wm_get_state(tv->window)&GEMTK_WM_STATUS_ICONIFIED) != 0);
+ return((gemtk_wm_get_state(tv->window)&GEMTK_WM_STATUS_ICONIFIED) != 0);
}
-static void atari_treeview_redraw_icon(struct core_window *cw, GRECT *clip)
-{
- struct atari_treeview_window *tv = (struct atari_treeview_window *)cw;
- GRECT visible, work;
- OBJECT * tree = gemtk_obj_get_tree(ICONIFY);
- short aesh = gemtk_wm_get_handle(tv->window);
-
- gemtk_wm_get_grect(tv->window, GEMTK_WM_AREA_WORK, &work);
-
- tree->ob_x = work.g_x;
- tree->ob_y = work.g_y;
- tree->ob_width = work.g_w;
- tree->ob_height = work.g_h;
-
- wind_get_grect(aesh, WF_FIRSTXYWH, &visible);
- while (visible.g_h > 0 && visible.g_w > 0) {
-
- if (rc_intersect(&work, &visible)) {
- objc_draw(tree, 0, 8, visible.g_x, visible.g_y, visible.g_w,
- visible.g_h);
- } else {
- //dbg_grect("redraw vis area outside", &visible);
- }
-
- wind_get_grect(aesh, WF_NEXTXYWH, &visible);
- }
-}
-void atari_treeview_redraw(struct core_window *cw)
+static void atari_treeview_redraw_icon(struct core_window *cw, GRECT *clip)
{
struct atari_treeview_window *tv = (struct atari_treeview_window *)cw;
- short pxy[4];
-
- if (tv != NULL && tv->is_open) {
- if( tv->redraw && ((plot_get_flags() & PLOT_FLAG_OFFSCREEN) == 0) ) {
-
- short todo[4];
- GRECT work;
- short handle = gemtk_wm_get_handle(tv->window);
- struct gemtk_wm_scroll_info_s *slid;
-
- gemtk_wm_get_grect(tv->window, GEMTK_WM_AREA_CONTENT, &work);
- slid = gemtk_wm_get_scroll_info(tv->window);
-
-// // Debug code: this 3 lines help to inspect the redraw
-// // areas...
-// pxy[0] = work.g_x;
-// pxy[1] = work.g_y;
-// pxy[2] = pxy[0] + work.g_w-1;
-// pxy[3] = pxy[1] + work.g_h-1;
-//
-// vsf_color(plot_get_vdi_handle(), 0);
-// v_bar(plot_get_vdi_handle(), (short*)&pxy);
-// evnt_timer(500);
-
- struct redraw_context ctx = {
- .interactive = true,
- .background_images = true,
- .plot = &atari_plotters
- };
- plot_set_dimensions(&ctx,
- work.g_x,
- work.g_y,
- work.g_w,
- work.g_h);
- if (plot_lock() == false)
- return;
-
- if( wind_get(handle, WF_FIRSTXYWH,
- &todo[0], &todo[1], &todo[2], &todo[3] )!=0 ) {
- while (todo[2] && todo[3]) {
-
- if(!rc_intersect(&work, (GRECT*)&todo)){
- if (wind_get(handle, WF_NEXTXYWH,
- &todo[0], &todo[1], &todo[2], &todo[3])==0) {
- break;
- }
- continue;
- }
- pxy[0] = todo[0];
- pxy[1] = todo[1];
- pxy[2] = todo[0] + todo[2]-1;
- pxy[3] = todo[1] + todo[3]-1;
- vs_clip(plot_get_vdi_handle(), 1, (short*)&pxy);
-
- // Debug code: this 3 lines help to inspect the redraw
- // areas...
-
-// vsf_color(plot_get_vdi_handle(), 3);
-// v_bar(plot_get_vdi_handle(), (short*)&pxy);
-// evnt_timer(500);
-
+ GRECT visible, work;
+ OBJECT * tree = gemtk_obj_get_tree(ICONIFY);
+ short aesh = gemtk_wm_get_handle(tv->window);
- /* convert screen to treeview coords: */
- todo[0] = todo[0] - work.g_x ;//+ slid->x_pos*slid->x_unit_px;
- todo[1] = todo[1] - work.g_y ;//+ slid->y_pos*slid->y_unit_px;
- if( todo[0] < 0 ){
- todo[2] = todo[2] + todo[0];
- todo[0] = 0;
- }
- if( todo[1] < 0 ){
- todo[3] = todo[3] + todo[1];
- todo[1] = 0;
- }
+ gemtk_wm_get_grect(tv->window, GEMTK_WM_AREA_WORK, &work);
- if (rc_intersect((GRECT *)&tv->rdw_area,(GRECT *)&todo)) {
- struct rect clip;
+ tree->ob_x = work.g_x;
+ tree->ob_y = work.g_y;
+ tree->ob_width = work.g_w;
+ tree->ob_height = work.g_h;
- clip.x0 = todo[0]+(slid->x_pos*slid->x_unit_px);
- clip.y0 = todo[1]+(slid->y_pos*slid->y_unit_px);
- clip.x1 = clip.x0 + todo[2]+(slid->x_pos*slid->x_unit_px);
- clip.y1 = clip.y0 + todo[3]+(slid->y_pos*slid->y_unit_px);
+ wind_get_grect(aesh, WF_FIRSTXYWH, &visible);
+ while (visible.g_h > 0 && visible.g_w > 0) {
- tv->io->draw(cw, -(slid->x_pos*slid->x_unit_px),
- -(slid->y_pos*slid->y_unit_px),
- &clip, &ctx);
- }
- vs_clip(plot_get_vdi_handle(), 0, (short*)&pxy);
- if (wind_get(handle, WF_NEXTXYWH,
- &todo[0], &todo[1], &todo[2], &todo[3])==0) {
- break;
- }
- }
- } else {
- plot_unlock();
- return;
- }
- plot_unlock();
- tv->redraw = false;
- tv->rdw_area.g_x = 65000;
- tv->rdw_area.g_y = 65000;
- tv->rdw_area.g_w = -1;
- tv->rdw_area.g_h = -1;
+ if (rc_intersect(&work, &visible)) {
+ objc_draw(tree, 0, 8, visible.g_x, visible.g_y, visible.g_w,
+ visible.g_h);
} else {
- /* just copy stuff from the offscreen buffer */
+ //dbg_grect("redraw vis area outside", &visible);
}
- }
-}
-
-
-/**
- * GEMTK (netsurf's GEM toolkit) event sink
- *
-*/
-static short handle_event(GUIWIN *win, EVMULT_OUT *ev_out, short msg[8])
-{
- short retval = 0;
- struct atari_treeview_window *tv = (struct atari_treeview_window *)
- gemtk_wm_get_user_data(win);
- struct core_window *cw = (struct core_window *)tv;
-
- if( (ev_out->emo_events & MU_MESAG) != 0 ) {
- // handle message
- switch (msg[0]) {
-
- case WM_REDRAW:
- on_redraw_event(cw, ev_out, msg);
- break;
-
- default:
- break;
- }
- }
- if( (ev_out->emo_events & MU_KEYBD) != 0 ) {
- on_keybd_event(cw, ev_out, msg);
- }
- if( (ev_out->emo_events & MU_BUTTON) != 0 ) {
- LOG("Treeview click at: %d,%d\n", ev_out->emo_mouse.p_x, ev_out->emo_mouse.p_y);
- on_mbutton_event(cw, ev_out, msg);
- }
-
- if(tv != NULL && tv->io->gemtk_user_func != NULL){
- tv->io->gemtk_user_func(win, ev_out, msg);
- }
-
- // TODO: evaluate return values of event handler functions and pass them on:
- return(retval);
-}
-
-static void __CDECL on_keybd_event(struct core_window *cw, EVMULT_OUT *ev_out,
- short msg[8])
-{
- long kstate = 0;
- long kcode = 0;
- long ucs4;
- long ik;
- unsigned short nkc = 0;
- unsigned char ascii;
- struct atari_treeview_window *tv = (struct atari_treeview_window *)cw;
-
- kstate = ev_out->emo_kmeta;
- kcode = ev_out->emo_kreturn;
- nkc= gem_to_norm( (short)kstate, (short)kcode );
- ascii = (nkc & 0xFF);
- ik = nkc_to_input_key(nkc, &ucs4);
-
- if (ik == 0) {
- if (ascii >= 9) {
- tv->io->keypress(cw, ucs4);
- }
- } else {
- tv->io->keypress(cw, ik);
+ wind_get_grect(aesh, WF_NEXTXYWH, &visible);
}
}
-static void __CDECL on_redraw_event(struct core_window *cw,
- EVMULT_OUT *ev_out,
- short msg[8])
+static void __CDECL
+on_redraw_event(struct core_window *cw, EVMULT_OUT *ev_out, short msg[8])
{
GRECT work, clip;
struct atari_treeview_window *tv = (struct atari_treeview_window *)cw;
@@ -428,9 +199,9 @@ static void __CDECL on_redraw_event(struct core_window *cw,
}
}
-static void __CDECL on_mbutton_event(struct core_window *cw,
- EVMULT_OUT *ev_out,
- short msg[8])
+
+static void __CDECL
+on_mbutton_event(struct core_window *cw, EVMULT_OUT *ev_out, short msg[8])
{
struct atari_treeview_window *tv = (struct atari_treeview_window *)cw;
struct gemtk_wm_scroll_info_s *slid;
@@ -447,26 +218,26 @@ static void __CDECL on_mbutton_event(struct core_window *cw,
/* mouse click relative origin: */
- short origin_rel_x = (mx-work.g_x) +
- (slid->x_pos*slid->x_unit_px);
- short origin_rel_y = (my-work.g_y) +
- (slid->y_pos*slid->y_unit_px);
+ short origin_rel_x = (mx-work.g_x) + (slid->x_pos*slid->x_unit_px);
+ short origin_rel_y = (my-work.g_y) + (slid->y_pos*slid->y_unit_px);
/* Only pass on events in the content area: */
- if( origin_rel_x >= 0 && origin_rel_y >= 0
- && mx < work.g_x + work.g_w
- && my < work.g_y + work.g_h )
- {
+ if ((origin_rel_x >= 0) &&
+ (origin_rel_y >= 0) &&
+ (mx < work.g_x + work.g_w) &&
+ (my < work.g_y + work.g_h)) {
if (ev_out->emo_mclicks == 2) {
tv->io->mouse_action(cw,
- BROWSER_MOUSE_CLICK_1|BROWSER_MOUSE_DOUBLE_CLICK,
- origin_rel_x, origin_rel_y);
+ BROWSER_MOUSE_CLICK_1 |
+ BROWSER_MOUSE_DOUBLE_CLICK,
+ origin_rel_x,
+ origin_rel_y);
return;
}
graf_mkstate(&cur_rel_x, &cur_rel_y, &mbut, &dummy);
/* check for click or hold: */
- if( (mbut&1) == 0 ){
+ if ((mbut & 1) == 0 ) {
int bms;
bms = BROWSER_MOUSE_CLICK_1 | BROWSER_MOUSE_PRESS_1;
if(ev_out->emo_mclicks == 2 ) {
@@ -486,174 +257,126 @@ static void __CDECL on_mbutton_event(struct core_window *cw,
tv->startdrag.x = origin_rel_x;
tv->startdrag.y = origin_rel_y;
/* First, report mouse press, to trigger entry selection */
- tv->io->mouse_action(cw, BROWSER_MOUSE_CLICK_1 | BROWSER_MOUSE_PRESS_1, cur_rel_x,
- cur_rel_y);
+ tv->io->mouse_action(cw,
+ BROWSER_MOUSE_CLICK_1 |
+ BROWSER_MOUSE_PRESS_1,
+ cur_rel_x,
+ cur_rel_y);
atari_treeview_redraw(cw);
- tv->io->mouse_action(cw, BROWSER_MOUSE_DRAG_1 | BROWSER_MOUSE_DRAG_ON,
- cur_rel_x, cur_rel_y);
- do{
- if (abs(prev_x-cur_rel_x) > 5 || abs(prev_y-cur_rel_y) > 5) {
+ tv->io->mouse_action(cw,
+ BROWSER_MOUSE_DRAG_1 |
+ BROWSER_MOUSE_DRAG_ON,
+ cur_rel_x,
+ cur_rel_y);
+ do {
+ if (abs(prev_x-cur_rel_x) > 5 ||
+ abs(prev_y-cur_rel_y) > 5) {
tv->io->mouse_action(cw,
- BROWSER_MOUSE_HOLDING_1 | BROWSER_MOUSE_DRAG_ON,
- cur_rel_x, cur_rel_y);
+ BROWSER_MOUSE_HOLDING_1 |
+ BROWSER_MOUSE_DRAG_ON,
+ cur_rel_x,
+ cur_rel_y);
prev_x = cur_rel_x;
prev_y = cur_rel_y;
}
if (tv->redraw) {
// TODO: maybe GUI poll would fit better here?
- // ... is gui_poll re-entrance save?
+ // ... is gui_poll re-entrance save?
atari_treeview_redraw(cw);
}
/* sample mouse button state: */
- graf_mkstate(&cur_rel_x, &cur_rel_y, &mbut, &dummy);
- cur_rel_x = (cur_rel_x-work.g_x)+(slid->x_pos*slid->x_unit_px);
- cur_rel_y = (cur_rel_y-work.g_y)+(slid->y_pos*slid->y_unit_px);
- } while( mbut & 1 );
+ graf_mkstate(&cur_rel_x,
+ &cur_rel_y,
+ &mbut,
+ &dummy);
+ cur_rel_x = (cur_rel_x-work.g_x) +
+ (slid->x_pos*slid->x_unit_px);
+ cur_rel_y = (cur_rel_y-work.g_y) +
+ (slid->y_pos*slid->y_unit_px);
+ } while (mbut & 1);
/* End drag: */
- tv->io->mouse_action(cw, BROWSER_MOUSE_HOVER, cur_rel_x, cur_rel_y);
+ tv->io->mouse_action(cw,
+ BROWSER_MOUSE_HOVER,
+ cur_rel_x,
+ cur_rel_y);
gem_set_cursor(&gem_cursors.arrow);
}
}
}
-struct core_window *
-atari_treeview_create(GUIWIN *win, struct atari_treeview_callbacks * callbacks,
- void * user_data, uint32_t flags)
+static void __CDECL
+on_keybd_event(struct core_window *cw, EVMULT_OUT *ev_out, short msg[8])
{
+ long kstate = 0;
+ long kcode = 0;
+ long ucs4;
+ long ik;
+ unsigned short nkc = 0;
+ unsigned char ascii;
+ struct atari_treeview_window *tv = (struct atari_treeview_window *)cw;
- /* allocate the core_window struct: */
- struct atari_treeview_window * tv;
- struct gemtk_wm_scroll_info_s *slid;
+ kstate = ev_out->emo_kmeta;
+ kcode = ev_out->emo_kreturn;
+ nkc= gem_to_norm( (short)kstate, (short)kcode );
+ ascii = (nkc & 0xFF);
+ ik = nkc_to_input_key(nkc, &ucs4);
- tv = calloc(1, sizeof(struct atari_treeview_window));
- if (tv == NULL) {
- LOG("calloc failed");
- atari_warn_user(messages_get_errorcode(NSERROR_NOMEM), 0);
- return NULL;
+ if (ik == 0) {
+ if (ascii >= 9) {
+ tv->io->keypress(cw, ucs4);
+ }
+ } else {
+ tv->io->keypress(cw, ik);
}
+}
- /* Store the window ref inside the new treeview: */
- tv->window = win;
- tv->io = callbacks;
- tv->user_data = user_data;
-
- // Setup gemtk event handler function:
- gemtk_wm_set_event_handler(win, handle_event);
- // bind window user data to treeview ref:
- gemtk_wm_set_user_data(win, (void*)tv);
+/**
+ * GEMTK (netsurf's GEM toolkit) event sink
+ *
+ */
+static short handle_event(GUIWIN *win, EVMULT_OUT *ev_out, short msg[8])
+{
+ short retval = 0;
+ struct atari_treeview_window *tv = (struct atari_treeview_window *)
+ gemtk_wm_get_user_data(win);
+ struct core_window *cw = (struct core_window *)tv;
- // Get acces to the gemtk scroll info struct:
- slid = gemtk_wm_get_scroll_info(tv->window);
+ if( (ev_out->emo_events & MU_MESAG) != 0 ) {
+ // handle message
+ switch (msg[0]) {
- // Setup line and column height/width of the window,
- // each scroll takes the configured steps:
- slid->y_unit_px = 16;
- slid->x_unit_px = 16;
+ case WM_REDRAW:
+ on_redraw_event(cw, ev_out, msg);
+ break;
- assert(tv->io);
- assert(tv->io->init_phase2);
+ default:
+ break;
+ }
+ }
+ if ((ev_out->emo_events & MU_KEYBD) != 0 ) {
+ on_keybd_event(cw, ev_out, msg);
+ }
+ if ((ev_out->emo_events & MU_BUTTON) != 0 ) {
+ LOG("Treeview click at: %d,%d\n",
+ ev_out->emo_mouse.p_x, ev_out->emo_mouse.p_y);
+ on_mbutton_event(cw, ev_out, msg);
+ }
- /* Now that the window is configured for treeview content, */
- /* call init_phase2 which must create the treeview */
- /* descriptor, and at least setup the the default */
- /* event handlers of the treeview: */
- /* It would be more simple to not pass around the callbacks */
- /* but the treeview constructor requires them for initialization... */
- nserror err = tv->io->init_phase2((struct core_window *)tv, &cw_t);
- if (err != NSERROR_OK) {
- free(tv);
- tv = NULL;
+ if (tv != NULL && tv->io->gemtk_user_func != NULL){
+ tv->io->gemtk_user_func(win, ev_out, msg);
}
- return((struct core_window *)tv);
-}
-
-void atari_treeview_delete(struct core_window * cw)
-{
- struct atari_treeview_window *tv = (struct atari_treeview_window*)cw;
-
- assert(tv);
- assert(tv->io->finish);
-
- tv->io->finish(cw);
-
- free(tv);
-}
-
-
-void atari_treeview_open(struct core_window *cw, GRECT *pos)
-{
- struct atari_treeview_window *tv = (struct atari_treeview_window*)cw;
- if (tv->window != NULL && tv->is_open == false) {
- tv->is_open = true;
- wind_open_grect(gemtk_wm_get_handle(tv->window), pos);
- gemtk_wm_link(tv->window);
- if (treeviews_open == NULL) {
- treeviews_open = tv;
- treeviews_open->next_open = NULL;
- treeviews_open->prev_open = NULL;
- } else {
- struct atari_treeview_window * tmp;
- tmp = treeviews_open;
- while(tmp->next_open != NULL){
- tmp = tmp->next_open;
- }
- tmp->next_open = tv;
- tv->prev_open = tmp;
- tv->next_open = NULL;
- }
- }
-}
-
-bool atari_treeview_is_open(struct core_window *cw)
-{
- struct atari_treeview_window *tv = (struct atari_treeview_window*)cw;
- return(tv->is_open);
-}
-
-void atari_treeview_set_user_data(struct core_window * cw,
- void *user_data_ptr)
-{
- struct atari_treeview_window *tv = (struct atari_treeview_window*)cw;
- tv->user_data = user_data_ptr;
-}
-
-void * atari_treeview_get_user_data(struct core_window * cw)
-{
- struct atari_treeview_window *tv = (struct atari_treeview_window*)cw;
- return(tv->user_data);
-}
-
-void atari_treeview_close(struct core_window *cw)
-{
- struct atari_treeview_window *tv = (struct atari_treeview_window*)cw;
- if (tv->window != NULL) {
- tv->is_open = false;
- wind_close(gemtk_wm_get_handle(tv->window));
- gemtk_wm_unlink(tv->window);
- /* unlink the window: */
- if (tv->prev_open != NULL) {
- tv->prev_open->next_open = tv->next_open;
- } else {
- treeviews_open = tv->next_open;
- }
- if (tv->next_open != NULL) {
- tv->next_open->prev_open = tv->prev_open;
- }
- }
+ // TODO: evaluate return values of event handler functions and pass them on:
+ return(retval);
}
/**
- * Core Window Callbacks:
- */
-
-/**
* callback from core to request an invalidation of a window area.
*
* The specified area of the window should now be considered
@@ -664,7 +387,9 @@ void atari_treeview_close(struct core_window *cw)
* \param[in] r area to redraw or NULL for the entire window area.
* \return NSERROR_OK on success or appropriate error code.
*/
-nserror atari_treeview_invalidate_area(struct core_window *cw, const struct rect *r)
+static nserror
+atari_treeview_invalidate_area(struct core_window *cw,
+ const struct rect *r)
{
GRECT area;
struct gemtk_wm_scroll_info_s * slid;
@@ -693,6 +418,7 @@ nserror atari_treeview_invalidate_area(struct core_window *cw, const struct rect
return NSERROR_OK;
}
+
/**
* Update the limits of the window
*
@@ -700,7 +426,8 @@ nserror atari_treeview_invalidate_area(struct core_window *cw, const struct rect
* \param width the width in px, or negative if don't care
* \param height the height in px, or negative if don't care
*/
-void atari_treeview_update_size(struct core_window *cw, int width, int height)
+static void
+atari_treeview_update_size(struct core_window *cw, int width, int height)
{
GRECT area;
struct gemtk_wm_scroll_info_s *slid;
@@ -732,8 +459,10 @@ void atari_treeview_update_size(struct core_window *cw, int width, int height)
tv->extent.y = height;
- /*printf("units content: %d, units viewport: %d\n", (height/slid->y_unit_px),
- (area.g_h/slid->y_unit_px));*/
+ /* printf("units content: %d, units viewport: %d\n",
+ (height/slid->y_unit_px),
+ (area.g_h/slid->y_unit_px));
+ */
gemtk_wm_update_slider(tv->window, GEMTK_WM_VH_SLIDER);
}
}
@@ -745,10 +474,11 @@ void atari_treeview_update_size(struct core_window *cw, int width, int height)
* \param cw the core window object
* \param r rectangle to make visible
*/
-void atari_treeview_scroll_visible(struct core_window *cw, const struct rect *r)
+static void
+atari_treeview_scroll_visible(struct core_window *cw, const struct rect *r)
{
/* atari frontend doesn't support dragging outside the treeview */
- /* so there is no need to implement this? */
+ /* so there is no need to implement this? */
}
@@ -759,10 +489,13 @@ void atari_treeview_scroll_visible(struct core_window *cw, const struct rect *r)
* \param width to be set to viewport width in px, if non NULL
* \param height to be set to viewport height in px, if non NULL
*/
-void atari_treeview_get_window_dimensions(struct core_window *cw,
- int *width, int *height)
+static void
+atari_treeview_get_window_dimensions(struct core_window *cw,
+ int *width,
+ int *height)
{
- if (cw != NULL && (width != NULL || height != NULL)) {
+ if ((cw != NULL) &&
+ (width != NULL || height != NULL)) {
GRECT work;
atari_treeview_get_grect(cw, TREEVIEW_AREA_CONTENT, &work);
*width = work.g_w;
@@ -777,33 +510,322 @@ void atari_treeview_get_window_dimensions(struct core_window *cw,
* \param cw the core window object
* \param ds the current drag status
*/
-void atari_treeview_drag_status(struct core_window *cw,
- core_window_drag_status ds)
+static void
+atari_treeview_drag_status(struct core_window *cw, core_window_drag_status ds)
+{
+
+}
+
+
+/**
+ * Declare Core Window Callbacks:
+ */
+static struct core_window_callback_table cw_t = {
+ .invalidate = atari_treeview_invalidate_area,
+ .update_size = atari_treeview_update_size,
+ .scroll_visible = atari_treeview_scroll_visible,
+ .get_window_dimensions = atari_treeview_get_window_dimensions,
+ .drag_status = atari_treeview_drag_status
+};
+
+
+/* exported interface documented in atari/treeview.h */
+struct core_window *
+atari_treeview_create(GUIWIN *win, struct atari_treeview_callbacks * callbacks,
+ void * user_data, uint32_t flags)
+{
+
+ /* allocate the core_window struct: */
+ struct atari_treeview_window * tv;
+ struct gemtk_wm_scroll_info_s *slid;
+
+ tv = calloc(1, sizeof(struct atari_treeview_window));
+ if (tv == NULL) {
+ LOG("calloc failed");
+ atari_warn_user(messages_get_errorcode(NSERROR_NOMEM), 0);
+ return NULL;
+ }
+
+ /* Store the window ref inside the new treeview: */
+ tv->window = win;
+ tv->io = callbacks;
+ tv->user_data = user_data;
+
+ // Setup gemtk event handler function:
+ gemtk_wm_set_event_handler(win, handle_event);
+
+ // bind window user data to treeview ref:
+ gemtk_wm_set_user_data(win, (void*)tv);
+
+ // Get acces to the gemtk scroll info struct:
+ slid = gemtk_wm_get_scroll_info(tv->window);
+
+ // Setup line and column height/width of the window,
+ // each scroll takes the configured steps:
+ slid->y_unit_px = 16;
+ slid->x_unit_px = 16;
+
+ assert(tv->io);
+ assert(tv->io->init_phase2);
+
+ /* Now that the window is configured for treeview content, */
+ /* call init_phase2 which must create the treeview */
+ /* descriptor, and at least setup the the default */
+ /* event handlers of the treeview: */
+ /* It would be more simple to not pass around the callbacks */
+ /* but the treeview constructor requires them for initialization... */
+ nserror err = tv->io->init_phase2((struct core_window *)tv, &cw_t);
+ if (err != NSERROR_OK) {
+ free(tv);
+ tv = NULL;
+ }
+
+ return((struct core_window *)tv);
+}
+
+
+/* exported interface documented in atari/treeview.h */
+void
+atari_treeview_get_grect(struct core_window *cw,
+ enum treeview_area_e mode,
+ GRECT *dest)
+{
+
+ struct atari_treeview_window *tv = (struct atari_treeview_window *)cw;
+
+ if (mode == TREEVIEW_AREA_CONTENT) {
+ gemtk_wm_get_grect(tv->window, GEMTK_WM_AREA_CONTENT, dest);
+ }
+ else if (mode == TREEVIEW_AREA_TOOLBAR) {
+ gemtk_wm_get_grect(tv->window, GEMTK_WM_AREA_TOOLBAR, dest);
+ }
+}
+
+
+/* exported interface documented in atari/treeview.h */
+GUIWIN * atari_treeview_get_gemtk_window(struct core_window *cw)
+{
+ struct atari_treeview_window *tv = (struct atari_treeview_window *)cw;
+ return(tv->window);
+}
+
+
+/* exported interface documented in atari/treeview.h */
+void atari_treeview_redraw(struct core_window *cw)
+{
+ struct atari_treeview_window *tv = (struct atari_treeview_window *)cw;
+ short pxy[4];
+
+ if (tv != NULL && tv->is_open) {
+ if( tv->redraw && ((plot_get_flags() & PLOT_FLAG_OFFSCREEN) == 0) ) {
+
+ short todo[4];
+ GRECT work;
+ short handle = gemtk_wm_get_handle(tv->window);
+ struct gemtk_wm_scroll_info_s *slid;
+
+ gemtk_wm_get_grect(tv->window, GEMTK_WM_AREA_CONTENT, &work);
+ slid = gemtk_wm_get_scroll_info(tv->window);
+
+// // Debug code: this 3 lines help to inspect the redraw
+// // areas...
+// pxy[0] = work.g_x;
+// pxy[1] = work.g_y;
+// pxy[2] = pxy[0] + work.g_w-1;
+// pxy[3] = pxy[1] + work.g_h-1;
+//
+// vsf_color(plot_get_vdi_handle(), 0);
+// v_bar(plot_get_vdi_handle(), (short*)&pxy);
+// evnt_timer(500);
+
+ struct redraw_context ctx = {
+ .interactive = true,
+ .background_images = true,
+ .plot = &atari_plotters
+ };
+ plot_set_dimensions(&ctx,
+ work.g_x,
+ work.g_y,
+ work.g_w,
+ work.g_h);
+ if (plot_lock() == false)
+ return;
+
+ if( wind_get(handle, WF_FIRSTXYWH,
+ &todo[0], &todo[1], &todo[2], &todo[3] )!=0 ) {
+ while (todo[2] && todo[3]) {
+
+ if(!rc_intersect(&work, (GRECT*)&todo)){
+ if (wind_get(handle, WF_NEXTXYWH,
+ &todo[0], &todo[1], &todo[2], &todo[3])==0) {
+ break;
+ }
+ continue;
+ }
+ pxy[0] = todo[0];
+ pxy[1] = todo[1];
+ pxy[2] = todo[0] + todo[2]-1;
+ pxy[3] = todo[1] + todo[3]-1;
+ vs_clip(plot_get_vdi_handle(), 1, (short*)&pxy);
+
+ // Debug code: this 3 lines help to inspect the redraw
+ // areas...
+
+// vsf_color(plot_get_vdi_handle(), 3);
+// v_bar(plot_get_vdi_handle(), (short*)&pxy);
+// evnt_timer(500);
+
+
+ /* convert screen to treeview coords: */
+ todo[0] = todo[0] - work.g_x ;//+ slid->x_pos*slid->x_unit_px;
+ todo[1] = todo[1] - work.g_y ;//+ slid->y_pos*slid->y_unit_px;
+ if( todo[0] < 0 ){
+ todo[2] = todo[2] + todo[0];
+ todo[0] = 0;
+ }
+ if( todo[1] < 0 ){
+ todo[3] = todo[3] + todo[1];
+ todo[1] = 0;
+ }
+
+ if (rc_intersect((GRECT *)&tv->rdw_area,(GRECT *)&todo)) {
+ struct rect clip;
+
+ clip.x0 = todo[0]+(slid->x_pos*slid->x_unit_px);
+ clip.y0 = todo[1]+(slid->y_pos*slid->y_unit_px);
+ clip.x1 = clip.x0 + todo[2]+(slid->x_pos*slid->x_unit_px);
+ clip.y1 = clip.y0 + todo[3]+(slid->y_pos*slid->y_unit_px);
+
+ tv->io->draw(cw, -(slid->x_pos*slid->x_unit_px),
+ -(slid->y_pos*slid->y_unit_px),
+ &clip, &ctx);
+ }
+ vs_clip(plot_get_vdi_handle(), 0, (short*)&pxy);
+ if (wind_get(handle, WF_NEXTXYWH,
+ &todo[0], &todo[1], &todo[2], &todo[3])==0) {
+ break;
+ }
+ }
+ } else {
+ plot_unlock();
+ return;
+ }
+ plot_unlock();
+ tv->redraw = false;
+ tv->rdw_area.g_x = 65000;
+ tv->rdw_area.g_y = 65000;
+ tv->rdw_area.g_w = -1;
+ tv->rdw_area.g_h = -1;
+ } else {
+ /* just copy stuff from the offscreen buffer */
+ }
+ }
+}
+
+
+/* exported interface documented in atari/treeview.h */
+void atari_treeview_delete(struct core_window * cw)
+{
+ struct atari_treeview_window *tv = (struct atari_treeview_window*)cw;
+
+ assert(tv);
+ assert(tv->io->finish);
+
+ tv->io->finish(cw);
+
+ free(tv);
+}
+
+
+/* exported interface documented in atari/treeview.h */
+void atari_treeview_open(struct core_window *cw, GRECT *pos)
+{
+ struct atari_treeview_window *tv = (struct atari_treeview_window*)cw;
+ if (tv->window != NULL && tv->is_open == false) {
+ tv->is_open = true;
+ wind_open_grect(gemtk_wm_get_handle(tv->window), pos);
+ gemtk_wm_link(tv->window);
+ if (treeviews_open == NULL) {
+ treeviews_open = tv;
+ treeviews_open->next_open = NULL;
+ treeviews_open->prev_open = NULL;
+ } else {
+ struct atari_treeview_window * tmp;
+ tmp = treeviews_open;
+ while(tmp->next_open != NULL){
+ tmp = tmp->next_open;
+ }
+ tmp->next_open = tv;
+ tv->prev_open = tmp;
+ tv->next_open = NULL;
+ }
+ }
+}
+
+
+/* exported interface documented in atari/treeview.h */
+bool atari_treeview_is_open(struct core_window *cw)
{
+ struct atari_treeview_window *tv = (struct atari_treeview_window*)cw;
+ return(tv->is_open);
+}
+
+
+/* exported interface documented in atari/treeview.h */
+void atari_treeview_set_user_data(struct core_window *cw, void *user_data_ptr)
+{
+ struct atari_treeview_window *tv = (struct atari_treeview_window*)cw;
+ tv->user_data = user_data_ptr;
+}
+
+
+/* exported interface documented in atari/treeview.h */
+void * atari_treeview_get_user_data(struct core_window * cw)
+{
+ struct atari_treeview_window *tv = (struct atari_treeview_window*)cw;
+ return(tv->user_data);
+}
+
+/* exported interface documented in atari/treeview.h */
+void atari_treeview_close(struct core_window *cw)
+{
+ struct atari_treeview_window *tv = (struct atari_treeview_window*)cw;
+ if (tv->window != NULL) {
+ tv->is_open = false;
+ wind_close(gemtk_wm_get_handle(tv->window));
+ gemtk_wm_unlink(tv->window);
+ /* unlink the window: */
+ if (tv->prev_open != NULL) {
+ tv->prev_open->next_open = tv->next_open;
+ } else {
+ treeviews_open = tv->next_open;
+ }
+ if (tv->next_open != NULL) {
+ tv->next_open->prev_open = tv->prev_open;
+ }
+ }
}
+
+/* exported interface documented in atari/treeview.h */
void atari_treeview_flush_redraws(void)
{
struct atari_treeview_window *tmp;
tmp = treeviews_open;
- if(tmp){
- while(tmp){
- assert(tmp->is_open);
- if(tmp->redraw){
- if (atari_treeview_is_iconified((struct core_window *)tmp)) {
- /* No content redraw for iconified windows */
- /* because otherwise the icon draw function would */
- /* have to deal with plot canvas coords */
- continue;
- }
-
- atari_treeview_redraw((struct core_window *)tmp);
- }
- tmp = tmp->next_open;
+ while (tmp != NULL) {
+ assert(tmp->is_open);
+ if (tmp->redraw &&
+ (!atari_treeview_is_iconified((struct core_window *)tmp))) {
+ /* Content redraw only for iconified windows
+ * because otherwise the icon draw function
+ * would have to deal with plot canvas coords
+ */
+ atari_treeview_redraw((struct core_window *)tmp);
}
+ tmp = tmp->next_open;
}
-}
+}
diff --git a/frontends/atari/treeview.h b/frontends/atari/treeview.h
index d10129e..fe267b1 100644
--- a/frontends/atari/treeview.h
+++ b/frontends/atari/treeview.h
@@ -68,7 +68,7 @@ struct atari_treeview_callbacks {
/**
* Initalize an window to be an treeview window.
*
-*/
+ */
struct core_window *atari_treeview_create(GUIWIN *win, struct atari_treeview_callbacks * callbacks, void * user_data, uint32_t flags);
/**
-----------------------------------------------------------------------
Summary of changes:
frontends/atari/treeview.c | 910 +++++++++++++++++++++++---------------------
frontends/atari/treeview.h | 2 +-
2 files changed, 467 insertions(+), 445 deletions(-)
diff --git a/frontends/atari/treeview.c b/frontends/atari/treeview.c
index a72d268..abc1fa7 100644
--- a/frontends/atari/treeview.c
+++ b/frontends/atari/treeview.c
@@ -16,21 +16,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <sys/types.h>
-#include <string.h>
-
#include "assert.h"
-#include "cflib.h"
-#include "netsurf/inttypes.h"
-#include "utils/nsoption.h"
#include "utils/log.h"
#include "utils/messages.h"
-#include "utils/utils.h"
-#include "netsurf/plotters.h"
-#include "netsurf/mouse.h"
+#include "netsurf/inttypes.h"
#include "netsurf/core_window.h"
-#include "desktop/treeview.h"
+#include "netsurf/plotters.h"
#include "atari/gui.h"
#include "atari/plot/plot.h"
@@ -40,29 +32,6 @@
#include "atari/res/netsurf.rsh"
-/**
- * Declare Core Window Callbacks:
- */
-
-nserror atari_treeview_invalidate_area(struct core_window *cw, const struct rect *r);
-void atari_treeview_update_size(struct core_window *cw, int width, int height);
-void atari_treeview_scroll_visible(struct core_window *cw,
- const struct rect *r);
-void atari_treeview_get_window_dimensions(struct core_window *cw,
- int *width, int *height);
- // TODO: implement drag status!
-void atari_treeview_drag_status(struct core_window *cw,
- core_window_drag_status ds);
-
-static struct core_window_callback_table cw_t = {
- .invalidate = atari_treeview_invalidate_area,
- .update_size = atari_treeview_update_size,
- .scroll_visible = atari_treeview_scroll_visible,
- .get_window_dimensions = atari_treeview_get_window_dimensions,
- .drag_status = atari_treeview_drag_status
-};
-
-
struct atari_treeview_window {
struct atari_treeview_window * prev_open;
struct atari_treeview_window * next_open;
@@ -80,23 +49,12 @@ struct atari_treeview_window {
static struct atari_treeview_window * treeviews_open;
-/* native GUI event handlers: */
-static void on_mbutton_event(struct core_window *cw, EVMULT_OUT *ev_out,
- short msg[8]);
-static void on_keybd_event(struct core_window *cw, EVMULT_OUT *ev_out,
- short msg[8]);
-static void on_redraw_event(struct core_window *cw, EVMULT_OUT *ev_out,
- short msg[8]);
-
-/* static utils: */
-//static void atari_treeview_dump_info(struct atari_treeview_window *tv, char *s);
-
/**
* Schedule a redraw of the treeview content
*
*/
-static void atari_treeview_redraw_grect_request(struct core_window *cw,
- GRECT *area)
+static void
+atari_treeview_redraw_grect_request(struct core_window *cw, GRECT *area)
{
struct atari_treeview_window *tv = (struct atari_treeview_window *)cw;
if (cw != NULL) {
@@ -114,264 +72,77 @@ static void atari_treeview_redraw_grect_request(struct core_window *cw,
int oldy1 = tv->rdw_area.g_y + tv->rdw_area.g_h;
tv->rdw_area.g_x = MIN(tv->rdw_area.g_x, area->g_x);
tv->rdw_area.g_y = MIN(tv->rdw_area.g_y, area->g_y);
- tv->rdw_area.g_w = ( oldx1 > newx1 ) ? oldx1 - tv->rdw_area.g_x : newx1 - tv->rdw_area.g_x;
- tv->rdw_area.g_h = ( oldy1 > newy1 ) ? oldy1 - tv->rdw_area.g_y : newy1 - tv->rdw_area.g_y;
- }
- //dbg_grect("atari_treeview_request_redraw_grect", &tv->rdw_area);
- }
-}
-
-
-void atari_treeview_get_grect(struct core_window *cw, enum treeview_area_e mode,
- GRECT *dest)
-{
- struct atari_treeview_window *tv = (struct atari_treeview_window *)cw;
+ if ( oldx1 > newx1 ) {
+ tv->rdw_area.g_w = oldx1 - tv->rdw_area.g_x;
+ } else {
+ tv->rdw_area.g_w = newx1 - tv->rdw_area.g_x;
+ }
- if (mode == TREEVIEW_AREA_CONTENT) {
- gemtk_wm_get_grect(tv->window, GEMTK_WM_AREA_CONTENT, dest);
- }
- else if (mode == TREEVIEW_AREA_TOOLBAR) {
- gemtk_wm_get_grect(tv->window, GEMTK_WM_AREA_TOOLBAR, dest);
+ if ( oldy1 > newy1 ) {
+ tv->rdw_area.g_h = oldy1 - tv->rdw_area.g_y;
+ } else {
+ tv->rdw_area.g_h = newy1 - tv->rdw_area.g_y;
+ }
+ }
+ //dbg_grect("atari_treeview_request_redraw_grect", &tv->rdw_area);
}
}
-GUIWIN * atari_treeview_get_gemtk_window(struct core_window *cw)
-{
- struct atari_treeview_window *tv = (struct atari_treeview_window *)cw;
- return(tv->window);
-}
-/*
-static void atari_treeview_dump_info(struct atari_treeview_window *tv,
- char * title)
+#ifdef ATARI_TREEVIEW_DUMP
+static void
+atari_treeview_dump_info(struct atari_treeview_window *tv, char * title)
{
printf("Treeview Dump (%s)\n", title);
printf("=================================\n");
gemtk_wm_dump_window_info(atari_treeview_get_gemtk_window((struct core_window *)tv));
GEMTK_DBG_GRECT("Redraw Area: \n", &tv->rdw_area)
- dbg_grect("Redraw Area2: \n", &tv->rdw_area);
+ dbg_grect("Redraw Area2: \n", &tv->rdw_area);
printf("Extent: x: %d, y: %d\n", tv->extent.x, tv->extent.y);
}
-*/
+#endif
-static bool atari_treeview_is_iconified(struct core_window *cw){
- struct atari_treeview_window *tv = (struct atari_treeview_window *)cw;
+static bool atari_treeview_is_iconified(struct core_window *cw)
+{
+ struct atari_treeview_window *tv = (struct atari_treeview_window *)cw;
- return((gemtk_wm_get_state(tv->window)&GEMTK_WM_STATUS_ICONIFIED) != 0);
+ return((gemtk_wm_get_state(tv->window)&GEMTK_WM_STATUS_ICONIFIED) != 0);
}
-static void atari_treeview_redraw_icon(struct core_window *cw, GRECT *clip)
-{
- struct atari_treeview_window *tv = (struct atari_treeview_window *)cw;
- GRECT visible, work;
- OBJECT * tree = gemtk_obj_get_tree(ICONIFY);
- short aesh = gemtk_wm_get_handle(tv->window);
-
- gemtk_wm_get_grect(tv->window, GEMTK_WM_AREA_WORK, &work);
-
- tree->ob_x = work.g_x;
- tree->ob_y = work.g_y;
- tree->ob_width = work.g_w;
- tree->ob_height = work.g_h;
-
- wind_get_grect(aesh, WF_FIRSTXYWH, &visible);
- while (visible.g_h > 0 && visible.g_w > 0) {
-
- if (rc_intersect(&work, &visible)) {
- objc_draw(tree, 0, 8, visible.g_x, visible.g_y, visible.g_w,
- visible.g_h);
- } else {
- //dbg_grect("redraw vis area outside", &visible);
- }
-
- wind_get_grect(aesh, WF_NEXTXYWH, &visible);
- }
-}
-void atari_treeview_redraw(struct core_window *cw)
+static void atari_treeview_redraw_icon(struct core_window *cw, GRECT *clip)
{
struct atari_treeview_window *tv = (struct atari_treeview_window *)cw;
- short pxy[4];
-
- if (tv != NULL && tv->is_open) {
- if( tv->redraw && ((plot_get_flags() & PLOT_FLAG_OFFSCREEN) == 0) ) {
-
- short todo[4];
- GRECT work;
- short handle = gemtk_wm_get_handle(tv->window);
- struct gemtk_wm_scroll_info_s *slid;
-
- gemtk_wm_get_grect(tv->window, GEMTK_WM_AREA_CONTENT, &work);
- slid = gemtk_wm_get_scroll_info(tv->window);
-
-// // Debug code: this 3 lines help to inspect the redraw
-// // areas...
-// pxy[0] = work.g_x;
-// pxy[1] = work.g_y;
-// pxy[2] = pxy[0] + work.g_w-1;
-// pxy[3] = pxy[1] + work.g_h-1;
-//
-// vsf_color(plot_get_vdi_handle(), 0);
-// v_bar(plot_get_vdi_handle(), (short*)&pxy);
-// evnt_timer(500);
-
- struct redraw_context ctx = {
- .interactive = true,
- .background_images = true,
- .plot = &atari_plotters
- };
- plot_set_dimensions(&ctx,
- work.g_x,
- work.g_y,
- work.g_w,
- work.g_h);
- if (plot_lock() == false)
- return;
-
- if( wind_get(handle, WF_FIRSTXYWH,
- &todo[0], &todo[1], &todo[2], &todo[3] )!=0 ) {
- while (todo[2] && todo[3]) {
-
- if(!rc_intersect(&work, (GRECT*)&todo)){
- if (wind_get(handle, WF_NEXTXYWH,
- &todo[0], &todo[1], &todo[2], &todo[3])==0) {
- break;
- }
- continue;
- }
- pxy[0] = todo[0];
- pxy[1] = todo[1];
- pxy[2] = todo[0] + todo[2]-1;
- pxy[3] = todo[1] + todo[3]-1;
- vs_clip(plot_get_vdi_handle(), 1, (short*)&pxy);
-
- // Debug code: this 3 lines help to inspect the redraw
- // areas...
-
-// vsf_color(plot_get_vdi_handle(), 3);
-// v_bar(plot_get_vdi_handle(), (short*)&pxy);
-// evnt_timer(500);
-
+ GRECT visible, work;
+ OBJECT * tree = gemtk_obj_get_tree(ICONIFY);
+ short aesh = gemtk_wm_get_handle(tv->window);
- /* convert screen to treeview coords: */
- todo[0] = todo[0] - work.g_x ;//+ slid->x_pos*slid->x_unit_px;
- todo[1] = todo[1] - work.g_y ;//+ slid->y_pos*slid->y_unit_px;
- if( todo[0] < 0 ){
- todo[2] = todo[2] + todo[0];
- todo[0] = 0;
- }
- if( todo[1] < 0 ){
- todo[3] = todo[3] + todo[1];
- todo[1] = 0;
- }
+ gemtk_wm_get_grect(tv->window, GEMTK_WM_AREA_WORK, &work);
- if (rc_intersect((GRECT *)&tv->rdw_area,(GRECT *)&todo)) {
- struct rect clip;
+ tree->ob_x = work.g_x;
+ tree->ob_y = work.g_y;
+ tree->ob_width = work.g_w;
+ tree->ob_height = work.g_h;
- clip.x0 = todo[0]+(slid->x_pos*slid->x_unit_px);
- clip.y0 = todo[1]+(slid->y_pos*slid->y_unit_px);
- clip.x1 = clip.x0 + todo[2]+(slid->x_pos*slid->x_unit_px);
- clip.y1 = clip.y0 + todo[3]+(slid->y_pos*slid->y_unit_px);
+ wind_get_grect(aesh, WF_FIRSTXYWH, &visible);
+ while (visible.g_h > 0 && visible.g_w > 0) {
- tv->io->draw(cw, -(slid->x_pos*slid->x_unit_px),
- -(slid->y_pos*slid->y_unit_px),
- &clip, &ctx);
- }
- vs_clip(plot_get_vdi_handle(), 0, (short*)&pxy);
- if (wind_get(handle, WF_NEXTXYWH,
- &todo[0], &todo[1], &todo[2], &todo[3])==0) {
- break;
- }
- }
- } else {
- plot_unlock();
- return;
- }
- plot_unlock();
- tv->redraw = false;
- tv->rdw_area.g_x = 65000;
- tv->rdw_area.g_y = 65000;
- tv->rdw_area.g_w = -1;
- tv->rdw_area.g_h = -1;
+ if (rc_intersect(&work, &visible)) {
+ objc_draw(tree, 0, 8, visible.g_x, visible.g_y, visible.g_w,
+ visible.g_h);
} else {
- /* just copy stuff from the offscreen buffer */
+ //dbg_grect("redraw vis area outside", &visible);
}
- }
-}
-
-
-/**
- * GEMTK (netsurf's GEM toolkit) event sink
- *
-*/
-static short handle_event(GUIWIN *win, EVMULT_OUT *ev_out, short msg[8])
-{
- short retval = 0;
- struct atari_treeview_window *tv = (struct atari_treeview_window *)
- gemtk_wm_get_user_data(win);
- struct core_window *cw = (struct core_window *)tv;
-
- if( (ev_out->emo_events & MU_MESAG) != 0 ) {
- // handle message
- switch (msg[0]) {
-
- case WM_REDRAW:
- on_redraw_event(cw, ev_out, msg);
- break;
-
- default:
- break;
- }
- }
- if( (ev_out->emo_events & MU_KEYBD) != 0 ) {
- on_keybd_event(cw, ev_out, msg);
- }
- if( (ev_out->emo_events & MU_BUTTON) != 0 ) {
- LOG("Treeview click at: %d,%d\n", ev_out->emo_mouse.p_x, ev_out->emo_mouse.p_y);
- on_mbutton_event(cw, ev_out, msg);
- }
-
- if(tv != NULL && tv->io->gemtk_user_func != NULL){
- tv->io->gemtk_user_func(win, ev_out, msg);
- }
-
- // TODO: evaluate return values of event handler functions and pass them on:
- return(retval);
-}
-
-static void __CDECL on_keybd_event(struct core_window *cw, EVMULT_OUT *ev_out,
- short msg[8])
-{
- long kstate = 0;
- long kcode = 0;
- long ucs4;
- long ik;
- unsigned short nkc = 0;
- unsigned char ascii;
- struct atari_treeview_window *tv = (struct atari_treeview_window *)cw;
-
- kstate = ev_out->emo_kmeta;
- kcode = ev_out->emo_kreturn;
- nkc= gem_to_norm( (short)kstate, (short)kcode );
- ascii = (nkc & 0xFF);
- ik = nkc_to_input_key(nkc, &ucs4);
-
- if (ik == 0) {
- if (ascii >= 9) {
- tv->io->keypress(cw, ucs4);
- }
- } else {
- tv->io->keypress(cw, ik);
+ wind_get_grect(aesh, WF_NEXTXYWH, &visible);
}
}
-static void __CDECL on_redraw_event(struct core_window *cw,
- EVMULT_OUT *ev_out,
- short msg[8])
+static void __CDECL
+on_redraw_event(struct core_window *cw, EVMULT_OUT *ev_out, short msg[8])
{
GRECT work, clip;
struct atari_treeview_window *tv = (struct atari_treeview_window *)cw;
@@ -428,9 +199,9 @@ static void __CDECL on_redraw_event(struct core_window *cw,
}
}
-static void __CDECL on_mbutton_event(struct core_window *cw,
- EVMULT_OUT *ev_out,
- short msg[8])
+
+static void __CDECL
+on_mbutton_event(struct core_window *cw, EVMULT_OUT *ev_out, short msg[8])
{
struct atari_treeview_window *tv = (struct atari_treeview_window *)cw;
struct gemtk_wm_scroll_info_s *slid;
@@ -447,26 +218,26 @@ static void __CDECL on_mbutton_event(struct core_window *cw,
/* mouse click relative origin: */
- short origin_rel_x = (mx-work.g_x) +
- (slid->x_pos*slid->x_unit_px);
- short origin_rel_y = (my-work.g_y) +
- (slid->y_pos*slid->y_unit_px);
+ short origin_rel_x = (mx-work.g_x) + (slid->x_pos*slid->x_unit_px);
+ short origin_rel_y = (my-work.g_y) + (slid->y_pos*slid->y_unit_px);
/* Only pass on events in the content area: */
- if( origin_rel_x >= 0 && origin_rel_y >= 0
- && mx < work.g_x + work.g_w
- && my < work.g_y + work.g_h )
- {
+ if ((origin_rel_x >= 0) &&
+ (origin_rel_y >= 0) &&
+ (mx < work.g_x + work.g_w) &&
+ (my < work.g_y + work.g_h)) {
if (ev_out->emo_mclicks == 2) {
tv->io->mouse_action(cw,
- BROWSER_MOUSE_CLICK_1|BROWSER_MOUSE_DOUBLE_CLICK,
- origin_rel_x, origin_rel_y);
+ BROWSER_MOUSE_CLICK_1 |
+ BROWSER_MOUSE_DOUBLE_CLICK,
+ origin_rel_x,
+ origin_rel_y);
return;
}
graf_mkstate(&cur_rel_x, &cur_rel_y, &mbut, &dummy);
/* check for click or hold: */
- if( (mbut&1) == 0 ){
+ if ((mbut & 1) == 0 ) {
int bms;
bms = BROWSER_MOUSE_CLICK_1 | BROWSER_MOUSE_PRESS_1;
if(ev_out->emo_mclicks == 2 ) {
@@ -486,174 +257,126 @@ static void __CDECL on_mbutton_event(struct core_window *cw,
tv->startdrag.x = origin_rel_x;
tv->startdrag.y = origin_rel_y;
/* First, report mouse press, to trigger entry selection */
- tv->io->mouse_action(cw, BROWSER_MOUSE_CLICK_1 | BROWSER_MOUSE_PRESS_1, cur_rel_x,
- cur_rel_y);
+ tv->io->mouse_action(cw,
+ BROWSER_MOUSE_CLICK_1 |
+ BROWSER_MOUSE_PRESS_1,
+ cur_rel_x,
+ cur_rel_y);
atari_treeview_redraw(cw);
- tv->io->mouse_action(cw, BROWSER_MOUSE_DRAG_1 | BROWSER_MOUSE_DRAG_ON,
- cur_rel_x, cur_rel_y);
- do{
- if (abs(prev_x-cur_rel_x) > 5 || abs(prev_y-cur_rel_y) > 5) {
+ tv->io->mouse_action(cw,
+ BROWSER_MOUSE_DRAG_1 |
+ BROWSER_MOUSE_DRAG_ON,
+ cur_rel_x,
+ cur_rel_y);
+ do {
+ if (abs(prev_x-cur_rel_x) > 5 ||
+ abs(prev_y-cur_rel_y) > 5) {
tv->io->mouse_action(cw,
- BROWSER_MOUSE_HOLDING_1 | BROWSER_MOUSE_DRAG_ON,
- cur_rel_x, cur_rel_y);
+ BROWSER_MOUSE_HOLDING_1 |
+ BROWSER_MOUSE_DRAG_ON,
+ cur_rel_x,
+ cur_rel_y);
prev_x = cur_rel_x;
prev_y = cur_rel_y;
}
if (tv->redraw) {
// TODO: maybe GUI poll would fit better here?
- // ... is gui_poll re-entrance save?
+ // ... is gui_poll re-entrance save?
atari_treeview_redraw(cw);
}
/* sample mouse button state: */
- graf_mkstate(&cur_rel_x, &cur_rel_y, &mbut, &dummy);
- cur_rel_x = (cur_rel_x-work.g_x)+(slid->x_pos*slid->x_unit_px);
- cur_rel_y = (cur_rel_y-work.g_y)+(slid->y_pos*slid->y_unit_px);
- } while( mbut & 1 );
+ graf_mkstate(&cur_rel_x,
+ &cur_rel_y,
+ &mbut,
+ &dummy);
+ cur_rel_x = (cur_rel_x-work.g_x) +
+ (slid->x_pos*slid->x_unit_px);
+ cur_rel_y = (cur_rel_y-work.g_y) +
+ (slid->y_pos*slid->y_unit_px);
+ } while (mbut & 1);
/* End drag: */
- tv->io->mouse_action(cw, BROWSER_MOUSE_HOVER, cur_rel_x, cur_rel_y);
+ tv->io->mouse_action(cw,
+ BROWSER_MOUSE_HOVER,
+ cur_rel_x,
+ cur_rel_y);
gem_set_cursor(&gem_cursors.arrow);
}
}
}
-struct core_window *
-atari_treeview_create(GUIWIN *win, struct atari_treeview_callbacks * callbacks,
- void * user_data, uint32_t flags)
+static void __CDECL
+on_keybd_event(struct core_window *cw, EVMULT_OUT *ev_out, short msg[8])
{
+ long kstate = 0;
+ long kcode = 0;
+ long ucs4;
+ long ik;
+ unsigned short nkc = 0;
+ unsigned char ascii;
+ struct atari_treeview_window *tv = (struct atari_treeview_window *)cw;
- /* allocate the core_window struct: */
- struct atari_treeview_window * tv;
- struct gemtk_wm_scroll_info_s *slid;
+ kstate = ev_out->emo_kmeta;
+ kcode = ev_out->emo_kreturn;
+ nkc= gem_to_norm( (short)kstate, (short)kcode );
+ ascii = (nkc & 0xFF);
+ ik = nkc_to_input_key(nkc, &ucs4);
- tv = calloc(1, sizeof(struct atari_treeview_window));
- if (tv == NULL) {
- LOG("calloc failed");
- atari_warn_user(messages_get_errorcode(NSERROR_NOMEM), 0);
- return NULL;
+ if (ik == 0) {
+ if (ascii >= 9) {
+ tv->io->keypress(cw, ucs4);
+ }
+ } else {
+ tv->io->keypress(cw, ik);
}
+}
- /* Store the window ref inside the new treeview: */
- tv->window = win;
- tv->io = callbacks;
- tv->user_data = user_data;
-
- // Setup gemtk event handler function:
- gemtk_wm_set_event_handler(win, handle_event);
- // bind window user data to treeview ref:
- gemtk_wm_set_user_data(win, (void*)tv);
+/**
+ * GEMTK (netsurf's GEM toolkit) event sink
+ *
+ */
+static short handle_event(GUIWIN *win, EVMULT_OUT *ev_out, short msg[8])
+{
+ short retval = 0;
+ struct atari_treeview_window *tv = (struct atari_treeview_window *)
+ gemtk_wm_get_user_data(win);
+ struct core_window *cw = (struct core_window *)tv;
- // Get acces to the gemtk scroll info struct:
- slid = gemtk_wm_get_scroll_info(tv->window);
+ if( (ev_out->emo_events & MU_MESAG) != 0 ) {
+ // handle message
+ switch (msg[0]) {
- // Setup line and column height/width of the window,
- // each scroll takes the configured steps:
- slid->y_unit_px = 16;
- slid->x_unit_px = 16;
+ case WM_REDRAW:
+ on_redraw_event(cw, ev_out, msg);
+ break;
- assert(tv->io);
- assert(tv->io->init_phase2);
+ default:
+ break;
+ }
+ }
+ if ((ev_out->emo_events & MU_KEYBD) != 0 ) {
+ on_keybd_event(cw, ev_out, msg);
+ }
+ if ((ev_out->emo_events & MU_BUTTON) != 0 ) {
+ LOG("Treeview click at: %d,%d\n",
+ ev_out->emo_mouse.p_x, ev_out->emo_mouse.p_y);
+ on_mbutton_event(cw, ev_out, msg);
+ }
- /* Now that the window is configured for treeview content, */
- /* call init_phase2 which must create the treeview */
- /* descriptor, and at least setup the the default */
- /* event handlers of the treeview: */
- /* It would be more simple to not pass around the callbacks */
- /* but the treeview constructor requires them for initialization... */
- nserror err = tv->io->init_phase2((struct core_window *)tv, &cw_t);
- if (err != NSERROR_OK) {
- free(tv);
- tv = NULL;
+ if (tv != NULL && tv->io->gemtk_user_func != NULL){
+ tv->io->gemtk_user_func(win, ev_out, msg);
}
- return((struct core_window *)tv);
-}
-
-void atari_treeview_delete(struct core_window * cw)
-{
- struct atari_treeview_window *tv = (struct atari_treeview_window*)cw;
-
- assert(tv);
- assert(tv->io->finish);
-
- tv->io->finish(cw);
-
- free(tv);
-}
-
-
-void atari_treeview_open(struct core_window *cw, GRECT *pos)
-{
- struct atari_treeview_window *tv = (struct atari_treeview_window*)cw;
- if (tv->window != NULL && tv->is_open == false) {
- tv->is_open = true;
- wind_open_grect(gemtk_wm_get_handle(tv->window), pos);
- gemtk_wm_link(tv->window);
- if (treeviews_open == NULL) {
- treeviews_open = tv;
- treeviews_open->next_open = NULL;
- treeviews_open->prev_open = NULL;
- } else {
- struct atari_treeview_window * tmp;
- tmp = treeviews_open;
- while(tmp->next_open != NULL){
- tmp = tmp->next_open;
- }
- tmp->next_open = tv;
- tv->prev_open = tmp;
- tv->next_open = NULL;
- }
- }
-}
-
-bool atari_treeview_is_open(struct core_window *cw)
-{
- struct atari_treeview_window *tv = (struct atari_treeview_window*)cw;
- return(tv->is_open);
-}
-
-void atari_treeview_set_user_data(struct core_window * cw,
- void *user_data_ptr)
-{
- struct atari_treeview_window *tv = (struct atari_treeview_window*)cw;
- tv->user_data = user_data_ptr;
-}
-
-void * atari_treeview_get_user_data(struct core_window * cw)
-{
- struct atari_treeview_window *tv = (struct atari_treeview_window*)cw;
- return(tv->user_data);
-}
-
-void atari_treeview_close(struct core_window *cw)
-{
- struct atari_treeview_window *tv = (struct atari_treeview_window*)cw;
- if (tv->window != NULL) {
- tv->is_open = false;
- wind_close(gemtk_wm_get_handle(tv->window));
- gemtk_wm_unlink(tv->window);
- /* unlink the window: */
- if (tv->prev_open != NULL) {
- tv->prev_open->next_open = tv->next_open;
- } else {
- treeviews_open = tv->next_open;
- }
- if (tv->next_open != NULL) {
- tv->next_open->prev_open = tv->prev_open;
- }
- }
+ // TODO: evaluate return values of event handler functions and pass them on:
+ return(retval);
}
/**
- * Core Window Callbacks:
- */
-
-/**
* callback from core to request an invalidation of a window area.
*
* The specified area of the window should now be considered
@@ -664,7 +387,9 @@ void atari_treeview_close(struct core_window *cw)
* \param[in] r area to redraw or NULL for the entire window area.
* \return NSERROR_OK on success or appropriate error code.
*/
-nserror atari_treeview_invalidate_area(struct core_window *cw, const struct rect *r)
+static nserror
+atari_treeview_invalidate_area(struct core_window *cw,
+ const struct rect *r)
{
GRECT area;
struct gemtk_wm_scroll_info_s * slid;
@@ -693,6 +418,7 @@ nserror atari_treeview_invalidate_area(struct core_window *cw, const struct rect
return NSERROR_OK;
}
+
/**
* Update the limits of the window
*
@@ -700,7 +426,8 @@ nserror atari_treeview_invalidate_area(struct core_window *cw, const struct rect
* \param width the width in px, or negative if don't care
* \param height the height in px, or negative if don't care
*/
-void atari_treeview_update_size(struct core_window *cw, int width, int height)
+static void
+atari_treeview_update_size(struct core_window *cw, int width, int height)
{
GRECT area;
struct gemtk_wm_scroll_info_s *slid;
@@ -732,8 +459,10 @@ void atari_treeview_update_size(struct core_window *cw, int width, int height)
tv->extent.y = height;
- /*printf("units content: %d, units viewport: %d\n", (height/slid->y_unit_px),
- (area.g_h/slid->y_unit_px));*/
+ /* printf("units content: %d, units viewport: %d\n",
+ (height/slid->y_unit_px),
+ (area.g_h/slid->y_unit_px));
+ */
gemtk_wm_update_slider(tv->window, GEMTK_WM_VH_SLIDER);
}
}
@@ -745,10 +474,11 @@ void atari_treeview_update_size(struct core_window *cw, int width, int height)
* \param cw the core window object
* \param r rectangle to make visible
*/
-void atari_treeview_scroll_visible(struct core_window *cw, const struct rect *r)
+static void
+atari_treeview_scroll_visible(struct core_window *cw, const struct rect *r)
{
/* atari frontend doesn't support dragging outside the treeview */
- /* so there is no need to implement this? */
+ /* so there is no need to implement this? */
}
@@ -759,10 +489,13 @@ void atari_treeview_scroll_visible(struct core_window *cw, const struct rect *r)
* \param width to be set to viewport width in px, if non NULL
* \param height to be set to viewport height in px, if non NULL
*/
-void atari_treeview_get_window_dimensions(struct core_window *cw,
- int *width, int *height)
+static void
+atari_treeview_get_window_dimensions(struct core_window *cw,
+ int *width,
+ int *height)
{
- if (cw != NULL && (width != NULL || height != NULL)) {
+ if ((cw != NULL) &&
+ (width != NULL || height != NULL)) {
GRECT work;
atari_treeview_get_grect(cw, TREEVIEW_AREA_CONTENT, &work);
*width = work.g_w;
@@ -777,33 +510,322 @@ void atari_treeview_get_window_dimensions(struct core_window *cw,
* \param cw the core window object
* \param ds the current drag status
*/
-void atari_treeview_drag_status(struct core_window *cw,
- core_window_drag_status ds)
+static void
+atari_treeview_drag_status(struct core_window *cw, core_window_drag_status ds)
+{
+
+}
+
+
+/**
+ * Declare Core Window Callbacks:
+ */
+static struct core_window_callback_table cw_t = {
+ .invalidate = atari_treeview_invalidate_area,
+ .update_size = atari_treeview_update_size,
+ .scroll_visible = atari_treeview_scroll_visible,
+ .get_window_dimensions = atari_treeview_get_window_dimensions,
+ .drag_status = atari_treeview_drag_status
+};
+
+
+/* exported interface documented in atari/treeview.h */
+struct core_window *
+atari_treeview_create(GUIWIN *win, struct atari_treeview_callbacks * callbacks,
+ void * user_data, uint32_t flags)
+{
+
+ /* allocate the core_window struct: */
+ struct atari_treeview_window * tv;
+ struct gemtk_wm_scroll_info_s *slid;
+
+ tv = calloc(1, sizeof(struct atari_treeview_window));
+ if (tv == NULL) {
+ LOG("calloc failed");
+ atari_warn_user(messages_get_errorcode(NSERROR_NOMEM), 0);
+ return NULL;
+ }
+
+ /* Store the window ref inside the new treeview: */
+ tv->window = win;
+ tv->io = callbacks;
+ tv->user_data = user_data;
+
+ // Setup gemtk event handler function:
+ gemtk_wm_set_event_handler(win, handle_event);
+
+ // bind window user data to treeview ref:
+ gemtk_wm_set_user_data(win, (void*)tv);
+
+ // Get acces to the gemtk scroll info struct:
+ slid = gemtk_wm_get_scroll_info(tv->window);
+
+ // Setup line and column height/width of the window,
+ // each scroll takes the configured steps:
+ slid->y_unit_px = 16;
+ slid->x_unit_px = 16;
+
+ assert(tv->io);
+ assert(tv->io->init_phase2);
+
+ /* Now that the window is configured for treeview content, */
+ /* call init_phase2 which must create the treeview */
+ /* descriptor, and at least setup the the default */
+ /* event handlers of the treeview: */
+ /* It would be more simple to not pass around the callbacks */
+ /* but the treeview constructor requires them for initialization... */
+ nserror err = tv->io->init_phase2((struct core_window *)tv, &cw_t);
+ if (err != NSERROR_OK) {
+ free(tv);
+ tv = NULL;
+ }
+
+ return((struct core_window *)tv);
+}
+
+
+/* exported interface documented in atari/treeview.h */
+void
+atari_treeview_get_grect(struct core_window *cw,
+ enum treeview_area_e mode,
+ GRECT *dest)
+{
+
+ struct atari_treeview_window *tv = (struct atari_treeview_window *)cw;
+
+ if (mode == TREEVIEW_AREA_CONTENT) {
+ gemtk_wm_get_grect(tv->window, GEMTK_WM_AREA_CONTENT, dest);
+ }
+ else if (mode == TREEVIEW_AREA_TOOLBAR) {
+ gemtk_wm_get_grect(tv->window, GEMTK_WM_AREA_TOOLBAR, dest);
+ }
+}
+
+
+/* exported interface documented in atari/treeview.h */
+GUIWIN * atari_treeview_get_gemtk_window(struct core_window *cw)
+{
+ struct atari_treeview_window *tv = (struct atari_treeview_window *)cw;
+ return(tv->window);
+}
+
+
+/* exported interface documented in atari/treeview.h */
+void atari_treeview_redraw(struct core_window *cw)
+{
+ struct atari_treeview_window *tv = (struct atari_treeview_window *)cw;
+ short pxy[4];
+
+ if (tv != NULL && tv->is_open) {
+ if( tv->redraw && ((plot_get_flags() & PLOT_FLAG_OFFSCREEN) == 0) ) {
+
+ short todo[4];
+ GRECT work;
+ short handle = gemtk_wm_get_handle(tv->window);
+ struct gemtk_wm_scroll_info_s *slid;
+
+ gemtk_wm_get_grect(tv->window, GEMTK_WM_AREA_CONTENT, &work);
+ slid = gemtk_wm_get_scroll_info(tv->window);
+
+// // Debug code: this 3 lines help to inspect the redraw
+// // areas...
+// pxy[0] = work.g_x;
+// pxy[1] = work.g_y;
+// pxy[2] = pxy[0] + work.g_w-1;
+// pxy[3] = pxy[1] + work.g_h-1;
+//
+// vsf_color(plot_get_vdi_handle(), 0);
+// v_bar(plot_get_vdi_handle(), (short*)&pxy);
+// evnt_timer(500);
+
+ struct redraw_context ctx = {
+ .interactive = true,
+ .background_images = true,
+ .plot = &atari_plotters
+ };
+ plot_set_dimensions(&ctx,
+ work.g_x,
+ work.g_y,
+ work.g_w,
+ work.g_h);
+ if (plot_lock() == false)
+ return;
+
+ if( wind_get(handle, WF_FIRSTXYWH,
+ &todo[0], &todo[1], &todo[2], &todo[3] )!=0 ) {
+ while (todo[2] && todo[3]) {
+
+ if(!rc_intersect(&work, (GRECT*)&todo)){
+ if (wind_get(handle, WF_NEXTXYWH,
+ &todo[0], &todo[1], &todo[2], &todo[3])==0) {
+ break;
+ }
+ continue;
+ }
+ pxy[0] = todo[0];
+ pxy[1] = todo[1];
+ pxy[2] = todo[0] + todo[2]-1;
+ pxy[3] = todo[1] + todo[3]-1;
+ vs_clip(plot_get_vdi_handle(), 1, (short*)&pxy);
+
+ // Debug code: this 3 lines help to inspect the redraw
+ // areas...
+
+// vsf_color(plot_get_vdi_handle(), 3);
+// v_bar(plot_get_vdi_handle(), (short*)&pxy);
+// evnt_timer(500);
+
+
+ /* convert screen to treeview coords: */
+ todo[0] = todo[0] - work.g_x ;//+ slid->x_pos*slid->x_unit_px;
+ todo[1] = todo[1] - work.g_y ;//+ slid->y_pos*slid->y_unit_px;
+ if( todo[0] < 0 ){
+ todo[2] = todo[2] + todo[0];
+ todo[0] = 0;
+ }
+ if( todo[1] < 0 ){
+ todo[3] = todo[3] + todo[1];
+ todo[1] = 0;
+ }
+
+ if (rc_intersect((GRECT *)&tv->rdw_area,(GRECT *)&todo)) {
+ struct rect clip;
+
+ clip.x0 = todo[0]+(slid->x_pos*slid->x_unit_px);
+ clip.y0 = todo[1]+(slid->y_pos*slid->y_unit_px);
+ clip.x1 = clip.x0 + todo[2]+(slid->x_pos*slid->x_unit_px);
+ clip.y1 = clip.y0 + todo[3]+(slid->y_pos*slid->y_unit_px);
+
+ tv->io->draw(cw, -(slid->x_pos*slid->x_unit_px),
+ -(slid->y_pos*slid->y_unit_px),
+ &clip, &ctx);
+ }
+ vs_clip(plot_get_vdi_handle(), 0, (short*)&pxy);
+ if (wind_get(handle, WF_NEXTXYWH,
+ &todo[0], &todo[1], &todo[2], &todo[3])==0) {
+ break;
+ }
+ }
+ } else {
+ plot_unlock();
+ return;
+ }
+ plot_unlock();
+ tv->redraw = false;
+ tv->rdw_area.g_x = 65000;
+ tv->rdw_area.g_y = 65000;
+ tv->rdw_area.g_w = -1;
+ tv->rdw_area.g_h = -1;
+ } else {
+ /* just copy stuff from the offscreen buffer */
+ }
+ }
+}
+
+
+/* exported interface documented in atari/treeview.h */
+void atari_treeview_delete(struct core_window * cw)
+{
+ struct atari_treeview_window *tv = (struct atari_treeview_window*)cw;
+
+ assert(tv);
+ assert(tv->io->finish);
+
+ tv->io->finish(cw);
+
+ free(tv);
+}
+
+
+/* exported interface documented in atari/treeview.h */
+void atari_treeview_open(struct core_window *cw, GRECT *pos)
+{
+ struct atari_treeview_window *tv = (struct atari_treeview_window*)cw;
+ if (tv->window != NULL && tv->is_open == false) {
+ tv->is_open = true;
+ wind_open_grect(gemtk_wm_get_handle(tv->window), pos);
+ gemtk_wm_link(tv->window);
+ if (treeviews_open == NULL) {
+ treeviews_open = tv;
+ treeviews_open->next_open = NULL;
+ treeviews_open->prev_open = NULL;
+ } else {
+ struct atari_treeview_window * tmp;
+ tmp = treeviews_open;
+ while(tmp->next_open != NULL){
+ tmp = tmp->next_open;
+ }
+ tmp->next_open = tv;
+ tv->prev_open = tmp;
+ tv->next_open = NULL;
+ }
+ }
+}
+
+
+/* exported interface documented in atari/treeview.h */
+bool atari_treeview_is_open(struct core_window *cw)
{
+ struct atari_treeview_window *tv = (struct atari_treeview_window*)cw;
+ return(tv->is_open);
+}
+
+
+/* exported interface documented in atari/treeview.h */
+void atari_treeview_set_user_data(struct core_window *cw, void *user_data_ptr)
+{
+ struct atari_treeview_window *tv = (struct atari_treeview_window*)cw;
+ tv->user_data = user_data_ptr;
+}
+
+
+/* exported interface documented in atari/treeview.h */
+void * atari_treeview_get_user_data(struct core_window * cw)
+{
+ struct atari_treeview_window *tv = (struct atari_treeview_window*)cw;
+ return(tv->user_data);
+}
+
+/* exported interface documented in atari/treeview.h */
+void atari_treeview_close(struct core_window *cw)
+{
+ struct atari_treeview_window *tv = (struct atari_treeview_window*)cw;
+ if (tv->window != NULL) {
+ tv->is_open = false;
+ wind_close(gemtk_wm_get_handle(tv->window));
+ gemtk_wm_unlink(tv->window);
+ /* unlink the window: */
+ if (tv->prev_open != NULL) {
+ tv->prev_open->next_open = tv->next_open;
+ } else {
+ treeviews_open = tv->next_open;
+ }
+ if (tv->next_open != NULL) {
+ tv->next_open->prev_open = tv->prev_open;
+ }
+ }
}
+
+/* exported interface documented in atari/treeview.h */
void atari_treeview_flush_redraws(void)
{
struct atari_treeview_window *tmp;
tmp = treeviews_open;
- if(tmp){
- while(tmp){
- assert(tmp->is_open);
- if(tmp->redraw){
- if (atari_treeview_is_iconified((struct core_window *)tmp)) {
- /* No content redraw for iconified windows */
- /* because otherwise the icon draw function would */
- /* have to deal with plot canvas coords */
- continue;
- }
-
- atari_treeview_redraw((struct core_window *)tmp);
- }
- tmp = tmp->next_open;
+ while (tmp != NULL) {
+ assert(tmp->is_open);
+ if (tmp->redraw &&
+ (!atari_treeview_is_iconified((struct core_window *)tmp))) {
+ /* Content redraw only for iconified windows
+ * because otherwise the icon draw function
+ * would have to deal with plot canvas coords
+ */
+ atari_treeview_redraw((struct core_window *)tmp);
}
+ tmp = tmp->next_open;
}
-}
+}
diff --git a/frontends/atari/treeview.h b/frontends/atari/treeview.h
index d10129e..fe267b1 100644
--- a/frontends/atari/treeview.h
+++ b/frontends/atari/treeview.h
@@ -68,7 +68,7 @@ struct atari_treeview_callbacks {
/**
* Initalize an window to be an treeview window.
*
-*/
+ */
struct core_window *atari_treeview_create(GUIWIN *win, struct atari_treeview_callbacks * callbacks, void * user_data, uint32_t flags);
/**
--
NetSurf Browser
5 years, 9 months
libnslog: branch master updated. 73860cdc8625b4f8443cb8531019d6f57f8b59ce
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/libnslog.git/shortlog/73860cdc8625b4f8443c...
...commit http://git.netsurf-browser.org/libnslog.git/commit/73860cdc8625b4f8443cb8...
...tree http://git.netsurf-browser.org/libnslog.git/tree/73860cdc8625b4f8443cb853...
The branch, master has been updated
via 73860cdc8625b4f8443cb8531019d6f57f8b59ce (commit)
from 659477920e8fdbfee6e2776254d8f0463e7723fb (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff http://git.netsurf-browser.org/libnslog.git/commit/?id=73860cdc8625b4f844...
commit 73860cdc8625b4f8443cb8531019d6f57f8b59ce
Author: Daniel Silverstone <dsilvers(a)digital-scurf.org>
Commit: Daniel Silverstone <dsilvers(a)digital-scurf.org>
Add a main document for libnslog
diff --git a/docs/Doxyfile b/docs/Doxyfile
index 29be490..870b8ad 100644
--- a/docs/Doxyfile
+++ b/docs/Doxyfile
@@ -655,7 +655,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
-INPUT = include
+INPUT = include docs
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
@@ -773,6 +773,8 @@ FILTER_SOURCE_FILES = NO
FILTER_SOURCE_PATTERNS =
+USE_MDFILE_AS_MAINPAGE = mainpage.md
+
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
diff --git a/docs/mainpage.md b/docs/mainpage.md
new file mode 100644
index 0000000..1d29aee
--- /dev/null
+++ b/docs/mainpage.md
@@ -0,0 +1,160 @@
+Lib NSLOG
+=========
+
+The purpose of the NSLog library is to provide a flexible logging macro which
+permits logging with categories, and at levels. Then the library can queue
+log entries and permit filtering for log readers.
+
+Since logging may have to happen during static initialisation, or before the
+logging library is fully initialised, categories are progressively added to
+the logging system as they are encountered. Since, at their core, categories
+are essentially just strings, we can write filters which will be resolved to
+categories later as and when they are encountered.
+
+Libraries which use NSLog should *NOT* act as clients of the library excepting
+in tools, and test drivers. By implementing a client in the test drivers,
+libraries can verify the log messages sent. If a library might produce a lot
+of logging then it must implement a client in its test drivers or it might run
+out of RAM while running tests.
+
+How to log stuff
+----------------
+
+In order to log messages, you need to have a category to log under. We
+recommend that you have one category per library or application, and that you
+create sub-categories beneath that to divide the library (or app) into logical
+units.
+
+Categories should be declared in headers, and defined in C files. You declare
+a category thusly:
+
+ NSLOG_DECLARE_CATEGORY(catname);
+
+In that `catname` is a valid suffix for a C identifier, and will be used as
+the logical name of the category for the purpose of NSLOG statements.
+
+You define a category thusly:
+
+ NSLOG_DEFINE_CATEGORY(catname, description);
+
+In that `catname` matches the above, and `description` is a C string (or
+identifier to a C string) which describes the category.
+
+You define a subcategory thusly:
+
+ NSLOG_DEFINE_SUBCATEGORY(parentcatname, catname, description);
+
+In that `parentcategory` is the `catname` of another category which will be
+considered the parent of this subcategory. `catname` and `description` as
+above. Subcategories are rendered with slashes between their names when shown
+as text, so a category of `foo` with a subcategory of `bar` would result in
+two categories, one `foo` and one `foo/bar`.
+
+Once you have categories, you can log stuff. Your categories don't have to be
+entirely public, but you will need access to the symbol to be able to log
+things with the given category. To log something, you use:
+
+ NSLOG(catname, level, logmsg, args...);
+
+In that `catname` is a `catname` from the above, `level` is a bareword logging
+level which will be prefixed with `NSLOG_LEVEL_` for use (e.g. you can use
+`WARNING` directly). `logmsg` and `args...` are a `printf()` style log message
+which will be rendered by the time `NSLOG()` returns, so you don't have to
+worry about lifetimes.
+
+Lib NSLOG lets you define a minimum compiled-in logging level which can be used
+to elide deep debugging in release builds. The `NSLOG()` macro expands to a
+constant comparison which will be resolved at compile time (assuming
+optimisations are turned on) to result in logging which doesn't need to be
+compiled in, being compiled out (and thus is is basically zero-cost to sprinkle
+deep debugging in your code).
+
+Being a libnslog client
+-----------------------
+
+In order for code which uses `NSLOG()` to be hosted effectively, the client must
+do two things. Firstly a callback must be provided. The simplest callback
+would be:
+
+ static nslog__client_callback(void *context, nslog_entry_context_t *ctx,
+ const char *fmt, va_list args)
+ {
+ (void)context;
+ (void)ctx;
+ (void)fmt;
+ va_start(args, fmt);
+ va_end(args);
+ }
+
+In that `context` is a `void*` which is passed through to the client code
+directly, allowing a client to provide some struct or other through to the
+logging client callback. `ctx` is an NSLOG context which you can find out more
+about by reading the docs. It contains the information about the logging
+*site* such as the filename, line number, function name, level, and category
+used to make the log entry. `fmt` is the `logmsg` from above, and `args`
+is the variadic argument set used to format the arguments.
+
+This callback is registered into Lib NSLOG with something like:
+
+ nslog_set_render_callback(nslog__client_callback, NULL);
+
+If a callback is not set, then bad things will happen when the next thing is
+run. The final thing which must happen before the client will receive log
+statements is that the client must _uncork_ the logging library. Since logging
+can occur **before** the client is ready, the library will render and store the
+log messages in a list, awaiting the call to uncork. Once uncorked, log
+messages will be passed through as flatly as possible to the client. To uncork
+the library, call:
+
+ nslog_uncork();
+
+All corked messages will be passed to the client callback, in the order they
+were logged, before the uncork call returns.
+
+Filtering logs
+--------------
+
+The primary way to filter logs is to simply compile out the logging levels you
+do not wish to exist. Sadly this is a very coarse filter and is best used to
+exclude deep debug (and possibly debug) from release builds. If you wish to
+filter your logs more flexibly at runtime, then you need to set up a log
+filter. You *can* build the filters "by hand" but much easier is to use the
+text filter parser as such:
+
+ nslog_filter_t *filter = NULL;
+ if (nslog_filter_from_text(my_filter_text, &output) == NSLOG_NO_ERROR) {
+ nslog_filter_set_active(filter, NULL);
+ nslog_filter_unref(filter);
+ }
+
+The filter syntax is fairly simple:
+
+* A `filter` is one of a `NOT` an `AND`, `OR`, or `XOR`, or a `simple` filter.
+* a `NOT` filter is of the form `!filter`
+* an `AND` filter is of the form `(filter && filter)`
+* an `OR` filter is of the form `(filter || filter)`
+* an `XOR` filter is of the form `(filter ^ filter)`
+* A `simple` filter is one of a `level`, `category`, `filename`, `dirname`,
+ or `funcname` filter.
+* a `level` filter is of the form `level: FOOLEVEL` where `FOOLEVEL` is one of
+ `DEEPDEBUG`, `DEBUG`, `VERBOSE`....
+* a `category` filter is of the form `cat: catname` where `catname` is a
+ category name. If it is of the form `foo` then it will match all categories
+ `foo` or `foo/*` but not `foobar`
+* a `filename` filter is of the form `file: filename` and is essentially a
+ suffix match on the filename. `foo.c` will match `foo.c` and `bar/foo.c`
+ but not `barfoo.c`
+* a `dirname` filter is of the form `dir: dirname` and is essentially a prefix
+ match on the filename. `foo` will match `foo/bar.c` and `foo/bar/baz.c` but
+ not `foobar.c`
+
+Between tokens, any amount of whitespace is valid, but canonically only a small
+amount will be used. You can take any filter you have and re-render it in its
+canonical text form by using `nslog_filter_sprintf()` which is documented.
+
+Filters are evaluated in standard order, with parentheses doing the obvious
+thing. In addition, the `AND` and `OR` filters will short-circuit as you'd
+expect, so you can use that to your advantage to make your filters efficient.
+Internally, Lib NSLOG will cache filtering intermediates to make things as fast
+as possible, but a badly designed filter will end up slowing things down
+dramatically.
-----------------------------------------------------------------------
Summary of changes:
docs/Doxyfile | 4 +-
docs/mainpage.md | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 163 insertions(+), 1 deletion(-)
create mode 100644 docs/mainpage.md
diff --git a/docs/Doxyfile b/docs/Doxyfile
index 29be490..870b8ad 100644
--- a/docs/Doxyfile
+++ b/docs/Doxyfile
@@ -655,7 +655,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
-INPUT = include
+INPUT = include docs
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
@@ -773,6 +773,8 @@ FILTER_SOURCE_FILES = NO
FILTER_SOURCE_PATTERNS =
+USE_MDFILE_AS_MAINPAGE = mainpage.md
+
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
diff --git a/docs/mainpage.md b/docs/mainpage.md
new file mode 100644
index 0000000..1d29aee
--- /dev/null
+++ b/docs/mainpage.md
@@ -0,0 +1,160 @@
+Lib NSLOG
+=========
+
+The purpose of the NSLog library is to provide a flexible logging macro which
+permits logging with categories, and at levels. Then the library can queue
+log entries and permit filtering for log readers.
+
+Since logging may have to happen during static initialisation, or before the
+logging library is fully initialised, categories are progressively added to
+the logging system as they are encountered. Since, at their core, categories
+are essentially just strings, we can write filters which will be resolved to
+categories later as and when they are encountered.
+
+Libraries which use NSLog should *NOT* act as clients of the library excepting
+in tools, and test drivers. By implementing a client in the test drivers,
+libraries can verify the log messages sent. If a library might produce a lot
+of logging then it must implement a client in its test drivers or it might run
+out of RAM while running tests.
+
+How to log stuff
+----------------
+
+In order to log messages, you need to have a category to log under. We
+recommend that you have one category per library or application, and that you
+create sub-categories beneath that to divide the library (or app) into logical
+units.
+
+Categories should be declared in headers, and defined in C files. You declare
+a category thusly:
+
+ NSLOG_DECLARE_CATEGORY(catname);
+
+In that `catname` is a valid suffix for a C identifier, and will be used as
+the logical name of the category for the purpose of NSLOG statements.
+
+You define a category thusly:
+
+ NSLOG_DEFINE_CATEGORY(catname, description);
+
+In that `catname` matches the above, and `description` is a C string (or
+identifier to a C string) which describes the category.
+
+You define a subcategory thusly:
+
+ NSLOG_DEFINE_SUBCATEGORY(parentcatname, catname, description);
+
+In that `parentcategory` is the `catname` of another category which will be
+considered the parent of this subcategory. `catname` and `description` as
+above. Subcategories are rendered with slashes between their names when shown
+as text, so a category of `foo` with a subcategory of `bar` would result in
+two categories, one `foo` and one `foo/bar`.
+
+Once you have categories, you can log stuff. Your categories don't have to be
+entirely public, but you will need access to the symbol to be able to log
+things with the given category. To log something, you use:
+
+ NSLOG(catname, level, logmsg, args...);
+
+In that `catname` is a `catname` from the above, `level` is a bareword logging
+level which will be prefixed with `NSLOG_LEVEL_` for use (e.g. you can use
+`WARNING` directly). `logmsg` and `args...` are a `printf()` style log message
+which will be rendered by the time `NSLOG()` returns, so you don't have to
+worry about lifetimes.
+
+Lib NSLOG lets you define a minimum compiled-in logging level which can be used
+to elide deep debugging in release builds. The `NSLOG()` macro expands to a
+constant comparison which will be resolved at compile time (assuming
+optimisations are turned on) to result in logging which doesn't need to be
+compiled in, being compiled out (and thus is is basically zero-cost to sprinkle
+deep debugging in your code).
+
+Being a libnslog client
+-----------------------
+
+In order for code which uses `NSLOG()` to be hosted effectively, the client must
+do two things. Firstly a callback must be provided. The simplest callback
+would be:
+
+ static nslog__client_callback(void *context, nslog_entry_context_t *ctx,
+ const char *fmt, va_list args)
+ {
+ (void)context;
+ (void)ctx;
+ (void)fmt;
+ va_start(args, fmt);
+ va_end(args);
+ }
+
+In that `context` is a `void*` which is passed through to the client code
+directly, allowing a client to provide some struct or other through to the
+logging client callback. `ctx` is an NSLOG context which you can find out more
+about by reading the docs. It contains the information about the logging
+*site* such as the filename, line number, function name, level, and category
+used to make the log entry. `fmt` is the `logmsg` from above, and `args`
+is the variadic argument set used to format the arguments.
+
+This callback is registered into Lib NSLOG with something like:
+
+ nslog_set_render_callback(nslog__client_callback, NULL);
+
+If a callback is not set, then bad things will happen when the next thing is
+run. The final thing which must happen before the client will receive log
+statements is that the client must _uncork_ the logging library. Since logging
+can occur **before** the client is ready, the library will render and store the
+log messages in a list, awaiting the call to uncork. Once uncorked, log
+messages will be passed through as flatly as possible to the client. To uncork
+the library, call:
+
+ nslog_uncork();
+
+All corked messages will be passed to the client callback, in the order they
+were logged, before the uncork call returns.
+
+Filtering logs
+--------------
+
+The primary way to filter logs is to simply compile out the logging levels you
+do not wish to exist. Sadly this is a very coarse filter and is best used to
+exclude deep debug (and possibly debug) from release builds. If you wish to
+filter your logs more flexibly at runtime, then you need to set up a log
+filter. You *can* build the filters "by hand" but much easier is to use the
+text filter parser as such:
+
+ nslog_filter_t *filter = NULL;
+ if (nslog_filter_from_text(my_filter_text, &output) == NSLOG_NO_ERROR) {
+ nslog_filter_set_active(filter, NULL);
+ nslog_filter_unref(filter);
+ }
+
+The filter syntax is fairly simple:
+
+* A `filter` is one of a `NOT` an `AND`, `OR`, or `XOR`, or a `simple` filter.
+* a `NOT` filter is of the form `!filter`
+* an `AND` filter is of the form `(filter && filter)`
+* an `OR` filter is of the form `(filter || filter)`
+* an `XOR` filter is of the form `(filter ^ filter)`
+* A `simple` filter is one of a `level`, `category`, `filename`, `dirname`,
+ or `funcname` filter.
+* a `level` filter is of the form `level: FOOLEVEL` where `FOOLEVEL` is one of
+ `DEEPDEBUG`, `DEBUG`, `VERBOSE`....
+* a `category` filter is of the form `cat: catname` where `catname` is a
+ category name. If it is of the form `foo` then it will match all categories
+ `foo` or `foo/*` but not `foobar`
+* a `filename` filter is of the form `file: filename` and is essentially a
+ suffix match on the filename. `foo.c` will match `foo.c` and `bar/foo.c`
+ but not `barfoo.c`
+* a `dirname` filter is of the form `dir: dirname` and is essentially a prefix
+ match on the filename. `foo` will match `foo/bar.c` and `foo/bar/baz.c` but
+ not `foobar.c`
+
+Between tokens, any amount of whitespace is valid, but canonically only a small
+amount will be used. You can take any filter you have and re-render it in its
+canonical text form by using `nslog_filter_sprintf()` which is documented.
+
+Filters are evaluated in standard order, with parentheses doing the obvious
+thing. In addition, the `AND` and `OR` filters will short-circuit as you'd
+expect, so you can use that to your advantage to make your filters efficient.
+Internally, Lib NSLOG will cache filtering intermediates to make things as fast
+as possible, but a badly designed filter will end up slowing things down
+dramatically.
--
NetSurf Parametric Logging Library
5 years, 10 months