netsurf: branch dsilvers/eventtarget updated. release/3.6-220-gbfde01c
by NetSurf Browser Project
Gitweb links:
...log http://git.netsurf-browser.org/netsurf.git/shortlog/bfde01c854284a9dcf1ae...
...commit http://git.netsurf-browser.org/netsurf.git/commit/bfde01c854284a9dcf1ae1e...
...tree http://git.netsurf-browser.org/netsurf.git/tree/bfde01c854284a9dcf1ae1e11...
The branch, dsilvers/eventtarget has been updated
discards 6b9a2e3aba35ea890604356fcf888268667ab9c5 (commit)
discards c0aadc56162e73509a1557e2cd69e2fd6125cf8f (commit)
discards bf80b18929da2dc3beb36aa96a6cea645e4088ef (commit)
via bfde01c854284a9dcf1ae1e11639566c79cf8019 (commit)
via 238d03fbe245b45e25033796b502b1ee3eab8e31 (commit)
via ce43bc236847b51e7ca833ea76c237130c1d6209 (commit)
via 1f52b2d514ac12bfbcb97f4ed3eb556d5e38739d (commit)
via b23f55c81bca21de7841111ace809df0f6408d65 (commit)
via e96bf013394c0dd06cb25e666e8c68d22c12a318 (commit)
via 6075feb4875ed2035de460fcdc7858f314ad0bef (commit)
via 11f11e0a7f8f7dd03d5b1fc22a8e54af305fbe6f (commit)
via 10248264ff43a917dd18796daa61ee5a5f1229d5 (commit)
via d1246c20612c6f6ad23b0e47497949bf2c0ec0a6 (commit)
via 70d700b26c13e04b601c4ac3db09514db473d01c (commit)
via a99c7a5c44fdd3f6ee1a0ec2b9beb5a1d6a32501 (commit)
via 2083375ec45d159a916caee3b7b570aa6670684c (commit)
via 53ce28c170ac5264405a7a12a718cf57a382518d (commit)
via d871be3ea00ef74ab28b936526768bbf121e3eb0 (commit)
via d843f78c202900409b0cd0c16397f6dae77bbe2b (commit)
via 9e814fd0f0f03584debb43b6d8acf144bd8675a2 (commit)
via b78d6f458e5d5cb9c78d7430aacf10abd227eb32 (commit)
via b8640956d48af03f2f7f6c07e66958fa825a4972 (commit)
via 8e7603e6a263eb765df4886a321537f209d88245 (commit)
via 606cc0c2196f5934a7c48e89ab05da7d5e05081f (commit)
via 52f98c9fb2b3dc04412ad25b7c24fa8cf357e78d (commit)
via 24fed9d51ccf3e786e59983ae84b4f13e68b0ea4 (commit)
via b6f7ea536cececaa07fb2c46c129675d91167177 (commit)
via e4d6d9a972736bbea70eb0af62a430e77cc05ee5 (commit)
via 313aaabdde2e6f0bb1f0dfe571b77261cc697a95 (commit)
via 9f10babe645fe67b02fae90f852d5e4cdfcbb70e (commit)
via 7dab7cb43d4091648ceb40684ff70aff7091c648 (commit)
via 0d9023148d2a34bd908aac38e44d449359b03438 (commit)
via 8ffc2e753b04a9e794e7a6302d57d590b311e41f (commit)
via 74e73a3b8b5ab3effd8e3d94c10463907d4c4ea9 (commit)
via 9e037376276aaa042b529499f1978766b9535f7b (commit)
via 439deddba14f509fa0be90beff07481643178b69 (commit)
via 4fab8f830bd4ffaf8faca408a5c1265887712704 (commit)
via c19ea4deaa61f8418db2c92f1843456be0389b7e (commit)
via 05e4463230d8ae9880ac3aef38ca12f09d30d960 (commit)
via 074afb43f424d671ce6d00b140df851a26f3ddd7 (commit)
via 3436c097d2be579440a021fe418d22957db7dbe6 (commit)
via bf3ba5c97bac5aa79c43153311ea0d3d5945bd4d (commit)
via 01e116ee1f5603ef6adeb365f403563a684a47b4 (commit)
via ae8959fa8b46fd21100b72669dcd4da03d91fd97 (commit)
via d885c79743a3169669d6400011ee667aa70e88d9 (commit)
via 22e25971ed4bc23d742cff7823a9f8224f544db7 (commit)
via 0f58d92ab6b4fa13e971b0b07d7ee58e7493c4ee (commit)
via 83840dca49ef6f720e825606555db19b2b659cc6 (commit)
via d1693c27c0d9658b655c158a9652f87683719325 (commit)
via 9be0f4ccaf9696173fb910660352be6648811040 (commit)
via a4bedbbaebec62294bcf6e7210c4c2b0b64f936c (commit)
via 917a602dce32286260a34d61b7c0db4bee502ec0 (commit)
via a86f2c8dd35c0cd8ba2f87097a68ad32373c28b5 (commit)
via 2d9ed9cbc4bd611d027b07f40bcf2dad68632857 (commit)
via 047b37d5f8c3810f8942f5744bb92640fbd4879f (commit)
via 5687f6c27d40ec596b4d64c705d16a97bdb3c893 (commit)
via e98a05bb087fb5c2c2ee8d94b3011ae8b3aa5c7a (commit)
via 6e957396a9bdc78a7d9823aaf76764bbb30c184a (commit)
via d6f6326ce9b6e60fcf9865e726b718ccfbbbea65 (commit)
via 26b98ac51b2f5a7c3d35050fcf79f521bfdb05f8 (commit)
via 57a2bb85992844b644433142e687940b3870ce40 (commit)
via 695783e33b9c100b1ce28ef71a59a00f52cc374f (commit)
via 2e11f7f3cbd7d563cb525a26ce79d76502ba7686 (commit)
via 5eb7ee97ed641e152c488dab6c33c37d0635e48b (commit)
via 3b1ef784fd53095213fa8b89806982567359dca4 (commit)
via 2bd8eb8c0b468799109191e63e939ea7bd69f8a1 (commit)
via 64bb74bdafa216d4163d6b717271a9f45ac0d287 (commit)
via 48e95ad2b3ede2b6170b635074bf0ee1010dfb39 (commit)
via eb63c1cc50847b88e598cdf0f775814a43a2799e (commit)
via 0fafa9576e8963928c13c81524e64b624b794c98 (commit)
via 4892497a19083cf328711f28376d16133a684353 (commit)
via 4b7abde7b0449a3a3fe03b43533b8d0697f55e0d (commit)
via 98f94c4bf39db60b0b686bccc84175e15214b348 (commit)
via e7c9b863b3d2dd8579cb2c9f80f4a20933d04315 (commit)
via a9cc0792a43d108e5ff61055354422a6c7218a74 (commit)
via a5222b579b8202f130e0afceb570b6e700385efe (commit)
via e3b2f792c0250d219dc56976f8305a05b6b04e36 (commit)
via 24b7fdf4382dcef274092b4735093fc390815455 (commit)
via dab118b6f7e9a22ed01413a2ce2fd60e4c4df97b (commit)
via 3227ed655609e731f3d216706c524028f566f114 (commit)
via eb1f39fe7d80893b1f7c804eb48ec61e89f17d78 (commit)
via 31c08f39be64f739cac727ab5a13fc513d1a61aa (commit)
via c40e8197c270b1600fa7b32056a2019cd83e6f3f (commit)
via 8196f5b60241a6389ca3b76446de131a3dd2e891 (commit)
via bb2341898113f37936832c8828bd515c3e3860c9 (commit)
via 86a0f14d0aa13c7808b57bbb6092ac6805babf02 (commit)
via 8af9a8407bc9f65fc34eecfe0fbd4beb6dacdfac (commit)
via 36b26b861f375de5b2be3ff9de37288049f05a26 (commit)
via 43bbdc520dd054acdf46088fbbee5d4a3b638d24 (commit)
via b7551fec72372df4cb40384818da5419904e4c98 (commit)
via 570212add2ec6b70474eb49b74259d7c73733c03 (commit)
via adac4d98bb9acdeb76725c946e53ff0e2c0235df (commit)
via 982a59744f634aee73dc11d4a30c93b4652a1e7e (commit)
via 205abcf18950bf3ee8600c4a4e4945b096985f9e (commit)
via 937dce4f2eef86c563bb93ded5c355c1446bf88c (commit)
via 493036a920aba5cf470637b7aa2ca69f7f57b41c (commit)
via a83afda7918cdb7ebc28db204ceb3e0f3d1cb0d3 (commit)
via 0804c43bf1afa0cb9d851ceb89e29ec8096f272f (commit)
via 5382ad2aa69b6ef8e479c5714052086eba8133b5 (commit)
via 48f868a9555be385f156e9396079ad5d0ee388f6 (commit)
via 76673bbf655592a62d21acfec860d5bf181bc848 (commit)
via 5e523b608a330c2c10f20a8913b7bad85388d475 (commit)
via 9df30eb78fc024448c39182a5d9fb0053c6ef137 (commit)
via d8eec1b048fe7c7cac4a0bd3bb4f31203524ee79 (commit)
via d9c8d1c70cac756d47586e2abf2dfbb9a1d96b59 (commit)
via d90e82d3f1c0ed0cdd665899c754b655f661976d (commit)
via 4893a9f9af8013fb81cdb81a4d49043719d0b851 (commit)
via 6ba5edaede1a04db5e374d94e8fd8d4d1fbc3f0a (commit)
via 47379c04442c805af95ba16b9932fbdb549a7594 (commit)
via 9379a64c6dfab6046ba56b8cdb299c4da3d6c3f2 (commit)
via 7ca75a4cee083ded7f3607bba5e841c430556d93 (commit)
via 7fc6e6c0c0053e5ca4f4e09e8f4457a8125a167c (commit)
via 32d2dda01c097be6a214499afa91d99bd198559e (commit)
via c60ab801f3cdd4cb7519245a9084fa7c6d4f66a8 (commit)
via 512a4335dae3fc27675cc6ba4ccfd219f20bfdba (commit)
via 354656b442cb9583fe8f690e9aa3e58ff50b6dce (commit)
via 4e5e9f1f5af2e526a87f38936aed0c4c100b5051 (commit)
via b6be869f19994070ec522d19455ea7eb47965be4 (commit)
via ded1979fa1b77ea6261df7a7f6f9177bde433f2d (commit)
via 7750d926adf3740448ec2fada2e207a4b5bd5851 (commit)
via 93fdbcc6de0d82323a67bc4c2d560f90a1f396cd (commit)
via b93ae2c28f2e1d3d4e0d20c5a5d09c930c49fb88 (commit)
via fb0cdfed79e5d55cf25a4e7866f0b084fde4ed2b (commit)
via 5f32f9ddd61ebd873ebb825c6e32d82e8965d840 (commit)
via e7598fb0b5c83fddca34d9f1adeb3c0989ce9ae5 (commit)
via 7b7b1507d01b3e078790150d6b5f59ebaf0b45c3 (commit)
via 2917af0a967bda993b8c1c5f194eea0b9881b6be (commit)
via 7aa1dd601e40d0684efbdd53b6ce5109846fcc37 (commit)
via 16b8d524e89e575230a46746bb117bc7f2a4f265 (commit)
via 07456db2dc6fc59a952e0160cb03ba494a05e05d (commit)
via 743637a8d2105df6ffc464a3cb4753cdc8c1401f (commit)
via 49b1b0b3a51092d7612e496ae6bc8d7d8651425b (commit)
via 96e073a29777bbe927f0bc7187f7032d3f51e68b (commit)
via af6139bcb5845d4cdbc852b113ac8fabcee29097 (commit)
via 337f9948d51d48f8b2a01694e07ea1bf4fa337af (commit)
via 72d3bec792c614783d6333267852675f14f7bf94 (commit)
via af3a78060fc18d1544b0d411d2d7584fcac9f3df (commit)
via 05a35725d19f9b5a2c8e347d638fb00dff21962f (commit)
via e2bad05338d5575bf485fbb509d496c5de012a64 (commit)
via c7cf2d18de0ac03ce4c6276072bc89fd847e3c22 (commit)
via c8c7de976a107c8e3362702f294f4f4d9c5ab7e4 (commit)
via 770c277ccc182f504be0a316390d59c05a59e041 (commit)
via 539d5da5c4b814322cfac07b825a2b222951dacd (commit)
via 7c03ae91fd8a99576cd5f0b8e5311f990ae5739b (commit)
via f68a3f9d61bf66640071ec2f32f7b2ed09215a87 (commit)
via f27cc16d426708c9267dcb290d4a32f2a5dcb686 (commit)
via d2742077b95cdc574c0b88284e5d04243de0ff9d (commit)
via b227be8cd2108405793e117fa150808dd6120f29 (commit)
via 71983d527ea86da0e8c8e2195715b9ca55b0de13 (commit)
via 54f01c7d7bb8a0b505ac6fabef252d332152f29d (commit)
via 6c441fd4b1a8d9be2a84b4ea9ba2a4e90857be3e (commit)
via 7a5b50be940de2d6156e756482a2297014fb620b (commit)
via 9d77dc83bdd86f3a46ff00102a43c46718dac00b (commit)
via f04103398b284b9defb85c98d3079b0dfc43a15e (commit)
via 407e58406b7a89b9c15a7e40c9b2bc26b866f31e (commit)
via 7318b5b65a2831b6cc6e87b51b6dcedc5a946c78 (commit)
via 4ad375c3b0e3f65416c02ca7b126b2e7fe375db1 (commit)
via ba0895121b44b21d351ee69a07613f524f322617 (commit)
via 9d694f56bbe28ba61eeeffd7472a4b7962a513c0 (commit)
via 433418a8e9655fe19ab704129ee652b7316dc343 (commit)
via 34a587849c9999f12d4199d744e7c72204369eab (commit)
via 68e8152f3eb95395cd47e0d703ed709e4ddaef89 (commit)
via 8f9a652774bbf1bdb469e0e7280a28983559b90d (commit)
via ecf2fdf6122eb6c11b66d08ab2d7b4079a1df108 (commit)
via 74d7c2d2c2b2161701c1f0258bbfc7feb753ac1e (commit)
via a440907b78f430ff7428e48f6fb0532db5f00cd5 (commit)
via c0a15de1e4609e942c037c340c5fed3c5bce839d (commit)
via 2b6a416970f3eff764f4a053cdade46566ce7dc7 (commit)
via f38b72a5833bfd9967308d6667c45c58a0ed10b8 (commit)
via 2dd97b0b8e1f363542dddb403d515cce132b7f29 (commit)
via 4b91c43003cdcbca09a72ce408d1e8cb93ad83e6 (commit)
via 2fe884be6532bb86ed8e2f2aa3d278ebaee6a406 (commit)
via 71afaacc80c6d94e1406249c61c338a4131d24a7 (commit)
via 2a9e89de751b6a6600feee2bc3960affb73c6988 (commit)
via 54e31b65d14dd1e228106eae0c60ab42802a97ed (commit)
via 4a93beb0393a8abddeb606cbb29a99bc1d73b67e (commit)
via 0bc32aa654271fd592d36fabf272e3fa0ca0a450 (commit)
via 4fb38f574a303d53fb3e4560e76163e4e97687b3 (commit)
via a76a36915c7d348582f905629fa0840a88b02edb (commit)
via c4b8857789e3f79a2ae0f7abe108999bf323b01a (commit)
via 20432237883a04677f30f1758979fa0a4b9111e3 (commit)
via f8f802cda5f54c0c2b1acd51efc08aa7d4afad1b (commit)
via af1f1f375d0f0fdaf885f72fdbcd873f2203d227 (commit)
via 67b7854737f23f76b700a6fe76ce6060435f5cff (commit)
via 811d7b71758917919a0c94b1289bd5608119ccc5 (commit)
via 540c6ee0ef432dfad375d64afa2c67d410f826d5 (commit)
via cd3720d5b63147fb97f3b7cdd056d3e8e6cc5586 (commit)
via 3f88c12315556d6f5f928c7e6a5e56357899ece7 (commit)
via 356e92c604ec6ab218302cfc1704f04ae171ddeb (commit)
via 30ca72b32eba20793b2888be35992fdc5dae375b (commit)
via b5fd0ae1ed4558b50cb7e3002e8f0c7042a4617d (commit)
via 31b1c72ddc66512c3a9cef4e59b94bdafc713ad4 (commit)
via 35146ef0c8f72526683f306a07d5cc70a070fe85 (commit)
via bcce8cc7b41f869fa2b022f85622cd389082d0f5 (commit)
via f679a9b1d6b652e06c24d543c7c5921753e3071b (commit)
via d436992eb2a28e2e056e96e42072b13d89b44a0b (commit)
via 5ce3b934571906c012567d898d83c652fad30567 (commit)
via 17128fd0ad119c801a17e06da1fd8b351fb17f21 (commit)
via b3042f6c1fcb708d8663f4ab51865fe6a1f8bec3 (commit)
via 9ff13d64c4ea9b3539f9b162bc8c70f2a30f288e (commit)
via 8828bdc7021714621ebef63e847c2998658b4863 (commit)
via 8acb224e90a03175133f8b295229b6f0e096177d (commit)
via 4bd4f3e82bc77c18ae38a8db94c0ad74747930b0 (commit)
via e8a9e3744523671228fef385ce7e1e11f93283b0 (commit)
via 3ab8032f1679c2a3526ccd458eb130c0d0f917bc (commit)
via eab6c0c99e29e10a3ac409b8de7c0e39ef918358 (commit)
via 15a68714919c64edc04d6e26679fabb490bdf9a2 (commit)
via 0513782fe3bb2884d0f63fb11c69f06055332388 (commit)
via 05fa29ba8bc2dbfaa9af7ed1263554c7cdc9214d (commit)
via 4f0c9b6c610d1eb9a5bcccf6dbf3f53410df9432 (commit)
via faf4c1fb6012941134046db14370f60748184b05 (commit)
via 2c6f2f4ef5a50c36676308f6663c0d21edc6aa70 (commit)
via a8bd2af7103bca7145f8c566ec46f27e2be8d182 (commit)
via 61a00c3832332bc27b991d3e20702a7f900e5098 (commit)
via 81a7e0cbe9851c2388e53950a6db3e75b1156ead (commit)
via cdde777d9cf157460201c59c5cc05c7479c3f830 (commit)
via 4b1b79582c5de530100b4ddb909163a6fb9b23c8 (commit)
via 6951d2327b0f0b6999f66452d5c38d74136cdb12 (commit)
via ec239402eac198af635f14970bf411e5690dd02e (commit)
This update added new revisions after undoing existing revisions. That is
to say, the old revision is not a strict subset of the new revision. This
situation occurs when you --force push a change and generate a repository
containing something like this:
* -- * -- B -- O -- O -- O (6b9a2e3aba35ea890604356fcf888268667ab9c5)
\
N -- N -- N (bfde01c854284a9dcf1ae1e11639566c79cf8019)
When this happens we assume that you've already had alert emails for all
of the O revisions, and so we here report only the revisions in the N
branch from the common base, B.
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=bfde01c854284a9dcf1...
commit bfde01c854284a9dcf1ae1e11639566c79cf8019
Author: Daniel Silverstone <dsilvers(a)digital-scurf.org>
Commit: Daniel Silverstone <dsilvers(a)digital-scurf.org>
Oops ' ' -> _
diff --git a/content/handlers/javascript/duktape/EventTarget.bnd b/content/handlers/javascript/duktape/EventTarget.bnd
index 9f7c91a..fb20883 100644
--- a/content/handlers/javascript/duktape/EventTarget.bnd
+++ b/content/handlers/javascript/duktape/EventTarget.bnd
@@ -43,8 +43,8 @@ static void event_target_push_listeners(duk_context *ctx) {
/* ... listeners type ??? */
duk_pop(ctx);
duk_push_object(ctx);
- duk dup(ctx, -2);
- duk dup(ctx, -2);
+ duk_dup(ctx, -2);
+ duk_dup(ctx, -2);
/* ... listeners type sublisteners type sublisteners */
duk_put_prop(ctx, -5);
/* ... listeners type sublisteners */
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=238d03fbe245b45e250...
commit 238d03fbe245b45e25033796b502b1ee3eab8e31
Author: Daniel Silverstone <dsilvers(a)digital-scurf.org>
Commit: Daniel Silverstone <dsilvers(a)digital-scurf.org>
More useful utilities for event listeners
diff --git a/content/handlers/javascript/duktape/EventTarget.bnd b/content/handlers/javascript/duktape/EventTarget.bnd
index a53e71d..9f7c91a 100644
--- a/content/handlers/javascript/duktape/EventTarget.bnd
+++ b/content/handlers/javascript/duktape/EventTarget.bnd
@@ -17,24 +17,69 @@ prologue EventTarget()
#define EVENT_LISTENER_JS_MAGIC MAGIC(EVENT_LISTENER_JS_MAP)
static void event_target_push_listeners(duk_context *ctx) {
- /* ... (this=EventTarget) */
+ /* ... type (this=EventTarget) */
duk_push_this(ctx);
- /* ... this */
+ /* ... type this */
duk_get_prop_string(ctx, -1, EVENT_LISTENER_JS_MAGIC);
if (duk_is_null(ctx, -1)) {
- /* ... this null */
+ /* ... type this null */
duk_pop(ctx);
duk_push_object(ctx);
duk_dup(ctx, -1);
- /* ... this listeners listeners */
+ /* ... type this listeners listeners */
duk_put_prop_string(ctx, -3, EVENT_LISTENER_JS_MAGIC);
- /* ... this listeners */
+ /* ... type this listeners */
}
- /* ... this listeners */
- duk_insert(ctx, -2);
- /* ... listeners this */
+ /* ... type this listeners */
+ duk_insert(ctx, -3);
+ /* ... listeners type this */
duk_pop(ctx);
- /* ... listeners */
+ /* ... listeners type */
+ duk_dup(ctx, -1);
+ /* ... listeners type type */
+ duk_get_prop(ctx, -3);
+ /* ... listeners type ??? */
+ if (duk_is_null(ctx, -1)) {
+ /* ... listeners type ??? */
+ duk_pop(ctx);
+ duk_push_object(ctx);
+ duk dup(ctx, -2);
+ duk dup(ctx, -2);
+ /* ... listeners type sublisteners type sublisteners */
+ duk_put_prop(ctx, -5);
+ /* ... listeners type sublisteners */
+ }
+ duk_insert(ctx, -3);
+ /* ... sublisteners listeners type */
+ duk_pop_2(ctx);
+ /* ... sublisteners */
+}
+
+typedef enum {
+ ELF_CAPTURE = 1 << 0,
+ ELF_PASSIVE = 1 << 1,
+ ELF_ONCE = 1 << 2,
+ ELF_NONE = 0
+} event_listener_flags;
+
+static event_listener_flags event_listener_pop_options(duk_context *ctx)
+{
+ event_listener_flags ret = ELF_NONE;
+ /* ... options */
+ duk_get_prop_string(ctx, -1, "capture");
+ if (duk_to_boolean(ctx, -1))
+ ret |= ELF_CAPTURE;
+ duk_pop(ctx);
+ duk_get_prop_string(ctx, -1, "passive");
+ if (duk_to_boolean(ctx, -1))
+ ret |= ELF_PASSIVE;
+ duk_pop(ctx);
+ duk_get_prop_string(ctx, -1, "once");
+ if (duk_to_boolean(ctx, -1))
+ ret |= ELF_CAPTURE;
+ duk_pop_2(ctx);
+ /* ... */
+ return ret;
}
%}
@@ -47,6 +92,7 @@ init EventTarget()
method EventTarget::addEventListener()
%{
dom_exception exc;
+ event_listener_flags flags = ELF_NONE;
/* Incoming stack is: type callback [options] */
if (duk_get_top(ctx) < 2) return 0; /* Bad arguments */
if (duk_get_top(ctx) > 3) return 0; /* Bad arguments */
@@ -64,8 +110,13 @@ method EventTarget::addEventListener()
/* ... options */
}
/* type callback options */
+ flags = event_listener_pop_options(ctx);
+ /* type callback */
+ duk_dup(ctx, -2);
+ /* type callback type */
event_target_push_listeners(ctx);
- /* type callback options listeners */
+ /* type callback typelisteners */
+
return 0;
%}
commitdiff http://git.netsurf-browser.org/netsurf.git/commit/?id=ce43bc236847b51e7ca...
commit ce43bc236847b51e7ca833ea76c237130c1d6209
Author: Daniel Silverstone <dsilvers(a)digital-scurf.org>
Commit: Daniel Silverstone <dsilvers(a)digital-scurf.org>
Early bits for event targets, nowhere near ready yet
diff --git a/content/handlers/javascript/duktape/EventTarget.bnd b/content/handlers/javascript/duktape/EventTarget.bnd
new file mode 100644
index 0000000..a53e71d
--- /dev/null
+++ b/content/handlers/javascript/duktape/EventTarget.bnd
@@ -0,0 +1,123 @@
+/* Event Target binding for browser using duktape and libdom
+ *
+ * Copyright 2016 Daniel Silverstone <dsilvers(a)digital-scurf.org>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * Released under the terms of the MIT License,
+ * http://www.opensource.org/licenses/mit-license
+ */
+
+class EventTarget {
+ private bool is_node;
+};
+
+prologue EventTarget()
+%{
+#define EVENT_LISTENER_JS_MAGIC MAGIC(EVENT_LISTENER_JS_MAP)
+
+static void event_target_push_listeners(duk_context *ctx) {
+ /* ... (this=EventTarget) */
+ duk_push_this(ctx);
+ /* ... this */
+ duk_get_prop_string(ctx, -1, EVENT_LISTENER_JS_MAGIC);
+ if (duk_is_null(ctx, -1)) {
+ /* ... this null */
+ duk_pop(ctx);
+ duk_push_object(ctx);
+ duk_dup(ctx, -1);
+ /* ... this listeners listeners */
+ duk_put_prop_string(ctx, -3, EVENT_LISTENER_JS_MAGIC);
+ /* ... this listeners */
+ }
+ /* ... this listeners */
+ duk_insert(ctx, -2);
+ /* ... listeners this */
+ duk_pop(ctx);
+ /* ... listeners */
+}
+
+%}
+
+init EventTarget()
+%{
+ priv->is_node = false;
+%}
+
+method EventTarget::addEventListener()
+%{
+ dom_exception exc;
+ /* Incoming stack is: type callback [options] */
+ if (duk_get_top(ctx) < 2) return 0; /* Bad arguments */
+ if (duk_get_top(ctx) > 3) return 0; /* Bad arguments */
+ if (duk_get_top(ctx) == 2) {
+ duk_push_object(ctx);
+ /* type callback options */
+ }
+ if (duk_get_type(ctx, -1) != DUK_TYPE_OBJECT) {
+ /* legacy support, if not object, it's the capture value */
+ duk_push_object(ctx);
+ /* ... capture options */
+ duk_insert(ctx, -2);
+ /* ... options capture */
+ duk_put_prop_string(ctx, -2, "capture");
+ /* ... options */
+ }
+ /* type callback options */
+ event_target_push_listeners(ctx);
+ /* type callback options listeners */
+ return 0;
+%}
+
+method EventTarget::removeEventListener()
+%{
+ dom_exception exc;
+ return 0;
+%}
+
+
+
+method EventTarget::dispatchEvent()
+%{
+ dom_exception exc;
+ if (!dukky_instanceof(ctx, 0, PROTO_NAME(EVENT))) return 0;
+
+ duk_get_prop_string(ctx, 0, PRIVATE_MAGIC);
+ event_private_t *evpriv = duk_get_pointer(ctx, -1);
+ duk_pop(ctx);
+
+ dom_event *evt = evpriv->evt;
+
+ /* Dispatch event logic, see:
+ * https://dom.spec.whatwg.org/#dom-eventtarget-dispatchevent
+ */
+ bool in_dispatch;
+ if (dom_event_in_dispatch(evt, &in_dispatch) != DOM_NO_ERR) return 0;
+ if (in_dispatch) {
+ /** \todo Raise InvalidStateException */
+ return 0;
+ }
+
+ bool is_initialised;
+ if (dom_event_is_initialised(evt, &is_initialised) != DOM_NO_ERR) return 0;
+ if (is_initialised == false) {
+ /** \todo Raise InvalidStateException */
+ return 0;
+ }
+
+ if (dom_event_set_is_trusted(evt, false) != DOM_NO_ERR) return 0;
+
+ /** \todo work out how to dispatch against non-node things */
+ if (priv->is_node == false) return 0;
+
+ bool success;
+ /* Event prepared, dispatch against ourselves */
+ exc = dom_event_target_dispatch_event(
+ ((node_private_t *)priv)->node,
+ evt,
+ &success);
+ if (exc != DOM_NO_ERR) return 0; /**< \todo raise correct exception */
+
+ duk_push_boolean(ctx, success);
+ return 1;
+%}
diff --git a/content/handlers/javascript/duktape/Node.bnd b/content/handlers/javascript/duktape/Node.bnd
index f237c87..f14cfc1 100644
--- a/content/handlers/javascript/duktape/Node.bnd
+++ b/content/handlers/javascript/duktape/Node.bnd
@@ -16,6 +16,7 @@ init Node(struct dom_node *node)
%{
priv->node = node;
dom_node_ref(node);
+ priv->parent.is_node = true;
%}
fini Node()
diff --git a/content/handlers/javascript/duktape/netsurf.bnd b/content/handlers/javascript/duktape/netsurf.bnd
index 4aca475..2a56ccc 100644
--- a/content/handlers/javascript/duktape/netsurf.bnd
+++ b/content/handlers/javascript/duktape/netsurf.bnd
@@ -54,6 +54,7 @@ struct dom_html_br_element;
};
+#include "EventTarget.bnd"
#include "Console.bnd"
#include "Window.bnd"
#include "Document.bnd"
-----------------------------------------------------------------------
Summary of changes:
!NetSurf/Resources/nl/welcome.html,faf | 1 -
.gitignore | 6 +-
Docs/core-window-interface | 2 +-
Docs/source-object-backing-store | 46 +-
Makefile | 12 +-
content/backing_store.h | 22 +-
content/content.c | 4 +-
content/fetch.c | 8 -
content/fetch.h | 7 -
content/fetchers/curl.c | 34 +-
content/fetchers/data.c | 3 +-
content/fetchers/file.c | 1 +
content/fetchers/resource.c | 1 +
content/fs_backing_store.c | 111 +-
content/handlers/css/hints.h | 4 +-
content/handlers/css/select.c | 1 +
content/handlers/image/image_cache.c | 98 +-
content/handlers/image/png.c | 1 +
content/handlers/javascript/duktape/Makefile | 5 +-
content/handlers/javascript/duktape/duk_config.h | 4 +-
content/handlers/javascript/duktape/dukky.c | 7 +-
content/handlers/javascript/duktape/duktape.c | 407 +++--
content/handlers/javascript/duktape/duktape.h | 23 +-
content/hlcache.c | 11 +-
content/llcache.c | 98 +-
desktop/Makefile | 4 +-
desktop/browser_history.c | 126 +-
desktop/browser_private.h | 3 +-
desktop/cookie_manager.c | 1 +
desktop/font_haru.h | 1 -
desktop/global_history.c | 1 +
desktop/hotlist.c | 39 +-
desktop/hotlist.h | 36 +-
desktop/knockout.c | 2 +-
desktop/netsurf.c | 5 +-
desktop/options.h | 2 +-
desktop/plot_style.c | 15 +-
desktop/scrollbar.c | 6 +-
desktop/searchweb.c | 12 +-
desktop/system_colour.h | 2 +-
desktop/textarea.h | 4 +-
desktop/treeview.c | 173 ++-
desktop/treeview.h | 22 +
frontends/amiga/Makefile | 11 +-
frontends/amiga/arexx.c | 30 +-
frontends/amiga/bitmap.c | 93 +-
frontends/amiga/bitmap.h | 10 +-
frontends/amiga/clipboard.c | 19 +-
frontends/amiga/cookies.c | 381 ++++-
frontends/amiga/cookies.h | 11 +-
frontends/amiga/corewindow.c | 1002 ++++++++++++
frontends/amiga/corewindow.h | 188 +++
frontends/amiga/dist/NetSurf.guide | 6 +-
frontends/amiga/download.c | 33 +-
frontends/amiga/download.h | 2 -
frontends/amiga/dt_anim.c | 5 +-
frontends/amiga/file.c | 15 +-
frontends/amiga/file.h | 4 +-
frontends/amiga/filetype.c | 5 +-
frontends/amiga/font.c | 2 +
frontends/amiga/font_bullet.c | 7 +-
frontends/amiga/font_cache.c | 2 +-
frontends/amiga/font_diskfont.c | 43 +-
frontends/amiga/font_diskfont.h | 1 +
frontends/amiga/font_scan.c | 10 +-
frontends/amiga/gui.c | 1602 ++++++++++----------
frontends/amiga/gui.h | 71 +-
frontends/amiga/gui_menu.c | 1123 ++++++++++++++
frontends/amiga/{menu.h => gui_menu.h} | 69 +-
frontends/amiga/gui_options.c | 39 +-
frontends/amiga/gui_options.h | 2 -
frontends/amiga/history.c | 457 +++++-
frontends/amiga/history.h | 16 +-
frontends/amiga/history_local.c | 30 +-
frontends/amiga/history_local.h | 12 +-
frontends/amiga/hotlist.c | 528 ++++++-
frontends/amiga/hotlist.h | 22 +-
frontends/amiga/icon.c | 13 +-
frontends/amiga/iff_dr2d.c | 29 +-
frontends/amiga/launch.c | 30 +-
frontends/amiga/login.c | 22 +-
frontends/amiga/login.h | 4 +-
frontends/amiga/memory.c | 169 +++
frontends/amiga/memory.h | 68 +
frontends/amiga/menu.c | 1124 +++-----------
frontends/amiga/menu.h | 153 +-
frontends/amiga/misc.c | 52 -
frontends/amiga/misc.h | 9 -
frontends/amiga/object.c | 40 +-
frontends/amiga/object.h | 1 +
frontends/amiga/options.h | 5 +-
frontends/amiga/os3support.c | 317 ++--
frontends/amiga/os3support.h | 1 -
frontends/amiga/plotters.c | 40 +-
frontends/amiga/print.c | 40 +-
frontends/amiga/print.h | 10 +-
frontends/amiga/schedule.c | 2 +-
frontends/amiga/schedule.h | 1 +
frontends/amiga/search.c | 22 +-
frontends/amiga/search.h | 5 -
frontends/amiga/sslcert.c | 361 ++++-
frontends/amiga/sslcert.h | 22 +-
frontends/amiga/theme.c | 16 +-
frontends/amiga/tree.c | 1474 ------------------
frontends/amiga/tree.h | 48 -
frontends/amiga/version.c | 12 +-
frontends/atari/Makefile | 14 +-
frontends/atari/bitmap.c | 2 +-
frontends/atari/cookies.c | 1 +
frontends/atari/deskmenu.c | 1 +
frontends/atari/download.c | 2 +-
frontends/atari/font.c | 2 +-
frontends/atari/gemtk/guiwin.c | 94 +-
frontends/atari/gemtk/objc.c | 2 +
frontends/atari/gui.c | 14 +-
frontends/atari/hotlist.c | 16 +-
frontends/atari/hotlist.h | 1 -
frontends/atari/misc.c | 1 -
frontends/atari/plot/font_freetype.c | 7 +-
frontends/atari/plot/font_internal.c | 4 +-
frontends/atari/plot/fontplot.c | 2 +-
frontends/atari/redrawslots.h | 4 +-
frontends/atari/rootwin.c | 4 +-
frontends/atari/settings.c | 7 +-
frontends/atari/toolbar.c | 2 -
frontends/atari/treeview.c | 23 +-
frontends/beos/Makefile | 20 +-
frontends/beos/cookies.cpp | 1 -
frontends/beos/fetch_rsrc.cpp | 1 -
frontends/beos/font.h | 2 +-
frontends/beos/gui.cpp | 29 +-
frontends/beos/scaffolding.cpp | 81 +-
frontends/beos/scaffolding.h | 2 +-
frontends/beos/window.cpp | 3 +-
frontends/cocoa/BookmarksController.m | 2 +-
frontends/cocoa/FormSelectMenu.m | 2 +-
frontends/cocoa/Makefile | 11 +-
frontends/cocoa/NetsurfApp.m | 2 +-
frontends/cocoa/Tree.h | 2 +-
frontends/cocoa/Tree.m | 2 +-
desktop/tree.h => frontends/cocoa/desktop-tree.h | 0
desktop/tree.c => frontends/cocoa/desktop-tree.m | 16 +-
frontends/cocoa/font.h | 2 +-
frontends/cocoa/plotter.h | 2 +-
frontends/cocoa/plotter.m | 1 -
frontends/framebuffer/Makefile | 4 +-
frontends/framebuffer/Makefile.defaults | 2 +-
frontends/framebuffer/convert_image.c | 2 +-
frontends/framebuffer/fbtk.h | 2 +-
frontends/framebuffer/fbtk/user.c | 1 -
frontends/framebuffer/font_freetype.c | 12 +-
frontends/framebuffer/font_internal.c | 9 +-
frontends/gtk/Makefile | 6 +-
frontends/gtk/corewindow.c | 27 +-
frontends/gtk/gui.c | 2 +
frontends/gtk/hotlist.c | 13 +-
frontends/gtk/layout_pango.c | 1 +
frontends/gtk/plotters.c | 1 -
frontends/gtk/toolbar.c | 1 -
frontends/gtk/window.c | 3 +-
frontends/monkey/layout.c | 2 +-
frontends/riscos/Makefile | 17 +-
frontends/riscos/configure/con_fonts.c | 2 +-
frontends/riscos/cookies.c | 517 ++++---
frontends/riscos/cookies.h | 49 +-
frontends/riscos/corewindow.c | 935 ++++++++++++
frontends/riscos/corewindow.h | 139 ++
frontends/riscos/dialog.c | 13 +-
frontends/riscos/font.c | 1 +
frontends/riscos/font.h | 5 +-
frontends/riscos/global_history.c | 534 ++++---
frontends/riscos/global_history.h | 40 +-
frontends/riscos/gui.c | 23 +-
frontends/riscos/gui.h | 5 -
frontends/riscos/gui/button_bar.h | 24 -
frontends/riscos/gui/url_bar.c | 5 +-
frontends/riscos/gui/url_bar.h | 1 +
frontends/riscos/help.c | 8 +-
frontends/riscos/hotlist.c | 860 ++++++-----
frontends/riscos/hotlist.h | 59 +-
frontends/riscos/iconbar.c | 11 +-
frontends/riscos/image.h | 2 +-
frontends/riscos/menus.c | 1 -
frontends/riscos/plotters.c | 1 -
frontends/riscos/print.c | 1 -
frontends/riscos/save_draw.c | 1 -
frontends/riscos/sslcert.c | 496 +++---
frontends/riscos/sslcert.h | 27 +-
frontends/riscos/templates/de | 2 +-
frontends/riscos/templates/en | 2 +-
frontends/riscos/templates/fr | 2 +-
frontends/riscos/templates/nl | 2 +-
frontends/riscos/theme.c | 2 +-
frontends/riscos/toolbar.c | 1 -
frontends/riscos/treeview.c | 1277 ----------------
frontends/riscos/treeview.h | 55 -
frontends/riscos/url_complete.h | 3 +-
frontends/riscos/window.c | 21 +-
frontends/windows/Makefile | 29 +-
frontends/windows/about.c | 1 -
frontends/windows/corewindow.c | 14 +-
frontends/windows/drawable.c | 1 -
frontends/windows/filetype.c | 1 -
frontends/windows/font.c | 27 +-
frontends/windows/font.h | 4 +-
frontends/windows/gui.c | 1 -
frontends/windows/hotlist.c | 15 +-
frontends/windows/localhistory.c | 1 -
frontends/windows/main.c | 2 +
frontends/windows/plot.c | 1 -
frontends/windows/pointers.c | 1 -
frontends/windows/prefs.c | 1 -
frontends/windows/res/installer.nsi | 67 +-
frontends/windows/schedule.c | 1 -
include/netsurf/clipboard.h | 2 +-
include/netsurf/content.h | 2 +-
include/netsurf/core_window.h | 24 +-
.../amiga/rtg.h => include/netsurf/inttypes.h | 50 +-
{desktop => include/netsurf}/plot_style.h | 166 +-
include/netsurf/plotters.h | 2 +-
desktop/gui_internal.h => include/netsurf/types.h | 24 +-
render/box.c | 6 +-
render/box_construct.c | 6 +-
render/font.c | 1 +
render/font.h | 4 +-
render/form.c | 13 +-
render/html.c | 1 +
render/html.h | 5 +-
render/html_css_fetcher.c | 10 +-
render/imagemap.c | 6 +-
render/search.c | 3 +-
resources/FatMessages | 9 +
test/Makefile | 11 +-
test/llcache.c | 1 -
utils/http/primitives.c | 2 +-
utils/idna.c | 6 +-
utils/messages.c | 25 +
utils/messages.h | 5 +
utils/nsoption.c | 2 +-
test-netsurf => utils/test-netsurf | 0
utils/utils.h | 33 +-
241 files changed, 10165 insertions(+), 7349 deletions(-)
mode change 100755 => 100644 frontends/amiga/cookies.c
mode change 100755 => 100644 frontends/amiga/cookies.h
create mode 100644 frontends/amiga/corewindow.c
create mode 100644 frontends/amiga/corewindow.h
create mode 100644 frontends/amiga/gui_menu.c
copy frontends/amiga/{menu.h => gui_menu.h} (63%)
mode change 100755 => 100644
mode change 100755 => 100644 frontends/amiga/history.c
mode change 100755 => 100644 frontends/amiga/history.h
mode change 100755 => 100644 frontends/amiga/hotlist.c
mode change 100755 => 100644 frontends/amiga/hotlist.h
create mode 100755 frontends/amiga/memory.c
create mode 100644 frontends/amiga/memory.h
mode change 100755 => 100644 frontends/amiga/menu.h
delete mode 100644 frontends/amiga/tree.c
delete mode 100755 frontends/amiga/tree.h
rename desktop/tree.h => frontends/cocoa/desktop-tree.h (100%)
rename desktop/tree.c => frontends/cocoa/desktop-tree.m (97%)
create mode 100644 frontends/riscos/corewindow.c
create mode 100644 frontends/riscos/corewindow.h
delete mode 100644 frontends/riscos/treeview.c
delete mode 100644 frontends/riscos/treeview.h
copy frontends/amiga/rtg.h => include/netsurf/inttypes.h (51%)
rename {desktop => include/netsurf}/plot_style.h (88%)
copy desktop/gui_internal.h => include/netsurf/types.h (64%)
rename test-netsurf => utils/test-netsurf (100%)
diff --git a/!NetSurf/Resources/nl/welcome.html,faf b/!NetSurf/Resources/nl/welcome.html,faf
index f35260b..aec47e7 100644
--- a/!NetSurf/Resources/nl/welcome.html,faf
+++ b/!NetSurf/Resources/nl/welcome.html,faf
@@ -3,7 +3,6 @@
<head>
<title>Welkom bij NetSurf</title>
<style type="text/css">html,body{margin:0;padding:0;}body{color:#000;background:#fff;font-family:sans-serif;margin:0 auto;}a:link{text-decoration:underline;color:#00f;}a:visited{text-decoration:underline;color:#60a;}a:hover{text-decoration:none;}a:active{text-decoration:underline;color:#f00;}.banner{margin:0;padding:0;background:#94adff;text-align:left;}.banner img{border:none;color:#000;height:86px;width:308px;display:block;}.onlycontent{margin:0 1em;}.nslinks{display:table;width:100%;margin:0;border-spacing:0;padding:0;background:#ccd8ff;font-size:88%;}.nslinks li{display:table-cell;text-align:center;padding:0.2em 0.3em 0.3em;vertical-align:middle;}.nslinks li+li{border-left:2px solid #b1c3ff;}.version{padding:0;margin:1.2em auto 0;width:90%;color:#444;font-size:160%;}.intro{width: 90%;margin:1em auto;color:#666;}.websearch{margin:1.5em auto;padding:1.2em 0.3em;background:#d8e2ff;border:2px solid #c5d3ff;width:80%;text-align:center;}input[type=text]{border:2px solid #b6c7ff;background:#f9faff;color:#000;margin:2px;}input[type=submit]{border:2px outset #cedaff;color:#000;background:#cedaff;margin:2px;}.links{display:table;width:80%;margin:0 auto 3em;font-size:94%;}.links p{display:table-cell;}.links ul{padding-left:0.8em;margin-top:-1em;}.links ul+ul{padding-left:1em;}.footer{font-style:italic;color:#666;text-align:right;}.footer p{margin-top:1.5em;padding-top:0.4em;border-top:2px solid #94adff;}</style>
-<link rel="icon" type="image/png" href="http://www.netsurf-browser.org/webimages/favicon.png">
</head>
<body>
diff --git a/.gitignore b/.gitignore
index b16d6f9..35de191 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,10 +16,6 @@ frontends/gtk/res/fr/Messages
frontends/gtk/res/de/Messages
frontends/gtk/res/nl/Messages
frontends/gtk/res/it/Messages
-test/nsoption
-test/nsurl
-test/urldbtest
-test/llcache
codedocs
nsgtk
nsfb
@@ -34,4 +30,4 @@ NetSurf.dmg
NetSurf
core
nsfb-*
-build-*
+build
diff --git a/Docs/core-window-interface b/Docs/core-window-interface
index 0267f37..3dfbcaf 100644
--- a/Docs/core-window-interface
+++ b/Docs/core-window-interface
@@ -259,7 +259,7 @@ frontends/example/corewindow.c
#include "utils/utf8.h"
#include "netsurf/keypress.h"
#include "netsurf/mouse.h"
-#include "desktop/plot_style.h"
+#include "netsurf/plot_style.h"
/* extremely likely there will be additional headers required in a real frontend */
#include "example/corewindow.h"
diff --git a/Docs/source-object-backing-store b/Docs/source-object-backing-store
index 5d4d304..0fb3614 100644
--- a/Docs/source-object-backing-store
+++ b/Docs/source-object-backing-store
@@ -5,30 +5,30 @@ Introduction
------------
The source object cache provides a system to extend the life of source
-objects (html files, images etc.) after they are no longer immediately
+objects (HTML files, images etc.) after they are no longer immediately
being used.
Only fetch types where we have well defined rules on caching are
considered, in practice this limits us to HTTP(S). The section in
RFC2616 [1] on caching specifies these rules.
-To futher extend the objects lifetime they can be pushed into a
+To further extend the objects lifetime they can be pushed into a
backing store where the objects are available for reuse less quickly
-than from RAM but faster than retriving from the network again.
+than from RAM but faster than retrieving from the network again.
The backing store implementation provides a key:value infrastructure
-with a simple store, retrive and invalidate interface.
+with a simple store, retrieve and invalidate interface.
Generic filesystem backing store
--------------------------------
Although the backing store interface is fully pluggable a generic
implementation based on storing objects on the filesystem in a
-heirachy of directories.
+hierarchy of directories.
-The option to alter the backing store format exists and is controled
+The option to alter the backing store format exists and is controlled
by a version field. It is implementation defined what happens if a
-version mis-match occours.
+version mis-match occurs.
As the backing store only holds cache data one should not expect a
great deal of effort to be expended converting formats (i.e. the cache
@@ -37,23 +37,23 @@ may simply be discarded).
Layout version 1.1
------------------
-An object has an identifier value generated from the url (NetSurf
-backing stores uses the url as the unique key). The value used is
+An object has an identifier value generated from the URL (NetSurf
+backing stores uses the URL as the unique key). The value used is
obtained using nsurl_hash() which is currently a 32 bit FNV so is
directly usable.
This identifier is adequate to ensure the collision rate for the
-hashed url values (a collision for every 2^16 urls added) is
+hashed URL values (a collision for every 2^16 URLs added) is
sufficiently low the overhead of returning the wrong object (which
-backing stores are permitted to do) is not significat.
+backing stores are permitted to do) is not significant.
An entry list is maintained which contains all the metadata about a
given identifier. This list is limited in length to constrain the
-resources necessary to maintain it. It is made persistant to avoid the
+resources necessary to maintain it. It is made persistent to avoid the
overhead of reconstructing it at initialisation and to keep the data
used to improve the eviction decisions.
-Each object is stored and retrived directly into the filesystem using
+Each object is stored and retrieved directly into the filesystem using
a filename generated from a RFC4648 base32 encoding of an address
value. The objects address is derived from the identifier by cropping
it to a shorter length.
@@ -63,7 +63,7 @@ uses storage directly proportional to the size of the address length.
The cropping length is stored in the control file with the default
values set at compile time. This allows existing backing stores to
-continue operating with existing data independantly of new default
+continue operating with existing data independently of new default
setting. This setting gives some ability to tune the default cache
index size to values suitable for a specific host operating system.
@@ -88,7 +88,7 @@ Version 1.0
The version 1 layout was identical to the 1.1 except base64url
encoding was used, this proved problematic as some systems filesystems
-were case insensitive so upper and lower case letetrs collided.
+were case insensitive so upper and lower case letters collided.
There is no upgrade provision from the previous version simply delete
the cache directory.
@@ -112,7 +112,7 @@ Each control file table entry is 28 bytes and consists of
- signed 64 bit value for last use time
- 32bit full url hash allowing for index reconstruction and
- addiitonal collision detection. Also the possibility of increasing
+ additional collision detection. Also the possibility of increasing
the ADDRESS_LENGTH although this would require renaming all the
existing files in the cache and is not currently implemented.
@@ -134,8 +134,8 @@ Address to entry index
An entry index is held in RAM that allows looking up the address to
map to an entry in the control file.
-The index is the only data structure whose size is directly depndant
-on the length of the hash specificaly:
+The index is the only data structure whose size is directly dependant
+on the length of the hash specifically:
(2 ^ (ADDRESS_BITS - 3)) * ENTRY_BITS) in bytes
@@ -152,9 +152,9 @@ list is limited to 448kilobytes.
The typical values for RISC OS would set ADDRESS_BITS to 18. This
spreads the entries over 262144 hash values which uses 512 kilobytes
for the index. Limiting the hash space like this reduces the
-efectiveness of the cache.
+effectiveness of the cache.
-A small ADDRESS_LENGTH causes a collision (two urls with the same
+A small ADDRESS_LENGTH causes a collision (two URLs with the same
address) to happen roughly for every 2 ^ (ADDRESS_BITS / 2) = 2 ^ 9 =
512 objects stored. This roughly translates to a cache miss due to
collision every ten pages navigated to.
@@ -164,7 +164,7 @@ Larger systems
In general ENTRY_BITS set to 16 as this limits the store to 65536
objects which given the average size of an object at 8 kilobytes
-yeilds half a gigabyte of disc used which is judged to be sufficient.
+yields half a gigabyte of disc used which is judged to be sufficient.
For larger systems e.g. those using GTK frontend we would most likely
select ADDRESS_BITS as 22 resulting in a collision every 2048 objects
@@ -176,11 +176,11 @@ Typical values
Example 1
~~~~~~~~~
-For a store with 1034 objects genrated from a random navigation of
+For a store with 1034 objects generated from a random navigation of
pages linked from the about:welcome page.
Metadata total size is 593608 bytes an average of 574 bytes. The
-majority of the storage is used to hold the urls and headers.
+majority of the storage is used to hold the URLs and headers.
Data total size is 9180475 bytes a mean of 8879 bytes 1648726 in the
largest 10 entries which if excluded gives 7355 bytes average size
diff --git a/Makefile b/Makefile
index f616c6d..5f2697f 100644
--- a/Makefile
+++ b/Makefile
@@ -44,7 +44,6 @@ HOST := $(shell uname -s)
# TODO: Ideally, we want the equivalent of s/[^A-Za-z0-9]/_/g here
HOST := $(subst .,_,$(subst -,_,$(subst /,_,$(HOST))))
-
ifeq ($(HOST),)
HOST := riscos
$(warning Build platform determination failed but that's a known problem for RISC OS so we're assuming a native RISC OS build.)
@@ -74,7 +73,7 @@ ifeq ($(HOST),beos)
TARGET := beos
endif
ifeq ($(TARGET),haiku)
- TARGET := beos
+ override TARGET := beos
endif
endif
@@ -298,9 +297,12 @@ else
CC := $(wildcard $(GCCSDK_INSTALL_CROSSBIN)/*gcc)
CXX := $(wildcard $(GCCSDK_INSTALL_CROSSBIN)/*g++)
endif
+
else
# All native targets
- PKG_CONFIG := pkg-config
+
+ # use native package config
+ PKG_CONFIG := pkg-config
# gtk target processing
ifeq ($(TARGET),gtk3)
@@ -342,7 +344,7 @@ endif
CC := $(CCACHE) $(CC)
# Target paths
-OBJROOT = build-$(HOST)-$(TARGET)$(SUBTARGET)
+OBJROOT = build/$(HOST)-$(TARGET)$(SUBTARGET)
DEPROOT := $(OBJROOT)/deps
TOOLROOT := $(OBJROOT)/tools
@@ -638,7 +640,7 @@ define split_messages
$$(MESSAGES_TARGET)/$(1)/Messages.tmp: resources/FatMessages
$$(VQ)echo "MSGSPLIT: Language: $(1) Filter: $$(MESSAGES_FILTER)"
- $$(Q)mkdir -p $$(MESSAGES_TARGET)/$(1)
+ $$(Q)$$(MKDIR) -p $$(MESSAGES_TARGET)/$(1)
$$(Q)$$(SPLIT_MESSAGES) -l $(1) -p $$(MESSAGES_FILTER) -f messages -o $$@ $$<
$$(MESSAGES_TARGET)/$(1)/Messages: $$(MESSAGES_TARGET)/$(1)/Messages.tmp
diff --git a/content/backing_store.h b/content/backing_store.h
index 4e29511..3a1ae8f 100644
--- a/content/backing_store.h
+++ b/content/backing_store.h
@@ -38,7 +38,7 @@ enum backing_store_flags {
* low level cache backing store operation table
*
* The low level cache (source objects) has the capability to make
- * objects and their metadata (headers etc) persistant by writing to a
+ * objects and their metadata (headers etc) persistent by writing to a
* backing store using these operations.
*/
struct gui_llcache_table {
@@ -46,14 +46,14 @@ struct gui_llcache_table {
* Initialise the backing store.
*
* @param parameters to configure backing store.
- * @return NSERROR_OK on success or error code on faliure.
+ * @return NSERROR_OK on success or error code on failure.
*/
nserror (*initialise)(const struct llcache_store_parameters *parameters);
/**
* Finalise the backing store.
*
- * @return NSERROR_OK on success or error code on faliure.
+ * @return NSERROR_OK on success or error code on failure.
*/
nserror (*finalise)(void);
@@ -72,16 +72,16 @@ struct gui_llcache_table {
* been completely written on return.
*
* @param[in] url The url is used as the unique primary key for the data.
- * @param[in] flags The flags to control how the obejct is stored.
+ * @param[in] flags The flags to control how the object is stored.
* @param[in] data The objects data.
* @param[in] datalen The length of the \a data.
- * @return NSERROR_OK on success or error code on faliure.
+ * @return NSERROR_OK on success or error code on failure.
*/
nserror (*store)(struct nsurl *url, enum backing_store_flags flags,
uint8_t *data, const size_t datalen);
/**
- * Retrive an object from the backing store.
+ * Retrieve an object from the backing store.
*
* The backing store will manage its own memory and the
* allocations returned in \a data *must* not be altered.
@@ -91,10 +91,10 @@ struct gui_llcache_table {
* calling the release method.
*
* @param[in] url The url is used as the unique primary key for the data.
- * @param[in] flags The flags to control how the object is retrived.
- * @param[out] data The retrived objects data.
+ * @param[in] flags The flags to control how the object is retrieved.
+ * @param[out] data The retrieved objects data.
* @param[out] datalen The length of the \a data retrieved.
- * @return NSERROR_OK on success or error code on faliure.
+ * @return NSERROR_OK on success or error code on failure.
*/
nserror (*fetch)(struct nsurl *url, enum backing_store_flags flags,
uint8_t **data, size_t *datalen);
@@ -104,7 +104,7 @@ struct gui_llcache_table {
*
* @param url The url is used as the unique primary key to invalidate.
* @param[in] flags The flags to control how the object data is released.
- * @return NSERROR_OK on success or error code on faliure.
+ * @return NSERROR_OK on success or error code on failure.
*/
nserror (*release)(struct nsurl *url, enum backing_store_flags flags);
@@ -117,7 +117,7 @@ struct gui_llcache_table {
* If the entry had data allocated it will be released.
*
* @param url The url is used as the unique primary key to invalidate.
- * @return NSERROR_OK on success or error code on faliure.
+ * @return NSERROR_OK on success or error code on failure.
*/
nserror (*invalidate)(struct nsurl *url);
diff --git a/content/content.c b/content/content.c
index f650af2..2eb035c 100644
--- a/content/content.c
+++ b/content/content.c
@@ -21,11 +21,11 @@
* Content handling implementation.
*/
-#include <inttypes.h>
+#include <stdint.h>
#include <stdlib.h>
#include <nsutils/time.h>
-#include "utils/utils.h"
+#include "netsurf/inttypes.h"
#include "utils/log.h"
#include "utils/messages.h"
#include "netsurf/browser_window.h"
diff --git a/content/fetch.c b/content/fetch.c
index 93c7de2..a1542eb 100644
--- a/content/fetch.c
+++ b/content/fetch.c
@@ -46,7 +46,6 @@
#include "utils/log.h"
#include "utils/messages.h"
#include "utils/nsurl.h"
-#include "utils/utils.h"
#include "utils/ring.h"
#include "netsurf/misc.h"
#include "desktop/gui_internal.h"
@@ -643,13 +642,6 @@ long fetch_http_code(struct fetch *fetch)
return fetch->http_code;
}
-/* exported interface documented in content/fetch.h */
-bool fetch_get_verifiable(struct fetch *fetch)
-{
- assert(fetch);
-
- return fetch->verifiable;
-}
/* exported interface documented in content/fetch.h */
struct fetch_multipart_data *
diff --git a/content/fetch.h b/content/fetch.h
index 51e08cf..5521778 100644
--- a/content/fetch.h
+++ b/content/fetch.h
@@ -158,13 +158,6 @@ void fetch_change_callback(struct fetch *fetch, fetch_callback callback, void *p
*/
long fetch_http_code(struct fetch *fetch);
-/**
- * Determine if a fetch was verifiable
- *
- * \param fetch Fetch to consider
- * \return Verifiable status of fetch
- */
-bool fetch_get_verifiable(struct fetch *fetch);
/**
* Free a linked list of fetch_multipart_data.
diff --git a/content/fetchers/curl.c b/content/fetchers/curl.c
index 66970ef..7d0e40c 100644
--- a/content/fetchers/curl.c
+++ b/content/fetchers/curl.c
@@ -128,6 +128,28 @@ static char fetch_error_buffer[CURL_ERROR_SIZE];
static char fetch_proxy_userpwd[100];
+/* OpenSSL 1.0.x to 1.1.0 certificate reference counting changed
+ * LibreSSL declares its OpenSSL version as 2.1 but only supports the old way
+ */
+#if (defined(LIBRESSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x1010000fL))
+static int ns_X509_up_ref(X509 *cert)
+{
+ cert->references++;
+ return 1;
+}
+
+static void ns_X509_free(X509 *cert)
+{
+ cert->references--;
+ if (cert->references == 0) {
+ X509_free(cert);
+ }
+}
+#else
+#define ns_X509_up_ref X509_up_ref
+#define ns_X509_free X509_free
+#endif
+
/**
* Initialise a cURL fetcher.
*/
@@ -438,7 +460,7 @@ fetch_curl_verify_callback(int verify_ok, X509_STORE_CTX *x509_ctx)
*/
if (!fetch->cert_data[depth].cert) {
fetch->cert_data[depth].cert = X509_STORE_CTX_get_current_cert(x509_ctx);
- fetch->cert_data[depth].cert->references++;
+ ns_X509_up_ref(fetch->cert_data[depth].cert);
fetch->cert_data[depth].err = X509_STORE_CTX_get_error(x509_ctx);
}
@@ -815,10 +837,7 @@ static void fetch_curl_free(void *vf)
}
for (i = 0; i < MAX_CERTS && f->cert_data[i].cert; i++) {
- f->cert_data[i].cert->references--;
- if (f->cert_data[i].cert->references == 0) {
- X509_free(f->cert_data[i].cert);
- }
+ ns_X509_free(f->cert_data[i].cert);
}
free(f);
@@ -986,10 +1005,7 @@ curl_start_cert_validate(struct curl_fetch_info *f,
X509_get_pubkey(certs[depth].cert));
/* and clean up */
- certs[depth].cert->references--;
- if (certs[depth].cert->references == 0) {
- X509_free(certs[depth].cert);
- }
+ ns_X509_free(certs[depth].cert);
}
msg.type = FETCH_CERT_ERR;
diff --git a/content/fetchers/data.c b/content/fetchers/data.c
index d82832a..cb99e6f 100644
--- a/content/fetchers/data.c
+++ b/content/fetchers/data.c
@@ -25,14 +25,15 @@
#include <string.h>
#include <stdlib.h>
#include <libwapcaplet/libwapcaplet.h>
+#include <nsutils/base64.h>
+#include "netsurf/inttypes.h"
#include "utils/url.h"
#include "utils/nsurl.h"
#include "utils/corestrings.h"
#include "utils/log.h"
#include "utils/utils.h"
#include "utils/ring.h"
-#include "nsutils/base64.h"
#include "content/fetch.h"
#include "content/fetchers.h"
diff --git a/content/fetchers/file.c b/content/fetchers/file.c
index 6ffa638..4fa1a21 100644
--- a/content/fetchers/file.c
+++ b/content/fetchers/file.c
@@ -44,6 +44,7 @@
#endif
#include <libwapcaplet/libwapcaplet.h>
+#include "netsurf/inttypes.h"
#include "utils/nsurl.h"
#include "utils/dirent.h"
#include "utils/corestrings.h"
diff --git a/content/fetchers/resource.c b/content/fetchers/resource.c
index 21ad8c7..b8b4b19 100644
--- a/content/fetchers/resource.c
+++ b/content/fetchers/resource.c
@@ -29,6 +29,7 @@
#include <stdarg.h>
#include <libwapcaplet/libwapcaplet.h>
+#include "netsurf/inttypes.h"
#include "utils/nsurl.h"
#include "utils/corestrings.h"
#include "utils/log.h"
diff --git a/content/fs_backing_store.c b/content/fs_backing_store.c
index 7d8ac4b..bcb97d2 100644
--- a/content/fs_backing_store.c
+++ b/content/fs_backing_store.c
@@ -27,9 +27,9 @@
*
* \todo Implement mmap retrieval where supported.
*
- * \todo Implement static retrival for metadata objects as their heap
+ * \todo Implement static retrieval for metadata objects as their heap
* lifetime is typically very short, though this may be obsoleted
- * by a small object storage stratagy.
+ * by a small object storage strategy.
*
*/
@@ -43,11 +43,11 @@
#include <stdlib.h>
#include <nsutils/unistd.h>
+#include "netsurf/inttypes.h"
#include "utils/filepath.h"
#include "utils/file.h"
#include "utils/nsurl.h"
#include "utils/log.h"
-#include "utils/utils.h"
#include "utils/messages.h"
#include "desktop/gui_internal.h"
#include "netsurf/misc.h"
@@ -63,7 +63,7 @@
/** Backing store file format version */
#define CONTROL_VERSION 130
-/** Number of milliseconds after a update before control data maintinance is performed */
+/** Number of milliseconds after a update before control data maintenance is performed */
#define CONTROL_MAINT_TIME 10000
/** Get address from ident */
@@ -100,7 +100,7 @@
#define BLOCK_USE_MAP_SIZE (1 << (BLOCK_ENTRY_COUNT - 3))
/**
- * The type used to store index values refering to store entries. Care
+ * The type used to store index values referring to store entries. Care
* must be taken with this type as it is used to build address to
* entry mapping so changing the size will have large impacts on
* memory usage.
@@ -109,7 +109,7 @@ typedef uint16_t entry_index_t;
/**
* The type used as a binary identifier for each entry derived from
- * the url. A larger identifier will have fewer collisions but
+ * the URL. A larger identifier will have fewer collisions but
* requires proportionately more storage.
*/
typedef uint32_t entry_ident_t;
@@ -184,7 +184,7 @@ struct store_entry_element {
* @note Order is important to avoid excessive structure packing overhead.
*/
struct store_entry {
- int64_t last_used; /**< unix time the entry was last used */
+ int64_t last_used; /**< UNIX time the entry was last used */
entry_ident_t ident; /**< entry identifier */
uint16_t use_count; /**< number of times this entry has been accessed */
uint8_t flags; /**< entry flags */
@@ -227,7 +227,7 @@ struct store_state {
unsigned int entry_bits; /**< log2 number of bits in entry index. */
unsigned int last_entry; /**< index of last usable entry. */
- /** flag indicating if the entries have been made persistant
+ /** flag indicating if the entries have been made persistent
* since they were last changed.
*/
bool entries_dirty;
@@ -235,9 +235,9 @@ struct store_state {
/**
* URL identifier to entry index mapping.
*
- * This is an open coded index on the entries url field and
- * provides a computationaly inexpensive way to go from the
- * url to an entry.
+ * This is an open coded index on the entries URL field and
+ * provides a computationally inexpensive way to go from the
+ * URL to an entry.
*/
entry_index_t *addrmap;
@@ -246,12 +246,12 @@ struct store_state {
struct block_file blocks[ENTRY_ELEM_COUNT][BLOCK_FILE_COUNT];
/** flag indicating if the block file use maps have been made
- * persistant since they were last changed.
+ * persistent since they were last changed.
*/
bool blocks_dirty;
/** flag indicating if a block file has been opened for update
- * since maintinance was previously done.
+ * since maintenance was previously done.
*/
bool blocks_opened;
@@ -283,8 +283,8 @@ struct store_state *storestate;
*
* @param[in] state The store state to use.
* @param[in, out] bse Pointer to the entry to be removed.
- * @return NSERROR_OK and \a bse updated on succes or NSERROR_NOT_FOUND
- * if no entry coresponds to the url.
+ * @return NSERROR_OK and \a bse updated on success or NSERROR_NOT_FOUND
+ * if no entry corresponds to the URL.
*/
static nserror
remove_store_entry(struct store_state *state, struct store_entry **bse)
@@ -460,7 +460,7 @@ store_fname(struct store_state *state,
* @param state The store state to use.
* @param bse The entry to invalidate.
* @param elem_idx The element index to invalidate.
- * @return NSERROR_OK on sucess or error code on failure.
+ * @return NSERROR_OK on success or error code on failure.
*/
static nserror
invalidate_element(struct store_state *state,
@@ -500,7 +500,7 @@ invalidate_element(struct store_state *state,
*
* @param state The store state to use.
* @param bse The entry to invalidate.
- * @return NSERROR_OK on sucess or error code on failure.
+ * @return NSERROR_OK on success or error code on failure.
*/
static nserror
invalidate_entry(struct store_state *state, struct store_entry *bse)
@@ -554,7 +554,7 @@ static int compar(const void *va, const void *vb)
const struct store_entry *b = &BS_ENTRY(*(entry_ident_t *)vb, storestate);
/* consider the allocation flags - if an entry has an
- * allocation it is considered more valuble as it cannot be
+ * allocation it is considered more valuable as it cannot be
* freed.
*/
if ((a->elem[ENTRY_ELEM_DATA].flags == ENTRY_ELEM_FLAG_NONE) &&
@@ -620,7 +620,7 @@ static nserror store_evict(struct store_state *state)
return NSERROR_OK;
}
- LOG("Evicting entries to reduce %"PRIu64" by %zd",
+ LOG("Evicting entries to reduce %"PRIu64" by %"PRIsizet,
state->total_alloc, state->hysteresis);
/* allocate storage for the list */
@@ -658,7 +658,7 @@ static nserror store_evict(struct store_state *state)
free(elist);
- LOG("removed %zd in %d entries", removed, ent);
+ LOG("removed %"PRIsizet" in %d entries", removed, ent);
return ret;
}
@@ -670,7 +670,7 @@ static nserror store_evict(struct store_state *state)
* Serialise entry index out to storage.
*
* @param state The backing store state to serialise.
- * @return NSERROR_OK on sucess or error code on faliure.
+ * @return NSERROR_OK on success or error code on failure.
*/
static nserror write_entries(struct store_state *state)
{
@@ -735,7 +735,7 @@ static nserror write_entries(struct store_state *state)
* Serialise block file use map out to storage.
*
* \param state The backing store state to serialise.
- * \return NSERROR_OK on sucess or error code on faliure.
+ * \return NSERROR_OK on success or error code on failure.
*/
static nserror write_blocks(struct store_state *state)
{
@@ -812,11 +812,11 @@ wr_err:
* Ensures block files are of the correct extent
*
* block files have their extent set to their maximum size to ensure
- * subsequent reads and writes do not need to extend teh file and are
+ * subsequent reads and writes do not need to extend the file and are
* therefore faster.
*
* \param state The backing store state to set block extent for.
- * \return NSERROR_OK on sucess or error code on faliure.
+ * \return NSERROR_OK on success or error code on failure.
*/
static nserror set_block_extents(struct store_state *state)
{
@@ -849,7 +849,7 @@ static nserror set_block_extents(struct store_state *state)
}
/**
- * maintinance of control structures.
+ * maintenance of control structures.
*
* callback scheduled when control data has been update. Currently
* this is for when the entries table is dirty and requires
@@ -959,7 +959,7 @@ static block_index_t alloc_block(struct store_state *state, int elem_idx)
* @param datalen The length of data in \a data
* @param bse Pointer used to return value.
* @return NSERROR_OK and \a bse updated on success or NSERROR_NOT_FOUND
- * if no entry coresponds to the url.
+ * if no entry corresponds to the url.
*/
static nserror
set_store_entry(struct store_state *state,
@@ -1045,12 +1045,12 @@ set_store_entry(struct store_state *state,
elem->size = datalen;
state->total_alloc += elem->size;
- /* if the elemnt will fit in a small block attempt to allocate one */
+ /* if the element will fit in a small block attempt to allocate one */
if (elem->size <= (1U << log2_block_size[elem_idx])) {
elem->block = alloc_block(state, elem_idx);
}
- /* ensure control maintinance scheduled. */
+ /* ensure control maintenance scheduled. */
state->entries_dirty = true;
guit->misc->schedule(CONTROL_MAINT_TIME, control_maintinance, state);
@@ -1118,7 +1118,7 @@ store_open(struct store_state *state,
* we also compute the total storage in use.
*
* @param state The backing store global state.
- * @return NSERROR_OK on sucess or NSERROR_NOMEM if the map storage
+ * @return NSERROR_OK on success or NSERROR_NOMEM if the map storage
* could not be allocated.
*/
static nserror
@@ -1163,7 +1163,7 @@ build_entrymap(struct store_state *state)
* Unlink entries file
*
* @param state The backing store state.
- * @return NSERROR_OK on sucess or error code on faliure.
+ * @return NSERROR_OK on success or error code on failure.
*/
static nserror
unlink_entries(struct store_state *state)
@@ -1186,7 +1186,7 @@ unlink_entries(struct store_state *state)
* Read description entries into memory.
*
* @param state The backing store state to put the loaded entries in.
- * @return NSERROR_OK on sucess or error code on faliure.
+ * @return NSERROR_OK on success or error code on faliure.
*/
static nserror
read_entries(struct store_state *state)
@@ -1204,7 +1204,7 @@ read_entries(struct store_state *state)
entries_size = (1 << state->entry_bits) * sizeof(struct store_entry);
- LOG("Allocating %zd bytes for max of %d entries of %ld length elements %ld length",
+ LOG("Allocating %"PRIsizet" bytes for max of %d entries of %ld length elements %ld length",
entries_size, 1 << state->entry_bits,
sizeof(struct store_entry),
sizeof(struct store_entry_element));
@@ -1236,7 +1236,7 @@ read_entries(struct store_state *state)
* Read block file usage bitmaps.
*
* @param state The backing store state to put the loaded entries in.
- * @return NSERROR_OK on sucess or error code on faliure.
+ * @return NSERROR_OK on success or error code on failure.
*/
static nserror
read_blocks(struct store_state *state)
@@ -1275,7 +1275,7 @@ read_blocks(struct store_state *state)
} else {
LOG("Initialising block use map to defaults");
- /* ensure block 0 (invalid sentinal) is skipped */
+ /* ensure block 0 (invalid sentinel) is skipped */
state->blocks[ENTRY_ELEM_DATA][0].use_map[0] = 1;
state->blocks[ENTRY_ELEM_META][0].use_map[0] = 1;
}
@@ -1293,7 +1293,7 @@ read_blocks(struct store_state *state)
* Write the cache tag file.
*
* @param state The cache state.
- * @return NSERROR_OK on sucess or error code on faliure.
+ * @return NSERROR_OK on success or error code on failure.
*/
static nserror
write_cache_tag(struct store_state *state)
@@ -1330,7 +1330,7 @@ write_cache_tag(struct store_state *state)
* Write the control file for the current state.
*
* @param state The state to write to the control file.
- * @return NSERROR_OK on sucess or error code on faliure.
+ * @return NSERROR_OK on success or error code on failure.
*/
static nserror
write_control(struct store_state *state)
@@ -1375,7 +1375,7 @@ write_control(struct store_state *state)
* Read and parse the control file.
*
* @param state The state to read from the control file.
- * @return NSERROR_OK on sucess or error code on faliure.
+ * @return NSERROR_OK on success or error code on failure.
*/
static nserror
read_control(struct store_state *state)
@@ -1461,7 +1461,7 @@ control_error: /* problem with the control file */
* Initialise the backing store.
*
* @param parameters to configure backing store.
- * @return NSERROR_OK on success or error code on faliure.
+ * @return NSERROR_OK on success or error code on failure.
*/
static nserror
initialise(const struct llcache_store_parameters *parameters)
@@ -1560,13 +1560,13 @@ initialise(const struct llcache_store_parameters *parameters)
LOG("FS backing store init successful");
- LOG("path:%s limit:%zd hyst:%zd addr:%d entries:%d",
+ LOG("path:%s limit:%"PRIsizet" hyst:%"PRIsizet" addr:%d entries:%d",
newstate->path,
newstate->limit,
newstate->hysteresis,
newstate->ident_bits,
newstate->entry_bits);
- LOG("Using %"PRIu64"/%zd", newstate->total_alloc, newstate->limit);
+ LOG("Using %"PRIu64"/%"PRIsizet, newstate->total_alloc, newstate->limit);
return NSERROR_OK;
}
@@ -1605,7 +1605,7 @@ finalise(void)
/* avoid division by zero */
if (op_count > 0) {
- LOG("Cache total/hit/miss/fail (counts) %d/%zd/%zd/%d (100%%/%zd%%/%zd%%/%d%%)",
+ LOG("Cache total/hit/miss/fail (counts) %d/%"PRIsizet"/%"PRIsizet"/%d (100%%/%"PRIsizet"%%/%"PRIsizet"%%/%d%%)",
op_count,
storestate->hit_count,
storestate->miss_count,
@@ -1661,7 +1661,7 @@ static nserror store_write_block(struct store_state *state,
bse->elem[elem_idx].size,
offst);
if (wr != (ssize_t)bse->elem[elem_idx].size) {
- LOG("Write failed %zd of %d bytes from %p at 0x%jx block %d errno %d",
+ LOG("Write failed %"PRIssizet" of %d bytes from %p at 0x%jx block %d errno %d",
wr,
bse->elem[elem_idx].size,
bse->elem[elem_idx].data,
@@ -1671,7 +1671,7 @@ static nserror store_write_block(struct store_state *state,
return NSERROR_SAVE_FAILED;
}
- LOG("Wrote %zd bytes from %p at 0x%jx block %d",
+ LOG("Wrote %"PRIssizet" bytes from %p at 0x%jx block %d",
wr,
bse->elem[elem_idx].data,
(uintmax_t)offst,
@@ -1708,7 +1708,7 @@ static nserror store_write_file(struct store_state *state,
close(fd);
if (wr != (ssize_t)bse->elem[elem_idx].size) {
- LOG("Write failed %zd of %d bytes from %p errno %d",
+ LOG("Write failed %"PRIssizet" of %d bytes from %p errno %d",
wr,
bse->elem[elem_idx].size,
bse->elem[elem_idx].data,
@@ -1718,7 +1718,7 @@ static nserror store_write_file(struct store_state *state,
return NSERROR_SAVE_FAILED;
}
- LOG("Wrote %zd bytes from %p", wr, bse->elem[elem_idx].data);
+ LOG("Wrote %"PRIssizet" bytes from %p", wr, bse->elem[elem_idx].data);
return NSERROR_OK;
}
@@ -1732,7 +1732,7 @@ static nserror store_write_file(struct store_state *state,
* @param bsflags The flags to control how the object is stored.
* @param data The objects source data.
* @param datalen The length of the \a data.
- * @return NSERROR_OK on success or error code on faliure.
+ * @return NSERROR_OK on success or error code on failure.
*/
static nserror
store(nsurl *url,
@@ -1829,7 +1829,7 @@ static nserror store_read_block(struct store_state *state,
bse->elem[elem_idx].size,
offst);
if (rd != (ssize_t)bse->elem[elem_idx].size) {
- LOG("Failed reading %zd of %d bytes into %p from 0x%jx block %d errno %d",
+ LOG("Failed reading %"PRIssizet" of %d bytes into %p from 0x%jx block %d errno %d",
rd,
bse->elem[elem_idx].size,
bse->elem[elem_idx].data,
@@ -1839,7 +1839,7 @@ static nserror store_read_block(struct store_state *state,
return NSERROR_SAVE_FAILED;
}
- LOG("Read %zd bytes into %p from 0x%jx block %d",
+ LOG("Read %"PRIssizet" bytes into %p from 0x%jx block %d",
rd,
bse->elem[elem_idx].data,
(uintmax_t)offst,
@@ -1878,7 +1878,8 @@ static nserror store_read_file(struct store_state *state,
bse->elem[elem_idx].data + tot,
bse->elem[elem_idx].size - tot);
if (rd <= 0) {
- LOG("read error returned %zd errno %d", rd, errno);
+ LOG("read error returned %"PRIssizet" errno %d",
+ rd, errno);
ret = NSERROR_NOT_FOUND;
break;
}
@@ -1887,19 +1888,19 @@ static nserror store_read_file(struct store_state *state,
close(fd);
- LOG("Read %zd bytes into %p", tot, bse->elem[elem_idx].data);
+ LOG("Read %"PRIsizet" bytes into %p", tot, bse->elem[elem_idx].data);
return ret;
}
/**
- * Retrive an object from the backing store.
+ * Retrieve an object from the backing store.
*
* @param[in] url The url is used as the unique primary key for the data.
* @param[in] bsflags The flags to control how the object is retrieved.
* @param[out] data_out The objects data.
* @param[out] datalen_out The length of the \a data retrieved.
- * @return NSERROR_OK on success or error code on faliure.
+ * @return NSERROR_OK on success or error code on failure.
*/
static nserror
fetch(nsurl *url,
@@ -1926,7 +1927,7 @@ fetch(nsurl *url,
}
storestate->hit_count++;
- LOG("retriving cache data for url:%s", nsurl_access(url));
+ LOG("retrieving cache data for url:%s", nsurl_access(url));
/* calculate the entry element index */
if ((bsflags & BACKING_STORE_META) != 0) {
@@ -1984,7 +1985,7 @@ fetch(nsurl *url,
*
* @param[in] url The url is used as the unique primary key to invalidate.
* @param[in] bsflags The flags to control how the object data is released.
- * @return NSERROR_OK on success or error code on faliure.
+ * @return NSERROR_OK on success or error code on failure.
*/
static nserror release(nsurl *url, enum backing_store_flags bsflags)
{
@@ -2032,7 +2033,7 @@ static nserror release(nsurl *url, enum backing_store_flags bsflags)
* be returned as a result to the fetch or meta operations.
*
* @param url The url is used as the unique primary key to invalidate.
- * @return NSERROR_OK on success or error code on faliure.
+ * @return NSERROR_OK on success or error code on failure.
*/
static nserror
invalidate(nsurl *url)
diff --git a/content/handlers/css/hints.h b/content/handlers/css/hints.h
index 2c18359..3d44d21 100644
--- a/content/handlers/css/hints.h
+++ b/content/handlers/css/hints.h
@@ -31,8 +31,8 @@ void css_hint_fini(void);
*
* \param[in] pw HTML document
* \param[in] node DOM node
- * \param[out] nhints number of hints retrived
- * \param[out] hints retrived hints
+ * \param[out] nhints number of hints retrieved
+ * \param[out] hints retrieved hints
* \return CSS_OK on success,
* CSS_PROPERTY_NOT_SET if there is no hint for the requested property,
* CSS_NOMEM on memory exhaustion.
diff --git a/content/handlers/css/select.c b/content/handlers/css/select.c
index aaede77..daa3b40 100644
--- a/content/handlers/css/select.c
+++ b/content/handlers/css/select.c
@@ -24,6 +24,7 @@
#include "utils/corestrings.h"
#include "utils/log.h"
#include "utils/nsurl.h"
+#include "netsurf/plot_style.h"
#include "netsurf/url_db.h"
#include "desktop/system_colour.h"
diff --git a/content/handlers/image/image_cache.c b/content/handlers/image/image_cache.c
index 3eb27ac..02107f7 100644
--- a/content/handlers/image/image_cache.c
+++ b/content/handlers/image/image_cache.c
@@ -16,13 +16,18 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+/**
+ * \file
+ * Cache implementation for bitmap images decoded into frontend format.
+ */
+
#include <assert.h>
-#include <inttypes.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
+#include "netsurf/inttypes.h"
#include "utils/utils.h"
#include "utils/log.h"
#include "netsurf/misc.h"
@@ -34,22 +39,26 @@
#include "image/image_cache.h"
#include "image/image.h"
-/** Age of an entry within the cache
+/**
+ * Age of an entry within the cache
*
* type deffed away so it can be readily changed later perhaps to a
* wallclock time structure.
*/
typedef unsigned int cache_age;
-/** Image cache entry
+/**
+ * Image cache entry
*/
struct image_cache_entry_s {
- struct image_cache_entry_s *next; /* next cache entry in list */
- struct image_cache_entry_s *prev; /* previous cache entry in list */
-
- struct content *content; /** content is used as a key */
- struct bitmap *bitmap; /** associated bitmap entry */
- /** Conversion routine */
+ struct image_cache_entry_s *next; /**< next cache entry in list */
+ struct image_cache_entry_s *prev; /**< previous cache entry in list */
+
+ /** content is used as a key */
+ struct content *content;
+ /** associated bitmap entry */
+ struct bitmap *bitmap;
+ /** routine to convert content into bitmap */
image_cache_convert_fn *convert;
/* Statistics for replacement algorithm */
@@ -62,7 +71,8 @@ struct image_cache_entry_s {
int conversion_count; /**< Number of times image has been converted */
};
-/** Current state of the cache.
+/**
+ * Current state of the cache.
*
* Global state of the cache. entries "age" is determined based on a
* monotonically incrementing operation count. This avoids issues with
@@ -90,12 +100,12 @@ struct image_cache_s {
/** Maximum size of bitmaps allocated at any one time */
size_t max_bitmap_size;
- /** The number of objects when maximum bitmap usage occoured */
+ /** The number of objects when maximum bitmap usage occurred */
int max_bitmap_size_count;
/** Maximum count of bitmaps allocated at any one time */
int max_bitmap_count;
- /** The size of the bitmaps when the max count occoured */
+ /** The size of the bitmaps when the max count occurred */
size_t max_bitmap_count_size;
/** Bitmap was not available at plot time required conversion */
@@ -130,7 +140,11 @@ struct image_cache_s {
static struct image_cache_s *image_cache = NULL;
-/** Find the nth cache entry
+/**
+ * Find a cache entry by index.
+ *
+ * \param entryn index of cache entry
+ * \return cache entry at index or NULL if not found.
*/
static struct image_cache_entry_s *image_cache__findn(int entryn)
{
@@ -144,7 +158,12 @@ static struct image_cache_entry_s *image_cache__findn(int entryn)
return found;
}
-/** Find the cache entry for a content
+
+/**
+ * Find the cache entry for a content
+ *
+ * \param c The content to get an entry for
+ * \return The image cache entry or NULL if not found.
*/
static struct image_cache_entry_s *image_cache__find(const struct content *c)
{
@@ -157,6 +176,11 @@ static struct image_cache_entry_s *image_cache__find(const struct content *c)
return found;
}
+/**
+ * Update the image cache statistics with an entry.
+ *
+ * \param centry The image cache entry to update the stats with.
+ */
static void image_cache_stats_bitmap_add(struct image_cache_entry_s *centry)
{
centry->bitmap_age = image_cache->current_age;
@@ -223,11 +247,20 @@ static void image_cache__unlink(struct image_cache_entry_s *centry)
}
}
+/**
+ * free bitmap from an image cache entry
+ *
+ * \param centry The image cache entry to free bitmap from.
+ */
static void image_cache__free_bitmap(struct image_cache_entry_s *centry)
{
if (centry->bitmap != NULL) {
#ifdef IMAGE_CACHE_VERBOSE
- LOG("Freeing bitmap %p size %d age %d redraw count %d", centry->bitmap, centry->bitmap_size, image_cache->current_age - centry->bitmap_age, centry->redraw_count);
+ LOG("Freeing bitmap %p size %d age %d redraw count %d",
+ centry->bitmap,
+ centry->bitmap_size,
+ image_cache->current_age - centry->bitmap_age,
+ centry->redraw_count);
#endif
guit->bitmap->destroy(centry->bitmap);
centry->bitmap = NULL;
@@ -240,7 +273,11 @@ static void image_cache__free_bitmap(struct image_cache_entry_s *centry)
}
-/* free cache entry */
+/**
+ * free image cache entry
+ *
+ * \param centry The image cache entry to free.
+ */
static void image_cache__free_entry(struct image_cache_entry_s *centry)
{
#ifdef IMAGE_CACHE_VERBOSE
@@ -258,7 +295,11 @@ static void image_cache__free_entry(struct image_cache_entry_s *centry)
free(centry);
}
-/** Cache cleaner */
+/**
+ * Image cache cleaner
+ *
+ * \param icache The image cache context.
+ */
static void image_cache__clean(struct image_cache_s *icache)
{
struct image_cache_entry_s *centry = icache->entries;
@@ -277,7 +318,11 @@ static void image_cache__clean(struct image_cache_s *icache)
}
}
-/** Cache background scheduled callback. */
+/**
+ * Cache background scheduled callback.
+ *
+ * \param p The image cache context.
+ */
static void image_cache__background_update(void *p)
{
struct image_cache_s *icache = p;
@@ -377,7 +422,7 @@ image_cache_init(const struct image_cache_parameters *image_cache_parameters)
image_cache__background_update,
image_cache);
- LOG("Image cache initilised with a limit of %" PRIsizet " hysteresis of %"PRIsizet,
+ LOG("Image cache initialised with a limit of %" PRIsizet " hysteresis of %"PRIsizet,
image_cache->params.limit, image_cache->params.hysteresis);
return NSERROR_OK;
@@ -678,7 +723,7 @@ int image_cache_snentryf(char *string, size_t size, unsigned int entryn,
case 'U':
slen += snprintf(string + slen, size - slen,
- "%s", nsurl_access(llcache_handle_get_url(centry->content->llcache)));
+ "%s", nsurl_access(llcache_handle_get_url(centry->content->llcache)));
break;
case 'o':
@@ -690,20 +735,20 @@ int image_cache_snentryf(char *string, size_t size, unsigned int entryn,
centry->content->
llcache),
NSURL_HOST);
-
+
slen += snprintf(string + slen,
size - slen, "%s",
- lwc_string_data(
- origin));
+ lwc_string_data(
+ origin));
lwc_string_unref(origin);
} else {
slen += snprintf(string + slen,
size - slen, "%s",
- "localhost");
+ "localhost");
}
break;
-
+
case 's':
if (centry->bitmap != NULL) {
slen += snprintf(string + slen,
@@ -774,6 +819,7 @@ bool image_cache_redraw(struct content *c,
return image_bitmap_plot(centry->bitmap, data, clip, ctx);
}
+/* exported interface documented in image_cache.h */
void image_cache_destroy(struct content *content)
{
struct image_cache_entry_s *centry;
@@ -787,11 +833,13 @@ void image_cache_destroy(struct content *content)
}
}
+/* exported interface documented in image_cache.h */
void *image_cache_get_internal(const struct content *c, void *context)
{
return image_cache_get_bitmap(c);
}
+/* exported interface documented in image_cache.h */
content_type image_cache_content_type(void)
{
return CONTENT_IMAGE;
diff --git a/content/handlers/image/png.c b/content/handlers/image/png.c
index 93185c1..0baf411 100644
--- a/content/handlers/image/png.c
+++ b/content/handlers/image/png.c
@@ -22,6 +22,7 @@
#include <stdlib.h>
#include <png.h>
+#include "netsurf/inttypes.h"
#include "utils/utils.h"
#include "utils/log.h"
#include "utils/messages.h"
diff --git a/content/handlers/javascript/duktape/Makefile b/content/handlers/javascript/duktape/Makefile
index 89f83b1..fce79de 100644
--- a/content/handlers/javascript/duktape/Makefile
+++ b/content/handlers/javascript/duktape/Makefile
@@ -12,14 +12,13 @@ BINDINGS := $(wildcard content/handlers/javascript/duktape/*.bnd)
GBFLAGS+=-D
$(OBJROOT)/duktape/binding.h $(OBJROOT)/duktape/Makefile: content/handlers/javascript/duktape/netsurf.bnd $(BINDINGS)
- $(Q)mkdir -p $(OBJROOT)/duktape
+ $(Q)$(MKDIR) -p $(OBJROOT)/duktape
$(VQ)echo " GENBIND: $<"
$(Q)nsgenbind $(GBFLAGS) -I content/handlers/javascript/WebIDL $< $(OBJROOT)/duktape
- $(VQ)echo " GENBIND: completed"
# create unimplemented report for doxygen
Docs/UnimplementedJavascript.txt: content/handlers/javascript/duktape/netsurf.bnd $(BINDINGS)
- $(Q)mkdir -p $(OBJROOT)/duktape
+ $(Q)$(MKDIR) -p $(OBJROOT)/duktape
$(VQ)echo "/** \page unimplemented Unimplemented javascript bindings" > $@
$(VQ)echo "This is a list of all the binding methods, getters and setters without an implementation in a binding." >> $@
$(VQ)echo "" >> $@
diff --git a/content/handlers/javascript/duktape/duk_config.h b/content/handlers/javascript/duktape/duk_config.h
index c336603..f9c95ae 100644
--- a/content/handlers/javascript/duktape/duk_config.h
+++ b/content/handlers/javascript/duktape/duk_config.h
@@ -1,8 +1,8 @@
/*
* duk_config.h configuration header generated by genconfig.py.
*
- * Git commit: 2cc76e9ff1f64869e1146ad7317d8cbe33bbd27e
- * Git describe: v1.5.1
+ * Git commit: 17e3d86cf8b4788bd0d37658f833ab440ce43a1c
+ * Git describe: v1.6.0
* Git branch: HEAD
*
* Supported platforms:
diff --git a/content/handlers/javascript/duktape/dukky.c b/content/handlers/javascript/duktape/dukky.c
index 7dd3bd7..1282ad9 100644
--- a/content/handlers/javascript/duktape/dukky.c
+++ b/content/handlers/javascript/duktape/dukky.c
@@ -23,16 +23,15 @@
* Duktapeish implementation of javascript engine functions.
*/
-#include <inttypes.h>
-
+#include <stdint.h>
#include <nsutils/time.h>
-#include "content/content.h"
-
+#include "netsurf/inttypes.h"
#include "utils/utils.h"
#include "utils/nsoption.h"
#include "utils/log.h"
#include "utils/corestrings.h"
+#include "content/content.h"
#include "javascript/js.h"
#include "javascript/content.h"
diff --git a/content/handlers/javascript/duktape/duktape.c b/content/handlers/javascript/duktape/duktape.c
index e1867c0..b64383b 100644
--- a/content/handlers/javascript/duktape/duktape.c
+++ b/content/handlers/javascript/duktape/duktape.c
@@ -1,9 +1,9 @@
/* Omit from static analysis. */
#ifndef __clang_analyzer__
/*
- * Single source autogenerated distributable for Duktape 1.5.1.
+ * Single source autogenerated distributable for Duktape 1.6.0.
*
- * Git commit 2cc76e9ff1f64869e1146ad7317d8cbe33bbd27e (v1.5.1).
+ * Git commit 17e3d86cf8b4788bd0d37658f833ab440ce43a1c (v1.6.0).
* Git branch HEAD.
*
* See Duktape AUTHORS.rst and LICENSE.txt for copyright and
@@ -1631,9 +1631,9 @@ DUK_INTERNAL_DECL const duk_c_function duk_bi_native_functions[149];
#endif /* !DUK_SINGLE_FILE */
#if defined(DUK_USE_BUILTIN_INITJS)
#if !defined(DUK_SINGLE_FILE)
-DUK_INTERNAL_DECL const duk_uint8_t duk_initjs_data[187];
+DUK_INTERNAL_DECL const duk_uint8_t duk_initjs_data[204];
#endif /* !DUK_SINGLE_FILE */
-#define DUK_BUILTIN_INITJS_DATA_LENGTH 187
+#define DUK_BUILTIN_INITJS_DATA_LENGTH 204
#endif /* DUK_USE_BUILTIN_INITJS */
#define DUK_BIDX_GLOBAL 0
#define DUK_BIDX_GLOBAL_ENV 1
@@ -9221,7 +9221,7 @@ DUK_INTERNAL const duk_c_function duk_bi_native_functions[149] = {
duk_bi_typedarray_set,
};
#if defined(DUK_USE_BUILTIN_INITJS)
-DUK_INTERNAL const duk_uint8_t duk_initjs_data[187] = {
+DUK_INTERNAL const duk_uint8_t duk_initjs_data[204] = {
40,102,117,110,99,116,105,111,110,40,100,44,97,41,123,102,117,110,99,116,
105,111,110,32,98,40,97,44,98,44,99,41,123,79,98,106,101,99,116,46,100,101,
102,105,110,101,80,114,111,112,101,114,116,121,40,97,44,98,44,123,118,97,
@@ -9229,8 +9229,9 @@ DUK_INTERNAL const duk_uint8_t duk_initjs_data[187] = {
109,101,114,97,98,108,101,58,33,49,44,99,111,110,102,105,103,117,114,97,98,
108,101,58,33,48,125,41,125,98,40,97,46,76,111,103,103,101,114,44,34,99,
108,111,103,34,44,110,101,119,32,97,46,76,111,103,103,101,114,40,34,67,34,
-41,41,59,98,40,97,44,34,109,111,100,76,111,97,100,101,100,34,44,123,125,41,
-125,41,40,116,104,105,115,44,68,117,107,116,97,112,101,41,59,10,0,
+41,41,59,98,40,97,44,34,109,111,100,76,111,97,100,101,100,34,44,79,98,106,
+101,99,116,46,99,114,101,97,116,101,40,110,117,108,108,41,41,125,41,40,116,
+104,105,115,44,68,117,107,116,97,112,101,41,59,10,0,
};
#endif /* DUK_USE_BUILTIN_INITJS */
#if defined(DUK_USE_DOUBLE_LE)
@@ -9354,7 +9355,7 @@ DUK_INTERNAL const duk_uint8_t duk_builtins_data[3833] = {
88,119,100,223,181,68,16,94,91,250,238,200,160,80,0,152,31,61,59,148,10,0,
21,4,231,199,151,69,2,128,5,192,250,97,220,160,80,0,192,127,255,128,20,23,
134,30,92,242,164,34,19,207,167,45,59,179,233,205,229,37,129,127,255,0,0,
-191,255,128,0,63,255,197,131,246,203,203,158,157,251,160,0,0,0,0,64,65,98,
+191,255,128,0,63,255,197,131,246,203,203,158,157,251,160,0,0,0,0,0,90,98,
32,3,166,156,30,53,32,249,165,131,76,223,159,62,94,70,172,114,16,176,144,
60,56,250,19,18,5,159,25,89,32,121,180,238,42,30,129,229,221,140,164,122,7,
147,46,50,129,232,62,61,251,120,97,199,208,156,129,83,127,0,50,250,69,3,
@@ -9534,7 +9535,7 @@ DUK_INTERNAL const duk_uint8_t duk_builtins_data[3833] = {
88,119,100,223,181,68,16,94,91,250,238,200,160,80,0,152,31,61,59,148,10,0,
21,4,231,199,151,69,2,128,5,192,250,97,220,160,80,0,192,127,255,128,20,23,
134,30,92,242,164,34,19,207,167,45,59,179,233,205,229,37,129,127,255,0,0,
-191,255,128,0,63,255,197,131,246,203,203,158,157,251,160,32,98,65,64,0,0,0,
+191,255,128,0,63,255,197,131,246,203,203,158,157,251,160,32,98,90,0,0,0,0,
0,3,166,156,30,53,32,249,165,131,76,223,159,62,94,70,172,114,16,176,144,60,
56,250,19,18,5,159,25,89,32,121,180,238,42,30,129,229,221,140,164,122,7,
147,46,50,129,232,62,61,251,120,97,199,208,156,129,83,127,0,50,250,69,3,
@@ -9714,7 +9715,7 @@ DUK_INTERNAL const duk_uint8_t duk_builtins_data[3833] = {
88,119,100,223,181,68,16,94,91,250,238,200,160,80,0,152,31,61,59,148,10,0,
21,4,231,199,151,69,2,128,5,192,250,97,220,160,80,0,192,127,255,128,20,23,
134,30,92,242,164,34,19,207,167,45,59,179,233,205,229,37,129,127,255,0,0,
-191,255,128,0,63,255,197,131,246,203,203,158,157,251,160,64,65,98,32,0,0,0,
+191,255,128,0,63,255,197,131,246,203,203,158,157,251,160,0,90,98,32,0,0,0,
0,3,166,156,30,53,32,249,165,131,76,223,159,62,94,70,172,114,16,176,144,60,
56,250,19,18,5,159,25,89,32,121,180,238,42,30,129,229,221,140,164,122,7,
147,46,50,129,232,62,61,251,120,97,199,208,156,129,83,127,0,50,250,69,3,
@@ -14047,6 +14048,15 @@ DUK_EXTERNAL void duk_debugger_pause(duk_context *ctx) {
/* include removed: duk_internal.h */
+typedef struct duk_internal_thread_state duk_internal_thread_state;
+
+struct duk_internal_thread_state {
+ duk_ljstate lj;
+ duk_bool_t handling_error;
+ duk_hthread *curr_thread;
+ duk_int_t call_recursion_depth;
+};
+
DUK_EXTERNAL
duk_context *duk_create_heap(duk_alloc_function alloc_func,
duk_realloc_function realloc_func,
@@ -14112,6 +14122,57 @@ DUK_EXTERNAL void duk_destroy_heap(duk_context *ctx) {
duk_heap_free(heap);
}
+DUK_EXTERNAL void duk_suspend(duk_context *ctx, duk_thread_state *state) {
+ duk_hthread *thr = (duk_hthread *) ctx;
+ duk_internal_thread_state *snapshot = (duk_internal_thread_state *) (void *) state;
+ duk_heap *heap;
+ duk_ljstate *lj;
+
+ DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT(thr != NULL);
+ DUK_ASSERT(thr->heap != NULL);
+ DUK_ASSERT(state != NULL); /* unvalidated */
+
+ heap = thr->heap;
+ lj = &heap->lj;
+
+ duk_push_tval(ctx, &lj->value1);
+ duk_push_tval(ctx, &lj->value2);
+
+ DUK_MEMCPY((void *) &snapshot->lj, (const void *) lj, sizeof(duk_ljstate));
+ snapshot->handling_error = heap->handling_error;
+ snapshot->curr_thread = heap->curr_thread;
+ snapshot->call_recursion_depth = heap->call_recursion_depth;
+
+ lj->jmpbuf_ptr = NULL;
+ lj->type = DUK_LJ_TYPE_UNKNOWN;
+ DUK_TVAL_SET_UNDEFINED(&lj->value1);
+ DUK_TVAL_SET_UNDEFINED(&lj->value2);
+ heap->handling_error = 0;
+ heap->curr_thread = NULL;
+ heap->call_recursion_depth = 0;
+}
+
+DUK_EXTERNAL void duk_resume(duk_context *ctx, const duk_thread_state *state) {
+ duk_hthread *thr = (duk_hthread *) ctx;
+ const duk_internal_thread_state *snapshot = (const duk_internal_thread_state *) (const void *) state;
+ duk_heap *heap;
+
+ DUK_ASSERT_CTX_VALID(ctx);
+ DUK_ASSERT(thr != NULL);
+ DUK_ASSERT(thr->heap != NULL);
+ DUK_ASSERT(state != NULL); /* unvalidated */
+
+ heap = thr->heap;
+
+ DUK_MEMCPY((void *) &heap->lj, (const void *) &snapshot->lj, sizeof(duk_ljstate));
+ heap->handling_error = snapshot->handling_error;
+ heap->curr_thread = snapshot->curr_thread;
+ heap->call_recursion_depth = snapshot->call_recursion_depth;
+
+ duk_pop_2(ctx);
+}
+
/* XXX: better place for this */
DUK_EXTERNAL void duk_set_global_object(duk_context *ctx) {
duk_hthread *thr = (duk_hthread *) ctx;
@@ -14417,7 +14478,7 @@ DUK_INTERNAL duk_bool_t duk_get_prop_stridx_boolean(duk_context *ctx, duk_idx_t
return rc;
}
-DUK_EXTERNAL duk_bool_t duk_put_prop(duk_context *ctx, duk_idx_t obj_index) {
+DUK_LOCAL duk_bool_t duk__put_prop_shared(duk_context *ctx, duk_idx_t obj_idx, duk_idx_t idx_key) {
duk_hthread *thr = (duk_hthread *) ctx;
duk_tval *tv_obj;
duk_tval *tv_key;
@@ -14425,16 +14486,19 @@ DUK_EXTERNAL duk_bool_t duk_put_prop(duk_context *ctx, duk_idx_t obj_index) {
duk_small_int_t throw_flag;
duk_bool_t rc;
- DUK_ASSERT_CTX_VALID(ctx);
-
/* Note: copying tv_obj and tv_key to locals to shield against a valstack
* resize is not necessary for a property put right now (putprop protects
* against it internally).
*/
- tv_obj = duk_require_tval(ctx, obj_index);
- tv_key = duk_require_tval(ctx, -2);
- tv_val = duk_require_tval(ctx, -1);
+ /* Key and value indices are either (-2, -1) or (-1, -2). Given idx_key,
+ * idx_val is always (idx_key ^ 0x01).
+ */
+ DUK_ASSERT((idx_key == -2 && (idx_key ^ 1) == -1) ||
+ (idx_key == -1 && (idx_key ^ 1) == -2));
+ tv_obj = duk_require_tval(ctx, obj_idx);
+ tv_key = duk_require_tval(ctx, idx_key);
+ tv_val = duk_require_tval(ctx, idx_key ^ 1);
throw_flag = duk_is_strict_call(ctx);
rc = duk_hobject_putprop(thr, tv_obj, tv_key, tv_val, throw_flag);
@@ -14444,26 +14508,33 @@ DUK_EXTERNAL duk_bool_t duk_put_prop(duk_context *ctx, duk_idx_t obj_index) {
return rc; /* 1 if property found, 0 otherwise */
}
-DUK_EXTERNAL duk_bool_t duk_put_prop_string(duk_context *ctx, duk_idx_t obj_index, const char *key) {
+DUK_EXTERNAL duk_bool_t duk_put_prop(duk_context *ctx, duk_idx_t obj_idx) {
+ DUK_ASSERT_CTX_VALID(ctx);
+ return duk__put_prop_shared(ctx, obj_idx, -2);
+}
+
+DUK_EXTERNAL duk_bool_t duk_put_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key) {
DUK_ASSERT_CTX_VALID(ctx);
DUK_ASSERT(key != NULL);
- obj_index = duk_require_normalize_index(ctx, obj_index);
- duk_push_string(ctx, key);
- duk_swap_top(ctx, -2); /* [val key] -> [key val] */
- return duk_put_prop(ctx, obj_index);
+ /* Careful here and with other duk_put_prop_xxx() helpers: the
+ * target object and the property value may be in the same value
+ * stack slot (unusual, but still conceptually clear).
+ */
+ obj_idx = duk_normalize_index(ctx, obj_idx);
+ (void) duk_push_string(ctx, key);
+ return duk__put_prop_shared(ctx, obj_idx, -1);
}
-DUK_EXTERNAL duk_bool_t duk_put_prop_index(duk_context *ctx, duk_idx_t obj_index, duk_uarridx_t arr_index) {
+DUK_EXTERNAL duk_bool_t duk_put_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx) {
DUK_ASSERT_CTX_VALID(ctx);
- obj_index = duk_require_normalize_index(ctx, obj_index);
- duk_push_uarridx(ctx, arr_index);
- duk_swap_top(ctx, -2); /* [val key] -> [key val] */
- return duk_put_prop(ctx, obj_index);
+ obj_idx = duk_require_normalize_index(ctx, obj_idx);
+ duk_push_uarridx(ctx, arr_idx);
+ return duk__put_prop_shared(ctx, obj_idx, -1);
}
-DUK_INTERNAL duk_bool_t duk_put_prop_stridx(duk_context *ctx, duk_idx_t obj_index, duk_small_int_t stridx) {
+DUK_INTERNAL duk_bool_t duk_put_prop_stridx(duk_context *ctx, duk_idx_t obj_idx, duk_small_int_t stridx) {
duk_hthread *thr = (duk_hthread *) ctx;
DUK_ASSERT_CTX_VALID(ctx);
@@ -14471,10 +14542,9 @@ DUK_INTERNAL duk_bool_t duk_put_prop_stridx(duk_context *ctx, duk_idx_t obj_inde
DUK_ASSERT(stridx < DUK_HEAP_NUM_STRINGS);
DUK_UNREF(thr);
- obj_index = duk_require_normalize_index(ctx, obj_index);
+ obj_idx = duk_require_normalize_index(ctx, obj_idx);
duk_push_hstring(ctx, DUK_HTHREAD_GET_STRING(thr, stridx));
- duk_swap_top(ctx, -2); /* [val key] -> [key val] */
- return duk_put_prop(ctx, obj_index);
+ return duk__put_prop_shared(ctx, obj_idx, -1);
}
DUK_EXTERNAL duk_bool_t duk_del_prop(duk_context *ctx, duk_idx_t obj_index) {
@@ -31391,12 +31461,17 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du
* standard JSON (and no JX/JC support here now).
*/
DUK_D(DUK_DPRINT("gap in array, no conflicting inherited property, remain on fast path"));
+#if defined(DUK_USE_JX)
+ DUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_undefined);
+#else
DUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL);
+#endif
} else {
if (duk__json_stringify_fast_value(js_ctx, tv_val) == 0) {
DUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL);
}
}
+
DUK__EMIT_1(js_ctx, DUK_ASC_COMMA);
emitted = 1;
}
@@ -31729,6 +31804,7 @@ void duk_bi_json_stringify_helper(duk_context *ctx,
* combinations properly.
*/
#if defined(DUK_USE_JX) || defined(DUK_USE_JC)
+ js_ctx->stridx_custom_undefined = DUK_STRIDX_LC_NULL; /* standard JSON; array gaps */
#if defined(DUK_USE_JX)
if (flags & DUK_JSON_FLAG_EXT_CUSTOM) {
js_ctx->stridx_custom_undefined = DUK_STRIDX_LC_UNDEFINED;
@@ -33931,7 +34007,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_constructor_from_char_code(duk_context *ctx
cp = (duk_ucodepoint_t) duk_to_uint32(ctx, i);
DUK_BW_WRITE_ENSURE_XUTF8(thr, bw, cp);
#else
- cp = (duk_ucodepoint_t) duk_to_uint32(ctx, i);
+ cp = (duk_ucodepoint_t) duk_to_uint16(ctx, i);
DUK_BW_WRITE_ENSURE_CESU8(thr, bw, cp);
#endif
}
@@ -42036,18 +42112,23 @@ DUK_LOCAL void duk__mark_hobject(duk_heap *heap, duk_hobject *h) {
duk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HCOMPILEDFUNCTION_GET_DATA(heap, f));
- tv = DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE(heap, f);
- tv_end = DUK_HCOMPILEDFUNCTION_GET_CONSTS_END(heap, f);
- while (tv < tv_end) {
- duk__mark_tval(heap, tv);
- tv++;
- }
+ if (DUK_HCOMPILEDFUNCTION_GET_DATA(heap, f) != NULL) {
+ tv = DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE(heap, f);
+ tv_end = DUK_HCOMPILEDFUNCTION_GET_CONSTS_END(heap, f);
+ while (tv < tv_end) {
+ duk__mark_tval(heap, tv);
+ tv++;
+ }
- fn = DUK_HCOMPILEDFUNCTION_GET_FUNCS_BASE(heap, f);
- fn_end = DUK_HCOMPILEDFUNCTION_GET_FUNCS_END(heap, f);
- while (fn < fn_end) {
- duk__mark_heaphdr(heap, (duk_heaphdr *) *fn);
- fn++;
+ fn = DUK_HCOMPILEDFUNCTION_GET_FUNCS_BASE(heap, f);
+ fn_end = DUK_HCOMPILEDFUNCTION_GET_FUNCS_END(heap, f);
+ while (fn < fn_end) {
+ duk__mark_heaphdr(heap, (duk_heaphdr *) *fn);
+ fn++;
+ }
+ } else {
+ /* May happen in some out-of-memory corner cases. */
+ DUK_D(DUK_DPRINT("duk_hcompiledfunction 'data' is NULL, skipping marking"));
}
} else if (DUK_HOBJECT_IS_NATIVEFUNCTION(h)) {
duk_hnativefunction *f = (duk_hnativefunction *) h;
@@ -43927,20 +44008,23 @@ DUK_LOCAL void duk__refcount_finalize_hobject(duk_hthread *thr, duk_hobject *h)
duk_tval *tv, *tv_end;
duk_hobject **funcs, **funcs_end;
- DUK_ASSERT(DUK_HCOMPILEDFUNCTION_GET_DATA(thr->heap, f) != NULL); /* compiled functions must be created 'atomically' */
-
- tv = DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE(thr->heap, f);
- tv_end = DUK_HCOMPILEDFUNCTION_GET_CONSTS_END(thr->heap, f);
- while (tv < tv_end) {
- duk_tval_decref(thr, tv);
- tv++;
- }
+ if (DUK_HCOMPILEDFUNCTION_GET_DATA(thr->heap, f) != NULL) {
+ tv = DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE(thr->heap, f);
+ tv_end = DUK_HCOMPILEDFUNCTION_GET_CONSTS_END(thr->heap, f);
+ while (tv < tv_end) {
+ duk_tval_decref(thr, tv);
+ tv++;
+ }
- funcs = DUK_HCOMPILEDFUNCTION_GET_FUNCS_BASE(thr->heap, f);
- funcs_end = DUK_HCOMPILEDFUNCTION_GET_FUNCS_END(thr->heap, f);
- while (funcs < funcs_end) {
- duk_heaphdr_decref(thr, (duk_heaphdr *) *funcs);
- funcs++;
+ funcs = DUK_HCOMPILEDFUNCTION_GET_FUNCS_BASE(thr->heap, f);
+ funcs_end = DUK_HCOMPILEDFUNCTION_GET_FUNCS_END(thr->heap, f);
+ while (funcs < funcs_end) {
+ duk_heaphdr_decref(thr, (duk_heaphdr *) *funcs);
+ funcs++;
+ }
+ } else {
+ /* May happen in some out-of-memory corner cases. */
+ DUK_D(DUK_DPRINT("duk_hcompiledfunction 'data' is NULL, skipping decref"));
}
duk_heaphdr_decref(thr, (duk_heaphdr *) DUK_HCOMPILEDFUNCTION_GET_DATA(thr->heap, f));
@@ -46870,8 +46954,13 @@ DUK_INTERNAL duk_bool_t duk_hobject_prototype_chain_contains(duk_hthread *thr, d
duk_uint_t sanity;
DUK_ASSERT(thr != NULL);
- DUK_ASSERT(h != NULL);
- /* allow 'p' to be NULL; then the result is always false */
+
+ /* False if the object is NULL or the prototype 'p' is NULL.
+ * In particular, false if both are NULL (don't compare equal).
+ */
+ if (h == NULL || p == NULL) {
+ return 0;
+ }
sanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;
do {
@@ -51358,8 +51447,17 @@ DUK_INTERNAL duk_bool_t duk_hobject_delprop_raw(duk_hthread *thr, duk_hobject *o
DUK_TVAL_SET_UNUSED_UPDREF(thr, tv); /* side effects */
goto success;
} else {
+ duk_hobject *h_get = NULL;
+ duk_hobject *h_set = NULL;
+ duk_tval tv_tmp;
+
DUK_ASSERT(desc.a_idx < 0);
+ /* Set property slot to an empty state. Careful not to invoke
+ * any side effects while using desc.e_idx so that it doesn't
+ * get invalidated by a finalizer mutating our object.
+ */
+
/* remove hash entry (no decref) */
#if defined(DUK_USE_HOBJECT_HASH_PART)
if (desc.h_idx >= 0) {
@@ -51380,21 +51478,17 @@ DUK_INTERNAL duk_bool_t duk_hobject_delprop_raw(duk_hthread *thr, duk_hobject *o
DUK_DDD(DUK_DDDPRINT("before removing value, e_idx %ld, key %p, key at slot %p",
(long) desc.e_idx, (void *) key, (void *) DUK_HOBJECT_E_GET_KEY(thr->heap, obj, desc.e_idx)));
DUK_DDD(DUK_DDDPRINT("removing value at e_idx %ld", (long) desc.e_idx));
+ DUK_MEMSET((void *) &tv_tmp, 0, sizeof(tv_tmp));
+ DUK_TVAL_SET_UNDEFINED(&tv_tmp);
if (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, desc.e_idx)) {
- duk_hobject *tmp;
-
- tmp = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, desc.e_idx);
+ h_get = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, desc.e_idx);
+ h_set = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, desc.e_idx);
DUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, desc.e_idx, NULL);
- DUK_UNREF(tmp);
- DUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp); /* side effects */
-
- tmp = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, desc.e_idx);
DUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, desc.e_idx, NULL);
- DUK_UNREF(tmp);
- DUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp); /* side effects */
} else {
tv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, desc.e_idx);
- DUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv); /* side effects */
+ DUK_TVAL_SET_TVAL(&tv_tmp, tv);
+ DUK_TVAL_SET_UNDEFINED(tv);
}
#if 0
/* Not strictly necessary because if key == NULL, flag MUST be ignored. */
@@ -51407,7 +51501,14 @@ DUK_INTERNAL duk_bool_t duk_hobject_delprop_raw(duk_hthread *thr, duk_hobject *o
DUK_DDD(DUK_DDDPRINT("removing key at e_idx %ld", (long) desc.e_idx));
DUK_ASSERT(key == DUK_HOBJECT_E_GET_KEY(thr->heap, obj, desc.e_idx));
DUK_HOBJECT_E_SET_KEY(thr->heap, obj, desc.e_idx, NULL);
- DUK_HSTRING_DECREF(thr, key); /* side effects */
+
+ /* Do decrefs only with safe pointers to avoid side effects
+ * disturbing e_idx.
+ */
+ DUK_TVAL_DECREF(thr, &tv_tmp);
+ DUK_HOBJECT_DECREF_ALLOWNULL(thr, h_get);
+ DUK_HOBJECT_DECREF_ALLOWNULL(thr, h_set);
+ DUK_HSTRING_DECREF(thr, key);
goto success;
}
@@ -52581,6 +52682,7 @@ void duk_hobject_define_property_helper(duk_context *ctx,
} else {
duk_bool_t rc;
duk_tval *tv1;
+ duk_tval tv_tmp;
/* curr is data, desc is accessor */
if (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) {
@@ -52600,9 +52702,12 @@ void duk_hobject_define_property_helper(duk_context *ctx,
DUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));
+ /* Avoid side effects that might disturb curr.e_idx until
+ * we're done editing the slot.
+ */
tv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx);
- /* XXX: just decref */
- DUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv1); /* side effects */
+ DUK_TVAL_SET_TVAL(&tv_tmp, tv1);
+ DUK_TVAL_SET_UNDEFINED(tv1);
DUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, curr.e_idx, NULL);
DUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, curr.e_idx, NULL);
@@ -52612,6 +52717,8 @@ void duk_hobject_define_property_helper(duk_context *ctx,
DUK_DDD(DUK_DDDPRINT("flags after data->accessor conversion: 0x%02lx",
(unsigned long) DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, curr.e_idx)));
+ DUK_TVAL_DECREF(thr, &tv_tmp); /* side effects */
+
/* re-lookup to update curr.flags
* XXX: would be faster to update directly
*/
@@ -52627,7 +52734,8 @@ void duk_hobject_define_property_helper(duk_context *ctx,
if (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {
duk_bool_t rc;
- duk_hobject *tmp;
+ duk_hobject *h_get;
+ duk_hobject *h_set;
/* curr is accessor, desc is data */
if (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) {
@@ -52639,15 +52747,14 @@ void duk_hobject_define_property_helper(duk_context *ctx,
DUK_DDD(DUK_DDDPRINT("convert property to data property"));
+ /* Avoid side effects that might disturb curr.e_idx until
+ * we're done editing the slot.
+ */
DUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));
- tmp = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, curr.e_idx);
- DUK_UNREF(tmp);
+ h_get = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, curr.e_idx);
DUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, curr.e_idx, NULL);
- DUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp); /* side effects */
- tmp = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, curr.e_idx);
- DUK_UNREF(tmp);
+ h_set = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, curr.e_idx);
DUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, curr.e_idx, NULL);
- DUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp); /* side effects */
DUK_TVAL_SET_UNDEFINED(DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx));
DUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(thr->heap, obj, curr.e_idx);
@@ -52656,6 +52763,9 @@ void duk_hobject_define_property_helper(duk_context *ctx,
DUK_DDD(DUK_DDDPRINT("flags after accessor->data conversion: 0x%02lx",
(unsigned long) DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, curr.e_idx)));
+ DUK_HOBJECT_DECREF_ALLOWNULL(thr, h_get); /* side effects */
+ DUK_HOBJECT_DECREF_ALLOWNULL(thr, h_set); /* side effects */
+
/* re-lookup to update curr.flags
* XXX: would be faster to update directly
*/
@@ -59766,6 +59876,7 @@ DUK_LOCAL void duk__ivalue_toplain_raw(duk_compiler_ctx *comp_ctx, duk_ivalue *x
}
case DUK_IVAL_NONE:
default: {
+ DUK_D(DUK_DPRINT("invalid ivalue type: %ld", (long) x->t));
break;
}
}
@@ -61735,13 +61846,24 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
* left-hand-side values (e.g. as in "f() = 1") must NOT cause a
* SyntaxError, but rather a run-time ReferenceError.
*
- * Assignment expression value is conceptually the LHS/RHS value
- * copied into a fresh temporary so that it won't change even if
- * LHS/RHS values change (e.g. when they're identifiers). Doing this
- * concretely produces inefficient bytecode, so we try to avoid the
- * extra temporary for some known-to-be-safe cases. Currently the
- * only safe case we detect is a "top level assignment", for example
- * "x = y + z;", where the assignment expression value is ignored.
+ * When evaluating X <op>= Y, the LHS (X) is conceptually evaluated
+ * to a temporary first. The RHS is then evaluated. Finally, the
+ * <op> is applied to the initial value of RHS (not the value after
+ * RHS evaluation), and written to X. Doing so concretely generates
+ * inefficient code so we'd like to avoid the temporary when possible.
+ * See: https://github.com/svaarala/duktape/pull/992.
+ *
+ * The expression value (final LHS value, written to RHS) is
+ * conceptually copied into a fresh temporary so that it won't
+ * change even if the LHS/RHS values change in outer expressions.
+ * For example, it'd be generally incorrect for the expression value
+ * to be the RHS register binding, unless there's a guarantee that it
+ * won't change during further expression evaluation. Using the
+ * temporary concretely produces inefficient bytecode, so we try to
+ * avoid the extra temporary for some known-to-be-safe cases.
+ * Currently the only safe case we detect is a "top level assignment",
+ * for example "x = y + z;", where the assignment expression value is
+ * ignored.
* See: test-dev-assign-expr.js and test-bug-assign-mutate-gh381.js.
*/
@@ -61761,7 +61883,9 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
* is a reg-bound identifier. The RHS ('res') is right associative
* so it has consumed all other assignment level operations; the
* only relevant lower binding power construct is comma operator
- * which will ignore the expression value provided here.
+ * which will ignore the expression value provided here. Usually
+ * the top level assignment expression value is ignored, but it
+ * is relevant for e.g. eval code.
*/
toplevel_assign = (comp_ctx->curr_func.nud_count == 1 && /* one token before */
comp_ctx->curr_func.led_count == 1); /* one operator (= assign) */
@@ -61777,23 +61901,17 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
DUK_ASSERT(left->x1.t == DUK_ISPEC_VALUE); /* LHS is already side effect free */
- /* Keep the RHS as an unresolved ivalue for now, so it
- * can be a plain value or a unary/binary operation here.
- * We resolve it before finishing but doing it later allows
- * better bytecode in some cases.
- */
- duk__expr(comp_ctx, res, args_rbp /*rbp_flags*/);
-
h_varname = duk_get_hstring(ctx, left->x1.valstack_idx);
DUK_ASSERT(h_varname != NULL);
if (duk__hstring_is_eval_or_arguments_in_strict_mode(comp_ctx, h_varname)) {
- /* E5 Section 11.13.1 (and others for other assignments), step 4 */
+ /* E5 Section 11.13.1 (and others for other assignments), step 4. */
goto syntax_error_lvalue;
}
duk_dup(ctx, left->x1.valstack_idx);
(void) duk__lookup_lhs(comp_ctx, ®_varbind, &rc_varname);
if (args_op == DUK_OP_NONE) {
+ duk__expr(comp_ctx, res, args_rbp /*rbp_flags*/);
if (toplevel_assign) {
/* Any 'res' will do. */
DUK_DDD(DUK_DDDPRINT("plain assignment, toplevel assign, use as is"));
@@ -61807,42 +61925,98 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
}
}
} else {
- duk__ivalue_toregconst(comp_ctx, res);
- DUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_REGCONST);
+ /* For X <op>= Y we need to evaluate the pre-op
+ * value of X before evaluating the RHS: the RHS
+ * can change X, but when we do <op> we must use
+ * the pre-op value.
+ */
+ duk_reg_t reg_temp;
+
+ reg_temp = DUK__ALLOCTEMP(comp_ctx);
if (reg_varbind >= 0) {
duk_reg_t reg_res;
+ duk_reg_t reg_src;
+ duk_int_t pc_temp_load;
+ duk_int_t pc_before_rhs;
+ duk_int_t pc_after_rhs;
if (toplevel_assign) {
/* 'reg_varbind' is the operation result and can also
* become the expression value for top level assignments
* such as: "var x; x += y;".
*/
+ DUK_DD(DUK_DDPRINT("<op>= expression is top level, write directly to reg_varbind"));
reg_res = reg_varbind;
} else {
/* Not safe to use 'reg_varbind' as assignment expression
* value, so go through a temp.
*/
- reg_res = DUK__ALLOCTEMP(comp_ctx);
+ DUK_DD(DUK_DDPRINT("<op>= expression is not top level, write to reg_temp"));
+ reg_res = reg_temp; /* reg_res should be smallest possible */
+ reg_temp = DUK__ALLOCTEMP(comp_ctx);
+ }
+
+ /* Try to optimize X <op>= Y for reg-bound
+ * variables. Detect side-effect free RHS
+ * narrowly by seeing whether it emits code.
+ * If not, rewind the code emitter and overwrite
+ * the unnecessary temp reg load.
+ */
+
+ pc_temp_load = duk__get_current_pc(comp_ctx);
+ duk__emit_a_bc(comp_ctx,
+ DUK_OP_LDREG,
+ (duk_regconst_t) reg_temp,
+ reg_varbind);
+
+ pc_before_rhs = duk__get_current_pc(comp_ctx);
+ duk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/);
+ DUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_REGCONST);
+ pc_after_rhs = duk__get_current_pc(comp_ctx);
+
+ DUK_DD(DUK_DDPRINT("pc_temp_load=%ld, pc_before_rhs=%ld, pc_after_rhs=%ld",
+ (long) pc_temp_load, (long) pc_before_rhs,
+ (long) pc_after_rhs));
+
+ if (pc_after_rhs == pc_before_rhs) {
+ /* Note: if the reg_temp load generated shuffling
+ * instructions, we may need to rewind more than
+ * one instruction, so use explicit PC computation.
+ */
+ DUK_DD(DUK_DDPRINT("rhs is side effect free, rewind and avoid unnecessary temp for reg-based <op>="));
+ DUK_BW_ADD_PTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code, (pc_temp_load - pc_before_rhs) * sizeof(duk_compiler_instr));
+ reg_src = reg_varbind;
+ } else {
+ DUK_DD(DUK_DDPRINT("rhs evaluation emitted code, not sure if rhs is side effect free; use temp reg for LHS"));
+ reg_src = reg_temp;
}
duk__emit_a_b_c(comp_ctx,
args_op,
(duk_regconst_t) reg_res,
- (duk_regconst_t) reg_varbind,
+ (duk_regconst_t) reg_src,
res->x1.regconst);
+
res->x1.regconst = (duk_regconst_t) reg_res;
+
+ /* Ensure compact use of temps. */
+ if (DUK__ISTEMP(comp_ctx, reg_res)) {
+ DUK__SETTEMP(comp_ctx, reg_res + 1);
+ }
} else {
/* When LHS is not register bound, always go through a
* temporary. No optimization for top level assignment.
*/
- duk_reg_t reg_temp;
- reg_temp = DUK__ALLOCTEMP(comp_ctx);
duk__emit_a_bc(comp_ctx,
DUK_OP_GETVAR,
(duk_regconst_t) reg_temp,
rc_varname);
+
+ duk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/);
+ DUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_REGCONST);
+
duk__emit_a_b_c(comp_ctx,
args_op,
(duk_regconst_t) reg_temp,
@@ -61928,10 +62102,10 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
DUK__IVAL_FLAG_REQUIRE_TEMP | DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);
/* Evaluate RHS only when LHS is safe. */
- duk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/);
- DUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_REGCONST);
if (args_op == DUK_OP_NONE) {
+ duk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/);
+ DUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_REGCONST);
rc_res = res->x1.regconst;
} else {
reg_temp = DUK__ALLOCTEMP(comp_ctx);
@@ -61940,6 +62114,10 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
(duk_regconst_t) reg_temp,
(duk_regconst_t) reg_obj,
rc_key);
+
+ duk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/);
+ DUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_REGCONST);
+
duk__emit_a_b_c(comp_ctx,
args_op,
(duk_regconst_t) reg_temp,
@@ -61971,17 +62149,18 @@ DUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_i
duk_regconst_t rc_res;
- /* first evaluate LHS fully to ensure all side effects are out */
+ /* First evaluate LHS fully to ensure all side effects are out. */
duk__ivalue_toplain_ignore(comp_ctx, left);
- /* then evaluate RHS fully (its value becomes the expression value too) */
+ /* Then evaluate RHS fully (its value becomes the expression value too).
+ * Technically we'd need the side effect safety check here too, but because
+ * we always throw using INVLHS the result doesn't matter.
+ */
rc_res = duk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/);
duk__emit_extraop_only(comp_ctx,
DUK_EXTRAOP_INVLHS);
- /* XXX: this value is irrelevant because of INVLHS? */
-
res->t = DUK_IVAL_PLAIN;
res->x1.t = DUK_ISPEC_REGCONST;
res->x1.regconst = rc_res;
@@ -71183,7 +71362,12 @@ DUK_LOCAL void duk__inc_data_inner_refcounts(duk_hthread *thr, duk_hcompiledfunc
duk_tval *tv, *tv_end;
duk_hobject **funcs, **funcs_end;
- DUK_ASSERT(DUK_HCOMPILEDFUNCTION_GET_DATA(thr->heap, f) != NULL); /* compiled functions must be created 'atomically' */
+ /* If function creation fails due to out-of-memory, the data buffer
+ * pointer may be NULL in some cases. That's actually possible for
+ * GC code, but shouldn't be possible here because the incomplete
+ * function will be unwound from the value stack and never instantiated.
+ */
+ DUK_ASSERT(DUK_HCOMPILEDFUNCTION_GET_DATA(thr->heap, f) != NULL);
DUK_UNREF(thr);
tv = DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE(thr->heap, f);
@@ -78997,6 +79181,7 @@ DUK_LOCAL void duk__regexp_match_helper(duk_hthread *thr, duk_small_int_t force_
duk_hobject *h_regexp;
duk_hstring *h_bytecode;
duk_hstring *h_input;
+ duk_uint8_t *p_buf;
const duk_uint8_t *pc;
const duk_uint8_t *sp;
duk_small_int_t match = 0;
@@ -79067,17 +79252,21 @@ DUK_LOCAL void duk__regexp_match_helper(duk_hthread *thr, duk_small_int_t force_
DUK_ASSERT(re_ctx.nsaved >= 2);
DUK_ASSERT((re_ctx.nsaved % 2) == 0);
- duk_push_fixed_buffer(ctx, sizeof(duk_uint8_t *) * re_ctx.nsaved);
+ p_buf = (duk_uint8_t *) duk_push_fixed_buffer(ctx, sizeof(duk_uint8_t *) * re_ctx.nsaved);
+ DUK_UNREF(p_buf);
re_ctx.saved = (const duk_uint8_t **) duk_get_buffer(ctx, -1, NULL);
DUK_ASSERT(re_ctx.saved != NULL);
/* [ ... re_obj input bc saved_buf ] */
- /* buffer is automatically zeroed */
-#ifdef DUK_USE_EXPLICIT_NULL_INIT
+#if defined(DUK_USE_EXPLICIT_NULL_INIT)
for (i = 0; i < re_ctx.nsaved; i++) {
re_ctx.saved[i] = (duk_uint8_t *) NULL;
}
+#elif defined(DUK_USE_ZERO_BUFFER_DATA)
+ /* buffer is automatically zeroed */
+#else
+ DUK_MEMZERO((void *) p_buf, sizeof(duk_uint8_t *) * re_ctx.nsaved);
#endif
DUK_DDD(DUK_DDDPRINT("regexp ctx initialized, flags=0x%08lx, nsaved=%ld, recursion_limit=%ld, steps_limit=%ld",
diff --git a/content/handlers/javascript/duktape/duktape.h b/content/handlers/javascript/duktape/duktape.h
index 2cb9a50..eb47a70 100644
--- a/content/handlers/javascript/duktape/duktape.h
+++ b/content/handlers/javascript/duktape/duktape.h
@@ -1,12 +1,12 @@
/*
- * Duktape public API for Duktape 1.5.1.
+ * Duktape public API for Duktape 1.6.0.
*
* See the API reference for documentation on call semantics.
* The exposed API is inside the DUK_API_PUBLIC_H_INCLUDED
* include guard. Other parts of the header are Duktape
* internal and related to platform/compiler/feature detection.
*
- * Git commit 2cc76e9ff1f64869e1146ad7317d8cbe33bbd27e (v1.5.1).
+ * Git commit 17e3d86cf8b4788bd0d37658f833ab440ce43a1c (v1.6.0).
* Git branch HEAD.
*
* See Duktape AUTHORS.rst and LICENSE.txt for copyright and
@@ -163,6 +163,7 @@ extern "C" {
* in Duktape web documentation.
*/
+struct duk_thread_state;
struct duk_memory_functions;
struct duk_function_list_entry;
struct duk_number_list_entry;
@@ -170,6 +171,7 @@ struct duk_number_list_entry;
/* duk_context is now defined in duk_config.h because it may also be
* referenced there by prototypes.
*/
+typedef struct duk_thread_state duk_thread_state;
typedef struct duk_memory_functions duk_memory_functions;
typedef struct duk_function_list_entry duk_function_list_entry;
typedef struct duk_number_list_entry duk_number_list_entry;
@@ -190,6 +192,14 @@ typedef void (*duk_debug_write_flush_function) (void *udata);
typedef duk_idx_t (*duk_debug_request_function) (duk_context *ctx, void *udata, duk_idx_t nvalues);
typedef void (*duk_debug_detached_function) (void *udata);
+struct duk_thread_state {
+ /* XXX: Enough space to hold internal suspend/resume structure.
+ * This is rather awkward and to be fixed when the internal
+ * structure is visible for the public API header.
+ */
+ char data[128];
+};
+
struct duk_memory_functions {
duk_alloc_function alloc_func;
duk_realloc_function realloc_func;
@@ -218,15 +228,15 @@ struct duk_number_list_entry {
* have 99 for patch level (e.g. 0.10.99 would be a development version
* after 0.10.0 but before the next official release).
*/
-#define DUK_VERSION 10501L
+#define DUK_VERSION 10600L
/* Git commit, describe, and branch for Duktape build. Useful for
* non-official snapshot builds so that application code can easily log
* which Duktape snapshot was used. Not available in the Ecmascript
* environment.
*/
-#define DUK_GIT_COMMIT "2cc76e9ff1f64869e1146ad7317d8cbe33bbd27e"
-#define DUK_GIT_DESCRIBE "v1.5.1"
+#define DUK_GIT_COMMIT "17e3d86cf8b4788bd0d37658f833ab440ce43a1c"
+#define DUK_GIT_DESCRIBE "v1.6.0"
#define DUK_GIT_BRANCH "HEAD"
/* Duktape debug protocol version used by this build. */
@@ -397,6 +407,9 @@ duk_context *duk_create_heap(duk_alloc_function alloc_func,
duk_fatal_function fatal_handler);
DUK_EXTERNAL_DECL void duk_destroy_heap(duk_context *ctx);
+DUK_EXTERNAL_DECL void duk_suspend(duk_context *ctx, duk_thread_state *state);
+DUK_EXTERNAL_DECL void duk_resume(duk_context *ctx, const duk_thread_state *state);
+
#define duk_create_heap_default() \
duk_create_heap(NULL, NULL, NULL, NULL, NULL)
diff --git a/content/hlcache.c b/content/hlcache.c
index 042e189..95edd21 100644
--- a/content/hlcache.c
+++ b/content/hlcache.c
@@ -16,8 +16,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/** \file
- * High-level resource cache (implementation)
+/**
+ * \file
+ * High-level resource cache implementation.
*/
#include <assert.h>
@@ -86,7 +87,7 @@ struct hlcache_s {
/** Ring of retrieval contexts */
hlcache_retrieval_ctx *retrieval_ctx_ring;
- /* statsistics */
+ /* statistics */
unsigned int hit_count;
unsigned int miss_count;
};
@@ -665,12 +666,12 @@ nserror hlcache_handle_retrieve(nsurl *url, uint32_t flags,
hlcache_llcache_callback, ctx,
&ctx->llcache);
if (error != NSERROR_OK) {
- /* error retriving handle so free context and return error */
+ /* error retrieving handle so free context and return error */
free((char *) ctx->child.charset);
free(ctx->handle);
free(ctx);
} else {
- /* successfuly started fetch so add new context to list */
+ /* successfully started fetch so add new context to list */
RING_INSERT(hlcache->retrieval_ctx_ring, ctx);
*result = ctx->handle;
diff --git a/content/llcache.c b/content/llcache.c
index e338c1f..eb30053 100644
--- a/content/llcache.c
+++ b/content/llcache.c
@@ -22,7 +22,7 @@
* Low-level resource cache implementation
*
* This is the implementation of the low level cache. This cache
- * stores source objects in memory and may use a persistant backing
+ * stores source objects in memory and may use a persistent backing
* store to extend their lifetime.
*
* \todo fix writeout conditions and ordering.
@@ -35,12 +35,10 @@
#include <stdint.h>
#include <string.h>
#include <strings.h>
-#include <inttypes.h>
-
#include <nsutils/time.h>
+#include "netsurf/inttypes.h"
#include "utils/config.h"
-
#include "utils/corestrings.h"
#include "utils/log.h"
#include "utils/messages.h"
@@ -201,8 +199,8 @@ struct llcache_object {
llcache_header *headers; /**< Fetch headers */
size_t num_headers; /**< Number of fetch headers */
- /* Instrumentation. These elemnts are strictly for information
- * to improve the cache performance and to provide performace
+ /* Instrumentation. These elements are strictly for information
+ * to improve the cache performance and to provide performance
* metrics. The values are non-authorative and must not be used to
* determine object lifetime etc.
*/
@@ -268,7 +266,7 @@ struct llcache_s {
uint64_t total_written;
/**
- * Total nuber of miliseconds taken to write to backing store.
+ * Total number of milliseconds taken to write to backing store.
*/
uint64_t total_elapsed;
@@ -804,7 +802,7 @@ static nserror llcache_fetch_process_header(llcache_object *object,
*
* sets up headers and attempts to start an actual fetch from the
* fetchers system updating the llcache object with the new fetch on
- * sucessful start.
+ * successful start.
*
* \pre The fetch parameters in object->fetch must be populated
*
@@ -876,7 +874,7 @@ static nserror llcache_object_refetch(llcache_object *object)
/* Reset fetch state */
object->fetch.state = LLCACHE_FETCH_INIT;
- LLCACHE_LOG("Refetching %p", object);
+ LLCACHE_LOG("Re-fetching %p", object);
/* Kick off fetch */
res = fetch_start(object->url,
@@ -1173,27 +1171,27 @@ llcache_object_remove_from_list(llcache_object *object, llcache_object **list)
}
/**
- * Retrieve source data for an object from persistant store if necessary.
+ * Retrieve source data for an object from persistent store if necessary.
*
- * If an objects source data has been placed in the persistant store
- * and the in memory copy released this will attempt to retrive the
+ * If an objects source data has been placed in the persistent store
+ * and the in memory copy released this will attempt to retrieve the
* source data.
*
* \param object the object to operate on.
- * \return apropriate error code.
+ * \return appropriate error code.
*/
static nserror llcache_persist_retrieve(llcache_object *object)
{
/* ensure the source data is present if necessary */
if ((object->source_data != NULL) ||
(object->store_state != LLCACHE_STATE_DISC)) {
- /* source data does not require retriving from
- * persistant store.
+ /* source data does not require retrieving from
+ * persistent store.
*/
return NSERROR_OK;
}
- /* Source data for the object may be in the persiatant store */
+ /* Source data for the object may be in the persistent store */
return guit->llcache->fetch(object->url,
BACKING_STORE_NONE,
&object->source_data,
@@ -1205,7 +1203,7 @@ static nserror llcache_persist_retrieve(llcache_object *object)
*
* The metadata includes object headers.
*
- * \param object The cache object to serialise teh metadata of.
+ * \param object The cache object to serialise the metadata of.
* \param data_out Where the serialised buffer will be placed.
* \param datasize_out The size of the serialised data.
* \return NSERROR_OK on success with \a data_out and \a datasize_out
@@ -1347,15 +1345,15 @@ operror:
/**
* Deserialisation of an objects metadata.
*
- * Attempt to retrive and deserialise the metadata for an object from
+ * Attempt to retrieve and deserialise the metadata for an object from
* the backing store.
*
- * This must only update object if it is sucessful otherwise difficult
+ * This must only update object if it is successful otherwise difficult
* to debug crashes happen later by using bad leftover object state.
*
* \param object The object to retrieve the metadata for.
- * \return NSERROR_OK if the metatdata was retrived and deserialised
- * or error code if url is not in persistant storage or in
+ * \return NSERROR_OK if the metatdata was retrieved and deserialised
+ * or error code if URL is not in persistent storage or in
* event of deserialisation error.
*/
static nserror
@@ -1376,7 +1374,7 @@ llcache_process_metadata(llcache_object *object)
size_t num_headers;
size_t hloop;
- LOG("Retriving metadata");
+ LOG("Retrieving metadata");
/* attempt to retrieve object metadata from the backing store */
res = guit->llcache->fetch(object->url,
@@ -1387,7 +1385,7 @@ llcache_process_metadata(llcache_object *object)
return res;
}
- LOG("Processing retrived data");
+ LOG("Processing retrieved data");
/* metadata line 1 is the url the metadata referrs to */
line = 1;
@@ -1405,7 +1403,7 @@ llcache_process_metadata(llcache_object *object)
if (nsurl_compare(object->url, metadataurl, NSURL_COMPLETE) != true) {
/* backing store returned the wrong object for the
- * request. This may occour if the backing store had
+ * request. This may occur if the backing store had
* a collision in its storage method. We cope with this
* by simply skipping caching of this object.
*/
@@ -1511,14 +1509,14 @@ format_error:
}
/**
- * Attempt to retrieve an object from persistant storage.
+ * Attempt to retrieve an object from persistent storage.
*
- * \param object The object to populate from persistant store.
+ * \param object The object to populate from persistent store.
* \param flags Fetch flags.
* \param referer The referring url.
* \param post Post data for fetch.
* \param redirect_count how many times this fetch has been redirected.
- * \return NSERROR_OK if the object was sucessfully retrived from the
+ * \return NSERROR_OK if the object was successfully retrieved from the
* cache else appropriate error code.
*/
static nserror
@@ -1572,7 +1570,7 @@ llcache_object_fetch_persistant(llcache_object *object,
* \param referer Referring URL, or NULL if none
* \param post POST data, or NULL for a GET request
* \param redirect_count Number of redirects followed so far
- * \param result Pointer to location to recieve retrieved object
+ * \param result Pointer to location to receive retrieved object
* \return NSERROR_OK on success, appropriate error otherwise
*/
static nserror
@@ -1602,7 +1600,7 @@ llcache_object_retrieve_from_cache(nsurl *url,
}
/* No viable object found in cache create one and attempt to
- * pull from persistant store.
+ * pull from persistent store.
*/
if (newest == NULL) {
LLCACHE_LOG("No viable object found in llcache");
@@ -1611,12 +1609,12 @@ llcache_object_retrieve_from_cache(nsurl *url,
if (error != NSERROR_OK)
return error;
- /* attempt to retrieve object from persistant store */
+ /* attempt to retrieve object from persistent store */
error = llcache_object_fetch_persistant(obj, flags, referer, post, redirect_count);
if (error == NSERROR_OK) {
- LLCACHE_LOG("retrived object from persistant store");
+ LLCACHE_LOG("retrieved object from persistent store");
- /* set newest object from persistant store which
+ /* set newest object from persistent store which
* will cause the normal object handling to be used.
*/
newest = obj;
@@ -1625,7 +1623,7 @@ llcache_object_retrieve_from_cache(nsurl *url,
llcache_object_add_to_list(obj, &llcache->cached_objects);
}
- /* else no object found and unretrivable from cache,
+ /* else no object found and irretrievable from cache,
* fall through with newest unset to start fetch
*/
}
@@ -1641,19 +1639,19 @@ llcache_object_retrieve_from_cache(nsurl *url,
/* ensure the source data is present */
error = llcache_persist_retrieve(newest);
if (error == NSERROR_OK) {
- /* source data was sucessfully retrived from
- * persistant store
+ /* source data was successfully retrieved from
+ * persistent store
*/
*result = newest;
return NSERROR_OK;
}
- /* retrival of source data from persistant store
+ /* retrieval of source data from persistent store
* failed, destroy cache object and fall though to
* cache miss to re-fetch
*/
- LLCACHE_LOG("Persistant retrival failed for %p", newest);
+ LLCACHE_LOG("Persistent retrieval failed for %p", newest);
llcache_object_remove_from_list(newest, &llcache->cached_objects);
llcache_object_destroy(newest);
@@ -1704,9 +1702,9 @@ llcache_object_retrieve_from_cache(nsurl *url,
return NSERROR_OK;
}
- LLCACHE_LOG("Persistant retrival failed for %p", newest);
+ LLCACHE_LOG("Persistent retrieval failed for %p", newest);
- /* retrival of source data from persistant store
+ /* retrieval of source data from persistent store
* failed, destroy cache object and fall though to
* cache miss to re-retch
*/
@@ -1743,7 +1741,7 @@ llcache_object_retrieve_from_cache(nsurl *url,
* \param referer Referring URL, or NULL if none
* \param post POST data, or NULL for a GET request
* \param redirect_count Number of redirects followed so far
- * \param result Pointer to location to recieve retrieved object
+ * \param result Pointer to location to receive retrieved object
* \return NSERROR_OK on success, appropriate error otherwise
*/
static nserror
@@ -2372,7 +2370,7 @@ build_candidate_list(struct llcache_object ***lst_out, int *lst_len_out)
/* cacehable objects with no pending fetches, not
* already on disc and with sufficient lifetime to
- * make disc cache worthwile
+ * make disc cache worthwhile
*/
if ((object->candidate_count == 0) &&
(object->fetch.fetch == NULL) &&
@@ -2526,20 +2524,20 @@ static void llcache_persist(void *p)
ret = build_candidate_list(&lst, &lst_count);
if (ret != NSERROR_OK) {
- LLCACHE_LOG("Unable to construct candidate list for persisatnt writeout");
+ LLCACHE_LOG("Unable to construct candidate list for persistent writeout");
return;
}
write_limit = (llcache->maximum_bandwidth * llcache->time_quantum) / 1000;
- /* obtained a candidate list, make each object persistant in turn */
+ /* obtained a candidate list, make each object persistent in turn */
for (idx = 0; idx < lst_count; idx++) {
ret = write_backing_store(lst[idx], &written, &elapsed);
if (ret != NSERROR_OK) {
continue;
}
- /* sucessfully wrote object to backing store */
+ /* successfully wrote object to backing store */
total_written += written;
total_elapsed += elapsed;
total_bandwidth = (total_written * 1000) / total_elapsed;
@@ -3138,7 +3136,7 @@ llcache_object_snapshot(llcache_object *object, llcache_object **snapshot)
/**
* total ram usage of object
*
- * \param object The object to caclulate the total RAM usage of.
+ * \param object The object to calculate the total RAM usage of.
* \return The total RAM usage in bytes.
*/
static inline uint32_t
@@ -3253,7 +3251,7 @@ void llcache_clean(bool purge)
}
/* if the cache limit is exceeded try to make some objects
- * persistant so their RAM can be reclaimed in the next
+ * persistent so their RAM can be reclaimed in the next
* step
*/
if (limit < llcache_size) {
@@ -3261,7 +3259,7 @@ void llcache_clean(bool purge)
}
/* Source data of fresh cacheable objects with no users, no
- * pending fetches and pushed to persistant store while the
+ * pending fetches and pushed to persistent store while the
* cache exceeds the configured size.
*/
for (object = llcache->cached_objects;
@@ -3286,8 +3284,8 @@ void llcache_clean(bool purge)
}
/* Fresh cacheable objects with no users, no pending fetches
- * and pushed to persistant store while the cache exceeds
- * the configured size. Efectively just the llcache object metadata.
+ * and pushed to persistent store while the cache exceeds
+ * the configured size. Effectively just the llcache object metadata.
*/
for (object = llcache->cached_objects;
((limit < llcache_size) && (object != NULL));
@@ -3317,7 +3315,7 @@ void llcache_clean(bool purge)
/* Fresh cacheable objects with no users or pending fetches
* while the cache exceeds the configured size. These are the
- * most valuble objects as replacing them is a full network
+ * most valuable objects as replacing them is a full network
* fetch
*/
for (object = llcache->cached_objects;
diff --git a/desktop/Makefile b/desktop/Makefile
index f7f660d..2dcd616 100644
--- a/desktop/Makefile
+++ b/desktop/Makefile
@@ -2,8 +2,8 @@
S_DESKTOP := cookie_manager.c knockout.c hotlist.c mouse.c \
plot_style.c print.c search.c searchweb.c scrollbar.c \
- sslcert_viewer.c textarea.c tree.c version.c \
- system_colour.c global_history.c treeview.c
+ sslcert_viewer.c textarea.c version.c system_colour.c \
+ global_history.c treeview.c
S_DESKTOP := $(addprefix desktop/,$(S_DESKTOP))
diff --git a/desktop/browser_history.c b/desktop/browser_history.c
index 5cd98cd..d21c5bc 100644
--- a/desktop/browser_history.c
+++ b/desktop/browser_history.c
@@ -37,6 +37,7 @@
#include "content/urldb.h"
#include "netsurf/bitmap.h"
+#include "desktop/system_colour.h"
#include "desktop/gui_internal.h"
#include "desktop/browser_history.h"
#include "desktop/browser_private.h"
@@ -235,6 +236,45 @@ static void browser_window_history__layout(struct history *history)
history->height += BOTTOM_MARGIN / 2;
}
+/** plot style for drawing lines between nodes */
+static plot_style_t pstyle_line = {
+ .stroke_type = PLOT_OP_TYPE_SOLID,
+ .stroke_width = 2,
+};
+
+/** plot style for drawing background */
+static plot_style_t pstyle_bg = {
+ .fill_type = PLOT_OP_TYPE_SOLID,
+};
+
+/** plot style for drawing rectangle round unselected nodes */
+static plot_style_t pstyle_rect = {
+ .stroke_type = PLOT_OP_TYPE_SOLID,
+ .stroke_width = 1,
+};
+
+/** plot style for drawing rectangle round selected nodes */
+static plot_style_t pstyle_rect_sel = {
+ .stroke_type = PLOT_OP_TYPE_SOLID,
+ .stroke_width = 3,
+};
+
+/** plot style for font on unselected nodes */
+static plot_font_style_t pfstyle_node = {
+ .family = PLOT_FONT_FAMILY_SANS_SERIF,
+ .size = 8 * FONT_SIZE_SCALE,
+ .weight = 400,
+ .flags = FONTF_NONE,
+};
+
+/** plot style for font on unselected nodes */
+static plot_font_style_t pfstyle_node_sel = {
+ .family = PLOT_FONT_FAMILY_SANS_SERIF,
+ .size = 8 * FONT_SIZE_SCALE,
+ .weight = 900,
+ .flags = FONTF_NONE,
+};
+
/**
* Recursively redraw a history_entry.
*
@@ -260,19 +300,25 @@ browser_window_history__redraw_entry(struct history *history,
size_t char_offset;
int actual_x;
struct history_entry *child;
- colour c = entry == history->current ?
- HISTORY_COLOUR_SELECTED : HISTORY_COLOUR_FOREGROUND;
int tailsize = 5;
int xoffset = x - x0;
int yoffset = y - y0;
- plot_style_t pstyle_history_rect = {
- .stroke_type = PLOT_OP_TYPE_SOLID,
- .stroke_colour = c,
- .stroke_width = entry == history->current ? 3 : 1,
- };
- plot_font_style_t fstyle = *plot_style_font;
+
+ plot_style_t *pstyle;
+ plot_font_style_t *pfstyle;
+
nserror res;
+ /* setup plot styles */
+ if (entry == history->current) {
+ pstyle = &pstyle_rect_sel;
+ pfstyle = &pfstyle_node_sel;
+ } else {
+ pstyle = &pstyle_rect;
+ pfstyle = &pfstyle_node;
+ }
+
+ /* setup clip area */
if (clip) {
struct rect rect;
rect.x0 = x0 + xoffset;
@@ -289,14 +335,16 @@ browser_window_history__redraw_entry(struct history *history,
plot->bitmap(entry->x + xoffset,
entry->y + yoffset,
WIDTH, HEIGHT,
- entry->bitmap, 0xffffff, 0);
+ entry->bitmap,
+ 0xffffff,
+ 0);
}
if (!plot->rectangle(entry->x - 1 + xoffset,
- entry->y - 1 + yoffset,
- entry->x + xoffset + WIDTH,
- entry->y + yoffset + HEIGHT,
- &pstyle_history_rect)) {
+ entry->y - 1 + yoffset,
+ entry->x + xoffset + WIDTH,
+ entry->y + yoffset + HEIGHT,
+ pstyle)) {
return false;
}
@@ -307,36 +355,42 @@ browser_window_history__redraw_entry(struct history *history,
return false;
}
- fstyle.background = HISTORY_COLOUR_BACKGROUND;
- fstyle.foreground = c;
- fstyle.weight = entry == history->current ? 900 : 400;
- if (!plot->text(entry->x + xoffset, entry->y + HEIGHT + 12 + yoffset,
- entry->page.title, char_offset, &fstyle))
+ if (!plot->text(entry->x + xoffset,
+ entry->y + HEIGHT + 12 + yoffset,
+ entry->page.title,
+ char_offset,
+ pfstyle)) {
return false;
+ }
+ /* for each child node draw a line and recurse redraw into it */
for (child = entry->forward; child; child = child->next) {
if (!plot->line(entry->x + WIDTH + xoffset,
entry->y + HEIGHT / 2 + yoffset,
- entry->x + WIDTH + tailsize + xoffset,
- entry->y + HEIGHT / 2 + yoffset,
- plot_style_stroke_history))
+ entry->x + WIDTH + tailsize + xoffset,
+ entry->y + HEIGHT / 2 + yoffset,
+ &pstyle_line)) {
return false;
+ }
if (!plot->line(entry->x + WIDTH + tailsize + xoffset,
- entry->y + HEIGHT / 2 + yoffset,
- child->x - tailsize +xoffset,
- child->y + HEIGHT / 2 + yoffset,
- plot_style_stroke_history))
+ entry->y + HEIGHT / 2 + yoffset,
+ child->x - tailsize +xoffset,
+ child->y + HEIGHT / 2 + yoffset,
+ &pstyle_line)) {
return false;
+ }
if (!plot->line(child->x - tailsize + xoffset,
- child->y + HEIGHT / 2 + yoffset,
- child->x + xoffset, child->y +
+ child->y + HEIGHT / 2 + yoffset,
+ child->x + xoffset, child->y +
HEIGHT / 2 + yoffset,
- plot_style_stroke_history))
+ &pstyle_line)) {
return false;
+ }
if (!browser_window_history__redraw_entry(history, child,
- x0, y0, x1, y1, x, y, clip, ctx))
+ x0, y0, x1, y1, x, y, clip, ctx)) {
return false;
+ }
}
return true;
@@ -415,6 +469,17 @@ nserror browser_window_history_create(struct browser_window *bw)
{
struct history *history;
+ pstyle_bg.fill_colour = ns_system_colour_char("Window");
+ pfstyle_node.background = pstyle_bg.fill_colour;
+ pfstyle_node_sel.background = pstyle_bg.fill_colour;
+
+ pstyle_line.stroke_colour = ns_system_colour_char("GrayText");
+ pstyle_rect.stroke_colour = pstyle_line.stroke_colour;
+ pfstyle_node.foreground = pstyle_line.stroke_colour;
+
+ pstyle_rect_sel.stroke_colour = ns_system_colour_char("Highlight");
+ pfstyle_node_sel.foreground = pstyle_rect_sel.stroke_colour;
+
bw->history = NULL;
history = calloc(1, sizeof *history);
@@ -426,6 +491,7 @@ nserror browser_window_history_create(struct browser_window *bw)
history->height = BOTTOM_MARGIN / 2;
bw->history = history;
+
return NSERROR_OK;
}
@@ -709,6 +775,7 @@ bool browser_window_history_redraw(struct browser_window *bw,
if (!history->start)
return true;
+
return browser_window_history__redraw_entry(history, history->start,
0, 0, 0, 0, 0, 0, false, ctx);
}
@@ -726,6 +793,7 @@ bool browser_window_history_redraw_rectangle(struct browser_window *bw,
if (!history->start)
return true;
+
return browser_window_history__redraw_entry(history, history->start,
x0, y0, x1, y1, x, y, true, ctx);
}
diff --git a/desktop/browser_private.h b/desktop/browser_private.h
index 64c698b..072a894 100644
--- a/desktop/browser_private.h
+++ b/desktop/browser_private.h
@@ -26,9 +26,10 @@
#include <libwapcaplet/libwapcaplet.h>
+#include "netsurf/types.h"
#include "netsurf/browser_window.h"
+
#include "desktop/frame_types.h"
-#include "desktop/plot_style.h"
struct box;
struct hlcache_handle;
diff --git a/desktop/cookie_manager.c b/desktop/cookie_manager.c
index 6134fa5..5429f68 100644
--- a/desktop/cookie_manager.c
+++ b/desktop/cookie_manager.c
@@ -843,6 +843,7 @@ nserror cookie_manager_fini(void)
/* Destroy the cookie manager treeview */
err = treeview_destroy(cm_ctx.tree);
+ cm_ctx.tree = NULL;
/* Free cookie manager treeview entry fields */
for (i = 0; i < COOKIE_M_N_FIELDS; i++)
diff --git a/desktop/font_haru.h b/desktop/font_haru.h
index 479f7de..988b9ba 100644
--- a/desktop/font_haru.h
+++ b/desktop/font_haru.h
@@ -26,7 +26,6 @@
#include <hpdf.h>
-#include "desktop/plot_style.h"
#include "desktop/font.h"
bool haru_nsfont_apply_style(const plot_font_style_t *fstyle,
diff --git a/desktop/global_history.c b/desktop/global_history.c
index b6f4882..a19349f 100644
--- a/desktop/global_history.c
+++ b/desktop/global_history.c
@@ -803,6 +803,7 @@ nserror global_history_fini(void)
/* Destroy the global history treeview */
err = treeview_destroy(gh_ctx.tree);
+ gh_ctx.tree = NULL;
/* Free global history treeview entry fields */
for (i = 0; i < N_FIELDS; i++)
diff --git a/desktop/hotlist.c b/desktop/hotlist.c
index e344b3b..78473c7 100644
--- a/desktop/hotlist.c
+++ b/desktop/hotlist.c
@@ -1227,8 +1227,7 @@ static nserror hotlist_populate(const char *path)
/* Exported interface, documented in hotlist.h */
-nserror hotlist_init(struct core_window_callback_table *cw_t,
- void *core_window_handle, const char *path)
+nserror hotlist_init(const char *path)
{
nserror err;
@@ -1252,8 +1251,7 @@ nserror hotlist_init(struct core_window_callback_table *cw_t,
/* Create the hotlist treeview */
err = treeview_create(&hl_ctx.tree, &hl_tree_cb_t,
- HL_N_FIELDS, hl_ctx.fields,
- cw_t, core_window_handle,
+ HL_N_FIELDS, hl_ctx.fields, NULL, NULL,
TREEVIEW_NO_FLAGS);
if (err != NSERROR_OK) {
hl_ctx.tree = NULL;
@@ -1271,10 +1269,41 @@ nserror hotlist_init(struct core_window_callback_table *cw_t,
* the treeview is built. */
hl_ctx.built = true;
+ LOG("Loaded hotlist");
+
+ return NSERROR_OK;
+}
+
+
+/* Exported interface, documented in hotlist.h */
+nserror hotlist_manager_init(struct core_window_callback_table *cw_t,
+ void *core_window_handle)
+{
+ nserror err;
+
+ /* Create the hotlist treeview */
+ err = treeview_cw_attach(hl_ctx.tree, cw_t, core_window_handle);
+ if (err != NSERROR_OK) {
+ return err;
+ }
+
/* Inform client of window height */
treeview_get_height(hl_ctx.tree);
- LOG("Loaded hotlist");
+ return NSERROR_OK;
+}
+
+
+/* Exported interface, documented in hotlist.h */
+nserror hotlist_manager_fini(void)
+{
+ nserror err;
+
+ /* Create the hotlist treeview */
+ err = treeview_cw_detach(hl_ctx.tree);
+ if (err != NSERROR_OK) {
+ return err;
+ }
return NSERROR_OK;
}
diff --git a/desktop/hotlist.h b/desktop/hotlist.h
index 31aa030..c77ac92 100644
--- a/desktop/hotlist.h
+++ b/desktop/hotlist.h
@@ -33,18 +33,44 @@ struct rect;
/**
* Initialise the hotlist.
*
- * This opens the hotlist file, generating the hotlist data, and creates a
+ * This opens the hotlist file, construct the hostlist, and creates a
* treeview. If there's no hotlist file, it generates a default hotlist.
*
- * This must be called before any other hotlist_* function.
+ * This must be called before any other hotlist_* function. It must
+ * be called before URLs can be added to the hotlist, and before the
+ * hotlist can be queried to ask if URLs are present in the hotlist.
+ *
+ * \param path The path to hotlist file to load
+ * \return NSERROR_OK on success, appropriate error otherwise
+ */
+nserror hotlist_init(const char *path);
+
+/**
+ * Initialise the hotlist manager.
+ *
+ * This connects the underlying hotlist treeview to a corewindow for display.
+ *
+ * The provided core window handle must be valid until hotlist_fini is called.
*
* \param cw_t Callback table for core_window containing the treeview
* \param core_window_handle The handle in which the treeview is shown
- * \param path The path to hotlist file to load
* \return NSERROR_OK on success, appropriate error otherwise
*/
-nserror hotlist_init(struct core_window_callback_table *cw_t,
- void *core_window_handle, const char *path);
+nserror hotlist_manager_init(struct core_window_callback_table *cw_t,
+ void *core_window_handle);
+
+
+/**
+ * Finalise the hotlist manager.
+ *
+ * This simply disconnects the underlying treeview from its corewindow,
+ * allowing destruction of a GUI hotlist window, without finalising the
+ * hotlist module.
+ *
+ * \param path The path to save hotlist to
+ * \return NSERROR_OK on success, appropriate error otherwise
+ */
+nserror hotlist_manager_fini(void);
/**
* Finalise the hotlist.
diff --git a/desktop/knockout.c b/desktop/knockout.c
index b930ef6..bcfc272 100644
--- a/desktop/knockout.c
+++ b/desktop/knockout.c
@@ -71,10 +71,10 @@
#include "utils/errors.h"
#include "netsurf/bitmap.h"
#include "content/content.h"
+#include "netsurf/plotters.h"
#include "desktop/gui_internal.h"
#include "desktop/knockout.h"
-#include "netsurf/plotters.h"
/* Define to enable knockout debug */
#undef KNOCKOUT_DEBUG
diff --git a/desktop/netsurf.c b/desktop/netsurf.c
index d129ef7..0f597aa 100644
--- a/desktop/netsurf.c
+++ b/desktop/netsurf.c
@@ -25,12 +25,12 @@
#include <stdlib.h>
#include <libwapcaplet/libwapcaplet.h>
+#include "netsurf/inttypes.h"
#include "utils/config.h"
#include "utils/nsoption.h"
#include "utils/corestrings.h"
#include "utils/log.h"
#include "utils/utf8.h"
-#include "utils/utils.h"
#include "utils/messages.h"
#include "content/content_factory.h"
#include "content/fetchers.h"
@@ -279,6 +279,9 @@ void netsurf_exit(void)
LOG("Destroying System colours");
ns_system_colour_finalize();
+ LOG("Destroying Messages");
+ messages_destroy();
+
corestrings_fini();
LOG("Remaining lwc strings:");
lwc_iterate_strings(netsurf_lwc_iterator, NULL);
diff --git a/desktop/options.h b/desktop/options.h
index 437d104..d91898c 100644
--- a/desktop/options.h
+++ b/desktop/options.h
@@ -30,7 +30,7 @@
#ifndef _NETSURF_DESKTOP_OPTIONS_H_
#define _NETSURF_DESKTOP_OPTIONS_H_
-#include "desktop/plot_style.h"
+#include "netsurf/types.h"
/* defines for system colour table */
#define NSOPTION_SYS_COLOUR_START NSOPTION_sys_colour_ActiveBorder
diff --git a/desktop/plot_style.c b/desktop/plot_style.c
index f9ba4bc..1f0ac39 100644
--- a/desktop/plot_style.c
+++ b/desktop/plot_style.c
@@ -16,14 +16,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/**
- * \file desktop/plot_style.c
+/**
+ * \file
* \brief Plotter global styles.
*
* These plot styles are globaly available and used in many places.
*/
-#include "netsurf/plotters.h"
+#include "netsurf/plot_style.h"
static plot_style_t plot_style_fill_white_static = {
.fill_type = PLOT_OP_TYPE_SOLID,
@@ -152,15 +152,6 @@ static plot_style_t plot_style_stroke_lightwbasec_static = {
};
plot_style_t *plot_style_stroke_lightwbasec = &plot_style_stroke_lightwbasec_static;
-/* history styles */
-
-/** stroke style for history core. */
-static plot_style_t plot_style_stroke_history_static = {
- .stroke_type = PLOT_OP_TYPE_SOLID,
- .stroke_colour = HISTORY_COLOUR_LINES,
- .stroke_width = 2,
-};
-plot_style_t *plot_style_stroke_history = &plot_style_stroke_history_static;
/* Generic font style */
static const plot_font_style_t plot_style_font_static = {
diff --git a/desktop/scrollbar.c b/desktop/scrollbar.c
index b9e963a..9a4d70f 100644
--- a/desktop/scrollbar.c
+++ b/desktop/scrollbar.c
@@ -29,14 +29,12 @@
#include "utils/messages.h"
#include "utils/utils.h"
#include "utils/nsoption.h"
-
#include "netsurf/browser_window.h"
-#include "desktop/system_colour.h"
#include "netsurf/mouse.h"
-#include "desktop/scrollbar.h"
#include "netsurf/plotters.h"
-#include "desktop/plot_style.h"
+#include "desktop/system_colour.h"
+#include "desktop/scrollbar.h"
struct scrollbar {
bool horizontal; /* Horizontal scrollbar if true, else vertical
diff --git a/desktop/searchweb.c b/desktop/searchweb.c
index 593591c..29a998e 100644
--- a/desktop/searchweb.c
+++ b/desktop/searchweb.c
@@ -60,7 +60,7 @@ static const char *default_search_icon_url = "resource:icons/search.png";
/**
* Read providers file.
*
- * Allocates stoage of sufficient size for the providers file and
+ * Allocates storage of sufficient size for the providers file and
* reads the entire file in.
*
* \param fname The filename to read.
@@ -132,7 +132,7 @@ read_providers(const char *fname,
* \param providers_size The size of the provider data.
* \param providers_out The resulting provider array.
* \param providers_count The number of providers in the output array.
- * \return NSERROR_OK on success or error code on faliure.
+ * \return NSERROR_OK on success or error code on failure.
*/
static nserror
parse_providers(char *providersd,
@@ -224,7 +224,7 @@ parse_providers(char *providersd,
* \param provider The provider to use.
* \param term The term being searched for.
* \param url_out The resulting url.
- * \return NSERROR_OK on sucess or appropriate error code.
+ * \return NSERROR_OK on success or appropriate error code.
*/
static nserror
make_search_nsurl(struct search_provider *provider,
@@ -289,7 +289,7 @@ search_web_ico_callback(hlcache_handle *ico,
switch (event->type) {
case CONTENT_MSG_DONE:
- LOG("icon '%s' retrived", nsurl_access(hlcache_handle_get_url(ico)));
+ LOG("icon '%s' retrieved", nsurl_access(hlcache_handle_get_url(ico)));
guit->search_web->provider_update(provider->name,
content_get_bitmap(ico));
break;
@@ -399,7 +399,7 @@ nserror search_web_select_provider(int selection)
guit->search_web->provider_update(provider->name, ico_bitmap);
- /* if the providers icon has not been retrived get it now */
+ /* if the providers icon has not been retrieved get it now */
if (provider->ico_handle == NULL) {
nsurl *icon_nsurl;
nserror ret;
@@ -438,7 +438,7 @@ default_ico_callback(hlcache_handle *ico,
switch (event->type) {
case CONTENT_MSG_DONE:
- LOG("default icon '%s' retrived", nsurl_access(hlcache_handle_get_url(ico)));
+ LOG("default icon '%s' retrieved", nsurl_access(hlcache_handle_get_url(ico)));
/* only set to default icon if providers icon has no handle */
if (ctx->providers[search_web_ctx.current].ico_handle == NULL) {
diff --git a/desktop/system_colour.h b/desktop/system_colour.h
index b5d4baa..8e82818 100644
--- a/desktop/system_colour.h
+++ b/desktop/system_colour.h
@@ -26,7 +26,7 @@
#include <libcss/libcss.h>
#include "utils/errors.h"
-#include "desktop/plot_style.h"
+#include "netsurf/types.h"
/** css callback to obtain named system colours. */
css_error ns_system_colour(void *pw, lwc_string *name, css_color *color);
diff --git a/desktop/textarea.h b/desktop/textarea.h
index 74652f3..65e2594 100644
--- a/desktop/textarea.h
+++ b/desktop/textarea.h
@@ -27,9 +27,7 @@
#include <stdint.h>
#include <stdbool.h>
-#include "utils/utils.h"
-
-#include "desktop/plot_style.h"
+#include "netsurf/plot_style.h"
#include "netsurf/mouse.h"
struct textarea;
diff --git a/desktop/treeview.c b/desktop/treeview.c
index 387b34e..4d8fbaa 100644
--- a/desktop/treeview.c
+++ b/desktop/treeview.c
@@ -22,6 +22,7 @@
* Treeview handling implementation.
*/
+#include "utils/utils.h"
#include "utils/log.h"
#include "utils/nsurl.h"
#include "utils/nsoption.h"
@@ -219,6 +220,72 @@ static struct treeview_resource treeview_res[TREE_RES_LAST] = {
}; /**< Treeview content resources */
+/**
+ * Corewindow callback wrapper: Request a redraw of the window
+ *
+ * \param[in] cw the core window object
+ * \param[in] r rectangle to redraw
+ */
+static inline void treeview__cw_redraw_request(
+ const struct treeview *tree,
+ const struct rect *r)
+{
+ if (tree->cw_t != NULL) {
+ tree->cw_t->redraw_request(tree->cw_h, r);
+ }
+}
+
+
+/**
+ * Corewindow callback wrapper: Update the limits of the window
+ *
+ * \param[in] cw the core window object
+ * \param[in] width the width in px, or negative if don't care
+ * \param[in] height the height in px, or negative if don't care
+ */
+static inline void treeview__cw_update_size(
+ const struct treeview *tree,
+ int width, int height)
+{
+ if (tree->cw_t != NULL) {
+ tree->cw_t->update_size(tree->cw_h, width, height);
+ }
+}
+
+
+/**
+ * Corewindow callback wrapper: Get window viewport dimensions
+ *
+ * \param[in] cw the core window object
+ * \param[out] width to be set to viewport width in px
+ * \param[out] height to be set to viewport height in px
+ */
+static inline void treeview__cw_get_window_dimensions(
+ const struct treeview *tree,
+ int *width, int *height)
+{
+ if (tree->cw_t != NULL) {
+ tree->cw_t->get_window_dimensions(tree->cw_h, width, height);
+ }
+}
+
+
+/**
+ * Corewindow callback wrapper: Inform corewindow owner of drag status
+ *
+ * \param[in] cw the core window object
+ * \param[in] ds the current drag status
+ */
+static inline void treeview__cw_drag_status(
+ const struct treeview *tree,
+ core_window_drag_status ds)
+{
+ if (tree->cw_t != NULL) {
+ tree->cw_t->drag_status(tree->cw_h, ds);
+ }
+}
+
+
/* Helper function to access the given field of a node
*
* \param tree Treeview that node belongs to
@@ -605,7 +672,7 @@ nserror treeview_create_node_folder(treeview *tree,
if (n->parent->flags & TV_NFLAGS_EXPANDED) {
/* Inform front end of change in dimensions */
if (!(flags & TREE_OPTION_SUPPRESS_RESIZE))
- tree->cw_t->update_size(tree->cw_h, -1,
+ treeview__cw_update_size(tree, -1,
tree->root->height);
/* Redraw */
@@ -615,7 +682,7 @@ nserror treeview_create_node_folder(treeview *tree,
r.y0 = treeview_node_y(tree, n);
r.x1 = REDRAW_MAX;
r.y1 = tree->root->height;
- tree->cw_t->redraw_request(tree->cw_h, &r);
+ treeview__cw_redraw_request(tree, &r);
}
}
@@ -665,7 +732,7 @@ nserror treeview_update_node_folder(treeview *tree,
r.y0 = treeview_node_y(tree, folder);
r.x1 = REDRAW_MAX;
r.y1 = r.y0 + tree_g.line_height;
- tree->cw_t->redraw_request(tree->cw_h, &r);
+ treeview__cw_redraw_request(tree, &r);
}
return NSERROR_OK;
@@ -736,7 +803,7 @@ nserror treeview_update_node_entry(treeview *tree,
r.y0 = treeview_node_y(tree, entry);
r.x1 = REDRAW_MAX;
r.y1 = r.y0 + entry->height;
- tree->cw_t->redraw_request(tree->cw_h, &r);
+ treeview__cw_redraw_request(tree, &r);
}
return NSERROR_OK;
@@ -811,7 +878,7 @@ nserror treeview_create_node_entry(treeview *tree,
if (n->parent->flags & TV_NFLAGS_EXPANDED) {
/* Inform front end of change in dimensions */
if (!(flags & TREE_OPTION_SUPPRESS_RESIZE))
- tree->cw_t->update_size(tree->cw_h, -1,
+ treeview__cw_update_size(tree, -1,
tree->root->height);
/* Redraw */
@@ -821,7 +888,7 @@ nserror treeview_create_node_entry(treeview *tree,
r.y0 = treeview_node_y(tree, n);
r.x1 = REDRAW_MAX;
r.y1 = tree->root->height;
- tree->cw_t->redraw_request(tree->cw_h, &r);
+ treeview__cw_redraw_request(tree, &r);
}
}
@@ -942,7 +1009,7 @@ static void treeview_edit_cancel(treeview *tree, bool redraw)
r.y0 = tree->edit.y;
r.x1 = tree->edit.x + tree->edit.w;
r.y1 = tree->edit.y + tree->edit.h;
- tree->cw_t->redraw_request(tree->cw_h, &r);
+ treeview__cw_redraw_request(tree, &r);
}
}
@@ -1110,7 +1177,7 @@ static nserror treeview_delete_node_internal(treeview *tree, treeview_node *n,
if (tree->root != NULL && p != NULL && p->flags & TV_NFLAGS_EXPANDED &&
nd.h_reduction > 0 &&
!(flags & TREE_OPTION_SUPPRESS_RESIZE)) {
- tree->cw_t->update_size(tree->cw_h, -1,
+ treeview__cw_update_size(tree, -1,
tree->root->height);
}
@@ -1253,7 +1320,7 @@ nserror treeview_delete_node(treeview *tree, treeview_node *n,
if (tree->root->height != h) {
r.y0 = 0;
if (!(flags & TREE_OPTION_SUPPRESS_RESIZE)) {
- tree->cw_t->update_size(tree->cw_h, -1,
+ treeview__cw_update_size(tree, -1,
tree->root->height);
}
}
@@ -1263,7 +1330,7 @@ nserror treeview_delete_node(treeview *tree, treeview_node *n,
if (visible && !(flags & TREE_OPTION_SUPPRESS_REDRAW)) {
r.x0 = 0;
r.x1 = REDRAW_MAX;
- tree->cw_t->redraw_request(tree->cw_h, &r);
+ treeview__cw_redraw_request(tree, &r);
}
return NSERROR_OK;
@@ -1280,8 +1347,7 @@ nserror treeview_create(treeview **tree,
nserror error;
int i;
- assert(cw_t != NULL);
- assert(cw != NULL);
+ assert((cw_t == NULL && cw == NULL) || (cw_t != NULL && cw != NULL));
assert(callbacks != NULL);
assert(fields != NULL);
@@ -1357,6 +1423,35 @@ nserror treeview_create(treeview **tree,
/* Exported interface, documented in treeview.h */
+nserror treeview_cw_attach(treeview *tree,
+ const struct core_window_callback_table *cw_t,
+ struct core_window *cw)
+{
+ assert(cw_t != NULL);
+ assert(cw != NULL);
+
+ if (tree->cw_t != NULL || tree->cw_h != NULL) {
+ LOG("Treeview already attached.");
+ return NSERROR_UNKNOWN;
+ }
+ tree->cw_t = cw_t;
+ tree->cw_h = cw;
+
+ return NSERROR_OK;
+}
+
+
+/* Exported interface, documented in treeview.h */
+nserror treeview_cw_detach(treeview *tree)
+{
+ tree->cw_t = NULL;
+ tree->cw_h = NULL;
+
+ return NSERROR_OK;
+}
+
+
+/* Exported interface, documented in treeview.h */
nserror treeview_destroy(treeview *tree)
{
int f;
@@ -1469,7 +1564,7 @@ static nserror treeview_node_expand_internal(treeview *tree,
/* Inform front end of change in dimensions */
if (additional_height != 0)
- tree->cw_t->update_size(tree->cw_h, -1, tree->root->height);
+ treeview__cw_update_size(tree, -1, tree->root->height);
return NSERROR_OK;
}
@@ -1491,7 +1586,7 @@ nserror treeview_node_expand(treeview *tree, treeview_node *node)
r.y1 = tree->root->height;
/* Redraw */
- tree->cw_t->redraw_request(tree->cw_h, &r);
+ treeview__cw_redraw_request(tree, &r);
return NSERROR_OK;
}
@@ -1563,7 +1658,7 @@ static nserror treeview_node_contract_internal(treeview *tree,
node->flags |= TV_NFLAGS_SELECTED;
/* Inform front end of change in dimensions */
- tree->cw_t->update_size(tree->cw_h, -1, tree->root->height);
+ treeview__cw_update_size(tree, -1, tree->root->height);
return NSERROR_OK;
}
@@ -1587,7 +1682,7 @@ nserror treeview_node_contract(treeview *tree, treeview_node *node)
return err;
/* Redraw */
- tree->cw_t->redraw_request(tree->cw_h, &r);
+ treeview__cw_redraw_request(tree, &r);
return NSERROR_OK;
}
@@ -1630,10 +1725,10 @@ nserror treeview_contract(treeview *tree, bool all)
}
/* Inform front end of change in dimensions */
- tree->cw_t->update_size(tree->cw_h, -1, tree->root->height);
+ treeview__cw_update_size(tree, -1, tree->root->height);
/* Redraw */
- tree->cw_t->redraw_request(tree->cw_h, &r);
+ treeview__cw_redraw_request(tree, &r);
return NSERROR_OK;
}
@@ -1687,7 +1782,7 @@ nserror treeview_expand(treeview *tree, bool only_folders)
r.y1 = tree->root->height;
/* Redraw */
- tree->cw_t->redraw_request(tree->cw_h, &r);
+ treeview__cw_redraw_request(tree, &r);
return NSERROR_OK;
}
@@ -2474,7 +2569,7 @@ static nserror treeview_move_selection(treeview *tree, struct rect *rect)
/* Tell window, if height has changed */
if (height != tree->root->height)
- tree->cw_t->update_size(tree->cw_h, -1, tree->root->height);
+ treeview__cw_update_size(tree, -1, tree->root->height);
/* TODO: Deal with redraw area properly */
rect->x0 = 0;
@@ -2782,7 +2877,7 @@ bool treeview_keypress(treeview *tree, uint32_t key)
/* Inform front end of change in dimensions */
if (tree->root->height != h) {
r.y0 = 0;
- tree->cw_t->update_size(tree->cw_h, -1,
+ treeview__cw_update_size(tree, -1,
tree->root->height);
}
}
@@ -2806,7 +2901,7 @@ bool treeview_keypress(treeview *tree, uint32_t key)
}
if (redraw) {
- tree->cw_t->redraw_request(tree->cw_h, &r);
+ treeview__cw_redraw_request(tree, &r);
}
return true;
@@ -2963,7 +3058,7 @@ static void treeview_textarea_callback(void *data, struct textarea_msg *msg)
/* Textarea drag started */
tree->drag.type = TV_DRAG_TEXTAREA;
}
- tree->cw_t->drag_status(tree->cw_h, tree->drag.type);
+ treeview__cw_drag_status(tree, tree->drag.type);
break;
case TEXTAREA_MSG_REDRAW_REQUEST:
@@ -2974,7 +3069,7 @@ static void treeview_textarea_callback(void *data, struct textarea_msg *msg)
r->y1 += tree->edit.y;
/* Redraw the textarea */
- tree->cw_t->redraw_request(tree->cw_h, r);
+ treeview__cw_redraw_request(tree, r);
break;
default:
@@ -3044,7 +3139,7 @@ static bool treeview_edit_node_at_point(treeview *tree, treeview_node *n,
}
/* Get window width/height */
- tree->cw_t->get_window_dimensions(tree->cw_h, &width, &height);
+ treeview__cw_get_window_dimensions(tree, &width, &height);
/* Anow textarea width/height */
field_x = n->inset + tree_g.step_width + tree_g.icon_step - 3;
@@ -3147,7 +3242,7 @@ void treeview_edit_selection(treeview *tree)
rect.y0 = y;
rect.x1 = REDRAW_MAX;
rect.y1 = y + tree_g.line_height;
- tree->cw_t->redraw_request(tree->cw_h, &rect);
+ treeview__cw_redraw_request(tree, &rect);
}
@@ -3266,7 +3361,7 @@ static nserror treeview_node_mouse_action_cb(treeview_node *node, void *ctx,
ma->tree->drag.selected == false &&
ma->tree->drag.part == TV_NODE_PART_NONE) {
ma->tree->drag.type = TV_DRAG_SELECTION;
- ma->tree->cw_t->drag_status(ma->tree->cw_h,
+ treeview__cw_drag_status(ma->tree,
CORE_WINDOW_DRAG_SELECTION);
} else if (!(ma->tree->flags & TREEVIEW_NO_MOVES) &&
@@ -3274,13 +3369,13 @@ static nserror treeview_node_mouse_action_cb(treeview_node *node, void *ctx,
(ma->tree->drag.selected == true ||
ma->tree->drag.part == TV_NODE_PART_ON_NODE)) {
ma->tree->drag.type = TV_DRAG_MOVE;
- ma->tree->cw_t->drag_status(ma->tree->cw_h,
+ treeview__cw_drag_status(ma->tree,
CORE_WINDOW_DRAG_MOVE);
redraw |= treeview_propagate_selection(ma->tree, &r);
} else if (ma->mouse & BROWSER_MOUSE_DRAG_2) {
ma->tree->drag.type = TV_DRAG_SELECTION;
- ma->tree->cw_t->drag_status(ma->tree->cw_h,
+ treeview__cw_drag_status(ma->tree,
CORE_WINDOW_DRAG_SELECTION);
}
@@ -3407,7 +3502,7 @@ static nserror treeview_node_mouse_action_cb(treeview_node *node, void *ctx,
}
if (redraw) {
- ma->tree->cw_t->redraw_request(ma->tree->cw_h, &r);
+ treeview__cw_redraw_request(ma->tree, &r);
}
*end = true; /* Reached line with click; stop walking tree */
@@ -3456,8 +3551,7 @@ void treeview_mouse_action(treeview *tree,
tree->drag.type = TV_DRAG_NONE;
tree->drag.start_node = NULL;
- tree->cw_t->drag_status(tree->cw_h,
- CORE_WINDOW_DRAG_NONE);
+ treeview__cw_drag_status(tree, CORE_WINDOW_DRAG_NONE);
return;
case TV_DRAG_MOVE:
treeview_move_selection(tree, &r);
@@ -3467,9 +3561,8 @@ void treeview_mouse_action(treeview *tree,
tree->move.target = NULL;
tree->move.target_pos = TV_TARGET_NONE;
- tree->cw_t->drag_status(tree->cw_h,
- CORE_WINDOW_DRAG_NONE);
- tree->cw_t->redraw_request(tree->cw_h, &r);
+ treeview__cw_drag_status(tree, CORE_WINDOW_DRAG_NONE);
+ treeview__cw_redraw_request(tree, &r);
return;
default:
/* No drag to end */
@@ -3506,11 +3599,11 @@ void treeview_mouse_action(treeview *tree,
tree->drag.selected == false &&
tree->drag.part == TV_NODE_PART_NONE) {
tree->drag.type = TV_DRAG_SELECTION;
- tree->cw_t->drag_status(tree->cw_h,
+ treeview__cw_drag_status(tree,
CORE_WINDOW_DRAG_SELECTION);
} else if (mouse & BROWSER_MOUSE_DRAG_2) {
tree->drag.type = TV_DRAG_SELECTION;
- tree->cw_t->drag_status(tree->cw_h,
+ treeview__cw_drag_status(tree,
CORE_WINDOW_DRAG_SELECTION);
}
@@ -3544,7 +3637,7 @@ void treeview_mouse_action(treeview *tree,
}
if (redraw) {
- tree->cw_t->redraw_request(tree->cw_h, &r);
+ treeview__cw_redraw_request(tree, &r);
}
} else {
@@ -3569,7 +3662,7 @@ int treeview_get_height(treeview *tree)
assert(tree != NULL);
assert(tree->root != NULL);
- tree->cw_t->update_size(tree->cw_h, -1, tree->root->height);
+ treeview__cw_update_size(tree, -1, tree->root->height);
return tree->root->height;
}
@@ -3670,6 +3763,8 @@ static void treeview_init_resources(void)
for (i = 0; i < TREE_RES_LAST; i++) {
nsurl *url;
+ treeview_res[i].ready = false;
+ treeview_res[i].height = 0;
if (nsurl_create(treeview_res[i].url, &url) == NSERROR_OK) {
hlcache_handle_retrieve(url, 0, NULL, NULL,
treeview_res_cb,
diff --git a/desktop/treeview.h b/desktop/treeview.h
index abe0e56..518f045 100644
--- a/desktop/treeview.h
+++ b/desktop/treeview.h
@@ -150,6 +150,28 @@ nserror treeview_create(treeview **tree,
struct core_window *cw, treeview_flags flags);
/**
+ * Attach a treeview to a corewindow.
+ *
+ * Treeview must be detached.
+ *
+ * \param tree Treeview object
+ * \param cw_t Callback table for core_window containing the treeview
+ * \param cw The core_window in which the treeview is shown
+ * \return NSERROR_OK on success, appropriate error otherwise
+ */
+nserror treeview_cw_attach(treeview *tree,
+ const struct core_window_callback_table *cw_t,
+ struct core_window *cw);
+
+/**
+ * Detach a treeview from a corewindow
+ *
+ * \param tree Treeview object
+ * \return NSERROR_OK on success, appropriate error otherwise
+ */
+nserror treeview_cw_detach(treeview *tree);
+
+/**
* Destroy a treeview object
*
* \param tree Treeview object to destroy
diff --git a/frontends/amiga/Makefile b/frontends/amiga/Makefile
index a2c1b13..f57b4ef 100644
--- a/frontends/amiga/Makefile
+++ b/frontends/amiga/Makefile
@@ -36,8 +36,8 @@ MESSAGES_FILTER=ami
# ----------------------------------------------------------------------------
# sources purely for the Amiga build
-S_FRONTEND := gui.c tree.c history.c hotlist.c schedule.c file.c \
- misc.c bitmap.c font.c filetype.c utf8.c login.c \
+S_FRONTEND := gui.c history.c hotlist.c schedule.c file.c \
+ misc.c bitmap.c font.c filetype.c utf8.c login.c memory.c \
plotters.c object.c menu.c save_pdf.c arexx.c version.c \
cookies.c ctxmenu.c clipboard.c help.c font_scan.c \
launch.c search.c history_local.c download.c iff_dr2d.c \
@@ -45,7 +45,8 @@ S_FRONTEND := gui.c tree.c history.c hotlist.c schedule.c file.c \
datatypes.c dt_picture.c dt_anim.c dt_sound.c plugin_hack.c \
stringview/stringview.c stringview/urlhistory.c rtg.c \
agclass/amigaguide_class.c os3support.c font_diskfont.c \
- selectmenu.c hash/xxhash.c font_cache.c font_bullet.c nsoption.c
+ selectmenu.c hash/xxhash.c font_cache.c font_bullet.c \
+ nsoption.c corewindow.c gui_menu.c
# This is the final source build list
# Note this is deliberately *not* expanded here as common and image
@@ -75,9 +76,9 @@ AMIGA_INSTALL_TARGET_DIR := NetSurf_Amiga
netsurf.lha: $(EXETARGET)
$(VQ)echo Creating netsurf.lha
$(Q)rm -rf $(AMIGA_INSTALL_TARGET_DIR)
- $(Q)mkdir -p $(AMIGA_INSTALL_TARGET_DIR)/NetSurf
+ $(Q)$(MKDIR) -p $(AMIGA_INSTALL_TARGET_DIR)/NetSurf
$(Q)cp -p $(EXETARGET) $(AMIGA_INSTALL_TARGET_DIR)/NetSurf
- $(Q)mkdir $(AMIGA_INSTALL_TARGET_DIR)/NetSurf/Resources
+ $(Q)$(MKDIR) $(AMIGA_INSTALL_TARGET_DIR)/NetSurf/Resources
$(Q)cp -rp $(AMIGA_RESOURCES) $(AMIGA_INSTALL_TARGET_DIR)/NetSurf/Resources
$(Q)cp -rp $(AMIGA_DISTRIBUTION_FILES) $(AMIGA_INSTALL_TARGET_DIR)/NetSurf
$(Q)cat resources/SearchEngines $(AMIGA_PKG_DIR)/SearchEngines >$(AMIGA_INSTALL_TARGET_DIR)/NetSurf/Resources/SearchEngines
diff --git a/frontends/amiga/arexx.c b/frontends/amiga/arexx.c
index 062f00b..7bb2f58 100644
--- a/frontends/amiga/arexx.c
+++ b/frontends/amiga/arexx.c
@@ -40,11 +40,14 @@
#include "amiga/gui.h"
#include "amiga/download.h"
#include "amiga/hotlist.h"
-#include "amiga/tree.h"
#include "amiga/libs.h"
#include "amiga/misc.h"
#include "amiga/theme.h"
+#ifndef __amigaos4__
+#include "amiga/memory.h"
+#endif
+
extern const char * const verarexx;
extern const char * const wt_revid;
@@ -65,7 +68,8 @@ enum
RX_WINDOWS,
RX_ACTIVE,
RX_CLOSE,
- RX_HOTLIST
+ RX_HOTLIST,
+ RX_SLABSTATS
};
static Object *arexx_obj = NULL;
@@ -93,6 +97,7 @@ RXHOOKF(rx_windows);
RXHOOKF(rx_active);
RXHOOKF(rx_close);
RXHOOKF(rx_hotlist);
+RXHOOKF(rx_slabstats);
STATIC struct ARexxCmd Commands[] =
{
@@ -112,6 +117,7 @@ STATIC struct ARexxCmd Commands[] =
{"ACTIVE", RX_ACTIVE, rx_active, "T=TAB/S", 0, NULL, 0, 0, NULL },
{"CLOSE", RX_CLOSE, rx_close, "W=WINDOW/K/N,T=TAB/K/N", 0, NULL, 0, 0, NULL },
{"HOTLIST", RX_HOTLIST, rx_hotlist, "A=ACTION/A", 0, NULL, 0, 0, NULL },
+ {"SLABSTATS", RX_SLABSTATS, rx_slabstats, "FILE", 0, NULL, 0, 0, NULL },
{ NULL, 0, NULL, NULL, 0, NULL, 0, 0, NULL }
};
@@ -271,7 +277,7 @@ RXHOOKF(rx_open)
{
if(!gw) return;
- dln = ami_misc_allocvec_clear(sizeof(struct dlnode), 0);
+ dln = calloc(1, sizeof(struct dlnode));
dln->filename = strdup((char *)cmd->ac_ArgList[3]);
dln->node.ln_Name = strdup((char *)cmd->ac_ArgList[0]);
dln->node.ln_Type = NT_USER;
@@ -658,9 +664,23 @@ RXHOOKF(rx_hotlist)
cmd->ac_RC = 0;
if(strcasecmp((char *)cmd->ac_ArgList[0], "OPEN") == 0) {
- ami_tree_open(hotlist_window, AMI_TREE_HOTLIST);
+ ami_hotlist_present();
} else if(strcasecmp((char *)cmd->ac_ArgList[0], "CLOSE") == 0) {
- ami_tree_close(hotlist_window);
+ ami_hotlist_close();
+ }
+}
+
+RXHOOKF(rx_slabstats)
+{
+#ifndef __amigaos4__
+ BPTR fh = 0;
+
+ if(cmd->ac_ArgList[0] != NULL) {
+ fh = Open((char *)cmd->ac_ArgList[0], MODE_NEWFILE);
}
+ ami_memory_slab_dump(fh);
+
+ if(fh != 0) Close(fh);
+#endif
}
diff --git a/frontends/amiga/bitmap.c b/frontends/amiga/bitmap.c
index 8c691ed..5fc772b 100644
--- a/frontends/amiga/bitmap.c
+++ b/frontends/amiga/bitmap.c
@@ -40,6 +40,7 @@
#endif
#ifdef __amigaos4__
+#include <exec/extmem.h>
#include <sys/param.h>
#endif
#include "assert.h"
@@ -54,8 +55,10 @@
#include "amiga/gui.h"
#include "amiga/bitmap.h"
#include "amiga/plotters.h"
+#include "amiga/memory.h"
#include "amiga/misc.h"
#include "amiga/rtg.h"
+#include "amiga/schedule.h"
// disable use of "triangle mode" for scaling
#ifdef AMI_NS_TRIANGLE_SCALING
@@ -66,6 +69,8 @@ struct bitmap {
int width;
int height;
UBYTE *pixdata;
+ struct ExtMemIFace *iextmem;
+ uint32 size;
bool opaque;
int native;
struct BitMap *nativebm;
@@ -107,12 +112,30 @@ void *amiga_bitmap_create(int width, int height, unsigned int state)
{
struct bitmap *bitmap;
- if(pool_bitmap == NULL) pool_bitmap = ami_misc_itempool_create(sizeof(struct bitmap));
+ if(pool_bitmap == NULL) pool_bitmap = ami_memory_itempool_create(sizeof(struct bitmap));
- bitmap = ami_misc_itempool_alloc(pool_bitmap, sizeof(struct bitmap));
+ bitmap = ami_memory_itempool_alloc(pool_bitmap, sizeof(struct bitmap));
if(bitmap == NULL) return NULL;
- bitmap->pixdata = ami_misc_allocvec_clear(width*height*4, 0xff);
+ bitmap->size = width * height * 4;
+
+#ifdef __amigaos4__
+ if(nsoption_bool(use_extmem) == true) {
+ uint64 size64 = bitmap->size;
+ bitmap->iextmem = AllocSysObjectTags(ASOT_EXTMEM,
+ ASOEXTMEM_Size, &size64,
+ ASOEXTMEM_AllocationPolicy, EXTMEMPOLICY_IMMEDIATE,
+ TAG_END);
+
+ bitmap->pixdata = NULL;
+ UBYTE *pixdata = amiga_bitmap_get_buffer(bitmap);
+ memset(pixdata, 0xff, bitmap->size);
+ } else
+#endif
+ {
+ bitmap->pixdata = ami_memory_clear_alloc(bitmap->size, 0xff);
+ }
+
bitmap->width = width;
bitmap->height = height;
@@ -132,11 +155,36 @@ void *amiga_bitmap_create(int width, int height, unsigned int state)
return bitmap;
}
+static void amiga_bitmap_unmap_buffer(void *p)
+{
+#ifdef __amigaos4__
+ struct bitmap *bm = p;
+
+ if((nsoption_bool(use_extmem) == true) && (bm->pixdata != NULL)) {
+ LOG("Unmapping ExtMem object %p for bitmap %p", bm->iextmem, bm);
+ bm->iextmem->Unmap(bm->pixdata, bm->size);
+ bm->pixdata = NULL;
+ }
+#endif
+}
/* exported function documented in amiga/bitmap.h */
unsigned char *amiga_bitmap_get_buffer(void *bitmap)
{
struct bitmap *bm = bitmap;
+
+#ifdef __amigaos4__
+ if(nsoption_bool(use_extmem) == true) {
+ if(bm->pixdata == NULL) {
+ LOG("Mapping ExtMem object %p for bitmap %p", bm->iextmem, bm);
+ bm->pixdata = bm->iextmem->Map(NULL, bm->size, 0LL, 0);
+ }
+
+ /* unmap the buffer after one second */
+ ami_schedule(1000, amiga_bitmap_unmap_buffer, bm);
+ }
+#endif
+
return bm->pixdata;
}
@@ -168,8 +216,19 @@ void amiga_bitmap_destroy(void *bitmap)
}
if(bm->native_mask) FreeRaster(bm->native_mask, bm->width, bm->height);
- if(bm->drawhandle) ReleaseDrawHandle(bm->drawhandle);
- FreeVec(bm->pixdata);
+
+#ifdef __amigaos4__
+ if(nsoption_bool(use_extmem) == true) {
+ ami_schedule(-1, amiga_bitmap_unmap_buffer, bm);
+ amiga_bitmap_unmap_buffer(bm);
+ FreeSysObject(ASOT_EXTMEM, bm->iextmem);
+ bm->iextmem = NULL;
+ } else
+#endif
+ {
+ if(bm->drawhandle) ReleaseDrawHandle(bm->drawhandle);
+ ami_memory_clear_free(bm->pixdata);
+ }
if(bm->url) nsurl_unref(bm->url);
if(bm->title) free(bm->title);
@@ -181,7 +240,7 @@ void amiga_bitmap_destroy(void *bitmap)
bm->url = NULL;
bm->title = NULL;
- ami_misc_itempool_free(pool_bitmap, bm, sizeof(struct bitmap));
+ ami_memory_itempool_free(pool_bitmap, bm, sizeof(struct bitmap));
bm = NULL;
}
}
@@ -217,9 +276,12 @@ void amiga_bitmap_modified(void *bitmap)
{
struct bitmap *bm = bitmap;
- if((bm->nativebm)) // && (bm->native == AMI_NSBM_TRUECOLOUR))
- ami_rtg_freebitmap(bm->nativebm);
-
+#ifdef __amigaos4__
+ /* unmap the buffer after 0.5s - we might need it imminently */
+ ami_schedule(500, amiga_bitmap_unmap_buffer, bm);
+#endif
+
+ if(bm->nativebm) ami_rtg_freebitmap(bm->nativebm);
if(bm->drawhandle) ReleaseDrawHandle(bm->drawhandle);
if(bm->native_mask) FreeRaster(bm->native_mask, bm->width, bm->height);
bm->nativebm = NULL;
@@ -654,13 +716,15 @@ struct BitMap *ami_bitmap_get_native(struct bitmap *bitmap,
void ami_bitmap_fini(void)
{
- if(pool_bitmap) ami_misc_itempool_delete(pool_bitmap);
+ if(pool_bitmap) ami_memory_itempool_delete(pool_bitmap);
pool_bitmap = NULL;
}
static nserror bitmap_render(struct bitmap *bitmap, struct hlcache_handle *content)
{
#ifdef __amigaos4__
+ LOG("Entering bitmap_render");
+
struct redraw_context ctx = {
.interactive = false,
.background_images = true,
@@ -729,14 +793,15 @@ void ami_bitmap_set_title(struct bitmap *bm, const char *title)
bm->title = strdup(title);
}
-ULONG *ami_bitmap_get_icondata(struct bitmap *bm)
+void ami_bitmap_set_icondata(struct bitmap *bm, ULONG *icondata)
{
- return bm->icondata;
+ bm->icondata = icondata;
}
-void ami_bitmap_set_icondata(struct bitmap *bm, ULONG *icondata)
+void ami_bitmap_free_icondata(struct bitmap *bm)
{
- bm->icondata = icondata;
+ if(bm->icondata) free(bm->icondata);
+ bm->icondata = NULL;
}
bool ami_bitmap_is_nativebm(struct bitmap *bm, struct BitMap *nbm)
diff --git a/frontends/amiga/bitmap.h b/frontends/amiga/bitmap.h
index 771ded4..a32d740 100755
--- a/frontends/amiga/bitmap.h
+++ b/frontends/amiga/bitmap.h
@@ -63,24 +63,24 @@ void ami_bitmap_set_url(struct bitmap *bm, struct nsurl *url);
void ami_bitmap_set_title(struct bitmap *bm, const char *title);
/**
- * Get an icondata pointer
+ * Set an icondata pointer
*
* \param bm a bitmap, as returned by bitmap_create()
- * \return pointer to the icondata area
+ * \param icondata a pointer to memory
*
* This function probably shouldn't be here!
*/
-ULONG *ami_bitmap_get_icondata(struct bitmap *bm);
+void ami_bitmap_set_icondata(struct bitmap *bm, ULONG *icondata);
/**
- * Set an icondata pointer
+ * Free an icondata pointer
*
* \param bm a bitmap, as returned by bitmap_create()
* \param icondata a pointer to memory
*
* This function probably shouldn't be here!
*/
-void ami_bitmap_set_icondata(struct bitmap *bm, ULONG *icondata);
+void ami_bitmap_free_icondata(struct bitmap *bm);
/**
* Test if a BitMap is owned by a bitmap.
diff --git a/frontends/amiga/clipboard.c b/frontends/amiga/clipboard.c
index 2dce068..27b8015 100644
--- a/frontends/amiga/clipboard.c
+++ b/frontends/amiga/clipboard.c
@@ -44,8 +44,7 @@
#include "amiga/gui.h"
#include "amiga/iff_cset.h"
#include "amiga/iff_dr2d.h"
-#include "amiga/menu.h"
-#include "amiga/misc.h"
+#include "amiga/gui_menu.h"
#include "amiga/utf8.h"
#define ID_UTF8 MAKE_ID('U','T','F','8')
@@ -90,11 +89,11 @@ void gui_start_selection(struct gui_window *g)
if(!g->shared->win) return;
if(nsoption_bool(kiosk_mode) == true) return;
- OnMenu(g->shared->win, AMI_MENU_CLEAR);
- OnMenu(g->shared->win, AMI_MENU_COPY);
+ ami_gui_menu_set_disabled(g->shared->win, g->shared->imenu, M_COPY, false);
+ ami_gui_menu_set_disabled(g->shared->win, g->shared->imenu, M_CLEAR, false);
if (browser_window_get_editor_flags(g->bw) & BW_EDITOR_CAN_CUT)
- OnMenu(g->shared->win, AMI_MENU_CUT);
+ ami_gui_menu_set_disabled(g->shared->win, g->shared->imenu, M_CUT, false);
}
static char *ami_clipboard_cat_collection(struct CollectionItem *ci, LONG codeset, size_t *text_length)
@@ -114,10 +113,10 @@ static char *ami_clipboard_cat_collection(struct CollectionItem *ci, LONG codese
case 0:
if(ci_new) {
- ci_next->ci_Next = ami_misc_allocvec_clear(sizeof(struct CollectionItem), 0);
+ ci_next->ci_Next = calloc(1, sizeof(struct CollectionItem));
ci_next = ci_next->ci_Next;
} else {
- ci_new = ami_misc_allocvec_clear(sizeof(struct CollectionItem), 0);
+ ci_new = calloc(1, sizeof(struct CollectionItem));
ci_next = ci_new;
}
@@ -128,10 +127,10 @@ static char *ami_clipboard_cat_collection(struct CollectionItem *ci, LONG codese
default:
if(ci_new) {
- ci_next->ci_Next = ami_misc_allocvec_clear(sizeof(struct CollectionItem), 0);
+ ci_next->ci_Next = calloc(1, sizeof(struct CollectionItem));
ci_next = ci_next->ci_Next;
} else {
- ci_new = ami_misc_allocvec_clear(sizeof(struct CollectionItem), 0);
+ ci_new = calloc(1, sizeof(struct CollectionItem));
ci_next = ci_new;
}
@@ -166,7 +165,7 @@ static char *ami_clipboard_cat_collection(struct CollectionItem *ci, LONG codese
if(ci_new) {
free(ci_curr->ci_Data);
- FreeVec(ci_curr);
+ free(ci_curr);
}
} while ((ci_curr = ci_next));
diff --git a/frontends/amiga/cookies.c b/frontends/amiga/cookies.c
old mode 100755
new mode 100644
index 15f6dce..877805c
--- a/frontends/amiga/cookies.c
+++ b/frontends/amiga/cookies.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2008, 2009 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
+ * Copyright 2017 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -16,26 +16,383 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <proto/exec.h>
+/**
+ * \file
+ * Implementation of Amiga cookie viewer using core windows.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdbool.h>
+
+#include <proto/intuition.h>
+
+#include <classes/window.h>
+#include <gadgets/layout.h>
+#include <gadgets/space.h>
+
+#include <reaction/reaction_macros.h>
#include "desktop/cookie_manager.h"
-#include "netsurf/mouse.h"
-#include "netsurf/window.h"
+#include "netsurf/keypress.h"
+#include "netsurf/plotters.h"
+#include "utils/log.h"
+#include "utils/messages.h"
+#include "utils/nsoption.h"
#include "amiga/cookies.h"
-#include "amiga/tree.h"
+#include "amiga/corewindow.h"
+#include "amiga/libs.h"
+#include "amiga/menu.h"
+#include "amiga/utf8.h"
+
+enum {
+ /* Project menu */
+ AMI_COOKIE_M_PROJECT = 0,
+ AMI_COOKIE_M_EXPAND,
+ AMI_COOKIE_M_EXPAND_ALL,
+ AMI_COOKIE_M_EXPAND_DOMAINS,
+ AMI_COOKIE_M_EXPAND_COOKIES,
+ AMI_COOKIE_M_COLLAPSE,
+ AMI_COOKIE_M_COLLAPSE_ALL,
+ AMI_COOKIE_M_COLLAPSE_DOMAINS,
+ AMI_COOKIE_M_COLLAPSE_COOKIES,
+ AMI_COOKIE_M_BAR_P1,
+ AMI_COOKIE_M_SNAPSHOT,
+ AMI_COOKIE_M_BAR_P2,
+ AMI_COOKIE_M_CLOSE,
+ /* Edit menu */
+ AMI_COOKIE_M_EDIT,
+ AMI_COOKIE_M_SELECTALL,
+ AMI_COOKIE_M_CLEAR,
+ AMI_COOKIE_M_BAR_E1,
+ AMI_COOKIE_M_DELETE,
+ AMI_COOKIE_M_LAST
+};
+
+/**
+ * Amiga cookie viewer window context
+ */
+struct ami_cookie_window {
+ /** Amiga core window context */
+ struct ami_corewindow core;
+
+ struct ami_menu_data *menu_data[AMI_COOKIE_M_LAST + 1];
+ struct Menu *imenu; /* Intuition menu */
+};
+
+static struct ami_cookie_window *cookie_window = NULL;
+
+
+static void
+ami_cookies_menu_free(struct ami_cookie_window *cookie_win)
+{
+ SetAttrs(cookie_win->core.objects[GID_CW_WIN],
+ WINDOW_MenuStrip, NULL,
+ TAG_DONE);
+
+ ami_menu_free_menu(cookie_win->menu_data, AMI_COOKIE_M_LAST, cookie_win->imenu);
+}
+
+/**
+ * destroy a previously created cookie view
+ */
+static void
+ami_cookies_destroy(struct ami_corewindow *ami_cw)
+{
+ nserror res;
+
+ if(cookie_window == NULL)
+ return;
+
+ res = cookie_manager_fini();
+ if (res == NSERROR_OK) {
+ ami_cookies_menu_free(cookie_window);
+ res = ami_corewindow_fini(&cookie_window->core); /* closes the window for us, frees cookie_win */
+ cookie_window = NULL;
+ }
+}
+
+
+/**
+ * callback for mouse action for cookie viewer on core window
+ *
+ * \param ami_cw The Amiga core window structure.
+ * \param mouse_state netsurf mouse state on event
+ * \param x location of event
+ * \param y location of event
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+ami_cookies_mouse(struct ami_corewindow *ami_cw,
+ browser_mouse_state mouse_state,
+ int x, int y)
+{
+ cookie_manager_mouse_action(mouse_state, x, y);
+
+ return NSERROR_OK;
+}
+
+/**
+ * callback for keypress for cookies viewer on core window
+ *
+ * \param example_cw The Amiga core window structure.
+ * \param nskey The netsurf key code
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+ami_cookies_key(struct ami_corewindow *ami_cw, uint32_t nskey)
+{
+ if (cookie_manager_keypress(nskey)) {
+ return NSERROR_OK;
+ }
+ return NSERROR_NOT_IMPLEMENTED;
+}
+
+/**
+ * callback on draw event for cookies viewer on core window
+ *
+ * \param ami_cw The Amiga core window structure.
+ * \param r The rectangle of the window that needs updating.
+ * \param ctx The drawing context
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+ami_cookies_draw(struct ami_corewindow *ami_cw, int x, int y, struct rect *r, struct redraw_context *ctx)
+{
+ cookie_manager_redraw(x, y, r, ctx);
+
+ return NSERROR_OK;
+}
+
+/**
+ * menu stuff
+ */
+
+ /* menu hook functions */
+
+HOOKF(void, ami_cookies_menu_item_project_expand_all, APTR, window, struct IntuiMessage *)
+{
+ cookie_manager_expand(false);
+}
+
+HOOKF(void, ami_cookies_menu_item_project_expand_domains, APTR, window, struct IntuiMessage *)
+{
+ cookie_manager_expand(true);
+}
+
+HOOKF(void, ami_cookies_menu_item_project_expand_cookies, APTR, window, struct IntuiMessage *)
+{
+ cookie_manager_expand(false);
+}
+
+HOOKF(void, ami_cookies_menu_item_project_collapse_all, APTR, window, struct IntuiMessage *)
+{
+ cookie_manager_contract(true);
+}
+
+HOOKF(void, ami_cookies_menu_item_project_collapse_domains, APTR, window, struct IntuiMessage *)
+{
+ cookie_manager_contract(true);
+}
+
+HOOKF(void, ami_cookies_menu_item_project_collapse_cookies, APTR, window, struct IntuiMessage *)
+{
+ cookie_manager_contract(false);
+}
+
+HOOKF(void, ami_cookies_menu_item_project_snapshot, APTR, window, struct IntuiMessage *)
+{
+ struct ami_corewindow *ami_cw;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&ami_cw);
+
+ nsoption_set_int(cookies_window_ypos, ami_cw->win->TopEdge);
+ nsoption_set_int(cookies_window_xpos, ami_cw->win->LeftEdge);
+ nsoption_set_int(cookies_window_xsize, ami_cw->win->Width);
+ nsoption_set_int(cookies_window_ysize, ami_cw->win->Height);
+}
+
+HOOKF(void, ami_cookies_menu_item_project_close, APTR, window, struct IntuiMessage *)
+{
+ struct ami_corewindow *ami_cw;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&ami_cw);
+
+ ami_cw->close_window = true;
+}
+
+HOOKF(void, ami_cookies_menu_item_edit_select_all, APTR, window, struct IntuiMessage *)
+{
+ cookie_manager_keypress(NS_KEY_SELECT_ALL);
+}
+
+HOOKF(void, ami_cookies_menu_item_edit_clear, APTR, window, struct IntuiMessage *)
+{
+ cookie_manager_keypress(NS_KEY_CLEAR_SELECTION);
+}
+
+HOOKF(void, ami_cookies_menu_item_edit_delete, APTR, window, struct IntuiMessage *)
+{
+ cookie_manager_keypress(NS_KEY_DELETE_LEFT);
+}
-struct treeview_window *cookies_window;
-void ami_cookies_initialise(void)
+/* menu setup */
+
+static void ami_cookies_menulabs(struct ami_menu_data **md)
+{
+ ami_menu_alloc_item(md, AMI_COOKIE_M_PROJECT, NM_TITLE, "Tree", NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, AMI_COOKIE_M_EXPAND, NM_ITEM, "Expand", NULL, "TBImages:list_folderunfold", NULL, NULL, 0);
+ ami_menu_alloc_item(md, AMI_COOKIE_M_EXPAND_ALL, NM_SUB, "All", "+", NULL,
+ ami_cookies_menu_item_project_expand_all, NULL, 0);
+ ami_menu_alloc_item(md, AMI_COOKIE_M_EXPAND_DOMAINS, NM_SUB, "Domains", NULL, NULL,
+ ami_cookies_menu_item_project_expand_domains, NULL, 0);
+ ami_menu_alloc_item(md, AMI_COOKIE_M_EXPAND_COOKIES, NM_SUB, "Cookies", NULL, NULL,
+ ami_cookies_menu_item_project_expand_cookies, NULL, 0);
+ ami_menu_alloc_item(md, AMI_COOKIE_M_COLLAPSE, NM_ITEM, "Collapse", NULL, "TBImages:list_folderfold", NULL, NULL, 0);
+ ami_menu_alloc_item(md, AMI_COOKIE_M_COLLAPSE_ALL, NM_SUB, "All", "-", NULL,
+ ami_cookies_menu_item_project_collapse_all, NULL, 0);
+ ami_menu_alloc_item(md, AMI_COOKIE_M_COLLAPSE_DOMAINS, NM_SUB, "Domains", NULL, NULL,
+ ami_cookies_menu_item_project_collapse_domains, NULL, 0);
+ ami_menu_alloc_item(md, AMI_COOKIE_M_COLLAPSE_COOKIES, NM_SUB, "Cookies", NULL, NULL,
+ ami_cookies_menu_item_project_collapse_cookies, NULL, 0);
+ ami_menu_alloc_item(md, AMI_COOKIE_M_BAR_P1, NM_ITEM, NM_BARLABEL, NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, AMI_COOKIE_M_SNAPSHOT, NM_ITEM, "SnapshotWindow", NULL, "TBImages:list_hold",
+ ami_cookies_menu_item_project_snapshot, NULL, 0);
+ ami_menu_alloc_item(md, AMI_COOKIE_M_BAR_P2, NM_ITEM, NM_BARLABEL, NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, AMI_COOKIE_M_CLOSE, NM_ITEM, "CloseWindow", "K", "TBImages:list_cancel",
+ ami_cookies_menu_item_project_close, NULL, 0);
+
+ ami_menu_alloc_item(md, AMI_COOKIE_M_EDIT, NM_TITLE, "Edit", NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, AMI_COOKIE_M_SELECTALL, NM_ITEM, "SelectAllNS", "A", NSA_SPACE,
+ ami_cookies_menu_item_edit_select_all, NULL, 0);
+ ami_menu_alloc_item(md, AMI_COOKIE_M_CLEAR, NM_ITEM, "ClearNS", NULL, NSA_SPACE,
+ ami_cookies_menu_item_edit_clear, NULL, 0);
+ ami_menu_alloc_item(md, AMI_COOKIE_M_BAR_E1, NM_ITEM, NM_BARLABEL, NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, AMI_COOKIE_M_DELETE, NM_ITEM, "TreeDelete", "Del", "TBImages:list_delete",
+ ami_cookies_menu_item_edit_delete, NULL, 0);
+
+ ami_menu_alloc_item(md, AMI_COOKIE_M_LAST, NM_END, NULL, NULL, NULL, NULL, NULL, 0);
+}
+
+static struct Menu *
+ami_cookies_menu_create(struct ami_cookie_window *cookie_win)
{
- cookies_window = ami_tree_create(TREE_COOKIES, NULL);
+ ami_cookies_menulabs(cookie_win->menu_data);
+ cookie_win->imenu = ami_menu_layout(cookie_win->menu_data, AMI_COOKIE_M_LAST);
+ if(cookie_win->imenu == NULL) return NULL;
+
+ return cookie_win->imenu;
+}
+
+
+static nserror
+ami_cookies_create_window(struct ami_cookie_window *cookie_win)
+{
+ struct ami_corewindow *ami_cw = (struct ami_corewindow *)&cookie_win->core;
+ ULONG refresh_mode = WA_SmartRefresh;
+
+ if(nsoption_bool(window_simple_refresh) == true) {
+ refresh_mode = WA_SimpleRefresh;
+ }
- if(!cookies_window) return;
+ ami_cw->objects[GID_CW_WIN] = WindowObj,
+ WA_ScreenTitle, ami_gui_get_screen_title(),
+ WA_Title, ami_cw->wintitle,
+ WA_Activate, TRUE,
+ WA_DepthGadget, TRUE,
+ WA_DragBar, TRUE,
+ WA_CloseGadget, TRUE,
+ WA_SizeGadget, TRUE,
+ WA_SizeBRight, TRUE,
+ WA_Top, nsoption_int(cookies_window_ypos),
+ WA_Left, nsoption_int(cookies_window_xpos),
+ WA_Width, nsoption_int(cookies_window_xsize),
+ WA_Height, nsoption_int(cookies_window_ysize),
+ WA_PubScreen, scrn,
+ WA_ReportMouse, TRUE,
+ refresh_mode, TRUE,
+ WA_IDCMP, IDCMP_MOUSEMOVE | IDCMP_MOUSEBUTTONS | IDCMP_NEWSIZE |
+ IDCMP_RAWKEY | IDCMP_GADGETUP | IDCMP_IDCMPUPDATE |
+ IDCMP_EXTENDEDMOUSE | IDCMP_SIZEVERIFY | IDCMP_REFRESHWINDOW,
+ WINDOW_IDCMPHook, &ami_cw->idcmp_hook,
+ WINDOW_IDCMPHookBits, IDCMP_IDCMPUPDATE | IDCMP_EXTENDEDMOUSE |
+ IDCMP_SIZEVERIFY | IDCMP_REFRESHWINDOW,
+ WINDOW_SharedPort, sport,
+ WINDOW_HorizProp, 1,
+ WINDOW_VertProp, 1,
+ WINDOW_UserData, cookie_win,
+ WINDOW_MenuStrip, ami_cookies_menu_create(cookie_win),
+ WINDOW_MenuUserData, WGUD_HOOK,
+ WINDOW_IconifyGadget, FALSE,
+ WINDOW_Position, WPOS_CENTERSCREEN,
+ WINDOW_ParentGroup, ami_cw->objects[GID_CW_MAIN] = LayoutVObj,
+ LAYOUT_AddChild, ami_cw->objects[GID_CW_DRAW] = SpaceObj,
+ GA_ID, GID_CW_DRAW,
+ SPACE_Transparent, TRUE,
+ SPACE_BevelStyle, BVS_DISPLAY,
+ GA_RelVerify, TRUE,
+ SpaceEnd,
+ EndGroup,
+ EndWindow;
+
+ if(ami_cw->objects[GID_CW_WIN] == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ return NSERROR_OK;
}
-void ami_cookies_free()
+/* exported interface documented in amiga/cookies.h */
+nserror ami_cookies_present(void)
{
- ami_tree_destroy(cookies_window);
- cookies_window = NULL;
+ struct ami_cookie_window *ncwin;
+ nserror res;
+
+ if(cookie_window != NULL) {
+ //windowtofront()
+ return NSERROR_OK;
+ }
+
+ ncwin = calloc(1, sizeof(struct ami_cookie_window));
+ if (ncwin == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ ncwin->core.wintitle = ami_utf8_easy((char *)messages_get("Cookies"));
+
+ res = ami_cookies_create_window(ncwin);
+ if (res != NSERROR_OK) {
+ LOG("SSL UI builder init failed");
+ ami_utf8_free(ncwin->core.wintitle);
+ free(ncwin);
+ return res;
+ }
+
+ /* initialise Amiga core window */
+ ncwin->core.draw = ami_cookies_draw;
+ ncwin->core.key = ami_cookies_key;
+ ncwin->core.mouse = ami_cookies_mouse;
+ ncwin->core.close = ami_cookies_destroy;
+ ncwin->core.event = NULL;
+
+ res = ami_corewindow_init(&ncwin->core);
+ if (res != NSERROR_OK) {
+ ami_utf8_free(ncwin->core.wintitle);
+ DisposeObject(ncwin->core.objects[GID_CW_WIN]);
+ free(ncwin);
+ return res;
+ }
+
+ res = cookie_manager_init(ncwin->core.cb_table, (struct core_window *)ncwin);
+ if (res != NSERROR_OK) {
+ ami_utf8_free(ncwin->core.wintitle);
+ DisposeObject(ncwin->core.objects[GID_CW_WIN]);
+ free(ncwin);
+ return res;
+ }
+
+ cookie_window = ncwin;
+
+ return NSERROR_OK;
}
+
diff --git a/frontends/amiga/cookies.h b/frontends/amiga/cookies.h
old mode 100755
new mode 100644
index 85e553c..6858e4c
--- a/frontends/amiga/cookies.h
+++ b/frontends/amiga/cookies.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008, 2009 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
+ * Copyright 2017 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -18,11 +18,8 @@
#ifndef AMIGA_COOKIES_H
#define AMIGA_COOKIES_H
-#include "desktop/tree.h"
-#include "amiga/tree.h"
-void ami_cookies_initialise(void);
-void ami_cookies_free(void);
-
-extern struct treeview_window *cookies_window;
+/** Open the cookie viewer */
+nserror ami_cookies_present(void);
#endif
+
diff --git a/frontends/amiga/corewindow.c b/frontends/amiga/corewindow.c
new file mode 100644
index 0000000..0ed16d1
--- /dev/null
+++ b/frontends/amiga/corewindow.c
@@ -0,0 +1,1002 @@
+/*
+ * Copyright 2017 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ * Amiga core window interface.
+ *
+ * Provides interface for core renderers to the Amiga Intuition drawable area.
+ *
+ * This module is an object that must be encapsulated. Client users
+ * should embed a struct ami_corewindow at the beginning of their
+ * context for this display surface, fill in relevant data and then
+ * call ami_corewindow_init()
+ *
+ * The Amiga core window structure requires the callback for draw, key and
+ * mouse operations.
+ */
+
+#include "amiga/os3support.h"
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "utils/log.h"
+#include "utils/utils.h"
+#include "utils/messages.h"
+#include "utils/utf8.h"
+#include "netsurf/keypress.h"
+#include "netsurf/mouse.h"
+#include "netsurf/plot_style.h"
+
+#include <proto/exec.h>
+#include <proto/intuition.h>
+#include <proto/layout.h>
+#include <proto/utility.h>
+
+#include <classes/window.h>
+#include <gadgets/layout.h>
+#include <gadgets/scroller.h>
+#include <gadgets/space.h>
+#include <intuition/icclass.h>
+#include <reaction/reaction_macros.h>
+
+#include "amiga/corewindow.h"
+#include "amiga/drag.h"
+#include "amiga/memory.h"
+#include "amiga/misc.h"
+#include "amiga/object.h"
+#include "amiga/schedule.h"
+#include "amiga/utf8.h"
+
+static void
+ami_cw_scroller_top(struct ami_corewindow *ami_cw, ULONG *restrict x, ULONG *restrict y)
+{
+ ULONG xs = 0;
+ ULONG ys = 0;
+
+ if(ami_cw->scroll_x_visible == true) {
+ GetAttr(SCROLLER_Top, ami_cw->objects[GID_CW_HSCROLL], (ULONG *)&xs);
+ }
+
+ if(ami_cw->scroll_y_visible == true) {
+ GetAttr(SCROLLER_Top, ami_cw->objects[GID_CW_VSCROLL], (ULONG *)&ys);
+ }
+
+ *x = xs;
+ *y = ys;
+}
+
+static void
+ami_cw_window_size(struct ami_corewindow *ami_cw, int *width, int *height)
+{
+ struct IBox *bbox;
+
+ if(ami_gui_get_space_box((Object *)ami_cw->objects[GID_CW_DRAW], &bbox) != NSERROR_OK) {
+ amiga_warn_user("NoMemory", "");
+ return;
+ }
+
+ *width = bbox->Width;
+ *height = bbox->Height;
+
+ ami_gui_free_space_box(bbox);
+}
+
+
+/**
+ * Convert co-ordinates relative to space.gadget
+ * into document co-ordinates
+ *
+ * @param ami_cw core window
+ * @param x co-ordinate, will be updated to new x co-ordinate
+ * @param y co-ordinate, will be updated to new y co-ordinate
+ */
+static void
+ami_cw_coord_amiga_to_ns(struct ami_corewindow *ami_cw, int *restrict x, int *restrict y)
+{
+ ULONG xs = 0;
+ ULONG ys = 0;
+
+ ami_cw_scroller_top(ami_cw, &xs, &ys);
+
+ *x = *x + xs;
+ *y = *y + ys;
+}
+
+/**
+ * check if mouse has moved since position was stored
+ * @param ami_cw corewindow
+ * @param x current x position
+ * @param y current y position
+ * @param click true to check since last click, false since last drag (press)
+ * @return true if it has, false otherwise
+ */
+static bool
+ami_cw_mouse_moved(struct ami_corewindow *ami_cw, int x, int y, bool click)
+{
+ int mx, my;
+
+ if(click == true) {
+ mx = ami_cw->mouse_x_click;
+ my = ami_cw->mouse_y_click;
+ } else {
+ mx = ami_cw->drag_x_start;
+ my = ami_cw->drag_y_start;
+ }
+
+ if(abs(x - mx) > 5) return true;
+ if(abs(y - my) > 5) return true;
+ return false;
+}
+
+/* get current mouse position in the draw area, adjusted for scroll.
+ * @return true if the mouse was in the draw area and co-ordinates updated
+ */
+static bool
+ami_cw_mouse_pos(struct ami_corewindow *ami_cw, int *restrict x, int *restrict y)
+{
+ int16 xm, ym;
+ ULONG xs, ys;
+ struct IBox *bbox;
+
+ xm = ami_cw->win->MouseX;
+ ym = ami_cw->win->MouseY;
+
+ if(ami_gui_get_space_box((Object *)ami_cw->objects[GID_CW_DRAW], &bbox) != NSERROR_OK) {
+ amiga_warn_user("NoMemory", "");
+ return false;
+ }
+
+ xm -= bbox->Left;
+ ym -= bbox->Top;
+
+ if((xm < 0) || (ym < 0) || (xm > bbox->Width) || (ym > bbox->Height))
+ return false;
+
+ ami_gui_free_space_box(bbox);
+ ami_cw_scroller_top(ami_cw, &xs, &ys);
+
+ xm += xs;
+ ym += ys;
+ *x = xm;
+ *y = ym;
+
+ return true;
+}
+
+/* handle keypress */
+static void
+ami_cw_key(struct ami_corewindow *ami_cw, int nskey)
+{
+ ami_cw->key(ami_cw, nskey);
+
+ switch(nskey) {
+ case NS_KEY_COPY_SELECTION:
+ /* if we've copied a selection we need to clear it - style guide rules */
+ ami_cw->key(ami_cw, NS_KEY_CLEAR_SELECTION);
+ break;
+
+ /* we may need to deal with scroll-related keys here */
+ }
+}
+
+
+/**
+ * Redraw functions
+ *
+ * This is slightly over-engineered as it was taken from the main browser/old tree redraws
+ * and supports deferred drawing of rectangles and tiling
+ */
+
+/**
+ * Redraw an area of a core window
+ *
+ * \param g a struct ami_corewindow
+ * \param r rect (in document co-ordinates)
+ */
+
+static void
+ami_cw_redraw_rect(struct ami_corewindow *ami_cw, struct rect *r)
+{
+ struct IBox *bbox;
+ ULONG pos_x, pos_y;
+ struct rect draw_rect;
+ int tile_size_x = ami_cw->gg.width;
+ int tile_size_y = ami_cw->gg.height;
+ int tile_x, tile_y, tile_w, tile_h;
+ int x = r->x0;
+ int y = r->y0;
+ int width = r->x1 - r->x0;
+ int height = r->y1 - r->y0;
+
+ struct redraw_context ctx = {
+ .interactive = true,
+ .background_images = true,
+ .plot = &amiplot
+ };
+
+ if(ami_gui_get_space_box((Object *)ami_cw->objects[GID_CW_DRAW], &bbox) != NSERROR_OK) {
+ amiga_warn_user("NoMemory", "");
+ return;
+ }
+
+ ami_cw_scroller_top(ami_cw, &pos_x, &pos_y);
+
+ glob = &ami_cw->gg;
+
+ if(x - pos_x + width > bbox->Width) width = bbox->Width - (x - pos_x);
+ if(y - pos_y + height > bbox->Height) height = bbox->Height - (y - pos_y);
+
+ if(x < pos_x) {
+ width -= pos_x - x;
+ x = pos_x;
+ }
+
+ if(y < pos_y) {
+ height -= pos_y - y;
+ y = pos_y;
+ }
+
+ for(tile_y = y; tile_y < (y + height); tile_y += tile_size_y) {
+ tile_h = tile_size_y;
+ if(((y + height) - tile_y) < tile_size_y)
+ tile_h = (y + height) - tile_y;
+
+ for(tile_x = x; tile_x < (x + width); tile_x += tile_size_x) {
+ tile_w = tile_size_x;
+ if(((x + width) - tile_x) < tile_size_x)
+ tile_w = (x + width) - tile_x;
+
+ draw_rect.x0 = tile_x; // was -
+ draw_rect.y0 = tile_y; // was -
+ draw_rect.x1 = tile_x + tile_w;
+ draw_rect.y1 = tile_y + tile_h;
+
+ ami_cw->draw(ami_cw, -tile_x, -tile_y, &draw_rect, &ctx);
+
+#ifdef __amigaos4__
+ BltBitMapTags(BLITA_SrcType, BLITT_BITMAP,
+ BLITA_Source, ami_cw->gg.bm,
+ BLITA_SrcX, 0,
+ BLITA_SrcY, 0,
+ BLITA_DestType, BLITT_RASTPORT,
+ BLITA_Dest, ami_cw->win->RPort,
+ BLITA_DestX, bbox->Left + tile_x - pos_x,
+ BLITA_DestY, bbox->Top + tile_y - pos_y,
+ BLITA_Width, tile_w,
+ BLITA_Height, tile_h,
+ TAG_DONE);
+#else
+ BltBitMapRastPort(ami_cw->gg.bm, 0, 0,
+ ami_cw->win->RPort, bbox->Left + tile_x - pos_x, bbox->Top + tile_y - pos_y,
+ tile_w, tile_h, 0xC0);
+#endif
+ }
+ }
+
+ ami_gui_free_space_box(bbox);
+ ami_clearclipreg(glob);
+ ami_gui_set_default_gg();
+}
+
+
+/**
+ * Draw the deferred rectangles
+ *
+ * @param draw set to false to just delete the queue
+ */
+static void ami_cw_redraw_queue(struct ami_corewindow *ami_cw, bool draw)
+{
+ struct nsObject *node;
+ struct nsObject *nnode;
+ struct rect *rect;
+
+ if(IsMinListEmpty(ami_cw->deferred_rects)) return;
+
+ if(draw == false) {
+ LOG("Ignoring deferred box redraw queue");
+ } // else should probably show busy pointer
+
+ node = (struct nsObject *)GetHead((struct List *)ami_cw->deferred_rects);
+
+ do {
+ if(draw == true) {
+ rect = (struct rect *)node->objstruct;
+ ami_cw_redraw_rect(ami_cw, rect);
+ }
+ nnode = (struct nsObject *)GetSucc((struct Node *)node);
+ ami_memory_itempool_free(ami_cw->deferred_rects_pool, node->objstruct, sizeof(struct rect));
+ DelObjectNoFree(node);
+ } while((node = nnode));
+}
+
+static void
+ami_cw_redraw_cb(void *p)
+{
+ struct ami_corewindow *ami_cw = (struct ami_corewindow *)p;
+
+ ami_cw_redraw_queue(ami_cw, true);
+}
+
+/**
+ * Queue a redraw of a rectangle
+ *
+ * @param ami_cw the core window to redraw
+ * @param r the rectangle (in doc coords) to redraw, or NULL for full window
+ */
+
+static void
+ami_cw_redraw(struct ami_corewindow *ami_cw, const struct rect *restrict r)
+{
+ struct nsObject *nsobj;
+ struct rect *restrict deferred_rect;
+ struct rect new_rect;
+
+ if(r == NULL) {
+ struct IBox *bbox;
+ if(ami_gui_get_space_box((Object *)ami_cw->objects[GID_CW_DRAW], &bbox) != NSERROR_OK) {
+ amiga_warn_user("NoMemory", "");
+ return;
+ }
+
+ new_rect.x0 = 0;
+ new_rect.y0 = 0;
+ ami_cw_coord_amiga_to_ns(ami_cw, &new_rect.x0, &new_rect.y0);
+ new_rect.x1 = new_rect.x0 + bbox->Width;
+ new_rect.y1 = new_rect.y0 + bbox->Height;
+
+ ami_gui_free_space_box(bbox);
+
+ r = &new_rect;
+ }
+
+ if(ami_gui_window_update_box_deferred_check(ami_cw->deferred_rects, r,
+ ami_cw->deferred_rects_pool)) {
+ deferred_rect = ami_memory_itempool_alloc(ami_cw->deferred_rects_pool, sizeof(struct rect));
+ CopyMem(r, deferred_rect, sizeof(struct rect));
+ nsobj = AddObject(ami_cw->deferred_rects, AMINS_RECT);
+ nsobj->objstruct = deferred_rect;
+ } else {
+ LOG("Ignoring duplicate or subset of queued box redraw");
+ }
+ ami_schedule(1, ami_cw_redraw_cb, ami_cw);
+}
+
+static void ami_cw_simplerefresh(struct ami_corewindow *ami_cw)
+{
+ struct rect r;
+ struct RegionRectangle *regrect;
+
+ BeginRefresh(ami_cw->win);
+
+ r.x0 = ami_cw->win->RPort->Layer->DamageList->bounds.MinX;
+ r.x1 = ami_cw->win->RPort->Layer->DamageList->bounds.MaxX;
+ r.y0 = ami_cw->win->RPort->Layer->DamageList->bounds.MinY;
+ r.y1 = ami_cw->win->RPort->Layer->DamageList->bounds.MaxY;
+
+ ami_cw_coord_amiga_to_ns(ami_cw, &r.x0, &r.y0);
+ ami_cw_coord_amiga_to_ns(ami_cw, &r.y0, &r.y1);
+
+ regrect = ami_cw->win->RPort->Layer->DamageList->RegionRectangle;
+
+ ami_cw_redraw(ami_cw, &r); /* queue redraw */
+
+ while(regrect) {
+ r.x0 = regrect->bounds.MinX;
+ r.x1 = regrect->bounds.MaxX;
+ r.y0 = regrect->bounds.MinY;
+ r.y1 = regrect->bounds.MaxY;
+ ami_cw_coord_amiga_to_ns(ami_cw, &r.x0, &r.y0);
+ ami_cw_coord_amiga_to_ns(ami_cw, &r.y0, &r.y1);
+
+ regrect = regrect->Next;
+
+ ami_cw_redraw(ami_cw, &r); /* queue redraw */
+ }
+
+ EndRefresh(ami_cw->win, TRUE);
+}
+
+static void
+ami_cw_toggle_scrollbar(struct ami_corewindow *ami_cw, bool vert, bool visible)
+{
+ Object *scroller;
+ Object *layout;
+ ULONG tag;
+
+ if(vert == true) {
+ if(visible == ami_cw->scroll_y_visible) {
+ return;
+ } else {
+ scroller = ami_cw->objects[GID_CW_VSCROLL];
+ layout = ami_cw->objects[GID_CW_VSCROLLLAYOUT];
+ tag = WINDOW_VertProp;
+ ami_cw->scroll_y_visible = visible;
+ }
+ } else {
+ if(visible == ami_cw->scroll_x_visible) {
+ return;
+ } else {
+ scroller = ami_cw->objects[GID_CW_HSCROLL];
+ layout = ami_cw->objects[GID_CW_HSCROLLLAYOUT];
+ tag = WINDOW_HorizProp;
+ ami_cw->scroll_x_visible = visible;
+ }
+ }
+
+ if(visible == true) {
+ if(ami_cw->in_border_scroll == true) {
+ SetAttrs(ami_cw->objects[GID_CW_WIN],
+ tag, 1,
+ TAG_DONE);
+ } else {
+#ifdef __amigaos4__
+ IDoMethod(layout, LM_ADDCHILD, ami_cw->win, scroller, NULL);
+#else
+ SetAttrs(layout, LAYOUT_AddChild, scroller, TAG_DONE);
+#endif
+ }
+ } else {
+ if(ami_cw->in_border_scroll == true) {
+ SetAttrs(ami_cw->objects[GID_CW_WIN],
+ tag, -1,
+ TAG_DONE);
+ } else {
+#ifdef __amigaos4__
+ IDoMethod(layout, LM_REMOVECHILD, ami_cw->win, scroller);
+#else
+ SetAttrs(layout, LAYOUT_RemoveChild, scroller, TAG_DONE);
+#endif
+ }
+ }
+
+ if(ami_cw->in_border_scroll == false) {
+ FlushLayoutDomainCache((struct Gadget *)ami_cw->objects[GID_CW_WIN]);
+ RethinkLayout((struct Gadget *)ami_cw->objects[GID_CW_WIN],
+ ami_cw->win, NULL, TRUE);
+ }
+
+ /* probably need to redraw here */
+ ami_cw_redraw(ami_cw, NULL);
+}
+
+static void
+ami_cw_close(void *w)
+{
+ struct ami_corewindow *ami_cw = (struct ami_corewindow *)w;
+
+ ami_cw->close(ami_cw);
+}
+
+HOOKF(void, ami_cw_idcmp_hook, Object *, object, struct IntuiMessage *)
+{
+ struct ami_corewindow *ami_cw = hook->h_Data;
+ struct IntuiWheelData *wheel;
+ ULONG gid = GetTagData( GA_ID, 0, msg->IAddress );
+
+ switch(msg->Class)
+ {
+ case IDCMP_IDCMPUPDATE:
+ switch(gid)
+ {
+ case GID_CW_HSCROLL:
+ case GID_CW_VSCROLL:
+ ami_cw_redraw(ami_cw, NULL);
+ break;
+ }
+ break;
+#ifdef __amigaos4__
+ case IDCMP_EXTENDEDMOUSE:
+ if(msg->Code == IMSGCODE_INTUIWHEELDATA)
+ {
+ wheel = (struct IntuiWheelData *)msg->IAddress;
+
+ //ami_tree_scroll(twin, (wheel->WheelX * 20), (wheel->WheelY * 20));
+ }
+ break;
+#endif
+
+ case IDCMP_SIZEVERIFY:
+ break;
+
+ case IDCMP_REFRESHWINDOW:
+ ami_cw_simplerefresh(ami_cw);
+ break;
+
+ default:
+ LOG("IDCMP hook unhandled event: %ld", msg->Class);
+ break;
+ }
+}
+
+/**
+ * Drag start
+ */
+static void
+ami_cw_drag_start(struct ami_corewindow *ami_cw, int x, int y)
+{
+ if(ami_cw->dragging == true) return;
+
+ ami_cw->dragging = true;
+ ami_cw->drag_x_start = x;
+ ami_cw->drag_y_start = y;
+
+ switch(ami_cw->drag_status) {
+ case CORE_WINDOW_DRAG_SELECTION:
+ break;
+
+ case CORE_WINDOW_DRAG_MOVE:
+ ami_drag_icon_show(ami_cw->win, "project");
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * Drag progress
+ */
+static void
+ami_cw_drag_progress(struct ami_corewindow *ami_cw, int x, int y)
+{
+ if(ami_cw->dragging == false) return;
+
+ switch(ami_cw->drag_status) {
+ case CORE_WINDOW_DRAG_SELECTION:
+ break;
+
+ case CORE_WINDOW_DRAG_MOVE:
+ ami_drag_icon_move();
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * Drag end
+ */
+static void
+ami_cw_drag_end(struct ami_corewindow *ami_cw, int x, int y)
+{
+ if(ami_cw->dragging == false) return;
+
+ switch(ami_cw->drag_status) {
+ case CORE_WINDOW_DRAG_SELECTION:
+ break;
+
+ case CORE_WINDOW_DRAG_MOVE:
+ ami_drag_icon_close(ami_cw->win);
+ if((ami_cw != ami_window_at_pointer(AMINS_COREWINDOW)) && (ami_cw->drag_end != NULL)) {
+ ami_cw->drag_end(ami_cw, scrn->MouseX, scrn->MouseY);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ ami_cw->drag_status = CORE_WINDOW_DRAG_NONE;
+ ami_cw->dragging = false;
+}
+
+/**
+ * User has resized window
+ */
+
+static void
+ami_cw_newsize(struct ami_corewindow *ami_cw)
+{
+ int win_w, win_h;
+ ami_cw_window_size(ami_cw, &win_w, &win_h);
+
+ if(ami_cw->objects[GID_CW_HSCROLL] != NULL) {
+ RefreshSetGadgetAttrs((struct Gadget *)ami_cw->objects[GID_CW_HSCROLL], ami_cw->win, NULL,
+ SCROLLER_Visible, win_w,
+ TAG_DONE);
+ }
+
+ if(ami_cw->objects[GID_CW_VSCROLL] != NULL) {
+ RefreshSetGadgetAttrs((struct Gadget *)ami_cw->objects[GID_CW_VSCROLL], ami_cw->win, NULL,
+ SCROLLER_Visible, win_h,
+ TAG_DONE);
+ }
+
+ ami_cw_redraw(ami_cw, NULL);
+}
+
+/**
+ * Main event loop for our core window
+ *
+ * \return TRUE if window destroyed
+ */
+static BOOL
+ami_cw_event(void *w)
+{
+ struct ami_corewindow *ami_cw = (struct ami_corewindow *)w;
+
+ ULONG result;
+ ULONG storage;
+ uint16 code;
+ struct InputEvent *ie;
+ int nskey;
+ int key_state = 0;
+ struct timeval curtime;
+ int x = 0, y = 0;
+
+ while((result = RA_HandleInput(ami_cw->objects[GID_CW_WIN], &code)) != WMHI_LASTMSG) {
+ if(ami_cw->close_window == true) {
+ ami_cw_close(ami_cw);
+ return TRUE;
+ }
+
+ switch(result & WMHI_CLASSMASK) {
+ case WMHI_MOUSEMOVE:
+ if(ami_cw_mouse_pos(ami_cw, &x, &y) == true) {
+ if(ami_cw_mouse_moved(ami_cw, x, y, false)) {
+ if(ami_cw->mouse_state & BROWSER_MOUSE_PRESS_1) {
+ /* Start button 1 drag */
+ ami_cw->mouse(ami_cw, BROWSER_MOUSE_DRAG_1, x, y);
+ /* Replace PRESS with HOLDING and declare drag in progress */
+ ami_cw->mouse_state = BROWSER_MOUSE_HOLDING_1 | BROWSER_MOUSE_DRAG_ON;
+ } else if(ami_cw->mouse_state & BROWSER_MOUSE_PRESS_2) {
+ /* Start button 2 drag */
+ ami_cw->mouse(ami_cw, BROWSER_MOUSE_DRAG_2, x, y);
+ /* Replace PRESS with HOLDING and declare drag in progress */
+ ami_cw->mouse_state = BROWSER_MOUSE_HOLDING_2 | BROWSER_MOUSE_DRAG_ON;
+ }
+ key_state = ami_gui_get_quals(ami_cw->objects[GID_CW_WIN]);
+ ami_cw->mouse(ami_cw, ami_cw->mouse_state | key_state, x, y);
+ if(ami_cw->mouse_state & BROWSER_MOUSE_DRAG_ON) {
+ ami_cw_drag_start(ami_cw, x, y);
+ }
+ } else {
+ key_state = ami_gui_get_quals(ami_cw->objects[GID_CW_WIN]);
+ ami_cw->mouse(ami_cw, ami_cw->mouse_state | key_state, x, y);
+ }
+ }
+ ami_cw_drag_progress(ami_cw, x, y);
+ break;
+
+ case WMHI_MOUSEBUTTONS:
+ if(ami_cw_mouse_pos(ami_cw, &x, &y) == true) {
+ key_state = ami_gui_get_quals(ami_cw->objects[GID_CW_WIN]);
+ switch(code) {
+ case SELECTDOWN:
+ ami_cw->mouse_state = BROWSER_MOUSE_PRESS_1;
+ ami_cw->drag_x_start = x;
+ ami_cw->drag_y_start = y;
+ break;
+
+ case MIDDLEDOWN:
+ ami_cw->mouse_state = BROWSER_MOUSE_PRESS_2;
+ ami_cw->drag_x_start = x;
+ ami_cw->drag_y_start = y;
+ break;
+
+ case SELECTUP:
+ if(ami_cw->mouse_state & BROWSER_MOUSE_PRESS_1) {
+ CurrentTime((ULONG *)&curtime.tv_sec, (ULONG *)&curtime.tv_usec);
+
+ ami_cw->mouse_state = BROWSER_MOUSE_CLICK_1;
+
+ if(ami_cw->lastclick.tv_sec) {
+ if((ami_cw_mouse_moved(ami_cw, x, y, true) == false) &&
+ (DoubleClick(ami_cw->lastclick.tv_sec,
+ ami_cw->lastclick.tv_usec,
+ curtime.tv_sec, curtime.tv_usec)))
+ ami_cw->mouse_state |= BROWSER_MOUSE_DOUBLE_CLICK;
+ }
+
+ ami_cw->mouse_x_click = x;
+ ami_cw->mouse_y_click = y;
+
+ if(ami_cw->mouse_state & BROWSER_MOUSE_DOUBLE_CLICK) {
+ ami_cw->lastclick.tv_sec = 0;
+ ami_cw->lastclick.tv_usec = 0;
+ } else {
+ ami_cw->lastclick.tv_sec = curtime.tv_sec;
+ ami_cw->lastclick.tv_usec = curtime.tv_usec;
+ }
+ }
+
+ ami_cw->mouse(ami_cw, ami_cw->mouse_state | key_state, x, y);
+ ami_cw->mouse_state = BROWSER_MOUSE_HOVER;
+ break;
+
+ case MIDDLEUP:
+ if(ami_cw->mouse_state & BROWSER_MOUSE_PRESS_2)
+ ami_cw->mouse_state = BROWSER_MOUSE_CLICK_2;
+
+ ami_cw->mouse(ami_cw, ami_cw->mouse_state | key_state, x, y);
+ ami_cw->mouse_state = BROWSER_MOUSE_HOVER;
+ break;
+ }
+
+ if(ami_cw->mouse_state == BROWSER_MOUSE_HOVER) {
+ ami_cw_drag_end(ami_cw, x, y);
+ }
+
+ ami_cw->mouse(ami_cw, ami_cw->mouse_state | key_state, x, y);
+ } else {
+ /* event is happening away from our corewindow area */
+ switch(code) {
+ case SELECTUP:
+ case MIDDLEUP:
+ ami_cw->mouse_state = BROWSER_MOUSE_HOVER;
+ break;
+
+ default:
+ break;
+ }
+
+ if(ami_cw->mouse_state == BROWSER_MOUSE_HOVER) {
+ ami_cw_drag_end(ami_cw, x, y);
+ ami_cw->mouse(ami_cw, ami_cw->mouse_state | key_state,
+ ami_cw->drag_x_start, ami_cw->drag_y_start); // placate core
+ }
+ }
+ break;
+
+ case WMHI_RAWKEY:
+ storage = result & WMHI_GADGETMASK;
+
+ GetAttr(WINDOW_InputEvent, ami_cw->objects[GID_CW_WIN], (ULONG *)&ie);
+ nskey = ami_key_to_nskey(storage, ie);
+
+ ami_cw_key(ami_cw, nskey);
+ break;
+
+ case WMHI_NEWSIZE:
+ ami_cw_newsize(ami_cw);
+ break;
+
+ case WMHI_CLOSEWINDOW:
+ ami_cw_close(ami_cw);
+ return TRUE;
+ break;
+
+ default:
+ /* pass the event to the window owner */
+ if(ami_cw->event != NULL)
+ if(ami_cw->event(ami_cw, result) == TRUE) {
+ return TRUE;
+ }
+ break;
+ }
+ };
+
+ return FALSE;
+}
+
+static const struct ami_win_event_table ami_cw_table = {
+ ami_cw_event,
+ ami_cw_close,
+};
+
+/**
+ * callback from core to request a redraw
+ */
+static void
+ami_cw_redraw_request(struct core_window *cw, const struct rect *r)
+{
+ struct ami_corewindow *ami_cw = (struct ami_corewindow *)cw;
+
+ ami_cw_redraw(ami_cw, r);
+}
+
+
+static void
+ami_cw_get_window_dimensions(struct core_window *cw, int *width, int *height)
+{
+ struct ami_corewindow *ami_cw = (struct ami_corewindow *)cw;
+
+ ami_cw_window_size(ami_cw, width, height);
+}
+
+
+static void
+ami_cw_update_size(struct core_window *cw, int width, int height)
+{
+ struct ami_corewindow *ami_cw = (struct ami_corewindow *)cw;
+ int win_w, win_h;
+
+ ami_cw_window_size(ami_cw, &win_w, &win_h);
+
+ if(width == -1) {
+ ami_cw_toggle_scrollbar(ami_cw, false, false);
+ } else {
+ ami_cw_toggle_scrollbar(ami_cw, false, true);
+ RefreshSetGadgetAttrs((struct Gadget *)ami_cw->objects[GID_CW_HSCROLL], ami_cw->win, NULL,
+ SCROLLER_Total, (ULONG)width,
+ SCROLLER_Visible, win_w,
+ TAG_DONE);
+ }
+
+ if(height == -1) {
+ ami_cw_toggle_scrollbar(ami_cw, true, false);
+ } else {
+ ami_cw_toggle_scrollbar(ami_cw, true, true);
+ RefreshSetGadgetAttrs((struct Gadget *)ami_cw->objects[GID_CW_VSCROLL], ami_cw->win, NULL,
+ SCROLLER_Total, height,
+ SCROLLER_Visible, win_h,
+ TAG_DONE);
+ }
+}
+
+
+static void
+ami_cw_scroll_visible(struct core_window *cw, const struct rect *r)
+{
+ struct ami_corewindow *ami_cw = (struct ami_corewindow *)cw;
+
+ int scrollsetx;
+ int scrollsety;
+ int win_w = 0, win_h = 0;
+ ULONG win_x0, win_y0;
+ int win_x1, win_y1;
+
+ ami_cw_window_size(ami_cw, &win_w, &win_h);
+
+ ami_cw_scroller_top(ami_cw, &win_x0, &win_y0);
+
+ win_x1 = win_x0 + win_w;
+ win_y1 = win_y0 + win_h;
+
+ if(r->y1 > win_y1) scrollsety = r->y1 - win_h;
+ if(r->y0 < win_y0) scrollsety = r->y0;
+ if(r->x1 > win_x1) scrollsetx = r->x1 - win_w;
+ if(r->x0 < win_x0) scrollsetx = r->x0;
+
+ if(ami_cw->scroll_y_visible == true) {
+ RefreshSetGadgetAttrs((APTR)ami_cw->objects[GID_CW_VSCROLL], ami_cw->win, NULL,
+ SCROLLER_Top, scrollsety,
+ TAG_DONE);
+ }
+
+ if(ami_cw->scroll_x_visible == true) {
+ RefreshSetGadgetAttrs((APTR)ami_cw->objects[GID_CW_HSCROLL], ami_cw->win, NULL,
+ SCROLLER_Top, scrollsetx,
+ TAG_DONE);
+ }
+
+ /* probably need to redraw here */
+ ami_cw_redraw(ami_cw, NULL);
+}
+
+
+static void
+ami_cw_drag_status(struct core_window *cw, core_window_drag_status ds)
+{
+ struct ami_corewindow *ami_cw = (struct ami_corewindow *)cw;
+ ami_cw->drag_status = ds;
+}
+
+
+struct core_window_callback_table ami_cw_cb_table = {
+ .redraw_request = ami_cw_redraw_request,
+ .update_size = ami_cw_update_size,
+ .scroll_visible = ami_cw_scroll_visible,
+ .get_window_dimensions = ami_cw_get_window_dimensions,
+ .drag_status = ami_cw_drag_status
+};
+
+/* exported function documented example/corewindow.h */
+nserror ami_corewindow_init(struct ami_corewindow *ami_cw)
+{
+ /* setup the core window callback table */
+ ami_cw->cb_table = &ami_cw_cb_table;
+
+ /* clear some vars */
+ ami_cw->mouse_state = BROWSER_MOUSE_HOVER;
+ ami_cw->lastclick.tv_sec = 0;
+ ami_cw->lastclick.tv_usec = 0;
+ ami_cw->scroll_x_visible = true;
+ ami_cw->scroll_y_visible = true;
+ ami_cw->in_border_scroll = false;
+ ami_cw->dragging = false;
+
+ /* allocate drawing area etc */
+ ami_init_layers(&ami_cw->gg, 100, 100, false); // force tiles to save memory
+ ami_cw->gg.shared_pens = ami_AllocMinList();
+
+ ami_cw->deferred_rects = NewObjList();
+ ami_cw->deferred_rects_pool = ami_memory_itempool_create(sizeof(struct rect));
+
+ /* add the core window to our window list so we process events */
+ ami_gui_win_list_add(ami_cw, AMINS_COREWINDOW, &ami_cw_table);
+
+ /* set up the IDCMP hook for event processing (extended mouse, scrollbars) */
+ ami_cw->idcmp_hook.h_Entry = (void *)ami_cw_idcmp_hook;
+ ami_cw->idcmp_hook.h_Data = ami_cw;
+
+ /* open the window */
+ ami_cw->win = (struct Window *)RA_OpenWindow(ami_cw->objects[GID_CW_WIN]);
+
+ /* attach the scrollbars for event processing _if they are in the window border_ */
+ if(ami_cw->objects[GID_CW_HSCROLL] == NULL) {
+ GetAttr(WINDOW_HorizObject, ami_cw->objects[GID_CW_WIN],
+ (ULONG *)&ami_cw->objects[GID_CW_HSCROLL]);
+
+ RefreshSetGadgetAttrs((APTR)ami_cw->objects[GID_CW_HSCROLL], ami_cw->win, NULL,
+ GA_ID, GID_CW_HSCROLL,
+ ICA_TARGET, ICTARGET_IDCMP,
+ TAG_DONE);
+
+ ami_cw->in_border_scroll = true;
+ }
+
+ if(ami_cw->objects[GID_CW_VSCROLL] == NULL) {
+ GetAttr(WINDOW_VertObject, ami_cw->objects[GID_CW_WIN],
+ (ULONG *)&ami_cw->objects[GID_CW_VSCROLL]);
+
+ RefreshSetGadgetAttrs((APTR)ami_cw->objects[GID_CW_VSCROLL], ami_cw->win, NULL,
+ GA_ID, GID_CW_VSCROLL,
+ ICA_TARGET, ICTARGET_IDCMP,
+ TAG_DONE);
+
+ ami_cw->in_border_scroll = true;
+ }
+
+ return NSERROR_OK;
+}
+
+/* exported interface documented in example/corewindow.h */
+nserror ami_corewindow_fini(struct ami_corewindow *ami_cw)
+{
+ /* remove any pending redraws */
+ ami_schedule(-1, ami_cw_redraw_cb, ami_cw);
+ FreeObjList(ami_cw->deferred_rects);
+ ami_memory_itempool_delete(ami_cw->deferred_rects_pool);
+
+ /* destroy the window */
+ ami_cw->win = NULL;
+ DisposeObject(ami_cw->objects[GID_CW_WIN]);
+
+#if 0
+ /* ensure our scrollbars are destroyed */
+ /* it appears these are disposed anyway,
+ * even if the gadgets are no longer attached to the window */
+ if(ami_cw->in_border_scroll == false) {
+ if(ami_cw->scroll_x_visible == false) {
+ DisposeObject(ami_cw->objects[GID_CW_HSCROLL]);
+ }
+ if(ami_cw->scroll_y_visible == false) {
+ DisposeObject(ami_cw->objects[GID_CW_VSCROLL]);
+ }
+ }
+#endif
+
+ /* release off-screen bitmap stuff */
+ ami_plot_release_pens(ami_cw->gg.shared_pens);
+ ami_free_layers(&ami_cw->gg);
+
+ /* free the window title */
+ ami_utf8_free(ami_cw->wintitle);
+
+ /* remove the core window from our window list */
+ ami_gui_win_list_remove(ami_cw);
+
+ return NSERROR_OK;
+}
+
diff --git a/frontends/amiga/corewindow.h b/frontends/amiga/corewindow.h
new file mode 100644
index 0000000..cfcd7fc
--- /dev/null
+++ b/frontends/amiga/corewindow.h
@@ -0,0 +1,188 @@
+/*
+ * Copyright 2017 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef AMIGA_COREWINDOW_H
+#define AMIGA_COREWINDOW_H
+
+#include "netsurf/core_window.h"
+
+#include "amiga/gui.h" /* need to know the size of ami_generic_window :( */
+#include "amiga/plotters.h"
+
+/**
+ * BOOPSI objects
+ */
+
+enum {
+ GID_CW_WIN = 0, /* window object */
+ GID_CW_MAIN, /* root layout object */
+ GID_CW_DRAW, /* drawing area (space.gadget) */
+ GID_CW_HSCROLL, /* horizontal scroller */
+ GID_CW_VSCROLL, /* vertical scroller */
+ GID_CW_HSCROLLLAYOUT, /* horizontal scroller container*/
+ GID_CW_VSCROLLLAYOUT, /* vertical scroller container */
+ GID_CW_LAST
+};
+
+/**
+ * Amiga core window state
+ */
+struct ami_corewindow {
+ /*
+ * Any variables common to any frontend window would go here.
+ * e.g. drawing area handles, toolkit pointers or other state
+ */
+ struct ami_generic_window w;
+ struct Window *win;
+ Object *objects[GID_CW_LAST];
+
+ struct Hook idcmp_hook;
+ struct timeval lastclick;
+
+ int mouse_x_click;
+ int mouse_y_click;
+ int mouse_state;
+
+ bool dragging;
+ int drag_x_start;
+ int drag_y_start;
+
+ bool close_window; // set to true to close the window during event loop
+
+ APTR deferred_rects_pool;
+ struct MinList *deferred_rects;
+
+ /** keep track of the scrollbar type we're using */
+ bool in_border_scroll;
+ bool scroll_x_visible;
+ bool scroll_y_visible;
+
+ /** window title, must be allocated wth ami_utf8 function */
+ char *wintitle;
+
+ /** stuff for our off-screen render bitmap */
+ struct gui_globals gg;
+ struct MinList *shared_pens;
+
+ /** drag status set by core */
+ core_window_drag_status drag_status;
+
+ /** table of callbacks for core window operations */
+ struct core_window_callback_table *cb_table;
+
+ /**
+ * callback to draw on drawable area of Amiga core window
+ *
+ * \param ami_cw The Amiga core window structure.
+ * \param x Plot origin (X)
+ * \param r Plot origin (Y)
+ * \param r The rectangle of the window that needs updating.
+ * \param ctx Redraw context
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+ nserror (*draw)(struct ami_corewindow *ami_cw, int x, int y, struct rect *r,
+ struct redraw_context *ctx);
+
+ /**
+ * callback for keypress on Amiga core window
+ *
+ * \param ami_cw The Amiga core window structure.
+ * \param nskey The netsurf key code.
+ * \return NSERROR_OK if key processed,
+ * NSERROR_NOT_IMPLEMENTED if key not processed
+ * otherwise apropriate error code
+ */
+ nserror (*key)(struct ami_corewindow *ami_cw, uint32_t nskey);
+
+ /**
+ * callback for mouse event on Amiga core window
+ *
+ * \param ami_cw The Amiga core window structure.
+ * \param mouse_state mouse state
+ * \param x location of event
+ * \param y location of event
+ * \return NSERROR_OK on sucess otherwise apropriate error code.
+ */
+ nserror (*mouse)(struct ami_corewindow *ami_cw, browser_mouse_state mouse_state, int x, int y);
+
+ /**
+ * callback for unknown events on Amiga core window
+ * eg. buttons in the ssl cert window
+ * (result & WMHI_CLASSMASK) gives the class of event (eg. WMHI_GADGETUP)
+ * (result & WMHI_GADGETMASK) gives the gadget ID (eg. GID_SSLCERT_ACCEPT)
+ *
+ * \param ami_cw The Amiga core window structure.
+ * \param result event as returned by RA_HandleInput()
+ * \return TRUE if window closed during event processing
+ */
+ BOOL (*event)(struct ami_corewindow *ami_cw, ULONG result);
+
+ /**
+ * callback for drag end on Amiga core window
+ * ie. a drag *from* this window to a different window
+ *
+ * \param ami_cw The Amiga core window structure.
+ * \param x mouse x position **in screen co-ordinates**
+ * \param y mouse y position **in screen co-ordinates**
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+ nserror (*drag_end)(struct ami_corewindow *ami_cw, int x, int y);
+
+ /**
+ * callback for icon drop on Amiga core window
+ * ie. a drag has ended *above* this window
+ * \todo this may not be very flexible but serves our current purposes
+ *
+ * \param ami_cw The Amiga core window structure.
+ * \param url url of dropped icon
+ * \param title title of dropped icon
+ * \param x mouse x position **in screen co-ordinates**
+ * \param y mouse y position **in screen co-ordinates**
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+ nserror (*icon_drop)(struct ami_corewindow *ami_cw, struct nsurl *url, const char *title, int x, int y);
+
+ /**
+ * callback to close an Amiga core window
+ *
+ * \param ami_cw The Amiga core window structure.
+ */
+ void (*close)(struct ami_corewindow *ami_cw);
+
+};
+
+/**
+ * initialise elements of Amiga core window.
+ *
+ * As a pre-requisite the draw, key and mouse callbacks must be defined
+ *
+ * \param example_cw An Amiga core window structure to initialise
+ * \return NSERROR_OK on successful initialisation otherwise error code.
+ */
+nserror ami_corewindow_init(struct ami_corewindow *ami_cw);
+
+/**
+ * finalise elements of Amiga core window.
+ *
+ * \param ami_cw An Amiga core window structure to finialise
+ * \return NSERROR_OK on successful finalisation otherwise error code.
+ */
+nserror ami_corewindow_fini(struct ami_corewindow *ami_cw);
+
+#endif
+
diff --git a/frontends/amiga/dist/NetSurf.guide b/frontends/amiga/dist/NetSurf.guide
index dd2f46d..512a264 100755
--- a/frontends/amiga/dist/NetSurf.guide
+++ b/frontends/amiga/dist/NetSurf.guide
@@ -145,7 +145,7 @@ There are a couple of Amiga-specific options which can only be changed directly
@{b}web_search_width@{ub} Defaults to 0. Larger values will increase the size of the web search gadget next to the URL bar.
@{b}mask_alpha@{ub} Threshold to use when determining which alpha values to convert to full transparency (0 - 255, where 255 will convert even opaque pixels to transparent). Defaults to 0. This is only used in palette-mapped modes where alpha blending is not currently supported.
@{b}tab_new_session{ub} If NetSurf is already running, this will cause any passed URLs to open in a new tab rather than a new window.
-
+@{b}use_extmem@{ub} Defaults to 1 (enabled). Setting to 0 will prevent NetSurf using Extended Memory to store uncompressed images - this may have a performance benefit and no disadvantage for <2GB configurations. OS4.1FEU1 only.
@{b}url_file@{ub} Path to URL database file
@{b}hotlist_file@{ub} Path to Hotlist file
@{b}arexx_dir@{ub} Path to ARexx scripts dir
@@ -285,11 +285,11 @@ Items from the hotlist can be added to the Hotlist menu as follows:
Select Hotlist => Show hotlist...
-Items in the "Hotlist menu" folder node, up to a maximum (currently) of 40 items, will be added to the Hotlist menu, within the limits of the Intuition menu system.
+Items in the "Hotlist menu" folder node, up to a maximum (currently) of 200 items, will be added to the Hotlist menu, within the limits of the Intuition menu system.
Items in folders within the Menu folder node will be converted to subitems in the menu.
-Folders more than one level down in the heirarchy will become menu items with no action. Items deeper will not be included in the menu at all (until we switch to using menuclass).
+When using a version of AmigaOS older than OS4.1FE, folders more than one level down in the heirarchy will become menu items with no action. Items deeper will not be included in the menu at all.
Folders with no items in them will show up disabled in the menu. If they are named "--" they will be displayed as separator bars.
diff --git a/frontends/amiga/download.c b/frontends/amiga/download.c
index 93536f4..47485e0 100644
--- a/frontends/amiga/download.c
+++ b/frontends/amiga/download.c
@@ -69,7 +69,7 @@
#include "amiga/utf8.h"
struct gui_download_window {
- struct nsObject *node;
+ struct ami_generic_window w;
struct Window *win;
Object *objects[GID_LAST];
BPTR fh;
@@ -89,6 +89,14 @@ enum {
AMINS_DLOAD_ABORT,
};
+static void ami_download_window_abort(void *w);
+static BOOL ami_download_window_event(void *w);
+
+static const struct ami_win_event_table ami_download_table = {
+ ami_download_window_event,
+ ami_download_window_abort,
+};
+
static int downloads_in_progress = 0;
static struct gui_download_window *gui_download_window_create(download_context *ctx,
@@ -100,7 +108,7 @@ static struct gui_download_window *gui_download_window_create(download_context *
char *dl_filename = ami_utf8_easy(download_context_get_filename(ctx));
APTR va[3];
- dw = ami_misc_allocvec_clear(sizeof(struct gui_download_window), 0);
+ dw = calloc(1, sizeof(struct gui_download_window));
if(gui && (!IsListEmpty(&gui->dllist)) && (dw->dln = (struct dlnode *)FindName(&gui->dllist,url)))
{
@@ -122,13 +130,13 @@ static struct gui_download_window *gui_download_window_create(download_context *
AddPart((STRPTR)&dw->fname,savereq->fr_File,1024);
if(!ami_download_check_overwrite(dw->fname, gui->shared->win, total_size))
{
- FreeVec(dw);
+ free(dw);
return NULL;
}
}
else
{
- FreeVec(dw);
+ free(dw);
return NULL;
}
}
@@ -145,7 +153,7 @@ static struct gui_download_window *gui_download_window_create(download_context *
if(!(dw->fh = FOpen((STRPTR)&dw->fname,MODE_NEWFILE,0)))
{
- FreeVec(dw);
+ free(dw);
return NULL;
}
@@ -190,8 +198,7 @@ static struct gui_download_window *gui_download_window_create(download_context *
dw->win = (struct Window *)RA_OpenWindow(dw->objects[OID_MAIN]);
dw->ctx = ctx;
- dw->node = AddObject(window_list,AMINS_DLWINDOW);
- dw->node->objstruct = dw;
+ ami_gui_win_list_add(dw, AMINS_DLWINDOW, &ami_download_table);
downloads_in_progress++;
@@ -260,7 +267,7 @@ static void gui_download_window_done(struct gui_download_window *dw)
free(dln->filename);
Remove((struct Node *)dln);
- FreeVec(dln);
+ free(dln);
}
FClose(dw->fh);
@@ -269,7 +276,7 @@ static void gui_download_window_done(struct gui_download_window *dw)
downloads_in_progress--;
DisposeObject(dw->objects[OID_MAIN]);
- DelObject(dw->node);
+ ami_gui_win_list_remove(dw);
if(queuedl) {
nsurl *url;
if (nsurl_create(dln2->node.ln_Name, &url) != NSERROR_OK) {
@@ -296,16 +303,18 @@ static void gui_download_window_error(struct gui_download_window *dw,
gui_download_window_done(dw);
}
-void ami_download_window_abort(struct gui_download_window *dw)
+static void ami_download_window_abort(void *w)
{
+ struct gui_download_window *dw = (struct gui_download_window *)dw;
download_context_abort(dw->ctx);
dw->result = AMINS_DLOAD_ABORT;
gui_download_window_done(dw);
}
-BOOL ami_download_window_event(struct gui_download_window *dw)
+static BOOL ami_download_window_event(void *w)
{
/* return TRUE if window destroyed */
+ struct gui_download_window *dw = (struct gui_download_window *)w;
ULONG result;
uint16 code;
@@ -343,7 +352,7 @@ void ami_free_download_list(struct List *dllist)
free(node->node.ln_Name);
free(node->filename);
Remove((struct Node *)node);
- FreeVec((struct Node *)node);
+ free((struct Node *)node);
}while((node=nnode));
}
diff --git a/frontends/amiga/download.h b/frontends/amiga/download.h
index 51981ed..b60b4f0 100755
--- a/frontends/amiga/download.h
+++ b/frontends/amiga/download.h
@@ -34,8 +34,6 @@ struct dlnode
char *filename;
};
-void ami_download_window_abort(struct gui_download_window *dw);
-BOOL ami_download_window_event(struct gui_download_window *dw);
void ami_free_download_list(struct List *dllist);
BOOL ami_download_check_overwrite(const char *file, struct Window *win, ULONG size);
diff --git a/frontends/amiga/dt_anim.c b/frontends/amiga/dt_anim.c
index 1946788..a486334 100644
--- a/frontends/amiga/dt_anim.c
+++ b/frontends/amiga/dt_anim.c
@@ -46,7 +46,6 @@
#include "amiga/bitmap.h"
#include "amiga/filetype.h"
#include "amiga/datatypes.h"
-#include "amiga/misc.h"
#include "amiga/plotters.h"
typedef struct amiga_dt_anim_content {
@@ -216,7 +215,7 @@ bool amiga_dt_anim_convert(struct content *c)
#else
#warning FIXME: Need to use a different blitter function for OS3!
#endif
- FreeVec(clut);
+ free(clut);
adt_frame.MethodID = ADTM_UNLOADFRAME;
IDoMethodA(plugin->dto, (Msg)&adt_frame);
@@ -344,7 +343,7 @@ content_type amiga_dt_anim_content_type(void)
static APTR ami_colormap_to_clut(struct ColorMap *cmap)
{
int i;
- UBYTE *clut = ami_misc_allocvec_clear(256 * 4, 0); /* NB: Was not MEMF_PRIVATE */
+ UBYTE *clut = calloc(1, 256 * 4);
ULONG colr[256 * 4];
if(!clut) return NULL;
diff --git a/frontends/amiga/file.c b/frontends/amiga/file.c
index 1bba30e..0fd4378 100644
--- a/frontends/amiga/file.c
+++ b/frontends/amiga/file.c
@@ -46,6 +46,9 @@
static struct Hook aslhookfunc;
+struct FileRequester *filereq;
+struct FileRequester *savereq;
+
HOOKF(ULONG, ami_file_asl_mime_hook, struct FileRequester *, fr, struct AnchorPathOld *)
{
char fname[1024];
@@ -89,7 +92,7 @@ void ami_file_open(struct gui_window_2 *gwin)
ASLFR_FilterFunc, &aslhookfunc,
TAG_DONE))
{
- if((temp = AllocVecTagList(1024, NULL)))
+ if((temp = malloc(1024)))
{
strlcpy(temp, filereq->fr_Drawer, 1024);
AddPart(temp, filereq->fr_File, 1024);
@@ -107,7 +110,7 @@ void ami_file_open(struct gui_window_2 *gwin)
nsurl_unref(url);
}
- FreeVec(temp);
+ free(temp);
}
}
}
@@ -212,7 +215,7 @@ void ami_file_save(int type, char *fname, struct Window *win,
void ami_file_save_req(int type, struct gui_window_2 *gwin,
struct hlcache_handle *object)
{
- char *fname = AllocVecTagList(1024, NULL);
+ char *fname = malloc(1024);
char *initial_fname = NULL;
char *fname_with_ext = NULL;
bool strip_ext = true;
@@ -223,7 +226,7 @@ void ami_file_save_req(int type, struct gui_window_2 *gwin,
}
if(initial_fname != NULL) {
- fname_with_ext = AllocVecTagList(strlen(initial_fname) + 5, NULL); /* 5 = .ext\0 */
+ fname_with_ext = malloc(strlen(initial_fname) + 5); /* 5 = .ext\0 */
strcpy(fname_with_ext, initial_fname);
@@ -260,8 +263,8 @@ void ami_file_save_req(int type, struct gui_window_2 *gwin,
ami_file_save(type, fname, gwin->win, object, gwin->gw->favicon, gwin->gw->bw);
}
- if(fname) FreeVec(fname);
- if(fname_with_ext) FreeVec(fname_with_ext);
+ if(fname) free(fname);
+ if(fname_with_ext) free(fname_with_ext);
}
void ami_file_req_init(void)
diff --git a/frontends/amiga/file.h b/frontends/amiga/file.h
index 29a76c4..9120fff 100644
--- a/frontends/amiga/file.h
+++ b/frontends/amiga/file.h
@@ -21,8 +21,8 @@ struct hlcache_object;
struct selection;
struct gui_window_2;
-struct FileRequester *filereq;
-struct FileRequester *savereq;
+extern struct FileRequester *filereq;
+extern struct FileRequester *savereq;
enum {
AMINS_SAVE_SOURCE,
diff --git a/frontends/amiga/filetype.c b/frontends/amiga/filetype.c
index 61e4929..a0449d8 100644
--- a/frontends/amiga/filetype.c
+++ b/frontends/amiga/filetype.c
@@ -31,7 +31,6 @@
#include "utils/utils.h"
#include "amiga/filetype.h"
-#include "amiga/misc.h"
#include "amiga/object.h"
/**
@@ -217,7 +216,7 @@ nserror ami_mime_init(const char *mimefile)
{
if ((node = AddObject(ami_mime_list, AMINS_MIME))) {
ObjectCallback(node, ami_mime_entry_free);
- mimeentry = ami_misc_allocvec_clear(sizeof(struct ami_mime_entry), 0);
+ mimeentry = calloc(1, sizeof(struct ami_mime_entry));
node->objstruct = mimeentry;
if(rarray[AMI_MIME_MIMETYPE])
@@ -361,7 +360,7 @@ static APTR ami_mime_guess_add_datatype(struct DataType *dt, lwc_string **lwc_mi
node = AddObject(ami_mime_list, AMINS_MIME);
if(node == NULL) return NULL;
- mimeentry = ami_misc_allocvec_clear(sizeof(struct ami_mime_entry), 0);
+ mimeentry = calloc(1, sizeof(struct ami_mime_entry));
if(mimeentry == NULL) return NULL;
node->objstruct = mimeentry;
diff --git a/frontends/amiga/font.c b/frontends/amiga/font.c
index d3b9c32..22a0f4a 100644
--- a/frontends/amiga/font.c
+++ b/frontends/amiga/font.c
@@ -115,6 +115,8 @@ void ami_font_fini(void)
{
if(nsoption_bool(bitmap_fonts) == false) {
ami_font_bullet_fini();
+ } else {
+ ami_font_diskfont_fini();
}
}
diff --git a/frontends/amiga/font_bullet.c b/frontends/amiga/font_bullet.c
index 48e49f3..fd41c29 100644
--- a/frontends/amiga/font_bullet.c
+++ b/frontends/amiga/font_bullet.c
@@ -41,6 +41,7 @@
#include "utils/utf8.h"
#include "utils/utils.h"
+#include "amiga/memory.h"
#include "amiga/misc.h"
#include "amiga/font.h"
#include "amiga/font_bullet.h"
@@ -362,7 +363,7 @@ static struct ami_font_cache_node *ami_font_open(const char *font, bool critical
{
LOG("Requested font not found: %s", font);
if(critical == true) amiga_warn_user("CompError", font);
- FreeVec(nodedata);
+ free(nodedata);
return NULL;
}
@@ -600,7 +601,7 @@ static inline int32 ami_font_plot_glyph(struct OutlineFont *ofont, struct RastPo
TAG_DONE);
#else
/* On OS3 the glyph needs to be in chip RAM */
- void *chip_glyph = AllocVec(glyph->glm_BMModulo * glyph->glm_BMRows, MEMF_CHIP);
+ void *chip_glyph = ami_memory_chip_alloc(glyph->glm_BMModulo * glyph->glm_BMRows);
if(chip_glyph != NULL) {
CopyMem(glyphbm, chip_glyph, glyph->glm_BMModulo * glyph->glm_BMRows);
@@ -611,7 +612,7 @@ static inline int32 ami_font_plot_glyph(struct OutlineFont *ofont, struct RastPo
y - glyph->glm_Y0 + glyph->glm_BlackTop,
glyph->glm_BlackWidth, glyph->glm_BlackHeight);
- FreeVec(chip_glyph);
+ ami_memory_chip_free(chip_glyph);
}
#endif
}
diff --git a/frontends/amiga/font_cache.c b/frontends/amiga/font_cache.c
index 08c2fe1..3d83309 100644
--- a/frontends/amiga/font_cache.c
+++ b/frontends/amiga/font_cache.c
@@ -158,7 +158,7 @@ struct ami_font_cache_node *ami_font_cache_alloc_entry(const char *font)
uint32 hash = XXH32(font, strlen(font), 0);
nodedata = (struct ami_font_cache_node *)InsertSkipNode(ami_font_cache_list, (APTR)hash, sizeof(struct ami_font_cache_node));
#else
- nodedata = AllocVecTagList(sizeof(struct ami_font_cache_node), NULL);
+ nodedata = malloc(sizeof(struct ami_font_cache_node));
#endif
GetSysTime(&nodedata->lastused);
diff --git a/frontends/amiga/font_diskfont.c b/frontends/amiga/font_diskfont.c
index 313e992..8593f81 100644
--- a/frontends/amiga/font_diskfont.c
+++ b/frontends/amiga/font_diskfont.c
@@ -39,6 +39,9 @@
#define MAX_FONT_NAME_SIZE 33
+static plot_font_style_t *prev_fstyle = NULL;
+static struct TextFont *prev_font = NULL;
+
static struct TextFont *ami_font_bm_open(struct RastPort *rp, const plot_font_style_t *fstyle)
{
struct TextFont *bmfont = NULL;
@@ -46,6 +49,15 @@ static struct TextFont *ami_font_bm_open(struct RastPort *rp, const plot_font_st
char *fontname;
char font[MAX_FONT_NAME_SIZE];
+ if((prev_fstyle != NULL) && (prev_font != NULL) &&
+ (fstyle->family == prev_fstyle->family) &&
+ (fstyle->size == prev_fstyle->size) &&
+ (fstyle->flags == prev_fstyle->flags) &&
+ (fstyle->weight == prev_fstyle->weight)) {
+ LOG("(using current font)");
+ return prev_font;
+ }
+
if(rp == NULL) return NULL;
tattr.ta_Flags = 0;
@@ -87,16 +99,19 @@ static struct TextFont *ami_font_bm_open(struct RastPort *rp, const plot_font_st
tattr.ta_Name = font;
tattr.ta_YSize = fstyle->size / FONT_SIZE_SCALE;
LOG("font: %s/%d", tattr.ta_Name, tattr.ta_YSize);
+
+ if(prev_font != NULL) CloseFont(prev_font);
+
if((bmfont = OpenDiskFont(&tattr))) {
SetRPAttrs(rp, RPTAG_Font, bmfont, TAG_DONE);
}
- return bmfont;
-}
+ if(prev_fstyle != NULL) {
+ memcpy(prev_fstyle, fstyle, sizeof(plot_font_style_t));
+ prev_font = bmfont;
+ }
-static void ami_font_bm_close(struct TextFont *bmfont)
-{
- CloseFont(bmfont);
+ return bmfont;
}
static size_t ami_font_bm_convert_local_to_utf8_offset(const char *utf8string, size_t length, UWORD offset)
@@ -125,15 +140,12 @@ static nserror amiga_bm_nsfont_width(const plot_font_style_t *fstyle,
if(bmfont == NULL) return NSERROR_INVALID;
if(utf8_to_local_encoding(string, length, &localtext) != NSERROR_OK) {
- ami_font_bm_close(bmfont);
return NSERROR_INVALID;
}
*width = TextLength(glob->rp, localtext, (UWORD)strlen(localtext));
free(localtext);
- ami_font_bm_close(bmfont);
-
return NSERROR_OK;
}
@@ -164,7 +176,6 @@ static nserror amiga_bm_nsfont_position_in_string(const plot_font_style_t *fstyl
if(bmfont == NULL) return NSERROR_INVALID;
if(utf8_to_local_encoding(string, length, &localtext) != NSERROR_OK) {
- ami_font_bm_close(bmfont);
return NSERROR_INVALID;
}
@@ -174,7 +185,6 @@ static nserror amiga_bm_nsfont_position_in_string(const plot_font_style_t *fstyl
*actual_x = extent.te_Extent.MaxX;
free(localtext);
- ami_font_bm_close(bmfont);
return NSERROR_OK;
}
@@ -218,7 +228,6 @@ static nserror amiga_bm_nsfont_split(const plot_font_style_t *fstyle,
if(bmfont == NULL) return NSERROR_INVALID;
if(utf8_to_local_encoding(string, length, &localtext) != NSERROR_OK) {
- ami_font_bm_close(bmfont);
return NSERROR_INVALID;
}
@@ -252,7 +261,6 @@ static nserror amiga_bm_nsfont_split(const plot_font_style_t *fstyle,
}
free(localtext);
- ami_font_bm_close(bmfont);
return NSERROR_OK;
}
@@ -273,8 +281,6 @@ static ULONG amiga_bm_nsfont_text(struct RastPort *rp, const char *string, ULONG
free(localtext);
}
- ami_font_bm_close(bmfont);
-
return 0;
}
@@ -289,5 +295,14 @@ void ami_font_diskfont_init(void)
{
/* Set up table */
ami_nsfont = &ami_font_diskfont_table;
+
+ /* Alloc space to hold currently open font - doesn't matter if this fails */
+ prev_fstyle = calloc(1, sizeof(plot_font_style_t));
+}
+
+void ami_font_diskfont_fini(void)
+{
+ if(prev_font != NULL) CloseFont(prev_font);
+ if(prev_fstyle != NULL) free(prev_fstyle);
}
diff --git a/frontends/amiga/font_diskfont.h b/frontends/amiga/font_diskfont.h
index de19e94..1c891d2 100644
--- a/frontends/amiga/font_diskfont.h
+++ b/frontends/amiga/font_diskfont.h
@@ -19,5 +19,6 @@
#ifndef AMIGA_FONT_DISKFONT_H
#define AMIGA_FONT_DISKFONT_H
void ami_font_diskfont_init(void);
+void ami_font_diskfont_fini(void);
#endif
diff --git a/frontends/amiga/font_scan.c b/frontends/amiga/font_scan.c
index c1c1732..932179e 100644
--- a/frontends/amiga/font_scan.c
+++ b/frontends/amiga/font_scan.c
@@ -99,7 +99,7 @@ const char *ami_font_scan_lookup(const uint16 *code, lwc_string **glypharray)
static struct ami_font_scan_window *ami_font_scan_gui_open(int32 fonts)
{
struct ami_font_scan_window *fsw =
- AllocVecTagList(sizeof(struct ami_font_scan_window), NULL);
+ malloc(sizeof(struct ami_font_scan_window));
if(fsw == NULL) return NULL;
@@ -201,7 +201,7 @@ static void ami_font_scan_gui_close(struct ami_font_scan_window *fsw)
if(fsw) {
DisposeObject(fsw->objects[FS_OID_MAIN]);
ami_utf8_free(fsw->title);
- FreeVec(fsw);
+ free(fsw);
}
}
@@ -317,10 +317,10 @@ static ULONG ami_font_scan_list(struct MinList *list)
struct nsObject *node;
do {
- if((afh = (struct AvailFontsHeader *)AllocVecTagList(afSize, NULL))) {
+ if((afh = (struct AvailFontsHeader *)malloc(afSize))) {
if(((afShortage = AvailFonts((STRPTR)afh, afSize,
AFF_DISK | AFF_OTAG | AFF_SCALED)))) {
- FreeVec(afh);
+ free(afh);
afSize += afShortage;
}
} else {
@@ -350,7 +350,7 @@ static ULONG ami_font_scan_list(struct MinList *list)
}
}
}
- FreeVec(afh);
+ free(afh);
} else {
return 0;
}
diff --git a/frontends/amiga/gui.c b/frontends/amiga/gui.c
index 459e768..b2a489e 100644
--- a/frontends/amiga/gui.c
+++ b/frontends/amiga/gui.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2015 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
+ * Copyright 2008-2016 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -116,7 +116,6 @@
#include "desktop/save_complete.h"
#include "desktop/scrollbar.h"
#include "desktop/searchweb.h"
-#include "desktop/tree.h"
/* NetSurf Amiga platform includes */
#include "amiga/gui.h"
@@ -140,6 +139,7 @@
#include "amiga/launch.h"
#include "amiga/libs.h"
#include "amiga/login.h"
+#include "amiga/memory.h"
#include "amiga/menu.h"
#include "amiga/misc.h"
#include "amiga/nsoption.h"
@@ -150,7 +150,6 @@
#include "amiga/search.h"
#include "amiga/selectmenu.h"
#include "amiga/theme.h"
-#include "amiga/tree.h"
#include "amiga/utf8.h"
#include "amiga/sslcert.h"
@@ -216,7 +215,6 @@ static bool cli_force = false;
#define USERS_DIR "PROGDIR:Users"
static char *users_dir = NULL;
-static char *current_user = NULL;
static char *current_user_dir;
static char *current_user_faviconcache;
@@ -244,7 +242,7 @@ static bool gui_window_get_scroll(struct gui_window *g, int *restrict sx, int *r
static void gui_window_set_scroll(struct gui_window *g, int sx, int sy);
static void gui_window_remove_caret(struct gui_window *g);
static void gui_window_place_caret(struct gui_window *g, int x, int y, int height, const struct rect *clip);
-
+static void gui_window_update_box(struct gui_window *g, const struct rect *restrict rect);
/* accessors for default options - user option is updated if it is set as per default */
@@ -284,6 +282,7 @@ STRPTR ami_locale_langs(int *codeset)
acceptlangs = ASPrintf("%s", remapped);
}
}
+ if(remapped != NULL) free(remapped);
}
else
{
@@ -353,8 +352,7 @@ static bool ami_gui_check_resource(char *fullpath, const char *file)
netsurf_mkpath(&fullpath, &fullpath_len, 2, fullpath, remapped);
lock = Lock(fullpath, ACCESS_READ);
- if(lock)
- {
+ if(lock) {
UnLock(lock);
found = true;
}
@@ -370,7 +368,7 @@ bool ami_locate_resource(char *fullpath, const char *file)
struct Locale *locale;
int i;
bool found = false;
- char *remapped;
+ char *remapped = NULL;
size_t fullpath_len = 1024;
/* Check NetSurf user data area first */
@@ -396,11 +394,12 @@ bool ami_locate_resource(char *fullpath, const char *file)
strcpy(fullpath, "PROGDIR:Resources/");
if(locale->loc_PrefLanguages[i]) {
- ami_gui_map_filename(&remapped, "PROGDIR:Resources",
- locale->loc_PrefLanguages[i], "LangNames");
- netsurf_mkpath(&fullpath, &fullpath_len, 2, fullpath, remapped);
-
- found = ami_gui_check_resource(fullpath, file);
+ if(ami_gui_map_filename(&remapped, "PROGDIR:Resources",
+ locale->loc_PrefLanguages[i], "LangNames") == true) {
+ netsurf_mkpath(&fullpath, &fullpath_len, 2, fullpath, remapped);
+ found = ami_gui_check_resource(fullpath, file);
+ free(remapped);
+ }
} else {
continue;
}
@@ -428,7 +427,17 @@ bool ami_locate_resource(char *fullpath, const char *file)
return found;
}
-static bool ami_open_resources(void)
+static void ami_gui_resources_free(void)
+{
+ ami_schedule_free();
+ ami_object_fini();
+
+ FreeSysObject(ASOT_PORT, appport);
+ FreeSysObject(ASOT_PORT, sport);
+ FreeSysObject(ASOT_PORT, schedulermsgport);
+}
+
+static bool ami_gui_resources_open(void)
{
urlStringClass = MakeStringClass();
@@ -444,6 +453,13 @@ static bool ami_open_resources(void)
ASO_NoTrack, FALSE,
TAG_DONE))) return false;
+ if(ami_schedule_create(schedulermsgport) != NSERROR_OK) {
+ ami_misc_fatal_error("Failed to initialise scheduler");
+ return false;
+ }
+
+ ami_object_init();
+
return true;
}
@@ -518,6 +534,28 @@ STRPTR ami_gui_get_screen_title(void)
static void ami_set_screen_defaults(struct Screen *screen)
{
+ /* various window size/position defaults */
+ int width = screen->Width / 2;
+ int height = screen->Height / 2;
+ int top = (screen->Height / 2) - (height / 2);
+ int left = (screen->Width / 2) - (width / 2);
+
+ nsoption_default_set_int(cookies_window_ypos, top);
+ nsoption_default_set_int(cookies_window_xpos, left);
+ nsoption_default_set_int(cookies_window_xsize, width);
+ nsoption_default_set_int(cookies_window_ysize, height);
+
+ nsoption_default_set_int(history_window_ypos, top);
+ nsoption_default_set_int(history_window_xpos, left);
+ nsoption_default_set_int(history_window_xsize, width);
+ nsoption_default_set_int(history_window_ysize, height);
+
+ nsoption_default_set_int(hotlist_window_ypos, top);
+ nsoption_default_set_int(hotlist_window_xpos, left);
+ nsoption_default_set_int(hotlist_window_xsize, width);
+ nsoption_default_set_int(hotlist_window_ysize, height);
+
+
nsoption_default_set_int(window_x, 0);
nsoption_default_set_int(window_y, screen->BarHeight + 1);
nsoption_default_set_int(window_width, screen->Width);
@@ -598,6 +636,11 @@ static nserror ami_set_options(struct nsoption_s *defaults)
/* Some OS-specific overrides */
#ifdef __amigaos4__
+ if(!LIB_IS_AT_LEAST((struct Library *)SysBase, 53, 89)) {
+ /* Disable ExtMem usage pre-OS4.1FEU1 */
+ nsoption_set_bool(use_extmem, false);
+ }
+
if(codeset == 0) codeset = 4; /* ISO-8859-1 */
const char *encname = (const char *)ObtainCharsetInfo(DFCS_NUMBER, codeset,
DFCS_MIMENAME);
@@ -904,11 +947,12 @@ static struct RDArgs *ami_gui_commandline(int *restrict argc, char ** argv,
return NULL;
}
-static void ami_gui_read_tooltypes(struct WBArg *wbarg)
+static char *ami_gui_read_tooltypes(struct WBArg *wbarg)
{
struct DiskObject *dobj;
STRPTR *toolarray;
char *s;
+ char *current_user = NULL;
if((*wbarg->wa_Name) && (dobj = GetDiskObject(wbarg->wa_Name))) {
toolarray = (STRPTR *)dobj->do_ToolTypes;
@@ -918,13 +962,16 @@ static void ami_gui_read_tooltypes(struct WBArg *wbarg)
FreeDiskObject(dobj);
}
+ return current_user;
}
-static void ami_gui_read_all_tooltypes(int argc, char **argv)
+static STRPTR ami_gui_read_all_tooltypes(int argc, char **argv)
{
struct WBStartup *WBenchMsg;
struct WBArg *wbarg;
char i = 0;
+ char *current_user = NULL;
+ char *cur_user = NULL;
if(argc == 0) { /* Started from WB */
WBenchMsg = (struct WBStartup *)argv;
@@ -933,11 +980,17 @@ static void ami_gui_read_all_tooltypes(int argc, char **argv)
if((wbarg->wa_Lock) && (*wbarg->wa_Name))
olddir = SetCurrentDir(wbarg->wa_Lock);
- ami_gui_read_tooltypes(wbarg);
+ cur_user = ami_gui_read_tooltypes(wbarg);
+ if(cur_user != NULL) {
+ if(current_user != NULL) FreeVec(current_user);
+ current_user = cur_user;
+ }
if(olddir !=-1) SetCurrentDir(olddir);
}
}
+
+ return current_user;
}
void ami_gui_set_default_gg(void)
@@ -969,9 +1022,7 @@ static void gui_init2(int argc, char** argv)
}
/**/
- ami_hotlist_initialise(nsoption_charp(hotlist_file));
- ami_cookies_initialise();
- ami_global_history_initialise();
+ hotlist_init(nsoption_charp(hotlist_file));
search_web_select_provider(nsoption_int(search_provider));
if (notalreadyrunning &&
@@ -1155,16 +1206,12 @@ static void ami_update_buttons(struct gui_window_2 *gwin)
if(!browser_window_reload_available(gwin->gw->bw))
reload=TRUE;
- if(nsoption_bool(kiosk_mode) == false)
- {
- if(gwin->tabs <= 1)
- {
+ if(nsoption_bool(kiosk_mode) == false) {
+ if(gwin->tabs <= 1) {
tabclose=TRUE;
- OffMenu(gwin->win,AMI_MENU_CLOSETAB);
- }
- else
- {
- OnMenu(gwin->win,AMI_MENU_CLOSETAB);
+ ami_gui_menu_set_disabled(gwin->win, gwin->imenu, M_CLOSETAB, true);
+ } else {
+ ami_gui_menu_set_disabled(gwin->win, gwin->imenu, M_CLOSETAB, false);
}
}
@@ -1310,8 +1357,9 @@ int ami_key_to_nskey(ULONG keycode, struct InputEvent *ie)
break;
default:
if((chars = MapRawKey(ie,buffer,20,NULL)) > 0) {
- utf8_from_local_encoding(buffer, chars, &utf8);
+ if(utf8_from_local_encoding(buffer, chars, &utf8) != NSERROR_OK) return 0;
nskey = utf8_to_ucs4(utf8, utf8_char_byte_length(utf8));
+ free(utf8);
if(ie->ie_Qualifier & IEQUALIFIER_RCOMMAND) {
switch(nskey) {
@@ -1342,27 +1390,34 @@ int ami_key_to_nskey(ULONG keycode, struct InputEvent *ie)
return nskey;
}
-static void ami_update_quals(struct gui_window_2 *gwin)
+int ami_gui_get_quals(Object *win_obj)
{
uint32 quals = 0;
+ int key_state = 0;
#ifdef __amigaos4__
- GetAttr(WINDOW_Qualifier,gwin->objects[OID_MAIN],(uint32 *)&quals);
+ GetAttr(WINDOW_Qualifier, win_obj, (uint32 *)&quals);
#else
#warning qualifier needs fixing for OS3
#endif
- gwin->key_state = 0;
if(quals & NSA_QUAL_SHIFT) {
- gwin->key_state |= BROWSER_MOUSE_MOD_1;
+ key_state |= BROWSER_MOUSE_MOD_1;
}
if(quals & IEQUALIFIER_CONTROL) {
- gwin->key_state |= BROWSER_MOUSE_MOD_2;
+ key_state |= BROWSER_MOUSE_MOD_2;
}
if(quals & NSA_QUAL_ALT) {
- gwin->key_state |= BROWSER_MOUSE_MOD_3;
+ key_state |= BROWSER_MOUSE_MOD_3;
}
+
+ return key_state;
+}
+
+static void ami_update_quals(struct gui_window_2 *gwin)
+{
+ gwin->key_state = ami_gui_get_quals(gwin->objects[OID_MAIN]);
}
/* exported interface documented in amiga/gui.h */
@@ -1370,7 +1425,7 @@ nserror ami_gui_get_space_box(Object *obj, struct IBox **bbox)
{
#ifdef __amigaos4__
if(LIB_IS_AT_LEAST((struct Library *)SpaceBase, 53, 6)) {
- *bbox = AllocVecTagList(sizeof(struct IBox), NULL);
+ *bbox = malloc(sizeof(struct IBox));
if(*bbox == NULL) return NSERROR_NOMEM;
GetAttr(SPACE_RenderBox, obj, (ULONG *)*bbox);
} else
@@ -1387,7 +1442,7 @@ void ami_gui_free_space_box(struct IBox *bbox)
{
#ifdef __amigaos4__
if(LIB_IS_AT_LEAST((struct Library *)SpaceBase, 53, 6)) {
- FreeVec(bbox);
+ free(bbox);
}
#endif
}
@@ -1515,7 +1570,7 @@ static struct IBox *ami_ns_rect_to_ibox(struct gui_window_2 *gwin, const struct
{
struct IBox *bbox, *ibox;
- ibox = AllocVecTagList(sizeof(struct IBox), NULL);
+ ibox = malloc(sizeof(struct IBox));
if(ibox == NULL) return NULL;
if(ami_gui_get_space_box((Object *)gwin->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
@@ -1536,7 +1591,7 @@ static struct IBox *ami_ns_rect_to_ibox(struct gui_window_2 *gwin, const struct
(ibox->Top > (bbox->Top + bbox->Height)) ||
(ibox->Width < 0) || (ibox->Height < 0))
{
- FreeVec(ibox);
+ free(ibox);
ami_gui_free_space_box(bbox);
return NULL;
}
@@ -1582,7 +1637,7 @@ static void ami_gui_menu_update_all(void)
if(node->Type == AMINS_WINDOW)
{
- ami_menu_update_checked(gwin);
+ ami_gui_menu_update_checked(gwin);
}
} while((node = nnode));
}
@@ -1648,7 +1703,7 @@ static bool ami_gui_hscroll_remove(struct gui_window_2 *gwin)
IDoMethod(gwin->objects[GID_HSCROLLLAYOUT], LM_REMOVECHILD,
gwin->win, gwin->objects[GID_HSCROLL]);
#else
- SetAttrs(gwin->objects[GID_HSCROLLLAYOUT], LAYOUT_RemoveChild, gwin->objects[GID_HSCROLL]);
+ SetAttrs(gwin->objects[GID_HSCROLLLAYOUT], LAYOUT_RemoveChild, gwin->objects[GID_HSCROLL], TAG_DONE);
#endif
gwin->objects[GID_HSCROLL] = NULL;
@@ -1693,7 +1748,7 @@ static bool ami_gui_vscroll_remove(struct gui_window_2 *gwin)
IDoMethod(gwin->objects[GID_VSCROLLLAYOUT], LM_REMOVECHILD,
gwin->win, gwin->objects[GID_VSCROLL]);
#else
- SetAttrs(gwin->objects[GID_VSCROLLLAYOUT], LAYOUT_RemoveChild, gwin->objects[GID_VSCROLL]);
+ SetAttrs(gwin->objects[GID_VSCROLLLAYOUT], LAYOUT_RemoveChild, gwin->objects[GID_VSCROLL], TAG_DONE);
#endif
gwin->objects[GID_VSCROLL] = NULL;
@@ -1874,679 +1929,642 @@ static void ami_set_border_gadget_size(struct gui_window_2 *gwin)
#endif
}
-static void ami_handle_msg(void)
+static BOOL ami_handle_msg(void)
{
- ULONG result,storage = 0,x,y,xs,ys,width=800,height=600;
- uint16 code;
- struct IBox *bbox;
+ struct ami_generic_window *w = NULL;
struct nsObject *node;
struct nsObject *nnode;
- struct gui_window_2 *gwin = NULL;
- struct InputEvent *ie;
- struct Node *tabnode;
- int nskey;
- struct timeval curtime;
- static int drag_x_move = 0, drag_y_move = 0;
- char *utf8 = NULL;
- nsurl *url;
+ BOOL win_closed = FALSE;
- if(IsMinListEmpty(window_list))
- {
+ if(IsMinListEmpty(window_list)) {
/* no windows in list, so NetSurf should not be running */
ami_try_quit();
- return;
+ return FALSE;
}
node = (struct nsObject *)GetHead((struct List *)window_list);
- do
- {
+ do {
nnode=(struct nsObject *)GetSucc((struct Node *)node);
- gwin = node->objstruct;
+ w = node->objstruct;
+ if(w == NULL) continue;
- if(node->Type == AMINS_TVWINDOW) {
- if(ami_tree_event((struct treeview_window *)gwin)) {
- ami_try_quit();
- break;
- } else {
- node = nnode;
- continue;
- }
- } else if(node->Type == AMINS_FINDWINDOW) {
- if(ami_search_event()) {
- ami_try_quit();
- break;
- } else {
- node = nnode;
- continue;
- }
- } else if(node->Type == AMINS_HISTORYWINDOW) {
- if(ami_history_event((struct history_window *)gwin)) {
- ami_try_quit();
- break;
- } else {
- node = nnode;
- continue;
- }
- } else if(node->Type == AMINS_PRINTWINDOW) {
- if(ami_print_event((struct ami_print_window *)gwin)) {
- ami_try_quit();
- break;
- } else {
- node = nnode;
- continue;
- }
- } else if(node->Type == AMINS_GUIOPTSWINDOW) {
- if(ami_gui_opts_event()) {
- /* last window possibly closed, so exit with conditions ;) */
- if(scrn) ami_try_quit();
- break;
- } else {
- node = nnode;
- continue;
- }
- } else if(node->Type == AMINS_DLWINDOW) {
- if(ami_download_window_event((struct gui_download_window *)gwin)) {
- ami_try_quit();
- break;
- } else {
- node = nnode;
- continue;
- }
- } else if(node->Type == AMINS_LOGINWINDOW) {
- if(ami_401login_event((struct gui_login_window *)gwin)) {
- ami_try_quit();
- break;
+ if(w->tbl->event != NULL) {
+ if((win_closed = w->tbl->event(w))) {
+ if((node->Type != AMINS_GUIOPTSWINDOW) ||
+ ((node->Type == AMINS_GUIOPTSWINDOW) && (scrn != NULL))) {
+ ami_try_quit();
+ break;
+ }
} else {
node = nnode;
continue;
}
}
+ } while((node = nnode));
- if((gwin == NULL) || (gwin->objects[OID_MAIN] == NULL)) continue;
+ if(ami_gui_menu_quit_selected() == true) {
+ ami_quit_netsurf();
+ }
+
+ if(ami_gui_menu_get_check_toggled() == true) {
+ ami_gui_menu_update_all();
+ }
- while((result = RA_HandleInput(gwin->objects[OID_MAIN], &code)) != WMHI_LASTMSG) {
- switch(result & WMHI_CLASSMASK) // class
- {
- case WMHI_MOUSEMOVE:
- ami_gui_trap_mouse(gwin); /* re-assert mouse area */
+ return win_closed;
+}
- drag_x_move = 0;
- drag_y_move = 0;
+static BOOL ami_gui_event(void *w)
+{
+ struct gui_window_2 *gwin = (struct gui_window_2 *)w;
+ ULONG result, storage = 0, x, y, xs, ys, width = 800, height = 600;
+ uint16 code;
+ struct IBox *bbox;
+ struct InputEvent *ie;
+ struct Node *tabnode;
+ int nskey;
+ struct timeval curtime;
+ static int drag_x_move = 0, drag_y_move = 0;
+ char *utf8 = NULL;
+ nsurl *url;
+ BOOL win_closed = FALSE;
- if(ami_gui_get_space_box((Object *)gwin->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
- amiga_warn_user("NoMemory", "");
- break;
- }
+ while((result = RA_HandleInput(gwin->objects[OID_MAIN], &code)) != WMHI_LASTMSG) {
+ switch(result & WMHI_CLASSMASK) // class
+ {
+ case WMHI_MOUSEMOVE:
+ ami_gui_trap_mouse(gwin); /* re-assert mouse area */
- x = (ULONG)((gwin->win->MouseX - bbox->Left) / gwin->gw->scale);
- y = (ULONG)((gwin->win->MouseY - bbox->Top) / gwin->gw->scale);
+ drag_x_move = 0;
+ drag_y_move = 0;
- ami_get_hscroll_pos(gwin, (ULONG *)&xs);
- ami_get_vscroll_pos(gwin, (ULONG *)&ys);
+ if(ami_gui_get_space_box((Object *)gwin->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
+ amiga_warn_user("NoMemory", "");
+ break;
+ }
- x += xs;
- y += ys;
+ x = (ULONG)((gwin->win->MouseX - bbox->Left) / gwin->gw->scale);
+ y = (ULONG)((gwin->win->MouseY - bbox->Top) / gwin->gw->scale);
- width=bbox->Width;
- height=bbox->Height;
+ ami_get_hscroll_pos(gwin, (ULONG *)&xs);
+ ami_get_vscroll_pos(gwin, (ULONG *)&ys);
- if(gwin->mouse_state & BROWSER_MOUSE_DRAG_ON)
- {
- if(ami_drag_icon_move() == TRUE) {
- if((gwin->win->MouseX < bbox->Left) &&
- ((gwin->win->MouseX - bbox->Left) > -AMI_DRAG_THRESHOLD))
- drag_x_move = gwin->win->MouseX - bbox->Left;
- if((gwin->win->MouseX > (bbox->Left + bbox->Width)) &&
- ((gwin->win->MouseX - (bbox->Left + bbox->Width)) < AMI_DRAG_THRESHOLD))
- drag_x_move = gwin->win->MouseX - (bbox->Left + bbox->Width);
- if((gwin->win->MouseY < bbox->Top) &&
- ((gwin->win->MouseY - bbox->Top) > -AMI_DRAG_THRESHOLD))
- drag_y_move = gwin->win->MouseY - bbox->Top;
- if((gwin->win->MouseY > (bbox->Top + bbox->Height)) &&
- ((gwin->win->MouseY - (bbox->Top + bbox->Height)) < AMI_DRAG_THRESHOLD))
- drag_y_move = gwin->win->MouseY - (bbox->Top + bbox->Height);
- }
+ x += xs;
+ y += ys;
+
+ width=bbox->Width;
+ height=bbox->Height;
+
+ if(gwin->mouse_state & BROWSER_MOUSE_DRAG_ON)
+ {
+ if(ami_drag_icon_move() == TRUE) {
+ if((gwin->win->MouseX < bbox->Left) &&
+ ((gwin->win->MouseX - bbox->Left) > -AMI_DRAG_THRESHOLD))
+ drag_x_move = gwin->win->MouseX - bbox->Left;
+ if((gwin->win->MouseX > (bbox->Left + bbox->Width)) &&
+ ((gwin->win->MouseX - (bbox->Left + bbox->Width)) < AMI_DRAG_THRESHOLD))
+ drag_x_move = gwin->win->MouseX - (bbox->Left + bbox->Width);
+ if((gwin->win->MouseY < bbox->Top) &&
+ ((gwin->win->MouseY - bbox->Top) > -AMI_DRAG_THRESHOLD))
+ drag_y_move = gwin->win->MouseY - bbox->Top;
+ if((gwin->win->MouseY > (bbox->Top + bbox->Height)) &&
+ ((gwin->win->MouseY - (bbox->Top + bbox->Height)) < AMI_DRAG_THRESHOLD))
+ drag_y_move = gwin->win->MouseY - (bbox->Top + bbox->Height);
}
+ }
- ami_gui_free_space_box(bbox);
+ ami_gui_free_space_box(bbox);
- if((x>=xs) && (y>=ys) && (x<width+xs) && (y<height+ys))
- {
- ami_update_quals(gwin);
+ if((x>=xs) && (y>=ys) && (x<width+xs) && (y<height+ys))
+ {
+ ami_update_quals(gwin);
- if(gwin->mouse_state & BROWSER_MOUSE_PRESS_1)
- {
- browser_window_mouse_track(gwin->gw->bw,BROWSER_MOUSE_DRAG_1 | gwin->key_state,x,y);
- gwin->mouse_state = BROWSER_MOUSE_HOLDING_1 | BROWSER_MOUSE_DRAG_ON;
- }
- else if(gwin->mouse_state & BROWSER_MOUSE_PRESS_2)
- {
- browser_window_mouse_track(gwin->gw->bw,BROWSER_MOUSE_DRAG_2 | gwin->key_state,x,y);
- gwin->mouse_state = BROWSER_MOUSE_HOLDING_2 | BROWSER_MOUSE_DRAG_ON;
- }
- else
- {
- browser_window_mouse_track(gwin->gw->bw,gwin->mouse_state | gwin->key_state,x,y);
- }
- } else {
- if(!gwin->mouse_state) ami_set_pointer(gwin, GUI_POINTER_DEFAULT, true);
+ if(gwin->mouse_state & BROWSER_MOUSE_PRESS_1)
+ {
+ browser_window_mouse_track(gwin->gw->bw,BROWSER_MOUSE_DRAG_1 | gwin->key_state,x,y);
+ gwin->mouse_state = BROWSER_MOUSE_HOLDING_1 | BROWSER_MOUSE_DRAG_ON;
}
- break;
-
- case WMHI_MOUSEBUTTONS:
- if(ami_gui_get_space_box((Object *)gwin->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
- amiga_warn_user("NoMemory", "");
- return;
+ else if(gwin->mouse_state & BROWSER_MOUSE_PRESS_2)
+ {
+ browser_window_mouse_track(gwin->gw->bw,BROWSER_MOUSE_DRAG_2 | gwin->key_state,x,y);
+ gwin->mouse_state = BROWSER_MOUSE_HOLDING_2 | BROWSER_MOUSE_DRAG_ON;
+ }
+ else
+ {
+ browser_window_mouse_track(gwin->gw->bw,gwin->mouse_state | gwin->key_state,x,y);
}
+ } else {
+ if(!gwin->mouse_state) ami_set_pointer(gwin, GUI_POINTER_DEFAULT, true);
+ }
+ break;
- x = (ULONG)((gwin->win->MouseX - bbox->Left) / gwin->gw->scale);
- y = (ULONG)((gwin->win->MouseY - bbox->Top) / gwin->gw->scale);
+ case WMHI_MOUSEBUTTONS:
+ if(ami_gui_get_space_box((Object *)gwin->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
+ amiga_warn_user("NoMemory", "");
+ return FALSE;
+ }
- ami_get_hscroll_pos(gwin, (ULONG *)&xs);
- ami_get_vscroll_pos(gwin, (ULONG *)&ys);
+ x = (ULONG)((gwin->win->MouseX - bbox->Left) / gwin->gw->scale);
+ y = (ULONG)((gwin->win->MouseY - bbox->Top) / gwin->gw->scale);
- x += xs;
- y += ys;
+ ami_get_hscroll_pos(gwin, (ULONG *)&xs);
+ ami_get_vscroll_pos(gwin, (ULONG *)&ys);
- width=bbox->Width;
- height=bbox->Height;
+ x += xs;
+ y += ys;
- ami_gui_free_space_box(bbox);
+ width=bbox->Width;
+ height=bbox->Height;
- ami_update_quals(gwin);
+ ami_gui_free_space_box(bbox);
+
+ ami_update_quals(gwin);
- if((x>=xs) && (y>=ys) && (x<width+xs) && (y<height+ys))
+ if((x>=xs) && (y>=ys) && (x<width+xs) && (y<height+ys))
+ {
+ //code = code>>16;
+ switch(code)
{
- //code = code>>16;
- switch(code)
- {
- case SELECTDOWN:
- browser_window_mouse_click(gwin->gw->bw,BROWSER_MOUSE_PRESS_1 | gwin->key_state,x,y);
- gwin->mouse_state=BROWSER_MOUSE_PRESS_1;
- break;
- case MIDDLEDOWN:
- browser_window_mouse_click(gwin->gw->bw,BROWSER_MOUSE_PRESS_2 | gwin->key_state,x,y);
- gwin->mouse_state=BROWSER_MOUSE_PRESS_2;
- break;
- }
+ case SELECTDOWN:
+ browser_window_mouse_click(gwin->gw->bw,BROWSER_MOUSE_PRESS_1 | gwin->key_state,x,y);
+ gwin->mouse_state=BROWSER_MOUSE_PRESS_1;
+ break;
+ case MIDDLEDOWN:
+ browser_window_mouse_click(gwin->gw->bw,BROWSER_MOUSE_PRESS_2 | gwin->key_state,x,y);
+ gwin->mouse_state=BROWSER_MOUSE_PRESS_2;
+ break;
}
+ }
- if(x<xs) x=xs;
- if(y<ys) y=ys;
- if(x>=width+xs) x=width+xs-1;
- if(y>=height+ys) y=height+ys-1;
+ if(x<xs) x=xs;
+ if(y<ys) y=ys;
+ if(x>=width+xs) x=width+xs-1;
+ if(y>=height+ys) y=height+ys-1;
- switch(code)
- {
- case SELECTUP:
- if(gwin->mouse_state & BROWSER_MOUSE_PRESS_1)
- {
- CurrentTime((ULONG *)&curtime.tv_sec, (ULONG *)&curtime.tv_usec);
+ switch(code)
+ {
+ case SELECTUP:
+ if(gwin->mouse_state & BROWSER_MOUSE_PRESS_1)
+ {
+ CurrentTime((ULONG *)&curtime.tv_sec, (ULONG *)&curtime.tv_usec);
- gwin->mouse_state = BROWSER_MOUSE_CLICK_1;
+ gwin->mouse_state = BROWSER_MOUSE_CLICK_1;
- if(gwin->lastclick.tv_sec)
- {
- if(DoubleClick(gwin->lastclick.tv_sec,
- gwin->lastclick.tv_usec,
- curtime.tv_sec, curtime.tv_usec)) {
- if(gwin->prev_mouse_state & BROWSER_MOUSE_DOUBLE_CLICK) {
- gwin->mouse_state |= BROWSER_MOUSE_TRIPLE_CLICK;
- } else {
- gwin->mouse_state |= BROWSER_MOUSE_DOUBLE_CLICK;
- }
+ if(gwin->lastclick.tv_sec)
+ {
+ if(DoubleClick(gwin->lastclick.tv_sec,
+ gwin->lastclick.tv_usec,
+ curtime.tv_sec, curtime.tv_usec)) {
+ if(gwin->prev_mouse_state & BROWSER_MOUSE_DOUBLE_CLICK) {
+ gwin->mouse_state |= BROWSER_MOUSE_TRIPLE_CLICK;
+ } else {
+ gwin->mouse_state |= BROWSER_MOUSE_DOUBLE_CLICK;
}
}
+ }
- browser_window_mouse_click(gwin->gw->bw,
- gwin->mouse_state | gwin->key_state,x,y);
+ browser_window_mouse_click(gwin->gw->bw,
+ gwin->mouse_state | gwin->key_state,x,y);
- if(gwin->mouse_state & BROWSER_MOUSE_TRIPLE_CLICK)
- {
- gwin->lastclick.tv_sec = 0;
- gwin->lastclick.tv_usec = 0;
- }
- else
- {
- gwin->lastclick.tv_sec = curtime.tv_sec;
- gwin->lastclick.tv_usec = curtime.tv_usec;
- }
+ if(gwin->mouse_state & BROWSER_MOUSE_TRIPLE_CLICK)
+ {
+ gwin->lastclick.tv_sec = 0;
+ gwin->lastclick.tv_usec = 0;
}
else
{
- browser_window_mouse_track(gwin->gw->bw, 0, x, y);
+ gwin->lastclick.tv_sec = curtime.tv_sec;
+ gwin->lastclick.tv_usec = curtime.tv_usec;
}
- gwin->prev_mouse_state = gwin->mouse_state;
- gwin->mouse_state=0;
- break;
+ }
+ else
+ {
+ browser_window_mouse_track(gwin->gw->bw, 0, x, y);
+ }
+ gwin->prev_mouse_state = gwin->mouse_state;
+ gwin->mouse_state=0;
+ break;
- case MIDDLEUP:
- if(gwin->mouse_state & BROWSER_MOUSE_PRESS_2)
- {
- CurrentTime((ULONG *)&curtime.tv_sec, (ULONG *)&curtime.tv_usec);
+ case MIDDLEUP:
+ if(gwin->mouse_state & BROWSER_MOUSE_PRESS_2)
+ {
+ CurrentTime((ULONG *)&curtime.tv_sec, (ULONG *)&curtime.tv_usec);
- gwin->mouse_state = BROWSER_MOUSE_CLICK_2;
+ gwin->mouse_state = BROWSER_MOUSE_CLICK_2;
- if(gwin->lastclick.tv_sec)
- {
- if(DoubleClick(gwin->lastclick.tv_sec,
- gwin->lastclick.tv_usec,
- curtime.tv_sec, curtime.tv_usec)) {
- if(gwin->prev_mouse_state & BROWSER_MOUSE_DOUBLE_CLICK) {
- gwin->mouse_state |= BROWSER_MOUSE_TRIPLE_CLICK;
- } else {
- gwin->mouse_state |= BROWSER_MOUSE_DOUBLE_CLICK;
- }
+ if(gwin->lastclick.tv_sec)
+ {
+ if(DoubleClick(gwin->lastclick.tv_sec,
+ gwin->lastclick.tv_usec,
+ curtime.tv_sec, curtime.tv_usec)) {
+ if(gwin->prev_mouse_state & BROWSER_MOUSE_DOUBLE_CLICK) {
+ gwin->mouse_state |= BROWSER_MOUSE_TRIPLE_CLICK;
+ } else {
+ gwin->mouse_state |= BROWSER_MOUSE_DOUBLE_CLICK;
}
}
+ }
- browser_window_mouse_click(gwin->gw->bw,
- gwin->mouse_state | gwin->key_state,x,y);
+ browser_window_mouse_click(gwin->gw->bw,
+ gwin->mouse_state | gwin->key_state,x,y);
- if(gwin->mouse_state & BROWSER_MOUSE_TRIPLE_CLICK)
- {
- gwin->lastclick.tv_sec = 0;
- gwin->lastclick.tv_usec = 0;
- }
- else
- {
- gwin->lastclick.tv_sec = curtime.tv_sec;
- gwin->lastclick.tv_usec = curtime.tv_usec;
- }
+ if(gwin->mouse_state & BROWSER_MOUSE_TRIPLE_CLICK)
+ {
+ gwin->lastclick.tv_sec = 0;
+ gwin->lastclick.tv_usec = 0;
}
else
{
- browser_window_mouse_track(gwin->gw->bw, 0, x, y);
+ gwin->lastclick.tv_sec = curtime.tv_sec;
+ gwin->lastclick.tv_usec = curtime.tv_usec;
}
- gwin->prev_mouse_state = gwin->mouse_state;
- gwin->mouse_state=0;
- break;
+ }
+ else
+ {
+ browser_window_mouse_track(gwin->gw->bw, 0, x, y);
+ }
+ gwin->prev_mouse_state = gwin->mouse_state;
+ gwin->mouse_state=0;
+ break;
#ifdef __amigaos4__
- case SIDEUP:
- ami_gui_history(gwin, true);
- break;
+ case SIDEUP:
+ ami_gui_history(gwin, true);
+ break;
- case EXTRAUP:
- ami_gui_history(gwin, false);
- break;
+ case EXTRAUP:
+ ami_gui_history(gwin, false);
+ break;
#endif
+ }
+
+ if(ami_drag_has_data() && !gwin->mouse_state)
+ ami_drag_save(gwin->win);
+ break;
+
+ case WMHI_GADGETUP:
+ switch(result & WMHI_GADGETMASK)
+ {
+ case GID_TABS:
+ if(gwin->objects[GID_TABS] == NULL) break;
+ if(ClickTabBase->lib_Version >= 53) {
+ GetAttrs(gwin->objects[GID_TABS],
+ CLICKTAB_NodeClosed, &tabnode, TAG_DONE);
+ } else {
+ tabnode = NULL;
+ }
+
+ if(tabnode) {
+ struct gui_window *closedgw;
+
+ GetClickTabNodeAttrs(tabnode,
+ TNA_UserData, &closedgw,
+ TAG_DONE);
+
+ browser_window_destroy(closedgw->bw);
+ } else {
+ ami_switch_tab(gwin, true);
+ }
+ break;
+
+ case GID_CLOSETAB:
+ browser_window_destroy(gwin->gw->bw);
+ break;
+
+ case GID_ADDTAB:
+ ami_gui_new_blank_tab(gwin);
+ break;
+
+ case GID_URL:
+ {
+ nserror ret;
+ nsurl *url;
+ GetAttr(STRINGA_TextVal,
+ (Object *)gwin->objects[GID_URL],
+ (ULONG *)&storage);
+ utf8 = ami_to_utf8_easy((const char *)storage);
+
+ ret = search_web_omni(utf8, SEARCH_WEB_OMNI_NONE, &url);
+ ami_utf8_free(utf8);
+ if (ret == NSERROR_OK) {
+ browser_window_navigate(gwin->gw->bw,
+ url,
+ NULL,
+ BW_NAVIGATE_HISTORY,
+ NULL,
+ NULL,
+ NULL);
+ nsurl_unref(url);
+ }
+ if (ret != NSERROR_OK) {
+ amiga_warn_user(messages_get_errorcode(ret), 0);
+ }
}
+ break;
- if(ami_drag_has_data() && !gwin->mouse_state)
- ami_drag_save(gwin->win);
- break;
+ case GID_TOOLBARLAYOUT:
+ /* Need fixing: never gets here */
+ search_web_select_provider(-1);
+ break;
- case WMHI_GADGETUP:
- switch(result & WMHI_GADGETMASK)
+ case GID_SEARCH_ICON:
+ GetAttr(CHOOSER_Selected, gwin->objects[GID_SEARCH_ICON], (ULONG *)&storage);
+ search_web_select_provider(storage);
+ break;
+
+ case GID_SEARCHSTRING:
{
- case GID_TABS:
- if(gwin->objects[GID_TABS] == NULL) break;
- if(ClickTabBase->lib_Version >= 53) {
- GetAttrs(gwin->objects[GID_TABS],
- CLICKTAB_NodeClosed, &tabnode, TAG_DONE);
- } else {
- tabnode = NULL;
- }
+ nserror ret;
+ nsurl *url;
+
+ GetAttr(STRINGA_TextVal,
+ (Object *)gwin->objects[GID_SEARCHSTRING],
+ (ULONG *)&storage);
+
+ utf8 = ami_to_utf8_easy((const char *)storage);
- if(tabnode) {
- struct gui_window *closedgw;
+ ret = search_web_omni(utf8, SEARCH_WEB_OMNI_SEARCHONLY, &url);
+ ami_utf8_free(utf8);
+ if (ret == NSERROR_OK) {
+ browser_window_navigate(gwin->gw->bw,
+ url,
+ NULL,
+ BW_NAVIGATE_HISTORY,
+ NULL,
+ NULL,
+ NULL);
+ nsurl_unref(url);
+ }
+ if (ret != NSERROR_OK) {
+ amiga_warn_user(messages_get_errorcode(ret), 0);
+ }
- GetClickTabNodeAttrs(tabnode,
- TNA_UserData, &closedgw,
- TAG_DONE);
+ }
+ break;
- browser_window_destroy(closedgw->bw);
+ case GID_HOME:
+ {
+ if (nsurl_create(nsoption_charp(homepage_url), &url) != NSERROR_OK) {
+ amiga_warn_user("NoMemory", 0);
} else {
- ami_switch_tab(gwin, true);
+ browser_window_navigate(gwin->gw->bw,
+ url,
+ NULL,
+ BW_NAVIGATE_HISTORY,
+ NULL,
+ NULL,
+ NULL);
+ nsurl_unref(url);
}
- break;
+ }
+ break;
- case GID_CLOSETAB:
- browser_window_destroy(gwin->gw->bw);
- break;
+ case GID_STOP:
+ if(browser_window_stop_available(gwin->gw->bw))
+ browser_window_stop(gwin->gw->bw);
+ break;
- case GID_ADDTAB:
- ami_gui_new_blank_tab(gwin);
- break;
+ case GID_RELOAD:
+ ami_update_quals(gwin);
- case GID_URL:
+ if(browser_window_reload_available(gwin->gw->bw))
{
- nserror ret;
- nsurl *url;
- GetAttr(STRINGA_TextVal,
- (Object *)gwin->objects[GID_URL],
- (ULONG *)&storage);
- utf8 = ami_to_utf8_easy((const char *)storage);
-
- ret = search_web_omni(utf8, SEARCH_WEB_OMNI_NONE, &url);
- ami_utf8_free(utf8);
- if (ret == NSERROR_OK) {
- browser_window_navigate(gwin->gw->bw,
- url,
- NULL,
- BW_NAVIGATE_HISTORY,
- NULL,
- NULL,
- NULL);
- nsurl_unref(url);
+ if(gwin->key_state & BROWSER_MOUSE_MOD_1)
+ {
+ browser_window_reload(gwin->gw->bw, true);
}
- if (ret != NSERROR_OK) {
- amiga_warn_user(messages_get_errorcode(ret), 0);
+ else
+ {
+ browser_window_reload(gwin->gw->bw, false);
}
}
- break;
+ break;
- case GID_TOOLBARLAYOUT:
- /* Need fixing: never gets here */
- search_web_select_provider(-1);
- break;
+ case GID_BACK:
+ ami_gui_history(gwin, true);
+ break;
- case GID_SEARCH_ICON:
- GetAttr(CHOOSER_Selected, gwin->objects[GID_SEARCH_ICON], (ULONG *)&storage);
- search_web_select_provider(storage);
- break;
+ case GID_FORWARD:
+ ami_gui_history(gwin, false);
+ break;
- case GID_SEARCHSTRING:
- {
- nserror ret;
- nsurl *url;
+ case GID_FAVE:
+ GetAttr(STRINGA_TextVal,
+ (Object *)gwin->objects[GID_URL],
+ (ULONG *)&storage);
+ if(nsurl_create((const char *)storage, &url) == NSERROR_OK) {
+ if(hotlist_has_url(url)) {
+ hotlist_remove_url(url);
+ } else {
+ hotlist_add_url(url);
+ }
+ nsurl_unref(url);
+ }
+ ami_gui_update_hotlist_button(gwin);
+ break;
- GetAttr(STRINGA_TextVal,
- (Object *)gwin->objects[GID_SEARCHSTRING],
- (ULONG *)&storage);
+ case GID_HOTLIST:
+ default:
+// printf("GADGET: %ld\n",(result & WMHI_GADGETMASK));
+ break;
+ }
+ break;
- utf8 = ami_to_utf8_easy((const char *)storage);
+ case WMHI_RAWKEY:
+ ami_update_quals(gwin);
+
+ storage = result & WMHI_GADGETMASK;
+ if(storage >= IECODE_UP_PREFIX) break;
- ret = search_web_omni(utf8, SEARCH_WEB_OMNI_SEARCHONLY, &url);
- ami_utf8_free(utf8);
- if (ret == NSERROR_OK) {
- browser_window_navigate(gwin->gw->bw,
- url,
- NULL,
- BW_NAVIGATE_HISTORY,
- NULL,
- NULL,
- NULL);
- nsurl_unref(url);
- }
- if (ret != NSERROR_OK) {
- amiga_warn_user(messages_get_errorcode(ret), 0);
- }
+ GetAttr(WINDOW_InputEvent,gwin->objects[OID_MAIN],(ULONG *)&ie);
- }
- break;
+ nskey = ami_key_to_nskey(storage, ie);
- case GID_HOME:
- {
- if (nsurl_create(nsoption_charp(homepage_url), &url) != NSERROR_OK) {
- amiga_warn_user("NoMemory", 0);
- } else {
- browser_window_navigate(gwin->gw->bw,
- url,
- NULL,
- BW_NAVIGATE_HISTORY,
- NULL,
- NULL,
- NULL);
- nsurl_unref(url);
- }
- }
+ if((ie->ie_Qualifier & IEQUALIFIER_RCOMMAND) &&
+ ((31 < nskey) && (nskey < 127))) {
+ /* NB: Some keypresses are converted to generic keypresses above
+ * rather than being "menu-emulated" here. */
+ switch(nskey)
+ {
+ /* The following aren't available from the menu at the moment */
+
+ case 'r': // reload
+ if(browser_window_reload_available(gwin->gw->bw))
+ browser_window_reload(gwin->gw->bw, false);
break;
- case GID_STOP:
- if(browser_window_stop_available(gwin->gw->bw))
- browser_window_stop(gwin->gw->bw);
+ case 'u': // open url
+ if((nsoption_bool(kiosk_mode) == false))
+ ActivateLayoutGadget((struct Gadget *)gwin->objects[GID_MAIN],
+ gwin->win, NULL, (uint32)gwin->objects[GID_URL]);
break;
+ }
+ }
+ else
+ {
+ if(!browser_window_key_press(gwin->gw->bw, nskey))
+ {
+ switch(nskey)
+ {
+ case NS_KEY_UP:
+ ami_gui_scroll_internal(gwin, 0, -NSA_KBD_SCROLL_PX);
+ break;
- case GID_RELOAD:
- ami_update_quals(gwin);
+ case NS_KEY_DOWN:
+ ami_gui_scroll_internal(gwin, 0, +NSA_KBD_SCROLL_PX);
+ break;
- if(browser_window_reload_available(gwin->gw->bw))
- {
- if(gwin->key_state & BROWSER_MOUSE_MOD_1)
- {
- browser_window_reload(gwin->gw->bw, true);
- }
- else
- {
- browser_window_reload(gwin->gw->bw, false);
- }
- }
- break;
+ case NS_KEY_LEFT:
+ ami_gui_scroll_internal(gwin, -NSA_KBD_SCROLL_PX, 0);
+ break;
- case GID_BACK:
- ami_gui_history(gwin, true);
- break;
+ case NS_KEY_RIGHT:
+ ami_gui_scroll_internal(gwin, +NSA_KBD_SCROLL_PX, 0);
+ break;
- case GID_FORWARD:
- ami_gui_history(gwin, false);
- break;
+ case NS_KEY_PAGE_UP:
+ ami_gui_scroll_internal(gwin, 0, SCROLL_PAGE_UP);
+ break;
- case GID_FAVE:
- GetAttr(STRINGA_TextVal,
- (Object *)gwin->objects[GID_URL],
- (ULONG *)&storage);
- if(nsurl_create((const char *)storage, &url) == NSERROR_OK) {
- if(hotlist_has_url(url)) {
- hotlist_remove_url(url);
- } else {
- hotlist_add_url(url);
- }
- nsurl_unref(url);
- }
- ami_gui_update_hotlist_button(gwin);
- break;
+ case NS_KEY_PAGE_DOWN:
+ case ' ':
+ ami_gui_scroll_internal(gwin, 0, SCROLL_PAGE_DOWN);
+ break;
- case GID_HOTLIST:
- default:
-// printf("GADGET: %ld\n",(result & WMHI_GADGETMASK));
- break;
- }
- break;
+ case NS_KEY_LINE_START: // page left
+ ami_gui_scroll_internal(gwin, SCROLL_PAGE_UP, 0);
+ break;
- case WMHI_RAWKEY:
- ami_update_quals(gwin);
-
- storage = result & WMHI_GADGETMASK;
- if(storage >= IECODE_UP_PREFIX) break;
+ case NS_KEY_LINE_END: // page right
+ ami_gui_scroll_internal(gwin, SCROLL_PAGE_DOWN, 0);
+ break;
+
+ case NS_KEY_TEXT_START: // home
+ ami_gui_scroll_internal(gwin, SCROLL_TOP, SCROLL_TOP);
+ break;
+
+ case NS_KEY_TEXT_END: // end
+ ami_gui_scroll_internal(gwin, SCROLL_BOTTOM, SCROLL_BOTTOM);
+ break;
- GetAttr(WINDOW_InputEvent,gwin->objects[OID_MAIN],(ULONG *)&ie);
+ case NS_KEY_WORD_RIGHT: // alt+right
+ ami_change_tab(gwin, 1);
+ break;
- nskey = ami_key_to_nskey(storage, ie);
+ case NS_KEY_WORD_LEFT: // alt+left
+ ami_change_tab(gwin, -1);
+ break;
- if((ie->ie_Qualifier & IEQUALIFIER_RCOMMAND) &&
- ((31 < nskey) && (nskey < 127))) {
- /* NB: Some keypresses are converted to generic keypresses above
- * rather than being "menu-emulated" here. */
- switch(nskey)
- {
- /* The following aren't available from the menu at the moment */
+ case NS_KEY_DELETE_LEFT: // backspace
+ ami_gui_history(gwin, true);
+ break;
- case 'r': // reload
+ /* RawKeys. NB: These are passthrus in ami_key_to_nskey() */
+ case RAWKEY_F5: // reload
if(browser_window_reload_available(gwin->gw->bw))
- browser_window_reload(gwin->gw->bw, false);
+ browser_window_reload(gwin->gw->bw,false);
break;
- case 'u': // open url
- if((nsoption_bool(kiosk_mode) == false))
- ActivateLayoutGadget((struct Gadget *)gwin->objects[GID_MAIN],
- gwin->win, NULL, (uint32)gwin->objects[GID_URL]);
+ case RAWKEY_F8: // scale 100%
+ ami_gui_set_scale(gwin->gw, 1.0);
break;
- }
- }
- else
- {
- if(!browser_window_key_press(gwin->gw->bw, nskey))
- {
- switch(nskey)
- {
- case NS_KEY_UP:
- ami_gui_scroll_internal(gwin, 0, -NSA_KBD_SCROLL_PX);
- break;
-
- case NS_KEY_DOWN:
- ami_gui_scroll_internal(gwin, 0, +NSA_KBD_SCROLL_PX);
- break;
-
- case NS_KEY_LEFT:
- ami_gui_scroll_internal(gwin, -NSA_KBD_SCROLL_PX, 0);
- break;
-
- case NS_KEY_RIGHT:
- ami_gui_scroll_internal(gwin, +NSA_KBD_SCROLL_PX, 0);
- break;
-
- case NS_KEY_PAGE_UP:
- ami_gui_scroll_internal(gwin, 0, SCROLL_PAGE_UP);
- break;
-
- case NS_KEY_PAGE_DOWN:
- case ' ':
- ami_gui_scroll_internal(gwin, 0, SCROLL_PAGE_DOWN);
- break;
-
- case NS_KEY_LINE_START: // page left
- ami_gui_scroll_internal(gwin, SCROLL_PAGE_UP, 0);
- break;
-
- case NS_KEY_LINE_END: // page right
- ami_gui_scroll_internal(gwin, SCROLL_PAGE_DOWN, 0);
- break;
-
- case NS_KEY_TEXT_START: // home
- ami_gui_scroll_internal(gwin, SCROLL_TOP, SCROLL_TOP);
- break;
-
- case NS_KEY_TEXT_END: // end
- ami_gui_scroll_internal(gwin, SCROLL_BOTTOM, SCROLL_BOTTOM);
- break;
-
- case NS_KEY_WORD_RIGHT: // alt+right
- ami_change_tab(gwin, 1);
- break;
-
- case NS_KEY_WORD_LEFT: // alt+left
- ami_change_tab(gwin, -1);
- break;
-
- case NS_KEY_DELETE_LEFT: // backspace
- ami_gui_history(gwin, true);
- break;
-
- /* RawKeys. NB: These are passthrus in ami_key_to_nskey() */
- case RAWKEY_F5: // reload
- if(browser_window_reload_available(gwin->gw->bw))
- browser_window_reload(gwin->gw->bw,false);
- break;
-
- case RAWKEY_F8: // scale 100%
- ami_gui_set_scale(gwin->gw, 1.0);
- break;
-
- case RAWKEY_F9: // decrease scale
- ami_gui_set_scale(gwin->gw, gwin->gw->scale - 0.1);
- break;
-
- case RAWKEY_F10: // increase scale
- ami_gui_set_scale(gwin->gw, gwin->gw->scale + 0.1);
- break;
-
- case RAWKEY_HELP: // help
- ami_help_open(AMI_HELP_GUI, scrn);
- break;
- }
- } else if(nskey == NS_KEY_COPY_SELECTION) {
- /* if we've copied a selection we need to clear it - style guide rules */
- browser_window_key_press(gwin->gw->bw, NS_KEY_CLEAR_SELECTION);
- }
- }
- break;
- case WMHI_NEWSIZE:
- ami_set_border_gadget_size(gwin);
- ami_throbber_redraw_schedule(0, gwin->gw);
- ami_schedule(0, ami_gui_refresh_favicon, gwin);
- browser_window_schedule_reformat(gwin->gw->bw);
- break;
+ case RAWKEY_F9: // decrease scale
+ ami_gui_set_scale(gwin->gw, gwin->gw->scale - 0.1);
+ break;
- case WMHI_CLOSEWINDOW:
- ami_gui_close_window(gwin);
- break;
-#ifdef __amigaos4__
- case WMHI_ICONIFY:
- {
- struct bitmap *bm;
-
- bm = urldb_get_thumbnail(browser_window_get_url(gwin->gw->bw));
- if(!bm) bm = content_get_bitmap(browser_window_get_content(gwin->gw->bw));
- gwin->dobj = amiga_icon_from_bitmap(bm);
- amiga_icon_superimpose_favicon_internal(gwin->gw->favicon,
- gwin->dobj);
- HideWindow(gwin->win);
- gwin->appicon = AddAppIcon((ULONG)gwin->objects[OID_MAIN],
- (ULONG)gwin, gwin->win->Title, appport,
- 0, gwin->dobj, NULL);
-
- cur_gw = NULL;
+ case RAWKEY_F10: // increase scale
+ ami_gui_set_scale(gwin->gw, gwin->gw->scale + 0.1);
+ break;
+
+ case RAWKEY_HELP: // help
+ ami_help_open(AMI_HELP_GUI, scrn);
+ break;
+ }
+ } else if(nskey == NS_KEY_COPY_SELECTION) {
+ /* if we've copied a selection we need to clear it - style guide rules */
+ browser_window_key_press(gwin->gw->bw, NS_KEY_CLEAR_SELECTION);
+ }
}
- break;
-#endif
- case WMHI_INACTIVE:
- gwin->gw->c_h_temp = gwin->gw->c_h;
- gui_window_remove_caret(gwin->gw);
- break;
-
- case WMHI_ACTIVE:
- if(gwin->gw->bw) cur_gw = gwin->gw;
- if(gwin->gw->c_h_temp)
- gwin->gw->c_h = gwin->gw->c_h_temp;
- break;
-
- case WMHI_INTUITICK:
- break;
+ break;
- default:
- //printf("class: %ld\n",(result & WMHI_CLASSMASK));
- break;
- }
+ case WMHI_NEWSIZE:
+ ami_set_border_gadget_size(gwin);
+ ami_throbber_redraw_schedule(0, gwin->gw);
+ ami_schedule(0, ami_gui_refresh_favicon, gwin);
+ browser_window_schedule_reformat(gwin->gw->bw);
+ break;
- if(win_destroyed)
+ case WMHI_CLOSEWINDOW:
+ ami_gui_close_window(gwin);
+ win_closed = TRUE;
+ break;
+#ifdef __amigaos4__
+ case WMHI_ICONIFY:
{
- /* we can't be sure what state our window_list is in, so let's
- jump out of the function and start again */
-
- win_destroyed = false;
- return;
+ struct bitmap *bm;
+
+ bm = urldb_get_thumbnail(browser_window_get_url(gwin->gw->bw));
+ if(!bm) bm = content_get_bitmap(browser_window_get_content(gwin->gw->bw));
+ gwin->dobj = amiga_icon_from_bitmap(bm);
+ amiga_icon_superimpose_favicon_internal(gwin->gw->favicon,
+ gwin->dobj);
+ HideWindow(gwin->win);
+ gwin->appicon = AddAppIcon((ULONG)gwin->objects[OID_MAIN],
+ (ULONG)gwin, gwin->win->Title, appport,
+ 0, gwin->dobj, NULL);
+
+ cur_gw = NULL;
}
+ break;
+#endif
+ case WMHI_INACTIVE:
+ gwin->gw->c_h_temp = gwin->gw->c_h;
+ gui_window_remove_caret(gwin->gw);
+ break;
- if(drag_x_move || drag_y_move)
- {
- gui_window_get_scroll(gwin->gw,
- &gwin->gw->scrollx, &gwin->gw->scrolly);
+ case WMHI_ACTIVE:
+ if(gwin->gw->bw) cur_gw = gwin->gw;
+ if(gwin->gw->c_h_temp)
+ gwin->gw->c_h = gwin->gw->c_h_temp;
+ break;
- gui_window_set_scroll(gwin->gw,
- gwin->gw->scrollx + drag_x_move,
- gwin->gw->scrolly + drag_y_move);
- }
+ case WMHI_INTUITICK:
+ break;
-// ReplyMsg((struct Message *)message);
+ default:
+ //printf("class: %ld\n",(result & WMHI_CLASSMASK));
+ break;
}
- if(gwin->closed == true) {
- ami_gui_close_window(gwin);
+ if(win_destroyed)
+ {
+ /* we can't be sure what state our window_list is in, so let's
+ jump out of the function and start again */
+
+ win_destroyed = false;
+ return TRUE;
}
- } while((node = nnode));
+ if(drag_x_move || drag_y_move)
+ {
+ gui_window_get_scroll(gwin->gw,
+ &gwin->gw->scrollx, &gwin->gw->scrolly);
- if(ami_menu_quit_selected() == true){
- ami_quit_netsurf();
+ gui_window_set_scroll(gwin->gw,
+ gwin->gw->scrollx + drag_x_move,
+ gwin->gw->scrolly + drag_y_move);
+ }
+
+// ReplyMsg((struct Message *)message);
}
-
- if(ami_menu_get_check_toggled() == true) {
- ami_gui_menu_update_all();
+
+ if(gwin->closed == true) {
+ win_closed = TRUE;
+ ami_gui_close_window(gwin);
}
+
+ return win_closed;
}
static void ami_gui_appicon_remove(struct gui_window_2 *gwin)
@@ -2584,7 +2602,7 @@ static void ami_handle_appmsg(void)
{
if((appwinargs = &appmsg->am_ArgList[i]))
{
- if((filename = AllocVecTagList(1024, NULL)))
+ if((filename = malloc(1024)))
{
if(appwinargs->wa_Lock)
{
@@ -2665,7 +2683,7 @@ static void ami_handle_appmsg(void)
}
}
}
- FreeVec(filename);
+ free(filename);
}
}
}
@@ -2800,7 +2818,7 @@ void ami_get_msg(void)
}
if(signal & winsignal)
- ami_handle_msg();
+ while(ami_handle_msg());
if(signal & appsig)
ami_handle_appmsg();
@@ -2885,7 +2903,7 @@ void ami_switch_tab(struct gui_window_2 *gwin, bool redraw)
ami_plot_release_pens(gwin->shared_pens);
ami_update_buttons(gwin);
- ami_menu_update_disabled(gwin->gw, browser_window_get_content(gwin->gw->bw));
+ ami_gui_menu_update_disabled(gwin->gw, browser_window_get_content(gwin->gw->bw));
if(redraw)
{
@@ -2911,34 +2929,24 @@ void ami_quit_netsurf(void)
{
struct nsObject *node;
struct nsObject *nnode;
- struct gui_window_2 *gwin;
+ struct ami_generic_window *w;
+
+ /* Disable the multiple tabs open warning */
+ nsoption_set_bool(tab_close_warn, false);
if(!IsMinListEmpty(window_list)) {
node = (struct nsObject *)GetHead((struct List *)window_list);
do {
nnode=(struct nsObject *)GetSucc((struct Node *)node);
- gwin = node->objstruct;
-
- switch(node->Type) {
- case AMINS_TVWINDOW:
- ami_tree_close((struct treeview_window *)gwin);
- break;
-
- case AMINS_WINDOW:
- /* This also closes windows that are attached to the
- * gui_window, such as local history and find. */
- ShowWindow(gwin->win, WINDOW_BACKMOST);
- ami_gui_close_window(gwin);
- break;
+ w = node->objstruct;
- case AMINS_GUIOPTSWINDOW:
- ami_gui_opts_close();
- break;
-
- case AMINS_DLWINDOW:
- ami_download_window_abort((struct gui_download_window *)gwin);
- break;
+ if(w->tbl->close != NULL) {
+ if(node->Type == AMINS_WINDOW) {
+ struct gui_window_2 *gwin = (struct gui_window_2 *)w;
+ ShowWindow(gwin->win, WINDOW_BACKMOST); // do we need this??
+ }
+ w->tbl->close(w);
}
} while((node = nnode));
@@ -2972,7 +2980,6 @@ void ami_quit_netsurf_delayed(void)
free(utf8gadgets);
#endif
if(res == -1) { /* Requester timed out */
- nsoption_set_bool(tab_close_warn, false);
ami_quit_netsurf();
}
}
@@ -3034,9 +3041,7 @@ static void gui_quit(void)
urldb_save(nsoption_charp(url_file));
urldb_save_cookies(nsoption_charp(cookie_file));
- ami_hotlist_free(nsoption_charp(hotlist_file));
- ami_cookies_free();
- ami_global_history_free();
+ hotlist_fini(nsoption_charp(hotlist_file));
#ifdef __amigaos4__
if(IApplication && ami_appid)
UnregisterApplication(ami_appid, NULL);
@@ -3060,6 +3065,13 @@ static void gui_quit(void)
FreeStringClass(urlStringClass);
FreeObjList(window_list);
+
+ ami_clipboard_free();
+ ami_gui_resources_free();
+
+ LOG("Closing screen");
+ ami_gui_close_screen(scrn, locked_screen, FALSE);
+ if(nsscreentitle) FreeVec(nsscreentitle);
}
char *ami_gui_get_cache_favicon_name(nsurl *url, bool only_if_avail)
@@ -3173,7 +3185,7 @@ static bool ami_gui_hotlist_add(void *userdata, int level, int item,
return true;
}
-static int ami_gui_hotlist_scan(struct tree *tree, struct List *speed_button_list, struct gui_window_2 *gwin)
+static int ami_gui_hotlist_scan(struct List *speed_button_list, struct gui_window_2 *gwin)
{
struct ami_gui_tb_userdata userdata;
userdata.gw = gwin;
@@ -3195,7 +3207,7 @@ static void ami_gui_hotlist_toolbar_add(struct gui_window_2 *gwin)
NewList(&gwin->hotlist_toolbar_list);
- if(ami_gui_hotlist_scan(ami_tree_get_tree(hotlist_window), &gwin->hotlist_toolbar_list, gwin) > 0) {
+ if(ami_gui_hotlist_scan(&gwin->hotlist_toolbar_list, gwin) > 0) {
gwin->objects[GID_HOTLIST] =
SpeedBarObj,
GA_ID, GID_HOTLIST,
@@ -3266,8 +3278,10 @@ static void ami_gui_hotlist_toolbar_remove(struct gui_window_2 *gwin)
IDoMethod(gwin->objects[GID_HOTLISTLAYOUT], LM_REMOVECHILD,
gwin->win, gwin->objects[GID_HOTLISTSEPBAR]);
#else
- SetAttrs(gwin->objects[GID_HOTLISTLAYOUT], LAYOUT_RemoveChild, gwin->objects[GID_HOTLIST]);
- SetAttrs(gwin->objects[GID_HOTLISTLAYOUT], LAYOUT_RemoveChild, gwin->objects[GID_HOTLISTSEPBAR]);
+ SetAttrs(gwin->objects[GID_HOTLISTLAYOUT],
+ LAYOUT_RemoveChild, gwin->objects[GID_HOTLIST], TAG_DONE);
+ SetAttrs(gwin->objects[GID_HOTLISTLAYOUT],
+ LAYOUT_RemoveChild, gwin->objects[GID_HOTLISTSEPBAR], TAG_DONE);
#endif
FlushLayoutDomainCache((struct Gadget *)gwin->objects[GID_MAIN]);
@@ -3292,7 +3306,7 @@ static void ami_gui_hotlist_toolbar_update(struct gui_window_2 *gwin)
ami_gui_hotlist_toolbar_free(gwin, &gwin->hotlist_toolbar_list);
- if(ami_gui_hotlist_scan(ami_tree_get_tree(hotlist_window), &gwin->hotlist_toolbar_list, gwin) > 0) {
+ if(ami_gui_hotlist_scan(&gwin->hotlist_toolbar_list, gwin) > 0) {
SetGadgetAttrs((struct Gadget *)gwin->objects[GID_HOTLIST],
gwin->win, NULL,
SPEEDBAR_Buttons, &gwin->hotlist_toolbar_list,
@@ -3313,16 +3327,16 @@ void ami_gui_hotlist_update_all(void)
if(IsMinListEmpty(window_list)) return;
+ ami_gui_menu_refresh_hotlist();
+
node = (struct nsObject *)GetHead((struct List *)window_list);
do {
nnode=(struct nsObject *)GetSucc((struct Node *)node);
gwin = node->objstruct;
- if(node->Type == AMINS_WINDOW)
- {
+ if(node->Type == AMINS_WINDOW) {
ami_gui_hotlist_toolbar_update(gwin);
- ami_menu_refresh(gwin);
}
} while((node = nnode));
}
@@ -3651,8 +3665,9 @@ static void ami_refresh_window(struct gui_window_2 *gwin)
/* simplerefresh only */
struct IBox *bbox;
- int x0, x1, y0, y1, sx, sy;
+ int sx, sy;
struct RegionRectangle *regrect;
+ struct rect r;
sx = gwin->gw->scrollx;
sy = gwin->gw->scrolly;
@@ -3666,33 +3681,33 @@ static void ami_refresh_window(struct gui_window_2 *gwin)
BeginRefresh(gwin->win);
- x0 = ((gwin->win->RPort->Layer->DamageList->bounds.MinX - bbox->Left) /
+ r.x0 = ((gwin->win->RPort->Layer->DamageList->bounds.MinX - bbox->Left) /
browser_window_get_scale(gwin->gw->bw)) + sx - 1;
- x1 = ((gwin->win->RPort->Layer->DamageList->bounds.MaxX - bbox->Left) /
+ r.x1 = ((gwin->win->RPort->Layer->DamageList->bounds.MaxX - bbox->Left) /
browser_window_get_scale(gwin->gw->bw)) + sx + 2;
- y0 = ((gwin->win->RPort->Layer->DamageList->bounds.MinY - bbox->Top) /
+ r.y0 = ((gwin->win->RPort->Layer->DamageList->bounds.MinY - bbox->Top) /
browser_window_get_scale(gwin->gw->bw)) + sy - 1;
- y1 = ((gwin->win->RPort->Layer->DamageList->bounds.MaxY - bbox->Top) /
+ r.y1 = ((gwin->win->RPort->Layer->DamageList->bounds.MaxY - bbox->Top) /
browser_window_get_scale(gwin->gw->bw)) + sy + 2;
regrect = gwin->win->RPort->Layer->DamageList->RegionRectangle;
- ami_do_redraw_limits(gwin->gw, gwin->gw->bw, false, x0, y0, x1, y1);
+ gui_window_update_box(gwin->gw, &r);
while(regrect)
{
- x0 = ((regrect->bounds.MinX - bbox->Left) /
+ r.x0 = ((regrect->bounds.MinX - bbox->Left) /
browser_window_get_scale(gwin->gw->bw)) + sx - 1;
- x1 = ((regrect->bounds.MaxX - bbox->Left) /
+ r.x1 = ((regrect->bounds.MaxX - bbox->Left) /
browser_window_get_scale(gwin->gw->bw)) + sx + 2;
- y0 = ((regrect->bounds.MinY - bbox->Top) /
+ r.y0 = ((regrect->bounds.MinY - bbox->Top) /
browser_window_get_scale(gwin->gw->bw)) + sy - 1;
- y1 = ((regrect->bounds.MaxY - bbox->Top) /
+ r.y1 = ((regrect->bounds.MaxY - bbox->Top) /
browser_window_get_scale(gwin->gw->bw)) + sy + 2;
regrect = regrect->Next;
- ami_do_redraw_limits(gwin->gw, gwin->gw->bw, false, x0, y0, x1, y1);
+ gui_window_update_box(gwin->gw, &r);
}
EndRefresh(gwin->win, TRUE);
@@ -3766,12 +3781,43 @@ HOOKF(void, ami_scroller_hook, Object *, object, struct IntuiMessage *)
break;
default:
- LOG("IDCMP hook unhandled event: %ld\n", msg->Class);
+ LOG("IDCMP hook unhandled event: %ld", msg->Class);
break;
}
// ReplyMsg((struct Message *)msg);
}
+/* exported function documented in gui.h */
+nserror ami_gui_win_list_add(void *win, int type, const struct ami_win_event_table *table)
+{
+ struct nsObject *node = AddObject(window_list, type);
+ if(node == NULL) return NSERROR_NOMEM;
+ node->objstruct = win;
+
+ struct ami_generic_window *w = (struct ami_generic_window *)win;
+ w->tbl = table;
+ w->node = node;
+
+ return NSERROR_OK;
+}
+
+/* exported function documented in gui.h */
+void ami_gui_win_list_remove(void *win)
+{
+ struct ami_generic_window *w = (struct ami_generic_window *)win;
+
+ if(w->node->Type == AMINS_TVWINDOW) {
+ DelObjectNoFree(w->node);
+ } else {
+ DelObject(w->node);
+ }
+}
+
+static const struct ami_win_event_table ami_gui_table = {
+ ami_gui_event,
+ ami_gui_close_window,
+};
+
static struct gui_window *
gui_window_create(struct browser_window *bw,
struct gui_window *existing,
@@ -3818,7 +3864,7 @@ gui_window_create(struct browser_window *bw,
if(curh > (scrn->Height - cury)) curh = scrn->Height - cury;
- g = ami_misc_allocvec_clear(sizeof(struct gui_window), 0);
+ g = calloc(1, sizeof(struct gui_window));
if(!g)
{
@@ -3828,7 +3874,7 @@ gui_window_create(struct browser_window *bw,
NewList(&g->dllist);
g->deferred_rects = NewObjList();
- g->deferred_rects_pool = ami_misc_itempool_create(sizeof(struct rect));
+ g->deferred_rects_pool = ami_memory_itempool_create(sizeof(struct rect));
g->bw = bw;
g->scale = browser_window_get_scale(bw);
@@ -3892,7 +3938,7 @@ gui_window_create(struct browser_window *bw,
return g;
}
- g->shared = ami_misc_allocvec_clear(sizeof(struct gui_window_2), 0);
+ g->shared = calloc(1, sizeof(struct gui_window_2));
if(!g->shared)
{
@@ -3939,7 +3985,7 @@ gui_window_create(struct browser_window *bw,
iconifygadget = TRUE;
LOG("Creating menu");
- struct Menu *menu = ami_menu_create(g->shared);
+ struct Menu *menu = ami_gui_menu_create(g->shared);
NewList(&g->shared->tab_list);
g->tab_node = AllocClickTabNode(TNA_Text,messages_get("NetSurf"),
@@ -3955,7 +4001,7 @@ gui_window_create(struct browser_window *bw,
g->shared->tabs=1;
g->shared->next_tab=1;
- g->shared->svbuffer = ami_misc_allocvec_clear(2000, 0);
+ g->shared->svbuffer = calloc(1, 2000);
g->shared->helphints[GID_BACK] =
translate_escape_chars(messages_get("HelpToolbarBack"));
@@ -4347,8 +4393,8 @@ gui_window_create(struct browser_window *bw,
if(!g->shared->win)
{
amiga_warn_user("NoMemory","");
- FreeVec(g->shared);
- FreeVec(g);
+ free(g->shared);
+ free(g);
return NULL;
}
@@ -4411,8 +4457,7 @@ gui_window_create(struct browser_window *bw,
g->shared->appwin = AddAppWindowA((ULONG)g->shared->objects[OID_MAIN],
(ULONG)g->shared, g->shared->win, appport, NULL);
- g->shared->node = AddObject(window_list,AMINS_WINDOW);
- g->shared->node->objstruct = g->shared;
+ ami_gui_win_list_add(g->shared, AMINS_WINDOW, &ami_gui_table);
ami_gui_set_default_gg();
@@ -4460,8 +4505,9 @@ static void ami_gui_close_tabs(struct gui_window_2 *gwin, bool other_tabs)
}
}
-void ami_gui_close_window(struct gui_window_2 *gwin)
+void ami_gui_close_window(void *w)
{
+ struct gui_window_2 *gwin = (struct gui_window_2 *)w;
ami_gui_close_tabs(gwin, false);
}
@@ -4491,7 +4537,7 @@ static void gui_window_destroy(struct gui_window *g)
ami_free_download_list(&g->dllist);
FreeObjList(g->deferred_rects);
- ami_misc_itempool_delete(g->deferred_rects_pool);
+ ami_memory_itempool_delete(g->deferred_rects_pool);
gui_window_stop_throbber(g);
cur_gw = NULL;
@@ -4526,14 +4572,13 @@ static void gui_window_destroy(struct gui_window *g)
if((g->shared->tabs == 1) && (nsoption_bool(tab_always_show) == false))
ami_toggletabbar(g->shared, false);
- ami_utf8_free(g->tabtitle);
-
- FreeVec(g);
+ if(g->tabtitle) free(g->tabtitle);
+ free(g);
return;
}
ami_plot_release_pens(g->shared->shared_pens);
- FreeVec(g->shared->shared_pens);
+ free(g->shared->shared_pens);
ami_schedule_redraw_remove(g->shared);
ami_schedule(-1, ami_gui_refresh_favicon, g->shared);
@@ -4558,22 +4603,22 @@ static void gui_window_destroy(struct gui_window *g)
DisposeObject((Object *)g->shared->history_ctxmenu[AMI_CTXMENU_HISTORY_BACK]);
DisposeObject((Object *)g->shared->history_ctxmenu[AMI_CTXMENU_HISTORY_FORWARD]);
ami_ctxmenu_release_hook(g->shared->ctxmenu_hook);
- ami_free_menulabs(g->shared);
- ami_menu_free(g->shared);
+ ami_gui_menu_free(g->shared);
free(g->shared->wintitle);
ami_utf8_free(g->shared->status);
- FreeVec(g->shared->svbuffer);
+ free(g->shared->svbuffer);
for(gid = 0; gid < GID_LAST; gid++)
free(g->shared->helphints[gid]);
- DelObject(g->shared->node);
+ ami_gui_win_list_remove(g->shared);
if(g->tab_node) {
Remove(g->tab_node);
FreeClickTabNode(g->tab_node);
}
- FreeVec(g); // g->shared should be freed by DelObject()
+ if(g->tabtitle) free(g->tabtitle);
+ free(g); // g->shared should be freed by DelObject()
if(IsMinListEmpty(window_list))
{
@@ -4594,8 +4639,7 @@ static void gui_window_set_title(struct gui_window *g, const char *restrict titl
utf8title = ami_utf8_easy((char *)title);
- if(g->tab_node) // && (g->shared->tabs > 1))
- {
+ if(g->tab_node) {
node = g->tab_node;
if((g->tabtitle == NULL) || (strcmp(utf8title, g->tabtitle)))
@@ -4605,7 +4649,7 @@ static void gui_window_set_title(struct gui_window *g, const char *restrict titl
CLICKTAB_Labels, ~0,
TAG_DONE);
- if(g->tabtitle) ami_utf8_free(g->tabtitle);
+ if(g->tabtitle) free(g->tabtitle);
g->tabtitle = strdup(utf8title);
SetClickTabNodeAttrs(node, TNA_Text, g->tabtitle,
@@ -4704,14 +4748,14 @@ static void ami_gui_window_update_box_deferred(struct gui_window *g, bool draw)
rect->x0, rect->y0, rect->x1, rect->y1);
}
nnode=(struct nsObject *)GetSucc((struct Node *)node);
- ami_misc_itempool_free(g->deferred_rects_pool, node->objstruct, sizeof(struct rect));
+ ami_memory_itempool_free(g->deferred_rects_pool, node->objstruct, sizeof(struct rect));
DelObjectNoFree(node);
} while((node = nnode));
if(draw == true) ami_reset_pointer(g->shared);
}
-static bool ami_gui_window_update_box_deferred_check(struct MinList *deferred_rects,
+bool ami_gui_window_update_box_deferred_check(struct MinList *deferred_rects,
const struct rect *restrict new_rect, APTR mempool)
{
struct nsObject *node;
@@ -4738,7 +4782,7 @@ static bool ami_gui_window_update_box_deferred_check(struct MinList *deferred_re
(new_rect->x1 >= rect->x1) &&
(new_rect->y1 >= rect->y1)) {
LOG("Removing queued redraw that is a subset of new box redraw");
- ami_misc_itempool_free(mempool, node->objstruct, sizeof(struct rect));
+ ami_memory_itempool_free(mempool, node->objstruct, sizeof(struct rect));
DelObjectNoFree(node);
/* Don't return - we might find more */
}
@@ -4755,7 +4799,7 @@ static void gui_window_update_box(struct gui_window *g, const struct rect *restr
if(ami_gui_window_update_box_deferred_check(g->deferred_rects, rect,
g->deferred_rects_pool)) {
- deferred_rect = ami_misc_itempool_alloc(g->deferred_rects_pool, sizeof(struct rect));
+ deferred_rect = ami_memory_itempool_alloc(g->deferred_rects_pool, sizeof(struct rect));
CopyMem(rect, deferred_rect, sizeof(struct rect));
nsobj = AddObject(g->deferred_rects, AMINS_RECT);
nsobj->objstruct = deferred_rect;
@@ -5213,7 +5257,7 @@ static void gui_window_place_caret(struct gui_window *g, int x, int y, int heigh
g->c_h = height;
if((nsoption_bool(kiosk_mode) == false))
- OnMenu(g->shared->win, AMI_MENU_PASTE);
+ ami_gui_menu_set_disabled(g->shared->win, g->shared->imenu, M_PASTE, false);
}
static void gui_window_remove_caret(struct gui_window *g)
@@ -5222,7 +5266,7 @@ static void gui_window_remove_caret(struct gui_window *g)
if(g->c_h == 0) return;
if((nsoption_bool(kiosk_mode) == false))
- OffMenu(g->shared->win, AMI_MENU_PASTE);
+ ami_gui_menu_set_disabled(g->shared->win, g->shared->imenu, M_PASTE, true);
ami_do_redraw_limits(g, g->bw, false, g->c_x, g->c_y,
g->c_x + g->c_w + 1, g->c_y + g->c_h + 1);
@@ -5246,7 +5290,7 @@ static void gui_window_new_content(struct gui_window *g)
g->shared->oldv = 0;
g->favicon = NULL;
ami_plot_release_pens(g->shared->shared_pens);
- ami_menu_update_disabled(g, c);
+ ami_gui_menu_update_disabled(g, c);
ami_gui_update_hotlist_button(g->shared);
ami_gui_scroller_update(g->shared);
}
@@ -5265,7 +5309,7 @@ static bool gui_window_drag_start(struct gui_window *g, gui_drag_type type,
if(g->shared->ptr_lock)
{
- FreeVec(g->shared->ptr_lock);
+ free(g->shared->ptr_lock);
g->shared->ptr_lock = NULL;
}
}
@@ -5346,9 +5390,24 @@ Object *ami_gui_splash_open(void)
LayoutEnd,
EndWindow;
+ if(win_obj == NULL) {
+ LOG("Splash window object not created");
+ return NULL;
+ }
+
LOG("Attempting to open splash window...");
win = RA_OpenWindow(win_obj);
+ if(win == NULL) {
+ LOG("Splash window did not open");
+ return NULL;
+ }
+
+ if(bm_obj == NULL) {
+ LOG("BitMap object not created");
+ return NULL;
+ }
+
GetAttrs(bm_obj, IA_Top, &top,
IA_Left, &left,
TAG_DONE);
@@ -5436,6 +5495,84 @@ uint32 ami_gui_get_app_id(void)
return ami_appid;
}
+/* Get current user directory for user-specific NetSurf data
+ * Returns NULL on error
+ */
+static char *ami_gui_get_user_dir(STRPTR current_user)
+{
+ BPTR lock = 0;
+ char temp[1024];
+ int32 user = 0;
+
+ if(current_user == NULL) {
+ user = GetVar("user", temp, 1024, GVF_GLOBAL_ONLY);
+ current_user = ASPrintf("%s", (user == -1) ? "Default" : temp);
+ }
+ LOG("User: %s", current_user);
+
+ if(users_dir == NULL) {
+ users_dir = ASPrintf("%s", USERS_DIR);
+ if(users_dir == NULL) {
+ ami_misc_fatal_error("Failed to allocate memory");
+ FreeVec(current_user);
+ return NULL;
+ }
+ }
+
+ if(LIB_IS_AT_LEAST((struct Library *)DOSBase, 51, 96)) {
+#ifdef __amigaos4__
+ struct InfoData *infodata = AllocDosObject(DOS_INFODATA, 0);
+ if(infodata == NULL) {
+ ami_misc_fatal_error("Failed to allocate memory");
+ FreeVec(current_user);
+ return NULL;
+ }
+ GetDiskInfoTags(GDI_StringNameInput, users_dir,
+ GDI_InfoData, infodata,
+ TAG_DONE);
+ if(infodata->id_DiskState == ID_DISKSTATE_WRITE_PROTECTED) {
+ FreeDosObject(DOS_INFODATA, infodata);
+ ami_misc_fatal_error("User directory MUST be on a writeable volume");
+ FreeVec(current_user);
+ return NULL;
+ }
+ FreeDosObject(DOS_INFODATA, infodata);
+#else
+#warning FIXME for OS3 and older OS4
+#endif
+ } else {
+//TODO: check volume write status using old API
+ }
+
+ int len = strlen(current_user);
+ len += strlen(users_dir);
+ len += 2; /* for poss path sep and NULL term */
+
+ current_user_dir = malloc(len);
+ if(current_user_dir == NULL) {
+ ami_misc_fatal_error("Failed to allocate memory");
+ FreeVec(current_user);
+ return NULL;
+ }
+
+ strlcpy(current_user_dir, users_dir, len);
+ AddPart(current_user_dir, current_user, len);
+ FreeVec(users_dir);
+ FreeVec(current_user);
+
+ LOG("User dir: %s", current_user_dir);
+
+ if((lock = CreateDirTree(current_user_dir)))
+ UnLock(lock);
+
+ ami_nsoption_set_location(current_user_dir);
+
+ current_user_faviconcache = ASPrintf("%s/IconCache", current_user_dir);
+ if((lock = CreateDirTree(current_user_faviconcache))) UnLock(lock);
+
+ return current_user_dir;
+}
+
static struct gui_window_table amiga_window_table = {
.create = gui_window_create,
.destroy = gui_window_destroy,
@@ -5487,7 +5624,7 @@ static struct gui_misc_table amiga_misc_table = {
.quit = gui_quit,
.launch_url = gui_launch_url,
- .cert_verify = gui_cert_verify,
+ .cert_verify = ami_cert_verify,
.login = gui_401login_open,
};
@@ -5499,8 +5636,8 @@ int main(int argc, char** argv)
char script[1024];
char temp[1024];
STRPTR current_user_cache = NULL;
+ STRPTR current_user = NULL;
BPTR lock = 0;
- int32 user = 0;
nserror ret;
int nargc = 0;
char *nargv = NULL;
@@ -5542,99 +5679,29 @@ int main(int argc, char** argv)
/* Open splash window */
Object *splash_window = ami_gui_splash_open();
- ami_object_init();
+#ifndef __amigaos4__
+ /* OS3 low memory handler */
+ struct Interupt *memhandler = ami_memory_init();
+#endif
- if (ami_open_resources() == false) { /* alloc message ports */
+ if (ami_gui_resources_open() == false) { /* alloc msgports, objects and other miscelleny */
ami_misc_fatal_error("Unable to allocate resources");
ami_gui_splash_close(splash_window);
ami_libs_close();
return RETURN_FAIL;
}
- if(ami_schedule_create(schedulermsgport) != NSERROR_OK) {
- ami_misc_fatal_error("Failed to initialise scheduler");
- ami_gui_splash_close(splash_window);
- ami_libs_close();
- return RETURN_FAIL;
- }
-
- ami_gui_read_all_tooltypes(argc, argv);
+ current_user = ami_gui_read_all_tooltypes(argc, argv);
struct RDArgs *args = ami_gui_commandline(&argc, argv, &nargc, &nargv);
- if(current_user == NULL) {
- user = GetVar("user", temp, 1024, GVF_GLOBAL_ONLY);
- current_user = ASPrintf("%s", (user == -1) ? "Default" : temp);
- }
- LOG("User: %s", current_user);
-
- if(users_dir == NULL) {
- users_dir = ASPrintf("%s", USERS_DIR);
- if(users_dir == NULL) {
- ami_misc_fatal_error("Failed to allocate memory");
- ami_schedule_free();
- ami_gui_splash_close(splash_window);
- ami_libs_close();
- return RETURN_FAIL;
- }
- }
-
- if(LIB_IS_AT_LEAST((struct Library *)DOSBase, 51, 96)) {
-#ifdef __amigaos4__
- struct InfoData *infodata = AllocDosObject(DOS_INFODATA, 0);
- if(infodata == NULL) {
- ami_misc_fatal_error("Failed to allocate memory");
- ami_schedule_free();
- ami_gui_splash_close(splash_window);
- ami_libs_close();
- return RETURN_FAIL;
- }
- GetDiskInfoTags(GDI_StringNameInput, users_dir,
- GDI_InfoData, infodata,
- TAG_DONE);
- if(infodata->id_DiskState == ID_DISKSTATE_WRITE_PROTECTED) {
- FreeDosObject(DOS_INFODATA, infodata);
- ami_misc_fatal_error("User directory MUST be on a writeable volume");
- ami_schedule_free();
- ami_gui_splash_close(splash_window);
- ami_libs_close();
- return RETURN_FAIL;
- }
- FreeDosObject(DOS_INFODATA, infodata);
-#else
-#warning FIXME for OS3 and older OS4
-#endif
- } else {
-//TODO: check volume write status using old API
- }
-
- int len = strlen(current_user);
- len += strlen(users_dir);
- len += 2; /* for poss path sep and NULL term */
-
- current_user_dir = AllocVecTagList(len, NULL);
+ current_user_dir = ami_gui_get_user_dir(current_user);
if(current_user_dir == NULL) {
- ami_misc_fatal_error("Failed to allocate memory");
- ami_schedule_free();
+ ami_gui_resources_free();
ami_gui_splash_close(splash_window);
ami_libs_close();
return RETURN_FAIL;
}
- strlcpy(current_user_dir, users_dir, len);
- AddPart(current_user_dir, current_user, len);
- FreeVec(users_dir);
- LOG("User dir: %s", current_user_dir);
-
- if((lock = CreateDirTree(current_user_dir)))
- UnLock(lock);
-
- ami_nsoption_set_location(current_user_dir);
- current_user_cache = ASPrintf("%s/Cache", current_user_dir);
- current_user_faviconcache = ASPrintf("%s/IconCache", current_user_dir);
-
- if((lock = CreateDirTree(current_user_cache))) UnLock(lock);
- if((lock = CreateDirTree(current_user_faviconcache))) UnLock(lock);
-
ami_mime_init("PROGDIR:Resources/mimetypes");
sprintf(temp, "%s/mimetypes.user", current_user_dir);
ami_mime_init(temp);
@@ -5652,7 +5719,7 @@ int main(int argc, char** argv)
ret = nsoption_init(ami_set_options, &nsoptions, &nsoptions_default);
if (ret != NSERROR_OK) {
ami_misc_fatal_error("Options failed to initialise");
- ami_schedule_free();
+ ami_gui_resources_free();
ami_gui_splash_close(splash_window);
ami_libs_close();
return RETURN_FAIL;
@@ -5665,7 +5732,9 @@ int main(int argc, char** argv)
if (ami_locate_resource(messages, "Messages") == false) {
ami_misc_fatal_error("Cannot open Messages file");
- ami_schedule_free();
+ ami_nsoption_free();
+ nsoption_finalise(nsoptions, nsoptions_default);
+ ami_gui_resources_free();
ami_gui_splash_close(splash_window);
ami_libs_close();
return RETURN_FAIL;
@@ -5673,16 +5742,23 @@ int main(int argc, char** argv)
ret = messages_add_from_file(messages);
+ current_user_cache = ASPrintf("%s/Cache", current_user_dir);
+ if((lock = CreateDirTree(current_user_cache))) UnLock(lock);
+
ret = netsurf_init(current_user_cache);
+
+ if(current_user_cache != NULL) FreeVec(current_user_cache);
+
if (ret != NSERROR_OK) {
ami_misc_fatal_error("NetSurf failed to initialise");
- ami_schedule_free();
+ ami_nsoption_free();
+ nsoption_finalise(nsoptions, nsoptions_default);
+ ami_gui_resources_free();
ami_gui_splash_close(splash_window);
ami_libs_close();
return RETURN_FAIL;
}
- if(current_user_cache != NULL) FreeVec(current_user_cache);
ret = amiga_icon_init();
search_web_init(nsoption_charp(search_engines_file));
@@ -5727,25 +5803,17 @@ int main(int argc, char** argv)
netsurf_exit();
+ nsoption_finalise(nsoptions, nsoptions_default);
ami_nsoption_free();
- FreeVec(current_user_dir);
+ free(current_user_dir);
FreeVec(current_user_faviconcache);
- FreeVec(current_user);
-
- ami_clipboard_free();
- ami_schedule_free();
- FreeSysObject(ASOT_PORT, appport);
- FreeSysObject(ASOT_PORT, sport);
- FreeSysObject(ASOT_PORT, schedulermsgport);
+#ifndef __amigaos4__
+ /* OS3 low memory handler */
+ ami_memory_fini(memhandler);
+#endif
- ami_object_fini();
ami_bitmap_fini();
-
- LOG("Closing screen");
- ami_gui_close_screen(scrn, locked_screen, FALSE);
- if(nsscreentitle) FreeVec(nsscreentitle);
-
ami_libs_close();
return RETURN_OK;
diff --git a/frontends/amiga/gui.h b/frontends/amiga/gui.h
index 6d5188e..07ff922 100644
--- a/frontends/amiga/gui.h
+++ b/frontends/amiga/gui.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2015 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
+ * Copyright 2008-2017 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -28,7 +28,7 @@
#include "netsurf/window.h"
#include "netsurf/mouse.h"
-#include "amiga/menu.h"
+#include "amiga/gui_menu.h"
#include "amiga/object.h"
#include "amiga/os3support.h"
@@ -91,8 +91,29 @@ struct history_window;
#define AMI_GUI_TOOLBAR_MAX 20
-struct gui_window_2 {
+struct ami_win_event_table {
+ /* callback to handle events when using a shared msgport
+ *
+ * @param pointer to our window structure (must start with ami_generic_window)
+ * @return TRUE if window was destroyed during event processing
+ */
+ BOOL (*event)(void *w);
+
+ /* callback for explicit window closure
+ * some windows are implicitly closed by the browser and should set this to NULL
+ */
+ void (*close)(void *w);
+};
+
+struct ami_generic_window {
struct nsObject *node;
+ const struct ami_win_event_table *tbl;
+};
+
+struct ami_menu_data;
+
+struct gui_window_2 {
+ struct ami_generic_window w;
struct Window *win;
Object *restrict objects[GID_LAST];
struct gui_window *gw; /* currently-displayed gui_window */
@@ -113,13 +134,7 @@ struct gui_window_2 {
int temp;
bool redraw_scroll;
bool new_content;
- char *restrict menulab[AMI_MENU_AREXX_MAX + 1];
- Object *restrict menuobj[AMI_MENU_AREXX_MAX + 1];
- char menukey[AMI_MENU_AREXX_MAX + 1];
- char *restrict menuicon[AMI_MENU_AREXX_MAX + 1];
- struct Hook menu_hook[AMI_MENU_AREXX_MAX + 1];
- UBYTE *menutype;
- struct NewMenu *menu;
+ struct ami_menu_data *menu_data[AMI_MENU_AREXX_MAX + 1]; /* only for GadTools menus */
ULONG hotlist_items;
Object *restrict hotlist_toolbar_lab[AMI_GUI_TOOLBAR_MAX];
struct List hotlist_toolbar_list;
@@ -144,7 +159,6 @@ struct gui_window_2 {
struct MinList *shared_pens;
gui_pointer_shape mouse_pointer;
struct Menu *imenu; /* Intuition menu */
- struct VisualInfo *vi; /* For GadTools menu */
bool closed; /* Window has been closed (via menu) */
};
@@ -171,16 +185,20 @@ struct gui_window
float scale;
};
-extern struct MinList *window_list;
+extern struct MinList *window_list; /**\todo stop arexx.c poking about in here */
extern struct Screen *scrn;
extern struct MsgPort *sport;
extern struct gui_window *cur_gw;
+/* The return value for these functions must be deallocated using FreeVec() */
+STRPTR ami_locale_langs(int *codeset);
+char *ami_gui_get_cache_favicon_name(struct nsurl *url, bool only_if_avail);
+
+/* Functions lacking documentation */
void ami_get_msg(void);
void ami_try_quit(void);
void ami_quit_netsurf(void);
void ami_schedule_redraw(struct gui_window_2 *gwin, bool full_redraw);
-STRPTR ami_locale_langs(int *codeset);
int ami_key_to_nskey(ULONG keycode, struct InputEvent *ie);
bool ami_text_box_at_point(struct gui_window_2 *gwin, ULONG *restrict x, ULONG *restrict y);
bool ami_mouse_to_ns_coords(struct gui_window_2 *gwin, int *restrict x, int *restrict y,
@@ -192,7 +210,6 @@ void ami_gui_tabs_toggle_all(void);
bool ami_locate_resource(char *fullpath, const char *file);
void ami_gui_update_hotlist_button(struct gui_window_2 *gwin);
nserror ami_gui_new_blank_tab(struct gui_window_2 *gwin);
-char *ami_gui_get_cache_favicon_name(struct nsurl *url, bool only_if_avail);
int ami_gui_count_windows(int window, int *tabs);
void ami_gui_set_scale(struct gui_window *gw, float scale);
@@ -200,9 +217,9 @@ void ami_gui_set_scale(struct gui_window *gw, float scale);
/**
* Close a window and all tabs attached to it.
*
- * @param gwin gui_window_2 to act upon.
+ * @param w gui_window_2 to act upon.
*/
-void ami_gui_close_window(struct gui_window_2 *gwin);
+void ami_gui_close_window(void *w);
/**
* Close all tabs in a window except the active one.
@@ -250,5 +267,27 @@ void ami_gui_set_default_gg(void);
* Switch to the most-recently-opened tab
*/
void ami_gui_switch_to_new_tab(struct gui_window_2 *gwin);
+
+/**
+ * Add a window to the NetSurf window list (to enable event processing)
+ */
+nserror ami_gui_win_list_add(void *win, int type, const struct ami_win_event_table *table);
+
+/**
+ * Remove a window from the NetSurf window list
+ */
+void ami_gui_win_list_remove(void *win);
+
+/**
+ * Get which qualifier keys are being pressed
+ */
+int ami_gui_get_quals(Object *win_obj);
+
+/**
+ * Check rect is not already queued for redraw
+ */
+bool ami_gui_window_update_box_deferred_check(struct MinList *deferred_rects,
+ const struct rect *restrict new_rect, APTR mempool);
+
#endif
diff --git a/frontends/amiga/gui_menu.c b/frontends/amiga/gui_menu.c
new file mode 100644
index 0000000..6b9b207
--- /dev/null
+++ b/frontends/amiga/gui_menu.c
@@ -0,0 +1,1123 @@
+/*
+ * Copyright 2017 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "amiga/os3support.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <proto/dos.h>
+#include <proto/asl.h>
+#include <proto/exec.h>
+#include <proto/gadtools.h>
+#include <proto/intuition.h>
+#include <proto/utility.h>
+#ifdef __amigaos4__
+#include <dos/anchorpath.h>
+#include <dos/obsolete.h> /* Needed for ExAll() */
+#endif
+
+#include <libraries/gadtools.h>
+#ifdef __amigaos4__
+#include <intuition/menuclass.h>
+#endif
+
+#include <classes/window.h>
+#include <proto/label.h>
+#include <images/label.h>
+#include <proto/bitmap.h>
+#include <images/bitmap.h>
+
+#include <reaction/reaction_macros.h>
+
+#include "utils/nsoption.h"
+#include "utils/messages.h"
+#include "utils/log.h"
+#include "utils/utils.h"
+#include "utils/nsurl.h"
+#include "netsurf/browser_window.h"
+#include "netsurf/mouse.h"
+#include "netsurf/window.h"
+#include "netsurf/content.h"
+#include "netsurf/keypress.h"
+#include "desktop/hotlist.h"
+#include "desktop/version.h"
+
+#include "amiga/arexx.h"
+#include "amiga/bitmap.h"
+#include "amiga/clipboard.h"
+#include "amiga/cookies.h"
+#include "amiga/file.h"
+#include "amiga/filetype.h"
+#include "amiga/gui.h"
+#include "amiga/gui_menu.h"
+#include "amiga/gui_options.h"
+#include "amiga/history.h"
+#include "amiga/history_local.h"
+#include "amiga/hotlist.h"
+#include "amiga/libs.h"
+#include "amiga/menu.h"
+#include "amiga/misc.h"
+#include "amiga/nsoption.h"
+#include "amiga/print.h"
+#include "amiga/search.h"
+#include "amiga/theme.h"
+#include "amiga/utf8.h"
+#include "amiga/schedule.h"
+
+#ifdef __amigaos4__
+static struct Menu *restrict gui_menu = NULL;
+static int gui_menu_count = 0;
+struct ami_menu_data *gui_menu_data[AMI_MENU_AREXX_MAX + 1];
+#endif
+
+static bool ami_menu_check_toggled = false;
+static bool menu_quit = false;
+
+const char * const netsurf_version;
+const char * const verdate;
+
+static nserror ami_menu_scan(struct ami_menu_data **md);
+void ami_menu_arexx_scan(struct ami_menu_data **md);
+
+/*
+ * The below functions are called automatically by window.class when menu items are selected.
+ */
+
+HOOKF(void, ami_menu_item_project_newwin, APTR, window, struct IntuiMessage *)
+{
+ nsurl *url;
+ nserror error;
+
+ error = nsurl_create(nsoption_charp(homepage_url), &url);
+ if (error == NSERROR_OK) {
+ error = browser_window_create(BW_CREATE_HISTORY,
+ url,
+ NULL,
+ NULL,
+ NULL);
+ nsurl_unref(url);
+ }
+ if (error != NSERROR_OK) {
+ amiga_warn_user(messages_get_errorcode(error), 0);
+ }
+}
+
+HOOKF(void, ami_menu_item_project_newtab, APTR, window, struct IntuiMessage *)
+{
+ struct gui_window_2 *gwin;
+
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+ ami_gui_new_blank_tab(gwin);
+}
+
+HOOKF(void, ami_menu_item_project_open, APTR, window, struct IntuiMessage *)
+{
+ struct gui_window_2 *gwin;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+
+ ami_file_open(gwin);
+}
+
+HOOKF(void, ami_menu_item_project_save, APTR, window, struct IntuiMessage *)
+{
+ struct gui_window_2 *gwin;
+ ULONG type = (ULONG)hook->h_Data;
+
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+
+ ami_file_save_req(type, gwin, browser_window_get_content(gwin->gw->bw));
+}
+
+HOOKF(void, ami_menu_item_project_closetab, APTR, window, struct IntuiMessage *)
+{
+ struct gui_window_2 *gwin;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+
+ browser_window_destroy(gwin->gw->bw);
+}
+
+HOOKF(void, ami_menu_item_project_closewin, APTR, window, struct IntuiMessage *)
+{
+ struct gui_window_2 *gwin;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+
+ gwin->closed = true;
+}
+
+HOOKF(void, ami_menu_item_project_print, APTR, window, struct IntuiMessage *)
+{
+ struct gui_window_2 *gwin;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+
+ ami_set_pointer(gwin, GUI_POINTER_WAIT, false);
+ ami_print_ui(browser_window_get_content(gwin->gw->bw));
+ ami_reset_pointer(gwin);
+}
+
+HOOKF(void, ami_menu_item_project_about, APTR, window, struct IntuiMessage *)
+{
+ struct gui_window_2 *gwin;
+ char *temp, *temp2;
+ int sel;
+ nsurl *url = NULL;
+ nserror error = NSERROR_OK;
+
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+
+ ami_set_pointer(gwin, GUI_POINTER_WAIT, false);
+
+ temp = ASPrintf("%s|%s|%s", messages_get("OK"),
+ messages_get("HelpCredits"),
+ messages_get("HelpLicence"));
+
+ temp2 = ami_utf8_easy(temp);
+ FreeVec(temp);
+#ifdef __amigaos4__
+ sel = TimedDosRequesterTags(TDR_ImageType,TDRIMAGE_INFO,
+ TDR_TitleString, messages_get("NetSurf"),
+ TDR_Window, gwin->win,
+ TDR_GadgetString, temp2,
+ TDR_FormatString,"NetSurf %s\nBuild date %s\n\nhttp://www.netsurf-browser.org",
+ TDR_Arg1,netsurf_version,
+ TDR_Arg2,verdate,
+ TAG_DONE);
+#else
+ struct EasyStruct about_req = {
+ sizeof(struct EasyStruct),
+ 0,
+ "NetSurf",
+ "NetSurf %s\nBuild date %s\n\nhttp://www.netsurf-browser.org",
+ temp2,
+ };
+
+ sel = EasyRequest(gwin->win, &about_req, NULL, netsurf_version, verdate);
+#endif
+ free(temp2);
+
+ if(sel == 2) {
+ error = nsurl_create("about:credits", &url);
+ } else if(sel == 0) {
+ error = nsurl_create("about:licence", &url);
+ }
+
+ if(url) {
+ if (error == NSERROR_OK) {
+ error = browser_window_create(BW_CREATE_HISTORY,
+ url,
+ NULL,
+ NULL,
+ NULL);
+ nsurl_unref(url);
+ }
+ if (error != NSERROR_OK) {
+ amiga_warn_user(messages_get_errorcode(error), 0);
+ }
+ }
+
+ ami_reset_pointer(gwin);
+}
+
+HOOKF(void, ami_menu_item_project_quit, APTR, window, struct IntuiMessage *)
+{
+ menu_quit = true;
+}
+
+HOOKF(void, ami_menu_item_edit_cut, APTR, window, struct IntuiMessage *)
+{
+ struct gui_window_2 *gwin;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+
+ browser_window_key_press(gwin->gw->bw, NS_KEY_CUT_SELECTION);
+}
+
+HOOKF(void, ami_menu_item_edit_copy, APTR, window, struct IntuiMessage *)
+{
+ struct bitmap *bm;
+ struct gui_window_2 *gwin;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+
+ if(browser_window_can_select(gwin->gw->bw)) {
+ browser_window_key_press(gwin->gw->bw, NS_KEY_COPY_SELECTION);
+ browser_window_key_press(gwin->gw->bw, NS_KEY_CLEAR_SELECTION);
+ }
+ else if((bm = content_get_bitmap(browser_window_get_content(gwin->gw->bw)))) {
+ /** @todo It should be checked that the lifetime of
+ * the objects containing the values returned (and the
+ * constness cast away) is safe.
+ */
+ ami_bitmap_set_url(bm, browser_window_get_url(gwin->gw->bw));
+ ami_bitmap_set_title(bm, browser_window_get_title(gwin->gw->bw));
+ ami_easy_clipboard_bitmap(bm);
+ }
+#ifdef WITH_NS_SVG
+ else if(ami_mime_compare(browser_window_get_content(gwin->gw->bw), "svg") == true) {
+ ami_easy_clipboard_svg(browser_window_get_content(gwin->gw->bw));
+ }
+#endif
+}
+
+HOOKF(void, ami_menu_item_edit_paste, APTR, window, struct IntuiMessage *)
+{
+ struct gui_window_2 *gwin;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+
+ browser_window_key_press(gwin->gw->bw, NS_KEY_PASTE);
+}
+
+HOOKF(void, ami_menu_item_edit_selectall, APTR, window, struct IntuiMessage *)
+{
+ struct gui_window_2 *gwin;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+
+ browser_window_key_press(gwin->gw->bw, NS_KEY_SELECT_ALL);
+ gui_start_selection(gwin->gw);
+}
+
+HOOKF(void, ami_menu_item_edit_clearsel, APTR, window, struct IntuiMessage *)
+{
+ struct gui_window_2 *gwin;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+
+ browser_window_key_press(gwin->gw->bw, NS_KEY_CLEAR_SELECTION);
+}
+
+HOOKF(void, ami_menu_item_edit_undo, APTR, window, struct IntuiMessage *)
+{
+ struct gui_window_2 *gwin;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+
+ browser_window_key_press(gwin->gw->bw, NS_KEY_UNDO);
+}
+
+HOOKF(void, ami_menu_item_edit_redo, APTR, window, struct IntuiMessage *)
+{
+ struct gui_window_2 *gwin;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+
+ browser_window_key_press(gwin->gw->bw, NS_KEY_REDO);
+}
+
+HOOKF(void, ami_menu_item_browser_find, APTR, window, struct IntuiMessage *)
+{
+ struct gui_window_2 *gwin;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+
+ ami_search_open(gwin->gw);
+}
+
+HOOKF(void, ami_menu_item_browser_localhistory, APTR, window, struct IntuiMessage *)
+{
+ struct gui_window_2 *gwin;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+
+ ami_history_open(gwin->gw);
+}
+
+HOOKF(void, ami_menu_item_browser_globalhistory, APTR, window, struct IntuiMessage *)
+{
+ ami_history_global_present();
+}
+
+HOOKF(void, ami_menu_item_browser_cookies, APTR, window, struct IntuiMessage *)
+{
+ ami_cookies_present();
+}
+
+HOOKF(void, ami_menu_item_browser_foreimg, APTR, window, struct IntuiMessage *)
+{
+ struct Menu *menustrip;
+ bool checked = false;
+
+ GetAttr(WINDOW_MenuStrip, (Object *)window, (ULONG *)&menustrip);
+ checked = ami_menu_get_selected(menustrip, msg);
+
+ nsoption_set_bool(foreground_images, checked);
+ ami_gui_menu_set_check_toggled();
+}
+
+HOOKF(void, ami_menu_item_browser_backimg, APTR, window, struct IntuiMessage *)
+{
+ struct Menu *menustrip;
+ bool checked = false;
+
+ GetAttr(WINDOW_MenuStrip, (Object *)window, (ULONG *)&menustrip);
+ checked = ami_menu_get_selected(menustrip, msg);
+
+ nsoption_set_bool(background_images, checked);
+ ami_gui_menu_set_check_toggled();
+}
+
+HOOKF(void, ami_menu_item_browser_enablejs, APTR, window, struct IntuiMessage *)
+{
+ struct Menu *menustrip;
+ bool checked = false;
+
+ GetAttr(WINDOW_MenuStrip, (Object *)window, (ULONG *)&menustrip);
+ checked = ami_menu_get_selected(menustrip, msg);
+
+ nsoption_set_bool(enable_javascript, checked);
+ ami_gui_menu_set_check_toggled();
+}
+
+HOOKF(void, ami_menu_item_browser_scale_decrease, APTR, window, struct IntuiMessage *)
+{
+ struct gui_window_2 *gwin;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+
+ ami_gui_set_scale(gwin->gw, gwin->gw->scale - 0.1);
+}
+
+HOOKF(void, ami_menu_item_browser_scale_normal, APTR, window, struct IntuiMessage *)
+{
+ struct gui_window_2 *gwin;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+
+ ami_gui_set_scale(gwin->gw, 1.0);
+}
+
+HOOKF(void, ami_menu_item_browser_scale_increase, APTR, window, struct IntuiMessage *)
+{
+ struct gui_window_2 *gwin;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+
+ ami_gui_set_scale(gwin->gw, gwin->gw->scale + 0.1);
+}
+
+HOOKF(void, ami_menu_item_browser_redraw, APTR, window, struct IntuiMessage *)
+{
+ struct gui_window_2 *gwin;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+
+ ami_schedule_redraw(gwin, true);
+ gwin->new_content = true;
+}
+
+HOOKF(void, ami_menu_item_hotlist_add, APTR, window, struct IntuiMessage *)
+{
+ struct browser_window *bw;
+ struct gui_window_2 *gwin;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+
+ bw = gwin->gw->bw;
+
+ if (bw == NULL || browser_window_has_content(bw) == false)
+ return;
+
+ hotlist_add_url(browser_window_get_url(bw));
+ ami_gui_update_hotlist_button(gwin);
+}
+
+HOOKF(void, ami_menu_item_hotlist_show, APTR, window, struct IntuiMessage *)
+{
+ ami_hotlist_present();
+}
+
+HOOKF(void, ami_menu_item_hotlist_entries, APTR, window, struct IntuiMessage *)
+{
+ nsurl *url = hook->h_Data;
+ struct gui_window_2 *gwin;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+
+ if(url == NULL) return;
+
+ browser_window_navigate(gwin->gw->bw,
+ url,
+ NULL,
+ BW_NAVIGATE_HISTORY,
+ NULL,
+ NULL,
+ NULL);
+}
+
+HOOKF(void, ami_menu_item_settings_edit, APTR, window, struct IntuiMessage *)
+{
+ ami_gui_opts_open();
+}
+
+HOOKF(void, ami_menu_item_settings_snapshot, APTR, window, struct IntuiMessage *)
+{
+ struct gui_window_2 *gwin;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+
+ nsoption_set_int(window_x, gwin->win->LeftEdge);
+ nsoption_set_int(window_y, gwin->win->TopEdge);
+ nsoption_set_int(window_width, gwin->win->Width);
+ nsoption_set_int(window_height, gwin->win->Height);
+}
+
+HOOKF(void, ami_menu_item_settings_save, APTR, window, struct IntuiMessage *)
+{
+ ami_nsoption_write();
+}
+
+HOOKF(void, ami_menu_item_arexx_execute, APTR, window, struct IntuiMessage *)
+{
+ char *temp;
+ struct gui_window_2 *gwin;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+
+ if(AslRequestTags(filereq,
+ ASLFR_Window, gwin->win,
+ ASLFR_SleepWindow, TRUE,
+ ASLFR_TitleText, messages_get("NetSurf"),
+ ASLFR_Screen, scrn,
+ ASLFR_DoSaveMode, FALSE,
+ ASLFR_InitialDrawer, nsoption_charp(arexx_dir),
+ ASLFR_InitialPattern, "#?.nsrx",
+ TAG_DONE)) {
+ if((temp = malloc(1024))) {
+ strlcpy(temp, filereq->fr_Drawer, 1024);
+ AddPart(temp, filereq->fr_File, 1024);
+ ami_arexx_execute(temp);
+ free(temp);
+ }
+ }
+}
+
+HOOKF(void, ami_menu_item_arexx_entries, APTR, window, struct IntuiMessage *)
+{
+ char *script = hook->h_Data;
+ char *temp;
+ struct gui_window_2 *gwin;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+
+ if(script) {
+ if((temp = malloc(1024))) {
+ BPTR lock;
+ if((lock = Lock(nsoption_charp(arexx_dir), SHARED_LOCK))) {
+ DevNameFromLock(lock, temp, 1024, DN_FULLPATH);
+ AddPart(temp, script, 1024);
+ ami_arexx_execute(temp);
+ free(temp);
+ UnLock(lock);
+ }
+ }
+ }
+}
+
+/* normal GUI-specific menu functions */
+
+ULONG ami_gui_menu_number(int item)
+{
+ /* horrible, horrible, horrible */
+ ULONG menu_num;
+
+ switch(item) {
+ case M_SAVETXT:
+ menu_num = FULLMENUNUM(0,4,1);
+ break;
+
+ case M_SAVECOMP:
+ menu_num = FULLMENUNUM(0,4,2);
+ break;
+
+ case M_SAVEIFF:
+ menu_num = FULLMENUNUM(0,4,3);
+ break;
+#ifdef WITH_PDF_EXPORT
+ case M_SAVEPDF:
+ menu_num = FULLMENUNUM(0,4,4);
+ break;
+#endif
+ case M_CLOSETAB:
+ menu_num = FULLMENUNUM(0,8,0);
+ break;
+
+ case M_CUT:
+ menu_num = FULLMENUNUM(1,0,0);
+ break;
+
+ case M_COPY:
+ menu_num = FULLMENUNUM(1,1,0);
+ break;
+
+ case M_PASTE:
+ menu_num = FULLMENUNUM(1,2,0);
+ break;
+
+ case M_SELALL:
+ menu_num = FULLMENUNUM(1,4,0);
+ break;
+
+ case M_CLEAR:
+ menu_num = FULLMENUNUM(1,5,0);
+ break;
+
+ case M_UNDO:
+ menu_num = FULLMENUNUM(1,8,0);
+ break;
+
+ case M_REDO:
+ menu_num = FULLMENUNUM(1,9,0);
+ break;
+
+ case M_FIND:
+ menu_num = FULLMENUNUM(2,0,0);
+ break;
+
+ case M_IMGFORE:
+ menu_num = FULLMENUNUM(2,8,0);
+ break;
+
+ case M_IMGBACK:
+ menu_num = FULLMENUNUM(2,8,1);
+ break;
+
+ case M_JS:
+ menu_num = FULLMENUNUM(2,9,0);
+ break;
+
+ default:
+ LOG("WARNING: Unrecognised menu item %d", item);
+ menu_num = 0;
+ break;
+ }
+
+ return menu_num;
+}
+
+#ifdef __amigaos4__
+static void ami_gui_menu_set_checked_mc(struct Menu *menu, int item, bool check)
+{
+ ULONG check_state = MS_CHECKED;
+
+ if(check == false) {
+ check_state = 0;
+ }
+
+ if(menu == NULL) {
+ menu = gui_menu;
+ }
+
+ IDoMethod((Object *)menu, MM_SETSTATE, 0, item, MS_CHECKED, check_state);
+}
+#endif
+
+static void ami_gui_menu_set_checked_gt(struct Menu *menu, int item, bool check)
+{
+ if(menu == NULL) {
+ return;
+ }
+
+ if(check == true) {
+ if((ItemAddress(menu, ami_gui_menu_number(item))->Flags & CHECKED) == 0)
+ ItemAddress(menu, ami_gui_menu_number(item))->Flags ^= CHECKED;
+ } else {
+ if(ItemAddress(menu, ami_gui_menu_number(item))->Flags & CHECKED)
+ ItemAddress(menu, ami_gui_menu_number(item))->Flags ^= CHECKED;
+ }
+}
+
+void ami_gui_menu_set_checked(struct Menu *menu, int item, bool check)
+{
+ if(LIB_IS_AT_LEAST((struct Library *)IntuitionBase, 54, 6)) {
+#ifdef __amigaos4__
+ return ami_gui_menu_set_checked_mc(menu, item, check);
+#endif
+ } else {
+ return ami_gui_menu_set_checked_gt(menu, item, check);
+ }
+}
+
+#ifdef __amigaos4__
+static void ami_gui_menu_set_disabled_mc(struct Window *win, struct Menu *menu, int item, bool disable)
+{
+ ULONG disable_state = MS_DISABLED;
+
+ if(disable == false) {
+ disable_state = 0;
+ }
+
+ IDoMethod((Object *)menu, MM_SETSTATE, 0, item, MS_DISABLED, disable_state);
+}
+#endif
+
+static void ami_gui_menu_set_disabled_gt(struct Window *win, struct Menu *menu, int item, bool disable)
+{
+ ULONG menu_num = ami_gui_menu_number(item);
+
+ if(disable == false) {
+ OnMenu(win, menu_num);
+ } else {
+ OffMenu(win, menu_num);
+ }
+}
+
+void ami_gui_menu_set_disabled(struct Window *win, struct Menu *menu, int item, bool disable)
+{
+ if(LIB_IS_AT_LEAST((struct Library *)IntuitionBase, 54, 6)) {
+#ifdef __amigaos4__
+ return ami_gui_menu_set_disabled_mc(win, menu, item, disable);
+#endif
+ } else {
+ return ami_gui_menu_set_disabled_gt(win, menu, item, disable);
+ }
+}
+
+
+void ami_gui_menu_update_checked(struct gui_window_2 *gwin)
+{
+ if(LIB_IS_AT_LEAST((struct Library *)IntuitionBase, 54, 6)) {
+ /* Irrelevant when using MenuClass */
+ return;
+ }
+
+ struct Menu *menustrip;
+
+ GetAttr(WINDOW_MenuStrip, gwin->objects[OID_MAIN], (ULONG *)&menustrip);
+ if(!menustrip) return;
+ if(nsoption_bool(enable_javascript) == true) {
+ if((ItemAddress(menustrip, ami_gui_menu_number(M_JS))->Flags & CHECKED) == 0)
+ ItemAddress(menustrip, ami_gui_menu_number(M_JS))->Flags ^= CHECKED;
+ } else {
+ if(ItemAddress(menustrip, ami_gui_menu_number(M_JS))->Flags & CHECKED)
+ ItemAddress(menustrip, ami_gui_menu_number(M_JS))->Flags ^= CHECKED;
+ }
+ if(nsoption_bool(foreground_images) == true) {
+ if((ItemAddress(menustrip, ami_gui_menu_number(M_IMGFORE))->Flags & CHECKED) == 0)
+ ItemAddress(menustrip, ami_gui_menu_number(M_IMGFORE))->Flags ^= CHECKED;
+ } else {
+ if(ItemAddress(menustrip, ami_gui_menu_number(M_IMGFORE))->Flags & CHECKED)
+ ItemAddress(menustrip, ami_gui_menu_number(M_IMGFORE))->Flags ^= CHECKED;
+ }
+
+ if(nsoption_bool(background_images) == true) {
+ if((ItemAddress(menustrip, ami_gui_menu_number(M_IMGBACK))->Flags & CHECKED) == 0)
+ ItemAddress(menustrip, ami_gui_menu_number(M_IMGBACK))->Flags ^= CHECKED;
+ } else {
+ if(ItemAddress(menustrip, ami_gui_menu_number(M_IMGBACK))->Flags & CHECKED)
+ ItemAddress(menustrip, ami_gui_menu_number(M_IMGBACK))->Flags ^= CHECKED;
+ }
+
+ ResetMenuStrip(gwin->win, menustrip);
+}
+
+void ami_gui_menu_update_disabled(struct gui_window *g, struct hlcache_handle *c)
+{
+ struct Window *win = g->shared->win;
+
+ if(nsoption_bool(kiosk_mode) == true) return;
+
+ if(content_get_type(c) <= CONTENT_CSS)
+ {
+ ami_gui_menu_set_disabled(win, g->shared->imenu, M_SAVETXT, false);
+ ami_gui_menu_set_disabled(win, g->shared->imenu, M_SAVECOMP, false);
+#ifdef WITH_PDF_EXPORT
+ ami_gui_menu_set_disabled(win, g->shared->imenu, M_SAVEPDF, false);
+#endif
+#if 0
+ if(browser_window_get_editor_flags(g->bw) & BW_EDITOR_CAN_COPY) {
+ OnMenu(win,AMI_MENU_COPY);
+ OnMenu(win,AMI_MENU_CLEAR);
+ } else {
+ OffMenu(win,AMI_MENU_COPY);
+ OffMenu(win,AMI_MENU_CLEAR);
+ }
+
+ if(browser_window_get_editor_flags(g->bw) & BW_EDITOR_CAN_CUT)
+ OnMenu(win,AMI_MENU_CUT);
+ else
+ OffMenu(win,AMI_MENU_CUT);
+
+ if(browser_window_get_editor_flags(g->bw) & BW_EDITOR_CAN_PASTE)
+ OnMenu(win,AMI_MENU_PASTE);
+ else
+ OffMenu(win,AMI_MENU_PASTE);
+#else
+ ami_gui_menu_set_disabled(win, g->shared->imenu, M_CUT, false);
+ ami_gui_menu_set_disabled(win, g->shared->imenu, M_COPY, false);
+ ami_gui_menu_set_disabled(win, g->shared->imenu, M_PASTE, false);
+ ami_gui_menu_set_disabled(win, g->shared->imenu, M_CLEAR, false);
+#endif
+ ami_gui_menu_set_disabled(win, g->shared->imenu, M_SELALL, false);
+ ami_gui_menu_set_disabled(win, g->shared->imenu, M_FIND, false);
+ ami_gui_menu_set_disabled(win, g->shared->imenu, M_SAVEIFF, true);
+ }
+ else
+ {
+ ami_gui_menu_set_disabled(win, g->shared->imenu, M_CUT, true);
+ ami_gui_menu_set_disabled(win, g->shared->imenu, M_PASTE, true);
+ ami_gui_menu_set_disabled(win, g->shared->imenu, M_CLEAR, true);
+
+ ami_gui_menu_set_disabled(win, g->shared->imenu, M_SAVETXT, true);
+ ami_gui_menu_set_disabled(win, g->shared->imenu, M_SAVECOMP, true);
+#ifdef WITH_PDF_EXPORT
+ ami_gui_menu_set_disabled(win, g->shared->imenu, M_SAVEPDF, true);
+#endif
+
+ ami_gui_menu_set_disabled(win, g->shared->imenu, M_SELALL, true);
+ ami_gui_menu_set_disabled(win, g->shared->imenu, M_FIND, true);
+
+#ifdef WITH_NS_SVG
+ if(content_get_bitmap(c) || (ami_mime_compare(c, "svg") == true))
+#else
+ if(content_get_bitmap(c))
+#endif
+ {
+ ami_gui_menu_set_disabled(win, g->shared->imenu, M_COPY, false);
+ ami_gui_menu_set_disabled(win, g->shared->imenu, M_SAVEIFF, false);
+ }
+ else
+ {
+ ami_gui_menu_set_disabled(win, g->shared->imenu, M_COPY, true);
+ ami_gui_menu_set_disabled(win, g->shared->imenu, M_SAVEIFF, true);
+ }
+ }
+}
+
+void ami_gui_menu_set_check_toggled(void)
+{
+ if(LIB_IS_AT_LEAST((struct Library *)IntuitionBase, 54, 6)) {
+ /* Irrelevant when using MenuClass */
+ return;
+ }
+
+ ami_menu_check_toggled = true;
+}
+
+bool ami_gui_menu_get_check_toggled(void)
+{
+ if(LIB_IS_AT_LEAST((struct Library *)IntuitionBase, 54, 6)) {
+ /* Irrelevant when using MenuClass */
+ return false;
+ }
+
+ bool check_toggled = ami_menu_check_toggled;
+ ami_menu_check_toggled = false;
+ return check_toggled;
+}
+
+void ami_menu_arexx_scan(struct ami_menu_data **md)
+{
+ /**\todo Rewrite this to not use ExAll() **/
+ int item = AMI_MENU_AREXX;
+ BPTR lock = 0;
+ UBYTE *buffer;
+ struct ExAllControl *ctrl;
+ char matchpatt[16];
+ LONG cont;
+ struct ExAllData *ead;
+ char *menu_lab;
+
+ if((lock = Lock(nsoption_charp(arexx_dir), SHARED_LOCK))) {
+ if((buffer = malloc(1024))) {
+ if((ctrl = AllocDosObject(DOS_EXALLCONTROL,NULL))) {
+ ctrl->eac_LastKey = 0;
+
+ if(ParsePatternNoCase("#?.nsrx",(char *)&matchpatt,16) != -1) {
+ ctrl->eac_MatchString = (char *)&matchpatt;
+ }
+
+ do {
+ cont = ExAll(lock,(struct ExAllData *)buffer,1024,ED_COMMENT,ctrl);
+ if((!cont) && (IoErr() != ERROR_NO_MORE_ENTRIES)) break;
+ if(!ctrl->eac_Entries) continue;
+
+ for(ead = (struct ExAllData *)buffer; ead; ead = ead->ed_Next) {
+ if(item >= AMI_MENU_AREXX_MAX) continue;
+ if(EAD_IS_FILE(ead)) {
+ if(ead->ed_Comment[0] != '\0')
+ menu_lab = ead->ed_Comment;
+ else
+ menu_lab = ead->ed_Name;
+
+ ami_menu_alloc_item(md, item, NM_ITEM, menu_lab, NULL, NSA_SPACE,
+ ami_menu_item_arexx_entries, (void *)strdup(ead->ed_Name), 0);
+
+ item++;
+ }
+ }
+ } while(cont);
+ FreeDosObject(DOS_EXALLCONTROL,ctrl);
+ }
+ free(buffer);
+ }
+ UnLock(lock);
+ }
+
+ ami_menu_alloc_item(md, item, NM_END, NULL, NULL, NULL, NULL, NULL, 0);
+}
+
+static bool ami_menu_hotlist_add(void *userdata, int level, int item, const char *title, nsurl *url, bool is_folder)
+{
+ UBYTE type;
+ STRPTR icon;
+ UWORD flags = 0;
+ struct ami_menu_data **md = (struct ami_menu_data **)userdata;
+
+ if(item >= AMI_MENU_HOTLIST_MAX) return false;
+
+ switch(level) {
+ case 1:
+ type = NM_ITEM;
+ break;
+ case 2:
+ type = NM_SUB;
+ break;
+ default:
+ if(LIB_IS_AT_LEAST((struct Library *)IntuitionBase, 54, 6)) {
+ type = NM_SUB + (level - 2);
+ } else {
+ /* entries not at level 1 or 2 are not able to be added */
+ return false;
+ }
+ break;
+ }
+
+ if(is_folder == true) {
+ icon = ASPrintf("icons/directory.png");
+ } else {
+ icon = ami_gui_get_cache_favicon_name(url, true);
+ if (icon == NULL) icon = ASPrintf("icons/content.png");
+ }
+
+ if(!LIB_IS_AT_LEAST((struct Library *)IntuitionBase, 54, 6)) {
+ if((is_folder == true) && (type == NM_SUB)) {
+ flags = NM_ITEMDISABLED;
+ }
+ }
+
+ ami_menu_alloc_item(md, item, type, title,
+ NULL, icon, ami_menu_item_hotlist_entries, (void *)url, flags);
+
+ if(icon) FreeVec(icon);
+
+ return true;
+}
+
+static nserror ami_menu_scan(struct ami_menu_data **md)
+{
+ ami_menu_alloc_item(md, M_HLADD, NM_ITEM, "HotlistAdd", "B", "TBImages:list_favouriteadd",
+ ami_menu_item_hotlist_add, NULL, 0);
+ ami_menu_alloc_item(md, M_HLSHOW, NM_ITEM,"HotlistShowNS", "H", "TBImages:list_favourite",
+ ami_menu_item_hotlist_show, NULL, 0);
+ ami_menu_alloc_item(md, M_BAR_H1, NM_ITEM, NM_BARLABEL, NULL, NULL, NULL, NULL, 0);
+
+ return ami_hotlist_scan((void *)md, AMI_MENU_HOTLIST, messages_get("HotlistMenu"), ami_menu_hotlist_add);
+}
+
+static void ami_init_menulabs(struct ami_menu_data **md)
+{
+ UWORD js_flags = CHECKIT | MENUTOGGLE;
+ if(nsoption_bool(enable_javascript) == true)
+ js_flags |= CHECKED;
+
+ UWORD imgfore_flags = CHECKIT | MENUTOGGLE;
+ if(nsoption_bool(foreground_images) == true)
+ imgfore_flags |= CHECKED;
+
+ UWORD imgback_flags = CHECKIT | MENUTOGGLE;
+ if(nsoption_bool(background_images) == true)
+ imgback_flags |= CHECKED;
+
+ ami_menu_alloc_item(md, M_PROJECT, NM_TITLE, "Project", NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, M_NEWWIN, NM_ITEM, "NewWindowNS", "N", "TBImages:list_app",
+ ami_menu_item_project_newwin, NULL, 0);
+ ami_menu_alloc_item(md, M_NEWTAB, NM_ITEM, "NewTab", "T", "TBImages:list_tab",
+ ami_menu_item_project_newtab, NULL, 0);
+ ami_menu_alloc_item(md, M_BAR_P1, NM_ITEM, NM_BARLABEL, NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, M_OPEN, NM_ITEM, "OpenFile", "O", "TBImages:list_folder_misc",
+ ami_menu_item_project_open, NULL, 0);
+ ami_menu_alloc_item(md, M_SAVEAS, NM_ITEM, "SaveAsNS", NULL, "TBImages:list_saveas", NULL, NULL, 0);
+ ami_menu_alloc_item(md, M_SAVESRC, NM_SUB, "Source", "S", NULL,
+ ami_menu_item_project_save, (void *)AMINS_SAVE_SOURCE, 0);
+ ami_menu_alloc_item(md, M_SAVETXT, NM_SUB, "TextNS", NULL, NULL,
+ ami_menu_item_project_save, (void *)AMINS_SAVE_TEXT, 0);
+ ami_menu_alloc_item(md, M_SAVECOMP, NM_SUB, "SaveCompNS", NULL, NULL,
+ ami_menu_item_project_save, (void *)AMINS_SAVE_COMPLETE, 0);
+#ifdef WITH_PDF_EXPORT
+ ami_menu_alloc_item(md, M_SAVEPDF, NM_SUB, "PDFNS", NULL, NULL,
+ ami_menu_item_project_save, (void *)AMINS_SAVE_PDF, 0);
+#endif
+ ami_menu_alloc_item(md, M_SAVEIFF, NM_SUB, "IFF", NULL, NULL,
+ ami_menu_item_project_save, (void *)AMINS_SAVE_IFF, 0);
+ ami_menu_alloc_item(md, M_BAR_P2, NM_ITEM, NM_BARLABEL, NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, M_PRINT, NM_ITEM, "PrintNS", "P", "TBImages:list_print",
+ ami_menu_item_project_print, NULL, NM_ITEMDISABLED);
+ ami_menu_alloc_item(md, M_BAR_P3, NM_ITEM, NM_BARLABEL, NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, M_CLOSETAB, NM_ITEM, "CloseTab", "K", "TBImages:list_remove",
+ ami_menu_item_project_closetab, NULL, 0);
+ ami_menu_alloc_item(md, M_CLOSEWIN, NM_ITEM, "CloseWindow", NULL, "TBImages:list_cancel",
+ ami_menu_item_project_closewin, NULL, 0);
+ ami_menu_alloc_item(md, M_BAR_P4, NM_ITEM, NM_BARLABEL, NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, M_ABOUT, NM_ITEM, "About", "?", "TBImages:list_info",
+ ami_menu_item_project_about, NULL, 0);
+ ami_menu_alloc_item(md, M_BAR_P5, NM_ITEM, NM_BARLABEL, NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, M_QUIT, NM_ITEM, "Quit", "Q", "TBImages:list_warning",
+ ami_menu_item_project_quit, NULL, 0);
+
+ ami_menu_alloc_item(md, M_EDIT, NM_TITLE, "Edit", NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, M_CUT, NM_ITEM, "CutNS", "X", "TBImages:list_cut",
+ ami_menu_item_edit_cut, NULL, 0);
+ ami_menu_alloc_item(md, M_COPY, NM_ITEM, "CopyNS", "C", "TBImages:list_copy",
+ ami_menu_item_edit_copy, NULL, 0);
+ ami_menu_alloc_item(md, M_PASTE, NM_ITEM, "PasteNS", "V", "TBImages:list_paste",
+ ami_menu_item_edit_paste, NULL, 0);
+ ami_menu_alloc_item(md, M_BAR_E1, NM_ITEM, NM_BARLABEL, NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, M_SELALL, NM_ITEM, "SelectAllNS", "A", NSA_SPACE,
+ ami_menu_item_edit_selectall, NULL, 0);
+ ami_menu_alloc_item(md, M_CLEAR, NM_ITEM, "ClearNS", NULL, NSA_SPACE,
+ ami_menu_item_edit_clearsel, NULL, 0);
+ ami_menu_alloc_item(md, M_BAR_E2, NM_ITEM, NM_BARLABEL, NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, M_UNDO, NM_ITEM, "Undo", "Z", "TBImages:list_undo",
+ ami_menu_item_edit_undo, NULL, 0);
+ ami_menu_alloc_item(md, M_REDO, NM_ITEM, "Redo", "Y", "TBImages:list_redo",
+ ami_menu_item_edit_redo, NULL, 0);
+
+ ami_menu_alloc_item(md, M_BROWSER, NM_TITLE, "Browser", NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, M_FIND, NM_ITEM, "FindTextNS", "F", "TBImages:list_search",
+ ami_menu_item_browser_find, NULL, 0);
+ ami_menu_alloc_item(md, M_BAR_B1, NM_ITEM, NM_BARLABEL, NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, M_HISTLOCL, NM_ITEM, "HistLocalNS", NULL, "TBImages:list_history",
+ ami_menu_item_browser_localhistory, NULL, 0);
+ ami_menu_alloc_item(md, M_HISTGLBL, NM_ITEM, "HistGlobalNS", NULL, "TBImages:list_history",
+ ami_menu_item_browser_globalhistory, NULL, 0);
+ ami_menu_alloc_item(md, M_BAR_B2, NM_ITEM, NM_BARLABEL, NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, M_COOKIES, NM_ITEM, "ShowCookiesNS",NULL, "TBImages:list_internet",
+ ami_menu_item_browser_cookies, NULL, 0);
+ ami_menu_alloc_item(md, M_BAR_B3, NM_ITEM, NM_BARLABEL, NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, M_SCALE, NM_ITEM, "ScaleNS", NULL, "TBImages:list_preview", NULL, NULL, 0);
+ ami_menu_alloc_item(md, M_SCALEDEC, NM_SUB, "ScaleDec", "-", "TBImages:list_zoom_out",
+ ami_menu_item_browser_scale_decrease, NULL, 0);
+ ami_menu_alloc_item(md, M_SCALENRM, NM_SUB, "ScaleNorm", "=", "TBImages:list_zoom_100",
+ ami_menu_item_browser_scale_normal, NULL, 0);
+ ami_menu_alloc_item(md, M_SCALEINC, NM_SUB, "ScaleInc", "+", "TBImages:list_zoom_in",
+ ami_menu_item_browser_scale_increase, NULL, 0);
+ ami_menu_alloc_item(md, M_IMAGES, NM_ITEM, "Images", NULL, "TBImages:list_image", NULL, NULL, 0);
+ ami_menu_alloc_item(md, M_IMGFORE, NM_SUB, "ForeImg", NULL, NULL,
+ ami_menu_item_browser_foreimg, NULL, imgfore_flags);
+ ami_menu_alloc_item(md, M_IMGBACK, NM_SUB, "BackImg", NULL, NULL,
+ ami_menu_item_browser_backimg, NULL, imgback_flags);
+ ami_menu_alloc_item(md, M_JS, NM_ITEM, "EnableJS", NULL, NULL,
+ ami_menu_item_browser_enablejs, NULL, js_flags);
+ ami_menu_alloc_item(md, M_BAR_B4, NM_ITEM, NM_BARLABEL, NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, M_REDRAW, NM_ITEM, "Redraw", NULL, "TBImages:list_wand",
+ ami_menu_item_browser_redraw, NULL, 0);
+
+ ami_menu_alloc_item(md, M_HOTLIST, NM_TITLE, "Hotlist", NULL, NULL, NULL, NULL, 0);
+ /* see ami_menu_scan for the rest of this menu */
+
+ ami_menu_alloc_item(md, M_PREFS, NM_TITLE, "Settings", NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, M_PREDIT, NM_ITEM, "SettingsEdit", NULL, "TBImages:list_prefs",
+ ami_menu_item_settings_edit, NULL, 0);
+ ami_menu_alloc_item(md, M_BAR_S1, NM_ITEM, NM_BARLABEL, NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, M_SNAPSHOT, NM_ITEM, "SnapshotWindow",NULL, "TBImages:list_hold",
+ ami_menu_item_settings_snapshot, NULL, 0);
+ ami_menu_alloc_item(md, M_PRSAVE, NM_ITEM, "SettingsSave", NULL, "TBImages:list_use",
+ ami_menu_item_settings_save, NULL, 0);
+
+ ami_menu_alloc_item(md, M_AREXX, NM_TITLE, "ARexx", NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, M_AREXXEX, NM_ITEM, "ARexxExecute", "E", "TBImages:list_arexx",
+ ami_menu_item_arexx_execute, NULL, 0);
+ ami_menu_alloc_item(md, M_BAR_A1, NM_ITEM, NM_BARLABEL, NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, AMI_MENU_AREXX_MAX, NM_END, NULL, NULL, NULL, NULL, NULL, 0);
+}
+
+struct Menu *ami_gui_menu_create(struct gui_window_2 *gwin)
+{
+ if(LIB_IS_AT_LEAST((struct Library *)IntuitionBase, 54, 6)) {
+#ifdef __amigaos4__
+ if(gui_menu != NULL) {
+ gwin->imenu = gui_menu;
+ gui_menu_count++;
+ return gwin->imenu;
+ }
+ ami_init_menulabs(gui_menu_data);
+ ami_menu_scan(gui_menu_data);
+ ami_menu_arexx_scan(gui_menu_data);
+ gwin->imenu = ami_menu_layout(gui_menu_data, AMI_MENU_AREXX_MAX);
+
+ gui_menu = gwin->imenu;
+ gui_menu_count++;
+#endif
+ } else {
+ ami_init_menulabs(gwin->menu_data);
+ ami_menu_scan(gwin->menu_data);
+ ami_menu_arexx_scan(gwin->menu_data);
+ gwin->imenu = ami_menu_layout(gwin->menu_data, AMI_MENU_AREXX_MAX);
+ }
+
+ return gwin->imenu;
+}
+
+static void ami_free_menulabs(struct ami_menu_data **md)
+{
+ int i;
+
+ for(i=0;i<=AMI_MENU_AREXX_MAX;i++) {
+ if(md[i] == NULL) continue;
+ if(md[i]->menulab &&
+ (md[i]->menulab != NM_BARLABEL) &&
+ (md[i]->menulab != ML_SEPARATOR)) {
+ if(md[i]->menutype & MENU_IMAGE) {
+ if(md[i]->menuobj) DisposeObject(md[i]->menuobj);
+ }
+
+ ami_utf8_free(md[i]->menulab);
+
+ if(i >= AMI_MENU_AREXX) {
+ if(md[i]->menu_hook.h_Data) free(md[i]->menu_hook.h_Data);
+ md[i]->menu_hook.h_Data = NULL;
+ }
+ }
+
+ if(md[i]->menukey != NULL) free(md[i]->menukey);
+
+ md[i]->menulab = NULL;
+ md[i]->menuobj = NULL;
+ md[i]->menukey = NULL;
+ md[i]->menutype = 0;
+ free(md[i]);
+ md[i] = NULL;
+ }
+}
+
+void ami_gui_menu_free(struct gui_window_2 *gwin)
+{
+ if(LIB_IS_AT_LEAST((struct Library *)IntuitionBase, 54, 6)) {
+#ifdef __amigaos4__
+ gui_menu_count--;
+
+ SetAttrs(gwin->objects[OID_MAIN], WINDOW_MenuStrip, NULL, TAG_DONE);
+
+ if(gui_menu_count == 0) {
+ ami_free_menulabs(gui_menu_data);
+ // if we detach our menu from the window we need to do this manually
+ DisposeObject((Object *)gui_menu);
+ gui_menu = NULL;
+ }
+#endif
+ } else {
+ ami_free_menulabs(gwin->menu_data);
+ FreeMenus(gwin->imenu);
+ }
+}
+
+bool ami_gui_menu_quit_selected(void)
+{
+ return menu_quit;
+}
+
+void ami_gui_menu_refresh_hotlist(void)
+{
+#ifdef __amigaos4__
+ ami_menu_refresh(gui_menu, gui_menu_data, M_HOTLIST, AMI_MENU_HOTLIST_MAX, ami_menu_scan);
+#endif
+}
+
diff --git a/frontends/amiga/menu.h b/frontends/amiga/gui_menu.h
old mode 100755
new mode 100644
similarity index 63%
copy from frontends/amiga/menu.h
copy to frontends/amiga/gui_menu.h
index ac74f38..16fc720
--- a/frontends/amiga/menu.h
+++ b/frontends/amiga/gui_menu.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008,2009,2013 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
+ * Copyright 2008-2017 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -16,17 +16,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef AMIGA_MENU_H
-#define AMIGA_MENU_H
-
-#include <exec/types.h>
-#include <intuition/intuition.h>
-#include <libraries/gadtools.h>
-
-struct hlcache_handle;
+#ifndef AMIGA_GUI_MENU_H
+#define AMIGA_GUI_MENU_H
/** Maximum number of hotlist items (somewhat arbitrary value) */
-#define AMI_HOTLIST_ITEMS 60
+#define AMI_HOTLIST_ITEMS 200
/** Maximum number of ARexx menu items (somewhat arbitrary value) */
#define AMI_MENU_AREXX_ITEMS 20
@@ -111,39 +105,21 @@ enum {
* only used for freeing the UTF-8 converted menu labels */
#define AMI_MENU_MAX AMI_MENU_AREXX
-/* The Intuition menu numbers of some menus we might need to modify */
-#define AMI_MENU_SAVEAS_TEXT FULLMENUNUM(0,4,1)
-#define AMI_MENU_SAVEAS_COMPLETE FULLMENUNUM(0,4,2)
-#define AMI_MENU_SAVEAS_IFF FULLMENUNUM(0,4,3)
-#define AMI_MENU_SAVEAS_PDF FULLMENUNUM(0,4,4)
-#define AMI_MENU_CLOSETAB FULLMENUNUM(0,8,0)
-#define AMI_MENU_CUT FULLMENUNUM(1,0,0)
-#define AMI_MENU_COPY FULLMENUNUM(1,1,0)
-#define AMI_MENU_PASTE FULLMENUNUM(1,2,0)
-#define AMI_MENU_SELECTALL FULLMENUNUM(1,4,0)
-#define AMI_MENU_CLEAR FULLMENUNUM(1,5,0)
-#define AMI_MENU_UNDO FULLMENUNUM(1,8,0)
-#define AMI_MENU_REDO FULLMENUNUM(1,9,0)
-#define AMI_MENU_FIND FULLMENUNUM(2,0,0)
-#define AMI_MENU_FOREIMG FULLMENUNUM(2,8,0)
-#define AMI_MENU_BACKIMG FULLMENUNUM(2,8,1)
-#define AMI_MENU_JS FULLMENUNUM(2,9,0)
-
struct gui_window;
struct gui_window_2;
+struct hlcache_handle;
+
+ULONG ami_gui_menu_number(int item);
+struct Menu *ami_gui_menu_create(struct gui_window_2 *gwin);
+void ami_gui_menu_free(struct gui_window_2 *gwin);
-void ami_free_menulabs(struct gui_window_2 *gwin);
-struct Menu *ami_menu_create(struct gui_window_2 *gwin);
-void ami_menu_refresh(struct gui_window_2 *gwin);
-void ami_menu_update_checked(struct gui_window_2 *gwin);
-void ami_menu_update_disabled(struct gui_window *g, struct hlcache_handle *c);
-void ami_menu_free_glyphs(void);
-void ami_menu_free(struct gui_window_2 *gwin);
+void ami_gui_menu_update_checked(struct gui_window_2 *gwin);
+void ami_gui_menu_update_disabled(struct gui_window *g, struct hlcache_handle *c);
/**
* Sets that an item linked to a toggle menu item has been changed.
*/
-void ami_menu_set_check_toggled(void);
+void ami_gui_menu_set_check_toggled(void);
/**
* Gets if the menu needs updating because an item linked
@@ -152,13 +128,30 @@ void ami_menu_set_check_toggled(void);
*
* \return true if the menus need refreshing
*/
-bool ami_menu_get_check_toggled(void);
+bool ami_gui_menu_get_check_toggled(void);
+
+/**
+ * Set checked state of a menu item
+ * almost generic, but not quite
+ */
+void ami_gui_menu_set_checked(struct Menu *menu, int item, bool check);
+
+/**
+ * Set disabled state of a menu item
+ * almost generic, but not quite
+ */
+void ami_gui_menu_set_disabled(struct Window *win, struct Menu *menu, int item, bool disable);
+
+/**
+ * Refresh the Hotlist menu
+ */
+void ami_gui_menu_refresh_hotlist(void);
/**
* Gets if NetSurf has been quit from the menu
*
* \return true if NetSurf has been quit
*/
-bool ami_menu_quit_selected(void);
+bool ami_gui_menu_quit_selected(void);
#endif
diff --git a/frontends/amiga/gui_options.c b/frontends/amiga/gui_options.c
index 2b1b7c9..78dea58 100755
--- a/frontends/amiga/gui_options.c
+++ b/frontends/amiga/gui_options.c
@@ -70,10 +70,10 @@
#include "amiga/font.h"
#include "amiga/font_bullet.h"
#include "amiga/gui.h"
+#include "amiga/gui_menu.h"
#include "amiga/gui_options.h"
#include "amiga/help.h"
#include "amiga/libs.h"
-#include "amiga/misc.h"
#include "amiga/nsoption.h"
#include "amiga/object.h"
#include "amiga/selectmenu.h"
@@ -221,7 +221,7 @@ enum {
};
struct ami_gui_opts_window {
- struct nsObject *node;
+ struct ami_generic_window w;
struct Window *win;
Object *objects[GID_OPTS_LAST];
#ifndef __amigaos4__
@@ -234,6 +234,14 @@ struct ami_gui_opts_window {
#endif
};
+static BOOL ami_gui_opts_event(void *w);
+static void ami_gui_opts_close(void *w);
+
+static const struct ami_win_event_table ami_guiopts_table = {
+ ami_gui_opts_event,
+ ami_gui_opts_close,
+};
+
static struct ami_gui_opts_window *gow = NULL;
static CONST_STRPTR tabs[OPTS_MAX_TABS];
@@ -636,7 +644,7 @@ void ami_gui_opts_open(void)
if(!gow)
{
- gow = ami_misc_allocvec_clear(sizeof(struct ami_gui_opts_window), 0);
+ gow = calloc(1, sizeof(struct ami_gui_opts_window));
if(gow == NULL) return;
ami_gui_opts_setup(gow);
@@ -1668,8 +1676,7 @@ void ami_gui_opts_open(void)
EndWindow;
gow->win = (struct Window *)RA_OpenWindow(gow->objects[OID_MAIN]);
- gow->node = AddObject(window_list,AMINS_GUIOPTSWINDOW);
- gow->node->objstruct = gow;
+ ami_gui_win_list_add(gow, AMINS_GUIOPTSWINDOW, &ami_guiopts_table);
}
ami_utf8_free(homepage_url_lc);
}
@@ -1720,7 +1727,9 @@ static void ami_gui_opts_use(bool save)
} else {
nsoption_set_bool(enable_javascript, false);
}
-
+
+ ami_gui_menu_set_checked(NULL, M_JS, nsoption_bool(enable_javascript));
+
GetAttr(GA_Selected,gow->objects[GID_OPTS_DONOTTRACK],(ULONG *)&data);
if (data) {
nsoption_set_bool(do_not_track, true);
@@ -2060,19 +2069,19 @@ static void ami_gui_opts_use(bool save)
ami_font_savescanner(); /* just in case it has changed and been used only */
}
- ami_menu_set_check_toggled();
+ ami_gui_menu_set_check_toggled();
ami_update_pointer(gow->win, GUI_POINTER_DEFAULT);
}
-void ami_gui_opts_close(void)
+static void ami_gui_opts_close(void *w)
{
DisposeObject(gow->objects[OID_MAIN]);
ami_gui_opts_free(gow);
- DelObject(gow->node);
+ ami_gui_win_list_remove(gow);
gow = NULL;
}
-BOOL ami_gui_opts_event(void)
+static BOOL ami_gui_opts_event(void *w)
{
/* return TRUE if window destroyed */
ULONG result,data = 0;
@@ -2084,7 +2093,7 @@ BOOL ami_gui_opts_event(void)
switch(result & WMHI_CLASSMASK) // class
{
case WMHI_CLOSEWINDOW:
- ami_gui_opts_close();
+ ami_gui_opts_close(gow);
return TRUE;
break;
@@ -2103,7 +2112,7 @@ BOOL ami_gui_opts_event(void)
{
case GID_OPTS_SAVE:
ami_gui_opts_use(true);
- ami_gui_opts_close();
+ ami_gui_opts_close(gow);
return TRUE;
break;
@@ -2112,7 +2121,7 @@ BOOL ami_gui_opts_event(void)
// fall through
case GID_OPTS_CANCEL:
- ami_gui_opts_close();
+ ami_gui_opts_close(gow);
return TRUE;
break;
@@ -2284,7 +2293,7 @@ struct List *ami_gui_opts_websearch(void)
const char *name;
int iter;
- list = AllocVecTagList(sizeof(struct List), NULL);
+ list = malloc(sizeof(struct List));
NewList(list);
if (nsoption_charp(search_engines_file) == NULL) return list;
@@ -2314,6 +2323,6 @@ void ami_gui_opts_websearch_free(struct List *websearchlist)
FreeChooserNode(node);
} while((node = nnode));
- FreeVec(websearchlist);
+ free(websearchlist);
}
diff --git a/frontends/amiga/gui_options.h b/frontends/amiga/gui_options.h
index abb0b11..7de35cc 100755
--- a/frontends/amiga/gui_options.h
+++ b/frontends/amiga/gui_options.h
@@ -20,8 +20,6 @@
#define AMIGA_GUI_OPTIONS_H
/* Prefs GUI control */
void ami_gui_opts_open(void);
-BOOL ami_gui_opts_event(void);
-void ami_gui_opts_close(void);
/* Web search list */
struct List *ami_gui_opts_websearch(void);
diff --git a/frontends/amiga/history.c b/frontends/amiga/history.c
old mode 100755
new mode 100644
index 2287c70..12c306a
--- a/frontends/amiga/history.c
+++ b/frontends/amiga/history.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2008, 2009 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
+ * Copyright 2017 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -16,28 +16,457 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+/**
+ * \file
+ * Implementation of Amiga global history viewer using core windows.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
#include <stdbool.h>
-#include <proto/exec.h>
+#include <string.h>
+
+#include <proto/asl.h>
+#include <proto/dos.h>
+#include <proto/intuition.h>
+
+#include <classes/window.h>
+#include <gadgets/layout.h>
+#include <gadgets/space.h>
-#include "utils/errors.h"
-#include "netsurf/mouse.h"
-#include "netsurf/window.h"
+#include <reaction/reaction_macros.h>
+#include "desktop/global_history.h"
+#include "netsurf/browser_window.h"
+#include "netsurf/keypress.h"
+#include "netsurf/plotters.h"
+#include "utils/log.h"
+#include "utils/messages.h"
+#include "utils/nsoption.h"
+
+#include "amiga/corewindow.h"
+#include "amiga/drag.h"
+#include "amiga/file.h"
#include "amiga/history.h"
-#include "amiga/tree.h"
-#include "amiga/tree.h"
+#include "amiga/libs.h"
+#include "amiga/menu.h"
+#include "amiga/theme.h"
+#include "amiga/utf8.h"
+
+enum {
+ /* Project menu */
+ AMI_HISTORY_M_PROJECT = 0,
+ AMI_HISTORY_M_EXPORT,
+ AMI_HISTORY_M_BAR_P1,
+ AMI_HISTORY_M_EXPAND,
+ AMI_HISTORY_M_EXPAND_ALL,
+ AMI_HISTORY_M_EXPAND_FOLDERS,
+ AMI_HISTORY_M_EXPAND_LINKS,
+ AMI_HISTORY_M_COLLAPSE,
+ AMI_HISTORY_M_COLLAPSE_ALL,
+ AMI_HISTORY_M_COLLAPSE_FOLDERS,
+ AMI_HISTORY_M_COLLAPSE_LINKS,
+ AMI_HISTORY_M_BAR_P2,
+ AMI_HISTORY_M_SNAPSHOT,
+ AMI_HISTORY_M_BAR_P3,
+ AMI_HISTORY_M_CLOSE,
+ /* Edit menu */
+ AMI_HISTORY_M_EDIT,
+ AMI_HISTORY_M_SELECTALL,
+ AMI_HISTORY_M_CLEAR,
+ AMI_HISTORY_M_BAR_E1,
+ AMI_HISTORY_M_DELETE,
+ AMI_HISTORY_M_LAST
+};
+
+/**
+ * Amiga history viewer window context
+ */
+struct ami_history_global_window {
+ /** Amiga core window context */
+ struct ami_corewindow core;
+
+ struct ami_menu_data *menu_data[AMI_HISTORY_M_LAST + 1];
+ struct Menu *imenu; /* Intuition menu */
+};
-struct treeview_window *global_history_window = NULL;
+static struct ami_history_global_window *history_window = NULL;
-void ami_global_history_initialise(void)
+
+static void
+ami_history_global_menu_free(struct ami_history_global_window *history_win)
+{
+ SetAttrs(history_win->core.objects[GID_CW_WIN],
+ WINDOW_MenuStrip, NULL,
+ TAG_DONE);
+
+ ami_menu_free_menu(history_win->menu_data, AMI_HISTORY_M_LAST, history_win->imenu);
+}
+
+/**
+ * destroy a previously created history view
+ */
+static void
+ami_history_global_destroy(struct ami_corewindow *ami_cw)
{
- global_history_window = ami_tree_create(TREE_HISTORY, NULL);
+ nserror res;
- if(!global_history_window) return;
+ if(history_window == NULL)
+ return;
+
+ res = global_history_fini();
+ if (res == NSERROR_OK) {
+ ami_history_global_menu_free(history_window);
+ res = ami_corewindow_fini(&history_window->core); /* closes the window for us, frees history_win */
+ history_window = NULL;
+ }
}
-void ami_global_history_free()
+
+/**
+ * callback for mouse action for history viewer on core window
+ *
+ * \param ami_cw The Amiga core window structure.
+ * \param mouse_state netsurf mouse state on event
+ * \param x location of event
+ * \param y location of event
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+ami_history_global_mouse(struct ami_corewindow *ami_cw,
+ browser_mouse_state mouse_state,
+ int x, int y)
{
- ami_tree_destroy(global_history_window);
- global_history_window = NULL;
+ global_history_mouse_action(mouse_state, x, y);
+
+ return NSERROR_OK;
}
+
+/**
+ * callback for keypress for history viewer on core window
+ *
+ * \param ami_cw The Amiga core window structure.
+ * \param nskey The netsurf key code
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+ami_history_global_key(struct ami_corewindow *ami_cw, uint32_t nskey)
+{
+ if (global_history_keypress(nskey)) {
+ return NSERROR_OK;
+ }
+ return NSERROR_NOT_IMPLEMENTED;
+}
+
+/**
+ * callback on draw event for history viewer on core window
+ *
+ * \param ami_cw The Amiga core window structure.
+ * \param r The rectangle of the window that needs updating.
+ * \param ctx The drawing context
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+ami_history_global_draw(struct ami_corewindow *ami_cw, int x, int y, struct rect *r, struct redraw_context *ctx)
+{
+ global_history_redraw(x, y, r, ctx);
+
+ return NSERROR_OK;
+}
+
+/**
+ * callback on drag end for history viewer
+ *
+ * \param ami_cw The Amiga core window structure.
+ * \param x mouse x co-ordinate
+ * \param y mouse y co-ordinate
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+ami_history_global_drag_end(struct ami_corewindow *ami_cw, int x, int y)
+{
+ struct nsurl *url = NULL;
+ const char *title = NULL;
+ bool ok = false;
+ struct gui_window_2 *gwin;
+ struct ami_corewindow *cw;
+
+ if(global_history_has_selection()) {
+ ok = global_history_get_selection(&url, &title);
+ }
+
+ if((ok == false) || (url == NULL)) {
+ DisplayBeep(scrn);
+ } else if(url) {
+ if((gwin = ami_window_at_pointer(AMINS_WINDOW))) {
+ browser_window_navigate(gwin->gw->bw,
+ url,
+ NULL,
+ BW_NAVIGATE_HISTORY,
+ NULL,
+ NULL,
+ NULL);
+ } else if((cw = (struct ami_corewindow *)ami_window_at_pointer(AMINS_COREWINDOW)) &&
+ (ami_cw->icon_drop != NULL)) {
+ cw->icon_drop(cw, url, title, x, y);
+ }
+ }
+ return NSERROR_OK;
+}
+
+/**
+ * menu stuff
+ */
+
+ /* menu hook functions */
+HOOKF(void, ami_history_global_menu_item_project_export, APTR, window, struct IntuiMessage *)
+{
+ char fname[1024];
+ struct ami_corewindow *ami_cw;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&ami_cw);
+
+ if(AslRequestTags(savereq,
+ ASLFR_Window, ami_cw->win,
+ ASLFR_SleepWindow, TRUE,
+ ASLFR_TitleText, messages_get("NetSurf"),
+ ASLFR_Screen, scrn,
+ ASLFR_InitialFile, "history.html",
+ TAG_DONE)) {
+ strlcpy(fname, savereq->fr_Drawer, 1024);
+ AddPart(fname, savereq->fr_File, 1024);
+ ami_update_pointer(ami_cw->win, GUI_POINTER_WAIT);
+ global_history_export(fname, NULL);
+ ami_update_pointer(ami_cw->win, GUI_POINTER_DEFAULT);
+ }
+}
+
+HOOKF(void, ami_history_global_menu_item_project_expand_all, APTR, window, struct IntuiMessage *)
+{
+ global_history_expand(false);
+}
+
+HOOKF(void, ami_history_global_menu_item_project_expand_folders, APTR, window, struct IntuiMessage *)
+{
+ global_history_expand(true);
+}
+
+HOOKF(void, ami_history_global_menu_item_project_expand_links, APTR, window, struct IntuiMessage *)
+{
+ global_history_expand(false);
+}
+
+HOOKF(void, ami_history_global_menu_item_project_collapse_all, APTR, window, struct IntuiMessage *)
+{
+ global_history_contract(true);
+}
+
+HOOKF(void, ami_history_global_menu_item_project_collapse_folders, APTR, window, struct IntuiMessage *)
+{
+ global_history_contract(true);
+}
+
+HOOKF(void, ami_history_global_menu_item_project_collapse_links, APTR, window, struct IntuiMessage *)
+{
+ global_history_contract(false);
+}
+
+HOOKF(void, ami_history_global_menu_item_project_snapshot, APTR, window, struct IntuiMessage *)
+{
+ struct ami_corewindow *ami_cw;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&ami_cw);
+
+ nsoption_set_int(history_window_ypos, ami_cw->win->TopEdge);
+ nsoption_set_int(history_window_xpos, ami_cw->win->LeftEdge);
+ nsoption_set_int(history_window_xsize, ami_cw->win->Width);
+ nsoption_set_int(history_window_ysize, ami_cw->win->Height);
+}
+
+HOOKF(void, ami_history_global_menu_item_project_close, APTR, window, struct IntuiMessage *)
+{
+ struct ami_corewindow *ami_cw;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&ami_cw);
+
+ ami_cw->close_window = true;
+}
+
+HOOKF(void, ami_history_global_menu_item_edit_select_all, APTR, window, struct IntuiMessage *)
+{
+ global_history_keypress(NS_KEY_SELECT_ALL);
+}
+
+HOOKF(void, ami_history_global_menu_item_edit_clear, APTR, window, struct IntuiMessage *)
+{
+ global_history_keypress(NS_KEY_CLEAR_SELECTION);
+}
+
+HOOKF(void, ami_history_global_menu_item_edit_delete, APTR, window, struct IntuiMessage *)
+{
+ global_history_keypress(NS_KEY_DELETE_LEFT);
+}
+
+
+/* menu setup */
+
+static void ami_history_global_menulabs(struct ami_menu_data **md)
+{
+ ami_menu_alloc_item(md, AMI_HISTORY_M_PROJECT, NM_TITLE, "Tree", NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HISTORY_M_EXPORT, NM_ITEM, "TreeExport", "S", "TBImages:list_save",
+ ami_history_global_menu_item_project_export, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HISTORY_M_BAR_P1, NM_ITEM, NM_BARLABEL, NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HISTORY_M_EXPAND, NM_ITEM, "Expand", NULL, "TBImages:list_folderunfold", NULL, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HISTORY_M_EXPAND_ALL, NM_SUB, "All", "+", NULL,
+ ami_history_global_menu_item_project_expand_all, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HISTORY_M_EXPAND_FOLDERS, NM_SUB, "Folders", NULL, NULL,
+ ami_history_global_menu_item_project_expand_folders, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HISTORY_M_EXPAND_LINKS, NM_SUB, "Links", NULL, NULL,
+ ami_history_global_menu_item_project_expand_links, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HISTORY_M_COLLAPSE, NM_ITEM, "Collapse", NULL, "TBImages:list_folderfold", NULL, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HISTORY_M_COLLAPSE_ALL, NM_SUB, "All", "-", NULL,
+ ami_history_global_menu_item_project_collapse_all, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HISTORY_M_COLLAPSE_FOLDERS, NM_SUB, "Folders", NULL, NULL,
+ ami_history_global_menu_item_project_collapse_folders, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HISTORY_M_COLLAPSE_LINKS, NM_SUB, "Links", NULL, NULL,
+ ami_history_global_menu_item_project_collapse_links, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HISTORY_M_BAR_P2, NM_ITEM, NM_BARLABEL, NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HISTORY_M_SNAPSHOT, NM_ITEM, "SnapshotWindow", NULL, "TBImages:list_hold",
+ ami_history_global_menu_item_project_snapshot, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HISTORY_M_BAR_P3, NM_ITEM, NM_BARLABEL, NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HISTORY_M_CLOSE, NM_ITEM, "CloseWindow", "K", "TBImages:list_cancel",
+ ami_history_global_menu_item_project_close, NULL, 0);
+
+ ami_menu_alloc_item(md, AMI_HISTORY_M_EDIT, NM_TITLE, "Edit", NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HISTORY_M_SELECTALL, NM_ITEM, "SelectAllNS", "A", NSA_SPACE,
+ ami_history_global_menu_item_edit_select_all, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HISTORY_M_CLEAR, NM_ITEM, "ClearNS", NULL, NSA_SPACE,
+ ami_history_global_menu_item_edit_clear, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HISTORY_M_BAR_E1, NM_ITEM, NM_BARLABEL, NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HISTORY_M_DELETE, NM_ITEM, "TreeDelete", "Del", "TBImages:list_delete",
+ ami_history_global_menu_item_edit_delete, NULL, 0);
+
+ ami_menu_alloc_item(md, AMI_HISTORY_M_LAST, NM_END, NULL, NULL, NULL, NULL, NULL, 0);
+}
+
+static struct Menu *
+ami_history_global_menu_create(struct ami_history_global_window *history_win)
+{
+ ami_history_global_menulabs(history_win->menu_data);
+ history_win->imenu = ami_menu_layout(history_win->menu_data, AMI_HISTORY_M_LAST);
+ if(history_win->imenu == NULL) return NULL;
+
+ return history_win->imenu;
+}
+
+
+static nserror
+ami_history_global_create_window(struct ami_history_global_window *history_win)
+{
+ struct ami_corewindow *ami_cw = (struct ami_corewindow *)&history_win->core;
+ ULONG refresh_mode = WA_SmartRefresh;
+
+ if(nsoption_bool(window_simple_refresh) == true) {
+ refresh_mode = WA_SimpleRefresh;
+ }
+
+ ami_cw->objects[GID_CW_WIN] = WindowObj,
+ WA_ScreenTitle, ami_gui_get_screen_title(),
+ WA_Title, ami_cw->wintitle,
+ WA_Activate, TRUE,
+ WA_DepthGadget, TRUE,
+ WA_DragBar, TRUE,
+ WA_CloseGadget, TRUE,
+ WA_SizeGadget, TRUE,
+ WA_SizeBRight, TRUE,
+ WA_Top, nsoption_int(history_window_ypos),
+ WA_Left, nsoption_int(history_window_xpos),
+ WA_Width, nsoption_int(history_window_xsize),
+ WA_Height, nsoption_int(history_window_ysize),
+ WA_PubScreen, scrn,
+ WA_ReportMouse, TRUE,
+ refresh_mode, TRUE,
+ WA_IDCMP, IDCMP_MOUSEMOVE | IDCMP_MOUSEBUTTONS | IDCMP_NEWSIZE |
+ IDCMP_RAWKEY | IDCMP_GADGETUP | IDCMP_IDCMPUPDATE |
+ IDCMP_EXTENDEDMOUSE | IDCMP_SIZEVERIFY | IDCMP_REFRESHWINDOW,
+ WINDOW_IDCMPHook, &ami_cw->idcmp_hook,
+ WINDOW_IDCMPHookBits, IDCMP_IDCMPUPDATE | IDCMP_EXTENDEDMOUSE |
+ IDCMP_SIZEVERIFY | IDCMP_REFRESHWINDOW,
+ WINDOW_SharedPort, sport,
+ WINDOW_HorizProp, 1,
+ WINDOW_VertProp, 1,
+ WINDOW_UserData, history_win,
+ WINDOW_MenuStrip, ami_history_global_menu_create(history_win),
+ WINDOW_MenuUserData, WGUD_HOOK,
+ WINDOW_IconifyGadget, FALSE,
+ WINDOW_Position, WPOS_CENTERSCREEN,
+ WINDOW_ParentGroup, ami_cw->objects[GID_CW_MAIN] = LayoutVObj,
+ LAYOUT_AddChild, ami_cw->objects[GID_CW_DRAW] = SpaceObj,
+ GA_ID, GID_CW_DRAW,
+ SPACE_Transparent, TRUE,
+ SPACE_BevelStyle, BVS_DISPLAY,
+ GA_RelVerify, TRUE,
+ SpaceEnd,
+ EndGroup,
+ EndWindow;
+
+ if(ami_cw->objects[GID_CW_WIN] == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ return NSERROR_OK;
+}
+
+/* exported interface documented in amiga/cookies.h */
+nserror ami_history_global_present(void)
+{
+ struct ami_history_global_window *ncwin;
+ nserror res;
+
+ if(history_window != NULL) {
+ //windowtofront()
+ return NSERROR_OK;
+ }
+
+ ncwin = calloc(1, sizeof(struct ami_history_global_window));
+ if (ncwin == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ ncwin->core.wintitle = ami_utf8_easy((char *)messages_get("GlobalHistory"));
+
+ res = ami_history_global_create_window(ncwin);
+ if (res != NSERROR_OK) {
+ LOG("SSL UI builder init failed");
+ ami_utf8_free(ncwin->core.wintitle);
+ free(ncwin);
+ return res;
+ }
+
+ /* initialise Amiga core window */
+ ncwin->core.draw = ami_history_global_draw;
+ ncwin->core.key = ami_history_global_key;
+ ncwin->core.mouse = ami_history_global_mouse;
+ ncwin->core.close = ami_history_global_destroy;
+ ncwin->core.event = NULL;
+ ncwin->core.drag_end = ami_history_global_drag_end;
+ ncwin->core.icon_drop = NULL;
+
+ res = ami_corewindow_init(&ncwin->core);
+ if (res != NSERROR_OK) {
+ ami_utf8_free(ncwin->core.wintitle);
+ DisposeObject(ncwin->core.objects[GID_CW_WIN]);
+ free(ncwin);
+ return res;
+ }
+
+ res = global_history_init(ncwin->core.cb_table, (struct core_window *)ncwin);
+ if (res != NSERROR_OK) {
+ ami_utf8_free(ncwin->core.wintitle);
+ DisposeObject(ncwin->core.objects[GID_CW_WIN]);
+ free(ncwin);
+ return res;
+ }
+
+ history_window = ncwin;
+
+ return NSERROR_OK;
+}
+
diff --git a/frontends/amiga/history.h b/frontends/amiga/history.h
old mode 100755
new mode 100644
index d20cfe0..67ab670
--- a/frontends/amiga/history.h
+++ b/frontends/amiga/history.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008,2009 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
+ * Copyright 2017 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -16,14 +16,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef AMIGA_HISTORY_H
-#define AMIGA_HISTORY_H
-#include "desktop/tree.h"
+#ifndef AMIGA_HISTORY_GLOBAL_H
+#define AMIGA_HISTORY_GLOBAL_H
-#define GLOBAL_HISTORY_RECENT_URLS 16
-
-void ami_global_history_initialise(void);
-void ami_global_history_free(void);
-
-extern struct treeview_window *global_history_window;
+/** Open the global history viewer */
+nserror ami_history_global_present(void);
#endif
+
diff --git a/frontends/amiga/history_local.c b/frontends/amiga/history_local.c
index c87b563..3d1c6f3 100755
--- a/frontends/amiga/history_local.c
+++ b/frontends/amiga/history_local.c
@@ -57,9 +57,25 @@
#include "amiga/gui.h"
#include "amiga/history_local.h"
+struct history_window {
+ struct ami_generic_window w;
+ struct Window *win;
+ Object *objects[GID_LAST];
+ struct gui_window *gw;
+ struct Hook scrollerhook;
+ struct gui_globals *gg;
+};
+
static void ami_history_update_extent(struct history_window *hw);
HOOKF(void, ami_history_scroller_hook, Object *, object, struct IntuiMessage *);
+static BOOL ami_history_event(void *w);
+
+static const struct ami_win_event_table ami_localhistory_table = {
+ ami_history_event,
+ NULL, /* we don't explicitly close the local history window on quit */
+};
+
/**
* Redraw history window.
*/
@@ -116,8 +132,8 @@ void ami_history_open(struct gui_window *gw)
if(!gw->hw)
{
- gw->hw = ami_misc_allocvec_clear(sizeof(struct history_window), 0);
- gw->hw->gg = ami_misc_allocvec_clear(sizeof(struct gui_globals), 0);
+ gw->hw = calloc(1, sizeof(struct history_window));
+ gw->hw->gg = calloc(1, sizeof(struct gui_globals));
ami_init_layers(gw->hw->gg, scrn->Width, scrn->Height, false);
@@ -159,8 +175,7 @@ void ami_history_open(struct gui_window *gw)
EndWindow;
gw->hw->win = (struct Window *)RA_OpenWindow(gw->hw->objects[OID_MAIN]);
- gw->hw->node = AddObject(window_list,AMINS_HISTORYWINDOW);
- gw->hw->node->objstruct = gw->hw;
+ ami_gui_win_list_add(gw->hw, AMINS_HISTORYWINDOW, &ami_localhistory_table);
GetAttr(WINDOW_HorizObject,gw->hw->objects[OID_MAIN],(ULONG *)&gw->hw->objects[OID_HSCROLL]);
GetAttr(WINDOW_VertObject,gw->hw->objects[OID_MAIN],(ULONG *)&gw->hw->objects[OID_VSCROLL]);
@@ -226,15 +241,16 @@ static bool ami_history_click(struct history_window *hw, uint16 code)
void ami_history_close(struct history_window *hw)
{
ami_free_layers(hw->gg);
- FreeVec(hw->gg);
+ free(hw->gg);
hw->gw->hw = NULL;
DisposeObject(hw->objects[OID_MAIN]);
- DelObject(hw->node);
+ ami_gui_win_list_remove(hw);
}
-BOOL ami_history_event(struct history_window *hw)
+static BOOL ami_history_event(void *w)
{
/* return TRUE if window destroyed */
+ struct history_window *hw = (struct history_window *)w;
ULONG result = 0;
uint16 code;
const char *url;
diff --git a/frontends/amiga/history_local.h b/frontends/amiga/history_local.h
index 284da34..97aea05 100755
--- a/frontends/amiga/history_local.h
+++ b/frontends/amiga/history_local.h
@@ -24,15 +24,7 @@
struct gui_window;
struct gui_globals;
-
-struct history_window {
- struct nsObject *node;
- struct Window *win;
- Object *objects[GID_LAST];
- struct gui_window *gw;
- struct Hook scrollerhook;
- struct gui_globals *gg;
-};
+struct history_window;
/**
* Open history window.
@@ -42,7 +34,5 @@ struct history_window {
void ami_history_open(struct gui_window *gw);
void ami_history_close(struct history_window *hw);
-BOOL ami_history_event(struct history_window *hw);
-
#endif
diff --git a/frontends/amiga/hotlist.c b/frontends/amiga/hotlist.c
old mode 100755
new mode 100644
index fc2342d..008e45a
--- a/frontends/amiga/hotlist.c
+++ b/frontends/amiga/hotlist.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2008, 2009 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
+ * Copyright 2008, 2009, 2017 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -16,16 +16,85 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+/**
+ * \file
+ * Implementation of Amiga hotlist viewer using core windows.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdbool.h>
#include <string.h>
-#include <proto/exec.h>
-#include "utils/nsurl.h"
+#include <proto/asl.h>
+#include <proto/dos.h>
+#include <proto/intuition.h>
+
+#include <classes/window.h>
+#include <gadgets/layout.h>
+#include <gadgets/space.h>
+
+#include <reaction/reaction_macros.h>
+
#include "desktop/hotlist.h"
-#include "netsurf/mouse.h"
-#include "netsurf/window.h"
+#include "netsurf/browser_window.h"
+#include "netsurf/keypress.h"
+#include "netsurf/plotters.h"
+#include "utils/log.h"
+#include "utils/messages.h"
+#include "utils/nsoption.h"
+#include "amiga/corewindow.h"
+#include "amiga/drag.h"
+#include "amiga/file.h"
#include "amiga/hotlist.h"
-#include "amiga/tree.h"
+#include "amiga/libs.h"
+#include "amiga/menu.h"
+#include "amiga/theme.h"
+#include "amiga/utf8.h"
+
+enum {
+ /* Project menu */
+ AMI_HOTLIST_M_PROJECT = 0,
+ AMI_HOTLIST_M_EXPORT,
+ AMI_HOTLIST_M_BAR_P1,
+ AMI_HOTLIST_M_EXPAND,
+ AMI_HOTLIST_M_EXPAND_ALL,
+ AMI_HOTLIST_M_EXPAND_FOLDERS,
+ AMI_HOTLIST_M_EXPAND_LINKS,
+ AMI_HOTLIST_M_COLLAPSE,
+ AMI_HOTLIST_M_COLLAPSE_ALL,
+ AMI_HOTLIST_M_COLLAPSE_FOLDERS,
+ AMI_HOTLIST_M_COLLAPSE_LINKS,
+ AMI_HOTLIST_M_BAR_P2,
+ AMI_HOTLIST_M_SNAPSHOT,
+ AMI_HOTLIST_M_BAR_P3,
+ AMI_HOTLIST_M_CLOSE,
+ /* Edit menu */
+ AMI_HOTLIST_M_EDIT,
+ AMI_HOTLIST_M_NEWFOLDER,
+ AMI_HOTLIST_M_NEWLINK,
+ AMI_HOTLIST_M_EDIT_EDIT,
+ AMI_HOTLIST_M_BAR_E1,
+ AMI_HOTLIST_M_SELECTALL,
+ AMI_HOTLIST_M_CLEAR,
+ AMI_HOTLIST_M_BAR_E2,
+ AMI_HOTLIST_M_DELETE,
+ AMI_HOTLIST_M_LAST
+};
+
+/**
+ * Amiga hotlist viewer window context
+ */
+struct ami_hotlist_window {
+ /** Amiga core window context */
+ struct ami_corewindow core;
+
+ struct ami_menu_data *menu_data[AMI_HOTLIST_M_LAST + 1];
+ struct Menu *imenu; /* Intuition menu */
+};
+
+static struct ami_hotlist_window *hotlist_window = NULL;
struct ami_hotlist_ctx {
void *userdata;
@@ -37,22 +106,7 @@ struct ami_hotlist_ctx {
bool (*cb)(void *userdata, int level, int item, const char *title, nsurl *url, bool folder);
};
-struct treeview_window *hotlist_window = NULL;
-
-void ami_hotlist_initialise(const char *hotlist_file)
-{
- tree_hotlist_path = hotlist_file;
- hotlist_window = ami_tree_create(TREE_HOTLIST, NULL);
- if(!hotlist_window) return;
-}
-
-void ami_hotlist_free(const char *hotlist_file)
-{
- ami_tree_destroy(hotlist_window);
- hotlist_window = NULL;
-}
-
-
+/** hotlist scanner */
static nserror ami_hotlist_folder_enter_cb(void *ctx, const char *title)
{
struct ami_hotlist_ctx *menu_ctx = (struct ami_hotlist_ctx *)ctx;
@@ -118,3 +172,433 @@ nserror ami_hotlist_scan(void *userdata, int first_item, const char *folder,
return error;
}
+
+
+/**
+ * callback for mouse action for hotlist viewer on core window
+ *
+ * \param ami_cw The Amiga core window structure.
+ * \param mouse_state netsurf mouse state on event
+ * \param x location of event
+ * \param y location of event
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+ami_hotlist_mouse(struct ami_corewindow *ami_cw,
+ browser_mouse_state mouse_state,
+ int x, int y)
+{
+ hotlist_mouse_action(mouse_state, x, y);
+
+ return NSERROR_OK;
+}
+
+/**
+ * callback for keypress for hotlist viewer on core window
+ *
+ * \param ami_cw The Amiga core window structure.
+ * \param nskey The netsurf key code
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+ami_hotlist_key(struct ami_corewindow *ami_cw, uint32_t nskey)
+{
+ if (hotlist_keypress(nskey)) {
+ return NSERROR_OK;
+ }
+ return NSERROR_NOT_IMPLEMENTED;
+}
+
+/**
+ * callback on draw event for hotlist viewer on core window
+ *
+ * \param ami_cw The Amiga core window structure.
+ * \param r The rectangle of the window that needs updating.
+ * \param ctx The drawing context
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+ami_hotlist_draw(struct ami_corewindow *ami_cw, int x, int y, struct rect *r, struct redraw_context *ctx)
+{
+ hotlist_redraw(x, y, r, ctx);
+
+ return NSERROR_OK;
+}
+
+/**
+ * callback for drag end on Amiga core window
+ * ie. a drag *from* this window has ended
+ *
+ * \param ami_cw The Amiga core window structure.
+ * \param x mouse x co-ordinate
+ * \param y mouse y co-ordinate
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+ami_hotlist_drag_end(struct ami_corewindow *ami_cw, int x, int y)
+{
+ nsurl *url = NULL;
+ const char *title = NULL;
+ bool ok = false;
+ struct gui_window_2 *gwin;
+ struct ami_corewindow *cw;
+
+ if(hotlist_has_selection()) {
+ ok = hotlist_get_selection(&url, &title);
+ }
+
+ if((ok == false) || (url == NULL)) {
+ DisplayBeep(scrn);
+ } else if(url) {
+ if((gwin = ami_window_at_pointer(AMINS_WINDOW))) {
+ browser_window_navigate(gwin->gw->bw,
+ url,
+ NULL,
+ BW_NAVIGATE_HISTORY,
+ NULL,
+ NULL,
+ NULL);
+ } else if((cw = (struct ami_corewindow *)ami_window_at_pointer(AMINS_COREWINDOW)) &&
+ (ami_cw->icon_drop != NULL)) {
+ cw->icon_drop(cw, url, title, x, y);
+ }
+ }
+ return NSERROR_OK;
+}
+
+/**
+ * callback for icon drop on Amiga core window
+ * ie. a drag has ended *above* this window
+ * \todo this may not be very flexible but serves our current purposes
+ *
+ * \param ami_cw The Amiga core window structure.
+ * \param url url of dropped icon
+ * \param title title of dropped icon
+ * \param x mouse x co-ordinate
+ * \param y mouse y co-ordinate
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+ami_hotlist_icon_drop(struct ami_corewindow *ami_cw, struct nsurl *url, const char *title, int x, int y)
+{
+ hotlist_add_entry(url, title, true, y);
+ return NSERROR_OK;
+}
+
+/**
+ * menu stuff
+ */
+
+static void
+ami_hotlist_menu_free(struct ami_hotlist_window *hotlist_win)
+{
+ SetAttrs(hotlist_win->core.objects[GID_CW_WIN],
+ WINDOW_MenuStrip, NULL,
+ TAG_DONE);
+
+ ami_menu_free_menu(hotlist_win->menu_data, AMI_HOTLIST_M_LAST, hotlist_win->imenu);
+}
+
+ /* menu hook functions */
+HOOKF(void, ami_hotlist_menu_item_project_export, APTR, window, struct IntuiMessage *)
+{
+ char fname[1024];
+ struct ami_corewindow *ami_cw;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&ami_cw);
+
+ if(AslRequestTags(savereq,
+ ASLFR_Window, ami_cw->win,
+ ASLFR_SleepWindow, TRUE,
+ ASLFR_TitleText, messages_get("NetSurf"),
+ ASLFR_Screen, scrn,
+ ASLFR_InitialFile, "hotlist.html",
+ TAG_DONE)) {
+ strlcpy(fname, savereq->fr_Drawer, 1024);
+ AddPart(fname, savereq->fr_File, 1024);
+ ami_update_pointer(ami_cw->win, GUI_POINTER_WAIT);
+ hotlist_export(fname, NULL);
+ ami_update_pointer(ami_cw->win, GUI_POINTER_DEFAULT);
+ }
+}
+
+HOOKF(void, ami_hotlist_menu_item_project_expand_all, APTR, window, struct IntuiMessage *)
+{
+ hotlist_expand(false);
+}
+
+HOOKF(void, ami_hotlist_menu_item_project_expand_folders, APTR, window, struct IntuiMessage *)
+{
+ hotlist_expand(true);
+}
+
+HOOKF(void, ami_hotlist_menu_item_project_expand_links, APTR, window, struct IntuiMessage *)
+{
+ hotlist_expand(false);
+}
+
+HOOKF(void, ami_hotlist_menu_item_project_collapse_all, APTR, window, struct IntuiMessage *)
+{
+ hotlist_contract(true);
+}
+
+HOOKF(void, ami_hotlist_menu_item_project_collapse_folders, APTR, window, struct IntuiMessage *)
+{
+ hotlist_contract(true);
+}
+
+HOOKF(void, ami_hotlist_menu_item_project_collapse_links, APTR, window, struct IntuiMessage *)
+{
+ hotlist_contract(false);
+}
+
+HOOKF(void, ami_hotlist_menu_item_project_snapshot, APTR, window, struct IntuiMessage *)
+{
+ struct ami_corewindow *ami_cw;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&ami_cw);
+
+ nsoption_set_int(hotlist_window_ypos, ami_cw->win->TopEdge);
+ nsoption_set_int(hotlist_window_xpos, ami_cw->win->LeftEdge);
+ nsoption_set_int(hotlist_window_xsize, ami_cw->win->Width);
+ nsoption_set_int(hotlist_window_ysize, ami_cw->win->Height);
+}
+
+HOOKF(void, ami_hotlist_menu_item_project_close, APTR, window, struct IntuiMessage *)
+{
+ struct ami_corewindow *ami_cw;
+ GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&ami_cw);
+
+ ami_cw->close_window = true;
+}
+
+HOOKF(void, ami_hotlist_menu_item_edit_newfolder, APTR, window, struct IntuiMessage *)
+{
+ hotlist_add_folder(NULL, false, 0);
+}
+
+HOOKF(void, ami_hotlist_menu_item_edit_newlink, APTR, window, struct IntuiMessage *)
+{
+ hotlist_add_entry(NULL, NULL, false, 0);
+}
+
+HOOKF(void, ami_hotlist_menu_item_edit_edit, APTR, window, struct IntuiMessage *)
+{
+ hotlist_edit_selection();
+}
+
+HOOKF(void, ami_hotlist_menu_item_edit_select_all, APTR, window, struct IntuiMessage *)
+{
+ hotlist_keypress(NS_KEY_SELECT_ALL);
+}
+
+HOOKF(void, ami_hotlist_menu_item_edit_clear, APTR, window, struct IntuiMessage *)
+{
+ hotlist_keypress(NS_KEY_CLEAR_SELECTION);
+}
+
+HOOKF(void, ami_hotlist_menu_item_edit_delete, APTR, window, struct IntuiMessage *)
+{
+ hotlist_keypress(NS_KEY_DELETE_LEFT);
+}
+
+
+/* menu setup */
+
+static void ami_hotlist_menulabs(struct ami_menu_data **md)
+{
+ ami_menu_alloc_item(md, AMI_HOTLIST_M_PROJECT, NM_TITLE, "Tree", NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HOTLIST_M_EXPORT, NM_ITEM, "TreeExport", "S", "TBImages:list_save",
+ ami_hotlist_menu_item_project_export, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HOTLIST_M_BAR_P1, NM_ITEM, NM_BARLABEL, NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HOTLIST_M_EXPAND, NM_ITEM, "Expand", NULL, "TBImages:list_folderunfold", NULL, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HOTLIST_M_EXPAND_ALL, NM_SUB, "All", "+", NULL,
+ ami_hotlist_menu_item_project_expand_all, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HOTLIST_M_EXPAND_FOLDERS, NM_SUB, "Folders", NULL, NULL,
+ ami_hotlist_menu_item_project_expand_folders, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HOTLIST_M_EXPAND_LINKS, NM_SUB, "Links", NULL, NULL,
+ ami_hotlist_menu_item_project_expand_links, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HOTLIST_M_COLLAPSE, NM_ITEM, "Collapse", NULL, "TBImages:list_folderfold", NULL, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HOTLIST_M_COLLAPSE_ALL, NM_SUB, "All", "-", NULL,
+ ami_hotlist_menu_item_project_collapse_all, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HOTLIST_M_COLLAPSE_FOLDERS, NM_SUB, "Folders", NULL, NULL,
+ ami_hotlist_menu_item_project_collapse_folders, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HOTLIST_M_COLLAPSE_LINKS, NM_SUB, "Links", NULL, NULL,
+ ami_hotlist_menu_item_project_collapse_links, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HOTLIST_M_BAR_P2, NM_ITEM, NM_BARLABEL, NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HOTLIST_M_SNAPSHOT, NM_ITEM, "SnapshotWindow", NULL, "TBImages:list_hold",
+ ami_hotlist_menu_item_project_snapshot, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HOTLIST_M_BAR_P3, NM_ITEM, NM_BARLABEL, NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HOTLIST_M_CLOSE, NM_ITEM, "CloseWindow", "K", "TBImages:list_cancel",
+ ami_hotlist_menu_item_project_close, NULL, 0);
+
+ ami_menu_alloc_item(md, AMI_HOTLIST_M_EDIT, NM_TITLE, "Edit", NULL, NULL, NULL, NULL, 0);
+
+ ami_menu_alloc_item(md, AMI_HOTLIST_M_NEWFOLDER, NM_ITEM, "TreeNewFolder", "N", "TBImages:list_drawer",
+ ami_hotlist_menu_item_edit_newfolder, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HOTLIST_M_NEWLINK, NM_ITEM, "TreeNewLink", NULL, "TBImages:list_favouriteadd",
+ ami_hotlist_menu_item_edit_newlink, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HOTLIST_M_EDIT_EDIT, NM_ITEM, "TreeEdit", "E", "TBImages:list_edit",
+ ami_hotlist_menu_item_edit_edit, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HOTLIST_M_BAR_E1, NM_ITEM, NM_BARLABEL, NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HOTLIST_M_SELECTALL, NM_ITEM, "SelectAllNS", "A", NSA_SPACE,
+ ami_hotlist_menu_item_edit_select_all, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HOTLIST_M_CLEAR, NM_ITEM, "ClearNS", NULL, NSA_SPACE,
+ ami_hotlist_menu_item_edit_clear, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HOTLIST_M_BAR_E2, NM_ITEM, NM_BARLABEL, NULL, NULL, NULL, NULL, 0);
+ ami_menu_alloc_item(md, AMI_HOTLIST_M_DELETE, NM_ITEM, "TreeDelete", "Del", "TBImages:list_delete",
+ ami_hotlist_menu_item_edit_delete, NULL, 0);
+
+ ami_menu_alloc_item(md, AMI_HOTLIST_M_LAST, NM_END, NULL, NULL, NULL, NULL, NULL, 0);
+}
+
+static struct Menu *
+ami_hotlist_menu_create(struct ami_hotlist_window *hotlist_win)
+{
+ ami_hotlist_menulabs(hotlist_win->menu_data);
+ hotlist_win->imenu = ami_menu_layout(hotlist_win->menu_data, AMI_HOTLIST_M_LAST);
+ if(hotlist_win->imenu == NULL) return NULL;
+
+ return hotlist_win->imenu;
+}
+
+
+static nserror
+ami_hotlist_create_window(struct ami_hotlist_window *hotlist_win)
+{
+ struct ami_corewindow *ami_cw = (struct ami_corewindow *)&hotlist_win->core;
+ ULONG refresh_mode = WA_SmartRefresh;
+
+ if(nsoption_bool(window_simple_refresh) == true) {
+ refresh_mode = WA_SimpleRefresh;
+ }
+
+ ami_cw->objects[GID_CW_WIN] = WindowObj,
+ WA_ScreenTitle, ami_gui_get_screen_title(),
+ WA_Title, ami_cw->wintitle,
+ WA_Activate, TRUE,
+ WA_DepthGadget, TRUE,
+ WA_DragBar, TRUE,
+ WA_CloseGadget, TRUE,
+ WA_SizeGadget, TRUE,
+ WA_SizeBRight, TRUE,
+ WA_Top, nsoption_int(hotlist_window_ypos),
+ WA_Left, nsoption_int(hotlist_window_xpos),
+ WA_Width, nsoption_int(hotlist_window_xsize),
+ WA_Height, nsoption_int(hotlist_window_ysize),
+ WA_PubScreen, scrn,
+ WA_ReportMouse, TRUE,
+ refresh_mode, TRUE,
+ WA_IDCMP, IDCMP_MOUSEMOVE | IDCMP_MOUSEBUTTONS | IDCMP_NEWSIZE |
+ IDCMP_RAWKEY | IDCMP_GADGETUP | IDCMP_IDCMPUPDATE |
+ IDCMP_EXTENDEDMOUSE | IDCMP_SIZEVERIFY | IDCMP_REFRESHWINDOW,
+ WINDOW_IDCMPHook, &ami_cw->idcmp_hook,
+ WINDOW_IDCMPHookBits, IDCMP_IDCMPUPDATE | IDCMP_EXTENDEDMOUSE |
+ IDCMP_SIZEVERIFY | IDCMP_REFRESHWINDOW,
+ WINDOW_SharedPort, sport,
+ WINDOW_HorizProp, 1,
+ WINDOW_VertProp, 1,
+ WINDOW_UserData, hotlist_win,
+ WINDOW_MenuStrip, ami_hotlist_menu_create(hotlist_win),
+ WINDOW_MenuUserData, WGUD_HOOK,
+ WINDOW_IconifyGadget, FALSE,
+ WINDOW_Position, WPOS_CENTERSCREEN,
+ WINDOW_ParentGroup, ami_cw->objects[GID_CW_MAIN] = LayoutVObj,
+ LAYOUT_AddChild, ami_cw->objects[GID_CW_DRAW] = SpaceObj,
+ GA_ID, GID_CW_DRAW,
+ SPACE_Transparent, TRUE,
+ SPACE_BevelStyle, BVS_DISPLAY,
+ GA_RelVerify, TRUE,
+ SpaceEnd,
+ EndGroup,
+ EndWindow;
+
+ if(ami_cw->objects[GID_CW_WIN] == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ return NSERROR_OK;
+}
+
+/**
+ * destroy a previously created hotlist view
+ */
+static void
+ami_hotlist_destroy(struct ami_corewindow *ami_cw)
+{
+ nserror res;
+
+ if(hotlist_window == NULL)
+ return;
+
+ res = hotlist_manager_fini();
+ if (res == NSERROR_OK) {
+ ami_hotlist_menu_free(hotlist_window);
+ res = ami_corewindow_fini(&hotlist_window->core); /* closes the window for us, frees hotlist_win */
+ hotlist_window = NULL;
+ }
+
+ ami_gui_hotlist_update_all();
+}
+
+
+/* exported interface documented in amiga/hotlist.h */
+nserror ami_hotlist_present(void)
+{
+ struct ami_hotlist_window *ncwin;
+ nserror res;
+
+ if(hotlist_window != NULL) {
+ //windowtofront()
+ return NSERROR_OK;
+ }
+
+ ncwin = calloc(1, sizeof(struct ami_hotlist_window));
+ if (ncwin == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ ncwin->core.wintitle = ami_utf8_easy((char *)messages_get("Hotlist"));
+
+ res = ami_hotlist_create_window(ncwin);
+ if (res != NSERROR_OK) {
+ LOG("SSL UI builder init failed");
+ ami_utf8_free(ncwin->core.wintitle);
+ free(ncwin);
+ return res;
+ }
+
+ /* initialise Amiga core window */
+ ncwin->core.draw = ami_hotlist_draw;
+ ncwin->core.key = ami_hotlist_key;
+ ncwin->core.mouse = ami_hotlist_mouse;
+ ncwin->core.close = ami_hotlist_destroy;
+ ncwin->core.event = NULL;
+ ncwin->core.drag_end = ami_hotlist_drag_end;
+ ncwin->core.icon_drop = ami_hotlist_icon_drop;
+
+ res = ami_corewindow_init(&ncwin->core);
+ if (res != NSERROR_OK) {
+ ami_utf8_free(ncwin->core.wintitle);
+ DisposeObject(ncwin->core.objects[GID_CW_WIN]);
+ free(ncwin);
+ return res;
+ }
+
+ res = hotlist_manager_init(ncwin->core.cb_table, (struct core_window *)ncwin);
+ if (res != NSERROR_OK) {
+ ami_utf8_free(ncwin->core.wintitle);
+ DisposeObject(ncwin->core.objects[GID_CW_WIN]);
+ free(ncwin);
+ return res;
+ }
+
+ hotlist_window = ncwin;
+
+ return NSERROR_OK;
+}
+
+/* exported interface documented in amiga/hotlist.h */
+void ami_hotlist_close(void)
+{
+ ami_hotlist_destroy((struct ami_corewindow *)hotlist_window);
+}
+
diff --git a/frontends/amiga/hotlist.h b/frontends/amiga/hotlist.h
old mode 100755
new mode 100644
index 113a2d1..588a72d
--- a/frontends/amiga/hotlist.h
+++ b/frontends/amiga/hotlist.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008, 2009 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
+ * Copyright 2017 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -19,16 +19,18 @@
#ifndef AMIGA_HOTLIST_H
#define AMIGA_HOTLIST_H
-struct nsurl;
-struct treeview_window;
+#include "utils/nsurl.h"
-extern struct treeview_window *hotlist_window;
-
-void ami_hotlist_initialise(const char *hotlist_file);
-
-void ami_hotlist_free(const char *hotlist_file);
-
-nserror ami_hotlist_scan(void *userdata, int first_item, const char *folder, bool (*cb_add_item)(void *userdata, int level, int item, const char *title, struct nsurl *url, bool folder));
+/** Open the hotlist viewer */
+nserror ami_hotlist_present(void);
+/** Close the hotlist viewer
+ * normally this shouldn't be used; only exists for ARexx use
+ */
+void ami_hotlist_close(void);
+/** Scan the hotlist */
+nserror ami_hotlist_scan(void *userdata, int first_item, const char *folder,
+ bool (*cb_add_item)(void *userdata, int level, int item, const char *title, nsurl *url, bool folder));
#endif
+
diff --git a/frontends/amiga/icon.c b/frontends/amiga/icon.c
index 7b73360..3f597a1 100644
--- a/frontends/amiga/icon.c
+++ b/frontends/amiga/icon.c
@@ -49,7 +49,6 @@
#include "amiga/os3support.h"
#include "amiga/bitmap.h"
#include "amiga/icon.h"
-#include "amiga/misc.h"
#define THUMBNAIL_WIDTH 100 /* Icon sizes for thumbnails, usually the same as */
#define THUMBNAIL_HEIGHT 86 /* WIDTH/HEIGHT in desktop/thumbnail.c */
@@ -239,7 +238,7 @@ bool amiga_icon_convert(struct content *c)
if(dobj) FreeDiskObject(dobj);
if(format==IDFMT_PALETTEMAPPED)
- FreeVec(imagebufptr);
+ free(imagebufptr);
return true;
}
@@ -326,7 +325,7 @@ static ULONG *amiga_icon_convertcolouricon32(UBYTE *icondata, ULONG width, ULONG
if (alpha==0) alpha=0xff;
- argbicon = (ULONG *)AllocVecTagList(width*height*4, NULL);
+ argbicon = (ULONG *)malloc(width * height * 4);
if (!argbicon) return(NULL);
cmap=GetColorMap(pals1);
@@ -485,8 +484,8 @@ void amiga_icon_superimpose_favicon(char *path, struct hlcache_handle *icon, cha
if(format == IDFMT_PALETTEMAPPED)
{
/* Free the 32-bit data we created */
- FreeVec(icondata1);
- FreeVec(icondata2);
+ free(icondata1);
+ free(icondata2);
}
}
@@ -501,7 +500,7 @@ struct DiskObject *amiga_icon_from_bitmap(struct bitmap *bm)
{
bitmap = ami_bitmap_get_native(bm, THUMBNAIL_WIDTH,
THUMBNAIL_HEIGHT, NULL);
- icondata = AllocVecTagList(THUMBNAIL_WIDTH * 4 * THUMBNAIL_HEIGHT, NULL);
+ icondata = malloc(THUMBNAIL_WIDTH * 4 * THUMBNAIL_HEIGHT);
ami_bitmap_set_icondata(bm, icondata);
if(bitmap) {
@@ -543,6 +542,6 @@ void amiga_icon_free(struct DiskObject *dobj)
struct bitmap *bm = dobj->do_Gadget.UserData;
FreeDiskObject(dobj);
- if(bm) FreeVec(ami_bitmap_get_icondata(bm));
+ if(bm) ami_bitmap_free_icondata(bm);
}
diff --git a/frontends/amiga/iff_dr2d.c b/frontends/amiga/iff_dr2d.c
index aea7738..a4c5855 100644
--- a/frontends/amiga/iff_dr2d.c
+++ b/frontends/amiga/iff_dr2d.c
@@ -19,22 +19,21 @@
#ifdef WITH_NS_SVG
#include <stdio.h>
-#include <inttypes.h>
+#include <stdlib.h>
#include <svgtiny.h>
#include <proto/exec.h>
#include <string.h>
#include <proto/dos.h>
+#include "netsurf/inttypes.h"
#ifndef AMIGA_DR2D_STANDALONE
#include "utils/nsurl.h"
#include "netsurf/content.h"
#include "amiga/os3support.h"
#include "amiga/iff_dr2d.h"
-#include "amiga/misc.h"
#else
#include "os3support.h"
#include "iff_dr2d.h"
-#include "misc.h"
#endif
static struct ColorRegister cm[1000];
@@ -171,7 +170,7 @@ bool ami_svg_to_dr2d(struct IFFHandle *iffh, const char *buffer,
}
for (unsigned int i = 0; i != diagram->shape_count; i++) {
- attr = ami_misc_allocvec_clear(sizeof(struct attr_struct), 0);
+ attr = calloc(1, sizeof(struct attr_struct));
if (diagram->shape[i].fill == svgtiny_TRANSPARENT)
attr->FillType = FT_NONE;
else
@@ -193,7 +192,7 @@ bool ami_svg_to_dr2d(struct IFFHandle *iffh, const char *buffer,
WriteChunkBytes(iffh,attr,14);
PopChunk(iffh);
}
- FreeVec(attr);
+ free(attr);
if (diagram->shape[i].path) {
union {
@@ -272,30 +271,30 @@ bool ami_svg_to_dr2d(struct IFFHandle *iffh, const char *buffer,
PopChunk(iffh);
}
} else if (diagram->shape[i].text) {
- stxt = ami_misc_allocvec_clear(sizeof(struct stxt_struct), 0);
+ stxt = calloc(1, sizeof(struct stxt_struct));
stxt->BaseX = diagram->shape[i].text_x;
stxt->BaseY = diagram->shape[i].text_y;
stxt->NumChars = strlen(diagram->shape[i].text);
if(!fons_written)
{
- fons = ami_misc_allocvec_clear(sizeof(struct fons_struct), 0);
- if(!(PushChunk(iffh,0,ID_FONS,IFFSIZE_UNKNOWN)))
+ fons = calloc(1, sizeof(struct fons_struct));
+ if(!(PushChunk(iffh, 0, ID_FONS, IFFSIZE_UNKNOWN)))
{
WriteChunkBytes(iffh, fons, sizeof(struct fons_struct));
WriteChunkBytes(iffh, "Topaz\0", 6);
PopChunk(iffh);
}
- FreeVec(fons);
+ free(fons);
fons_written = TRUE;
}
- if(!(PushChunk(iffh,0,ID_STXT,IFFSIZE_UNKNOWN)))
+ if(!(PushChunk(iffh, 0, ID_STXT, IFFSIZE_UNKNOWN)))
{
- WriteChunkBytes(iffh,stxt,26);
- WriteChunkBytes(iffh,diagram->shape[i].text,strlen(diagram->shape[i].text));
+ WriteChunkBytes(iffh, stxt, 26);
+ WriteChunkBytes(iffh, diagram->shape[i].text, strlen(diagram->shape[i].text));
PopChunk(iffh);
}
- FreeVec(stxt);
+ free(stxt);
}
}
@@ -380,7 +379,7 @@ int main(int argc, char **argv)
{
size = GetFileSize(fh);
- buffer = AllocVecTagList((uint32_t)size, NULL);
+ buffer = malloc((uint32_t)size);
Read(fh,buffer,(uint32_t)size);
Close(fh);
@@ -404,7 +403,7 @@ int main(int argc, char **argv)
ami_svg_to_dr2d(iffh,buffer,size,(char *)rarray[A_SVG]);
- FreeVec(buffer);
+ free(buffer);
if(iffh) CloseIFF(iffh);
if(iffh->iff_Stream) Close((BPTR)iffh->iff_Stream);
if(iffh) FreeIFF(iffh);
diff --git a/frontends/amiga/launch.c b/frontends/amiga/launch.c
index 8020dd6..10c32ae 100755
--- a/frontends/amiga/launch.c
+++ b/frontends/amiga/launch.c
@@ -50,10 +50,10 @@ static struct ami_protocol *ami_openurl_add_protocol(const char *url)
{
nsurl *ns_url;
struct ami_protocol *ami_p =
- (struct ami_protocol *)AllocVecTagList(sizeof(struct ami_protocol), NULL);
+ (struct ami_protocol *)malloc(sizeof(struct ami_protocol));
if (nsurl_create(url, &ns_url) != NSERROR_OK) {
- FreeVec(ami_p);
+ free(ami_p);
return NULL;
}
@@ -61,7 +61,7 @@ static struct ami_protocol *ami_openurl_add_protocol(const char *url)
nsurl_unref(ns_url);
if (ami_p->protocol == NULL)
{
- FreeVec(ami_p);
+ free(ami_p);
return NULL;
}
@@ -74,20 +74,20 @@ static void ami_openurl_free_list(struct MinList *list)
struct ami_protocol *node;
struct ami_protocol *nnode;
- if(IsMinListEmpty(list)) return;
- node = (struct ami_protocol *)GetHead((struct List *)list);
-
- do
- {
- nnode=(struct ami_protocol *)GetSucc((struct Node *)node);
+ if(IsMinListEmpty(list) == NULL) {
+ node = (struct ami_protocol *)GetHead((struct List *)list);
- Remove((struct Node *)node);
- if (node->protocol) lwc_string_unref(node->protocol);
- FreeVec(node);
- node = NULL;
- }while((node=nnode));
+ do
+ {
+ nnode=(struct ami_protocol *)GetSucc((struct Node *)node);
- FreeVec(list);
+ Remove((struct Node *)node);
+ if (node->protocol) lwc_string_unref(node->protocol);
+ free(node);
+ node = NULL;
+ }while((node=nnode));
+ }
+ free(list);
}
static BOOL ami_openurl_check_list(struct MinList *list, nsurl *url)
diff --git a/frontends/amiga/login.c b/frontends/amiga/login.c
index 3b338bf..85324b0 100755
--- a/frontends/amiga/login.c
+++ b/frontends/amiga/login.c
@@ -46,12 +46,11 @@
#include "amiga/gui.h"
#include "amiga/libs.h"
-#include "amiga/misc.h"
#include "amiga/object.h"
#include "amiga/login.h"
struct gui_login_window {
- struct nsObject *node;
+ struct ami_generic_window w;
struct Window *win;
Object *objects[GID_LAST];
nserror (*cb)(bool proceed, void *pw);
@@ -63,11 +62,19 @@ struct gui_login_window {
char pwd[256];
};
+static BOOL ami_401login_event(void *w);
+
+static const struct ami_win_event_table ami_login_table = {
+ ami_401login_event,
+ NULL, /* we don't explicitly close the login window at all.
+ @todo check if this prevents us from quitting NetSurf */
+};
+
void gui_401login_open(nsurl *url, const char *realm,
nserror (*cb)(bool proceed, void *pw), void *cbpw)
{
const char *auth;
- struct gui_login_window *lw = ami_misc_allocvec_clear(sizeof(struct gui_login_window), 0);
+ struct gui_login_window *lw = calloc(1, sizeof(struct gui_login_window));
lwc_string *host = nsurl_get_component(url, NSURL_HOST);
assert(host != NULL);
@@ -169,9 +176,7 @@ void gui_401login_open(nsurl *url, const char *realm,
EndWindow;
lw->win = (struct Window *)RA_OpenWindow(lw->objects[OID_MAIN]);
-
- lw->node = AddObject(window_list,AMINS_LOGINWINDOW);
- lw->node->objstruct = lw;
+ ami_gui_win_list_add(lw, AMINS_LOGINWINDOW, &ami_login_table);
}
static void ami_401login_close(struct gui_login_window *lw)
@@ -183,7 +188,7 @@ static void ami_401login_close(struct gui_login_window *lw)
DisposeObject(lw->objects[OID_MAIN]);
lwc_string_unref(lw->host);
nsurl_unref(lw->url);
- DelObject(lw->node);
+ ami_gui_win_list_remove(lw);
}
static void ami_401login_login(struct gui_login_window *lw)
@@ -207,9 +212,10 @@ static void ami_401login_login(struct gui_login_window *lw)
ami_401login_close(lw);
}
-BOOL ami_401login_event(struct gui_login_window *lw)
+static BOOL ami_401login_event(void *w)
{
/* return TRUE if window destroyed */
+ struct gui_login_window *lw = (struct gui_login_window *)w;
ULONG result;
uint16 code;
diff --git a/frontends/amiga/login.h b/frontends/amiga/login.h
index e3f7790..058fa59 100755
--- a/frontends/amiga/login.h
+++ b/frontends/amiga/login.h
@@ -23,9 +23,7 @@
struct gui_login_window;
-BOOL ami_401login_event(struct gui_login_window *lw);
-
void gui_401login_open(nsurl *url, const char *realm,
nserror (*cb)(bool proceed, void *pw), void *cbpw);
-
#endif
+
diff --git a/frontends/amiga/memory.c b/frontends/amiga/memory.c
new file mode 100755
index 0000000..d371d25
--- /dev/null
+++ b/frontends/amiga/memory.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2016 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __amigaos4__
+#include <proto/dos.h>
+#include <proto/exec.h>
+#include <exec/interrupts.h>
+#include <stdlib.h>
+#include "amiga/memory.h"
+#include "amiga/os3support.h"
+#include "amiga/schedule.h"
+#include "content/llcache.h"
+#include "utils/log.h"
+
+ULONG __slab_max_size = 2048; /* Enable clib2's slab allocator */
+
+enum {
+ PURGE_NONE = 0,
+ PURGE_STEP1,
+ PURGE_STEP2,
+ PURGE_DONE_STEP1,
+ PURGE_DONE_STEP2
+};
+static int low_mem_status = PURGE_NONE;
+
+/* Special clear (ie. non-zero) */
+void *ami_memory_clear_alloc(size_t size, UBYTE value)
+{
+ void *mem = malloc(size);
+ if (mem) memset(mem, value, size);
+ return mem;
+}
+
+/* clib2 slab allocator stats */
+static int ami_memory_slab_usage_cb(const struct __slab_usage_information * sui)
+{
+ if(sui->sui_slab_index <= 1) {
+ LOG("clib2 slab usage:");
+ LOG(" The size of all slabs, in bytes: %ld", sui->sui_slab_size);
+ LOG(" Number of allocations which are not managed by slabs: %ld",
+ sui->sui_num_single_allocations);
+ LOG(" Total number of bytes allocated for memory not managed by slabs: %ld",
+ sui->sui_total_single_allocation_size);
+ LOG(" Number of slabs currently in play: %ld", sui->sui_num_slabs);
+ LOG(" Number of currently unused slabs: %ld", sui->sui_num_empty_slabs);
+ LOG(" Number of slabs in use which are completely filled with data: %ld",
+ sui->sui_num_full_slabs);
+ LOG(" Total number of bytes allocated for all slabs: %ld",
+ sui->sui_total_slab_allocation_size);
+ }
+ LOG("Slab %d", sui->sui_slab_index);
+ LOG(" Memory chunk size managed by this slab: %ld", sui->sui_chunk_size);
+ LOG(" Number of memory chunks that fit in this slab: %ld", sui->sui_num_chunks);
+ LOG(" Number of memory chunks used in this slab: %ld", sui->sui_num_chunks_used);
+
+ return 0;
+}
+
+static int ami_memory_slab_alloc_cb(const struct __slab_allocation_information *sai)
+{
+ if(sai->sai_allocation_index <= 1) {
+ LOG("clib2 allocation usage:");
+ LOG(" Number of allocations which are not managed by slabs: %ld",
+ sai->sai_num_single_allocations);
+ LOG(" Total number of bytes allocated for memory not managed by slabs: %ld",
+ sai->sai_total_single_allocation_size);
+ }
+ LOG("Alloc %d", sai->sai_allocation_index);
+ LOG(" Size of this allocation, as requested: %ld", sai->sai_allocation_size);
+ LOG(" Total size of this allocation, including management data: %ld",
+ sai->sai_total_allocation_size);
+
+ return 0;
+}
+
+static int ami_memory_slab_stats_cb(void *user_data, const char *line, size_t line_length)
+{
+ BPTR fh = (BPTR)user_data;
+ long err = FPuts(fh, line);
+
+ if(err != 0) {
+ return -1;
+ } else {
+ return 0;
+ }
+}
+
+void ami_memory_slab_dump(BPTR fh)
+{
+ __get_slab_usage(ami_memory_slab_usage_cb);
+ __get_slab_allocations(ami_memory_slab_alloc_cb);
+ __get_slab_stats(fh, ami_memory_slab_stats_cb);
+}
+
+/* Low memory handler */
+static void ami_memory_low_mem_handler(void *p)
+{
+ if(low_mem_status == PURGE_STEP1) {
+ LOG("Purging llcache");
+ llcache_clean(true);
+ low_mem_status = PURGE_DONE_STEP1;
+ }
+
+ if(low_mem_status == PURGE_STEP2) {
+ LOG("Purging unused slabs");
+ __free_unused_slabs();
+ low_mem_status = PURGE_DONE_STEP2;
+ }
+}
+
+static ASM ULONG ami_memory_handler(REG(a0, struct MemHandlerData *mhd), REG(a1, void *userdata), REG(a6, struct ExecBase *execbase))
+{
+ if(low_mem_status == PURGE_DONE_STEP2) {
+ low_mem_status = PURGE_NONE;
+ return MEM_ALL_DONE;
+ }
+
+ if(low_mem_status == PURGE_DONE_STEP1) {
+ low_mem_status = PURGE_STEP2;
+ }
+
+ if(low_mem_status == PURGE_NONE) {
+ low_mem_status = PURGE_STEP1;
+ }
+
+ ami_schedule(1, ami_memory_low_mem_handler, NULL);
+
+ return MEM_TRY_AGAIN;
+}
+
+struct Interrupt *ami_memory_init(void)
+{
+ struct Interrupt *memhandler = malloc(sizeof(struct Interrupt));
+ if(memhandler == NULL) return NULL; // we're screwed
+
+ memhandler->is_Node.ln_Pri = -127; // low down as will be slow
+ memhandler->is_Node.ln_Name = "NetSurf low memory handler";
+ memhandler->is_Data = NULL;
+ memhandler->is_Code = (APTR)&ami_memory_handler;
+ AddMemHandler(memhandler);
+
+ return memhandler;
+}
+
+void ami_memory_fini(struct Interrupt *memhandler)
+{
+ if(memhandler != NULL) {
+ RemMemHandler(memhandler);
+ free(memhandler);
+ }
+}
+
+#endif
+
diff --git a/frontends/amiga/memory.h b/frontends/amiga/memory.h
new file mode 100644
index 0000000..a9a882e
--- /dev/null
+++ b/frontends/amiga/memory.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2016 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef AMIGA_MEMORY_H
+#define AMIGA_MEMORY_H
+
+#include <exec/types.h>
+
+/* Alloc/free chip memory */
+#ifdef __amigaos4__
+#define ami_memory_chip_alloc(s) malloc(s)
+#define ami_memory_chip_free(p) free(p)
+#else
+#define ami_memory_chip_alloc(s) AllocVec(s, MEMF_CHIP)
+#define ami_memory_chip_free(p) FreeVec(p)
+#endif
+
+/* Alloc/free a block cleared to non-zero */
+#ifdef __amigaos4__
+#define ami_memory_clear_alloc(s,v) AllocVecTags(s, AVT_ClearWithValue, v, TAG_DONE)
+#define ami_memory_clear_free(p) FreeVec(p)
+#else
+void *ami_memory_clear_alloc(size_t size, UBYTE value);
+#define ami_memory_clear_free(p) free(p)
+#endif
+
+/* Itempool cross-compatibility */
+#ifdef __amigaos4__
+#define ami_memory_itempool_create(s) AllocSysObjectTags(ASOT_ITEMPOOL, \
+ ASOITEM_MFlags, MEMF_PRIVATE, \
+ ASOITEM_ItemSize, s, \
+ ASOITEM_GCPolicy, ITEMGC_AFTERCOUNT, \
+ ASOITEM_GCParameter, 100, \
+ TAG_DONE)
+#define ami_memory_itempool_delete(p) FreeSysObject(ASOT_ITEMPOOL, p)
+#define ami_memory_itempool_alloc(p,s) ItemPoolAlloc(p)
+#define ami_memory_itempool_free(p,i,s) ItemPoolFree(p,i)
+#else
+#define ami_memory_itempool_create(s) ((APTR)1)
+#define ami_memory_itempool_delete(p) ((void)0)
+#define ami_memory_itempool_alloc(p,s) malloc(s)
+#define ami_memory_itempool_free(p,i,s) free(i)
+#endif
+
+/* clib2 slab allocator */
+#ifndef __amigaos4__
+void ami_memory_slab_dump(BPTR fh);
+struct Interrupt *ami_memory_init(void);
+void ami_memory_fini(struct Interrupt *memhandler);
+#endif
+
+#endif //AMIGA_MEMORY_H
+
diff --git a/frontends/amiga/menu.c b/frontends/amiga/menu.c
index 0fd730e..249ca07 100644
--- a/frontends/amiga/menu.c
+++ b/frontends/amiga/menu.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-9,2013 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
+ * Copyright 2008-9, 2013, 2017 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -21,18 +21,14 @@
#include <string.h>
#include <stdlib.h>
-#include <proto/dos.h>
-#include <proto/asl.h>
-#include <proto/exec.h>
#include <proto/gadtools.h>
+#include <proto/graphics.h>
#include <proto/intuition.h>
-#include <proto/utility.h>
-#ifdef __amigaos4__
-#include <dos/anchorpath.h>
-#include <dos/obsolete.h> /* Needed for ExAll() */
-#endif
#include <libraries/gadtools.h>
+#ifdef __amigaos4__
+#include <intuition/menuclass.h>
+#endif
#include <classes/window.h>
#include <proto/label.h>
@@ -42,43 +38,13 @@
#include <reaction/reaction_macros.h>
-#include "utils/nsoption.h"
-#include "utils/messages.h"
#include "utils/log.h"
-#include "utils/utils.h"
-#include "utils/nsurl.h"
-#include "netsurf/browser_window.h"
-#include "netsurf/mouse.h"
-#include "netsurf/window.h"
-#include "netsurf/content.h"
-#include "netsurf/keypress.h"
-#include "desktop/hotlist.h"
-#include "desktop/version.h"
-
-#include "amiga/arexx.h"
-#include "amiga/bitmap.h"
-#include "amiga/clipboard.h"
-#include "amiga/cookies.h"
-#include "amiga/file.h"
-#include "amiga/filetype.h"
+#include "utils/messages.h"
+
#include "amiga/gui.h"
-#include "amiga/gui_options.h"
-#include "amiga/history.h"
-#include "amiga/history_local.h"
-#include "amiga/hotlist.h"
#include "amiga/libs.h"
#include "amiga/menu.h"
-#include "amiga/misc.h"
-#include "amiga/nsoption.h"
-#include "amiga/print.h"
-#include "amiga/search.h"
-#include "amiga/theme.h"
-#include "amiga/tree.h"
#include "amiga/utf8.h"
-#include "amiga/schedule.h"
-
-#define NSA_SPACE "blankspace.png"
-#define NSA_MAX_HOTLIST_MENU_LEN 100
enum {
NSA_GLYPH_SUBMENU,
@@ -88,670 +54,106 @@ enum {
NSA_GLYPH_MAX
};
-static bool menu_quit = false;
-static bool ami_menu_check_toggled = false;
+#define NSA_MAX_HOTLIST_MENU_LEN 100
+
static Object *restrict menu_glyph[NSA_GLYPH_MAX];
static int menu_glyph_width[NSA_GLYPH_MAX];
static bool menu_glyphs_loaded = false;
-const char * const netsurf_version;
-const char * const verdate;
-
-static nserror ami_menu_scan(struct tree *tree, struct gui_window_2 *gwin);
-void ami_menu_arexx_scan(struct gui_window_2 *gwin);
-
-void ami_menu_set_check_toggled(void)
-{
- ami_menu_check_toggled = true;
-}
-
-bool ami_menu_get_check_toggled(void)
-{
- bool check_toggled = ami_menu_check_toggled;
- ami_menu_check_toggled = false;
- return check_toggled;
-}
-
-bool ami_menu_quit_selected(void)
-{
- return menu_quit;
-}
-
-/*
- * The below functions are called automatically by window.class when menu items are selected.
- */
-
-HOOKF(void, ami_menu_item_project_newwin, APTR, window, struct IntuiMessage *)
-{
- nsurl *url;
- nserror error;
-
- error = nsurl_create(nsoption_charp(homepage_url), &url);
- if (error == NSERROR_OK) {
- error = browser_window_create(BW_CREATE_HISTORY,
- url,
- NULL,
- NULL,
- NULL);
- nsurl_unref(url);
- }
- if (error != NSERROR_OK) {
- amiga_warn_user(messages_get_errorcode(error), 0);
- }
-}
-
-HOOKF(void, ami_menu_item_project_newtab, APTR, window, struct IntuiMessage *)
-{
- struct gui_window_2 *gwin;
-
- GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
- ami_gui_new_blank_tab(gwin);
-}
-
-HOOKF(void, ami_menu_item_project_open, APTR, window, struct IntuiMessage *)
-{
- struct gui_window_2 *gwin;
- GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
-
- ami_file_open(gwin);
-}
-
-HOOKF(void, ami_menu_item_project_save, APTR, window, struct IntuiMessage *)
-{
- struct gui_window_2 *gwin;
- ULONG type = (ULONG)hook->h_Data;
-
- GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
-
- ami_file_save_req(type, gwin, browser_window_get_content(gwin->gw->bw));
-}
-
-HOOKF(void, ami_menu_item_project_closetab, APTR, window, struct IntuiMessage *)
-{
- struct gui_window_2 *gwin;
- GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
-
- browser_window_destroy(gwin->gw->bw);
-}
-
-HOOKF(void, ami_menu_item_project_closewin, APTR, window, struct IntuiMessage *)
-{
- struct gui_window_2 *gwin;
- GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
-
- gwin->closed = true;
-}
-
-HOOKF(void, ami_menu_item_project_print, APTR, window, struct IntuiMessage *)
-{
- struct gui_window_2 *gwin;
- GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
-
- ami_set_pointer(gwin, GUI_POINTER_WAIT, false);
- ami_print_ui(browser_window_get_content(gwin->gw->bw));
- ami_reset_pointer(gwin);
-}
-
-HOOKF(void, ami_menu_item_project_about, APTR, window, struct IntuiMessage *)
+bool ami_menu_get_selected(struct Menu *menu, struct IntuiMessage *msg)
{
- struct gui_window_2 *gwin;
- char *temp, *temp2;
- int sel;
- nsurl *url = NULL;
- nserror error = NSERROR_OK;
-
- GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
-
- ami_set_pointer(gwin, GUI_POINTER_WAIT, false);
-
- temp = ASPrintf("%s|%s|%s", messages_get("OK"),
- messages_get("HelpCredits"),
- messages_get("HelpLicence"));
+ bool checked = false;
- temp2 = ami_utf8_easy(temp);
- FreeVec(temp);
+ if(LIB_IS_AT_LEAST((struct Library *)IntuitionBase, 54, 6)) {
#ifdef __amigaos4__
- sel = TimedDosRequesterTags(TDR_ImageType,TDRIMAGE_INFO,
- TDR_TitleString, messages_get("NetSurf"),
- TDR_Window, gwin->win,
- TDR_GadgetString, temp2,
- TDR_FormatString,"NetSurf %s\nBuild date %s\n\nhttp://www.netsurf-browser.org",
- TDR_Arg1,netsurf_version,
- TDR_Arg2,verdate,
- TAG_DONE);
-#else
- struct EasyStruct about_req = {
- sizeof(struct EasyStruct),
- 0,
- "NetSurf",
- "NetSurf %s\nBuild date %s\n\nhttp://www.netsurf-browser.org",
- temp2,
- };
-
- sel = EasyRequest(gwin->win, &about_req, NULL, netsurf_version, verdate);
-#endif
- free(temp2);
-
- if(sel == 2) {
- error = nsurl_create("about:credits", &url);
- } else if(sel == 0) {
- error = nsurl_create("about:licence", &url);
- }
-
- if(url) {
- if (error == NSERROR_OK) {
- error = browser_window_create(BW_CREATE_HISTORY,
- url,
- NULL,
- NULL,
- NULL);
- nsurl_unref(url);
- }
- if (error != NSERROR_OK) {
- amiga_warn_user(messages_get_errorcode(error), 0);
- }
- }
-
- ami_reset_pointer(gwin);
-}
-
-HOOKF(void, ami_menu_item_project_quit, APTR, window, struct IntuiMessage *)
-{
- menu_quit = true;
-}
-
-HOOKF(void, ami_menu_item_edit_cut, APTR, window, struct IntuiMessage *)
-{
- struct gui_window_2 *gwin;
- GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
-
- browser_window_key_press(gwin->gw->bw, NS_KEY_CUT_SELECTION);
-}
-
-HOOKF(void, ami_menu_item_edit_copy, APTR, window, struct IntuiMessage *)
-{
- struct bitmap *bm;
- struct gui_window_2 *gwin;
- GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
+ ULONG state;
+ struct ExtIntuiMessage *emsg = (struct ExtIntuiMessage *)msg;
- if(browser_window_can_select(gwin->gw->bw)) {
- browser_window_key_press(gwin->gw->bw, NS_KEY_COPY_SELECTION);
- browser_window_key_press(gwin->gw->bw, NS_KEY_CLEAR_SELECTION);
- }
- else if((bm = content_get_bitmap(browser_window_get_content(gwin->gw->bw)))) {
- /** @todo It should be checked that the lifetime of
- * the objects containing the values returned (and the
- * constness cast away) is safe.
- */
- ami_bitmap_set_url(bm, browser_window_get_url(gwin->gw->bw));
- ami_bitmap_set_title(bm, browser_window_get_title(gwin->gw->bw));
- ami_easy_clipboard_bitmap(bm);
- }
-#ifdef WITH_NS_SVG
- else if(ami_mime_compare(browser_window_get_content(gwin->gw->bw), "svg") == true) {
- ami_easy_clipboard_svg(browser_window_get_content(gwin->gw->bw));
+ state = IDoMethod((Object *)menu, MM_GETSTATE, 0, emsg->eim_LongCode, MS_CHECKED);
+ if(state & MS_CHECKED) checked = true;
+#endif
+ } else {
+ if(ItemAddress(menu, msg->Code)->Flags & CHECKED) checked = true;
}
-#endif
-}
-
-HOOKF(void, ami_menu_item_edit_paste, APTR, window, struct IntuiMessage *)
-{
- struct gui_window_2 *gwin;
- GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
-
- browser_window_key_press(gwin->gw->bw, NS_KEY_PASTE);
-}
-
-HOOKF(void, ami_menu_item_edit_selectall, APTR, window, struct IntuiMessage *)
-{
- struct gui_window_2 *gwin;
- GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
-
- browser_window_key_press(gwin->gw->bw, NS_KEY_SELECT_ALL);
- gui_start_selection(gwin->gw);
-}
-
-HOOKF(void, ami_menu_item_edit_clearsel, APTR, window, struct IntuiMessage *)
-{
- struct gui_window_2 *gwin;
- GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
-
- browser_window_key_press(gwin->gw->bw, NS_KEY_CLEAR_SELECTION);
-}
-
-HOOKF(void, ami_menu_item_edit_undo, APTR, window, struct IntuiMessage *)
-{
- struct gui_window_2 *gwin;
- GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
-
- browser_window_key_press(gwin->gw->bw, NS_KEY_UNDO);
-}
-
-HOOKF(void, ami_menu_item_edit_redo, APTR, window, struct IntuiMessage *)
-{
- struct gui_window_2 *gwin;
- GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
-
- browser_window_key_press(gwin->gw->bw, NS_KEY_REDO);
-}
-
-HOOKF(void, ami_menu_item_browser_find, APTR, window, struct IntuiMessage *)
-{
- struct gui_window_2 *gwin;
- GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
-
- ami_search_open(gwin->gw);
-}
-
-HOOKF(void, ami_menu_item_browser_localhistory, APTR, window, struct IntuiMessage *)
-{
- struct gui_window_2 *gwin;
- GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
-
- ami_history_open(gwin->gw);
-}
-
-HOOKF(void, ami_menu_item_browser_globalhistory, APTR, window, struct IntuiMessage *)
-{
- ami_tree_open(global_history_window,AMI_TREE_HISTORY);
-}
-
-HOOKF(void, ami_menu_item_browser_cookies, APTR, window, struct IntuiMessage *)
-{
- ami_tree_open(cookies_window,AMI_TREE_COOKIES);
-}
-
-HOOKF(void, ami_menu_item_browser_foreimg, APTR, window, struct IntuiMessage *)
-{
- struct Menu *menustrip;
- bool checked = false;
-
- GetAttr(WINDOW_MenuStrip, (Object *)window, (ULONG *)&menustrip);
- if(ItemAddress(menustrip, msg->Code)->Flags & CHECKED) checked = true;
-
- nsoption_set_bool(foreground_images, checked);
- ami_menu_set_check_toggled();
-}
-
-HOOKF(void, ami_menu_item_browser_backimg, APTR, window, struct IntuiMessage *)
-{
- struct Menu *menustrip;
- bool checked = false;
-
- GetAttr(WINDOW_MenuStrip, (Object *)window, (ULONG *)&menustrip);
- if(ItemAddress(menustrip, msg->Code)->Flags & CHECKED) checked = true;
-
- nsoption_set_bool(background_images, checked);
- ami_menu_set_check_toggled();
-}
-
-HOOKF(void, ami_menu_item_browser_enablejs, APTR, window, struct IntuiMessage *)
-{
- struct Menu *menustrip;
- bool checked = false;
-
- GetAttr(WINDOW_MenuStrip, (Object *)window, (ULONG *)&menustrip);
- if(ItemAddress(menustrip, msg->Code)->Flags & CHECKED) checked = true;
-
- nsoption_set_bool(enable_javascript, checked);
- ami_menu_set_check_toggled();
-}
-
-HOOKF(void, ami_menu_item_browser_scale_decrease, APTR, window, struct IntuiMessage *)
-{
- struct gui_window_2 *gwin;
- GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
-
- ami_gui_set_scale(gwin->gw, gwin->gw->scale - 0.1);
-}
-
-HOOKF(void, ami_menu_item_browser_scale_normal, APTR, window, struct IntuiMessage *)
-{
- struct gui_window_2 *gwin;
- GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
-
- ami_gui_set_scale(gwin->gw, 1.0);
-}
-
-HOOKF(void, ami_menu_item_browser_scale_increase, APTR, window, struct IntuiMessage *)
-{
- struct gui_window_2 *gwin;
- GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
-
- ami_gui_set_scale(gwin->gw, gwin->gw->scale + 0.1);
-}
-
-HOOKF(void, ami_menu_item_browser_redraw, APTR, window, struct IntuiMessage *)
-{
- struct gui_window_2 *gwin;
- GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
-
- ami_schedule_redraw(gwin, true);
- gwin->new_content = true;
-}
-
-HOOKF(void, ami_menu_item_hotlist_add, APTR, window, struct IntuiMessage *)
-{
- struct browser_window *bw;
- struct gui_window_2 *gwin;
- GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
-
- bw = gwin->gw->bw;
-
- if (bw == NULL || browser_window_has_content(bw) == false)
- return;
-
- hotlist_add_url(browser_window_get_url(bw));
- ami_gui_update_hotlist_button(gwin);
-}
-
-HOOKF(void, ami_menu_item_hotlist_show, APTR, window, struct IntuiMessage *)
-{
- ami_tree_open(hotlist_window, AMI_TREE_HOTLIST);
-}
-
-HOOKF(void, ami_menu_item_hotlist_entries, APTR, window, struct IntuiMessage *)
-{
- nsurl *url = hook->h_Data;
- struct gui_window_2 *gwin;
- GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
-
- if(url == NULL) return;
-
- browser_window_navigate(gwin->gw->bw,
- url,
- NULL,
- BW_NAVIGATE_HISTORY,
- NULL,
- NULL,
- NULL);
-}
-HOOKF(void, ami_menu_item_settings_edit, APTR, window, struct IntuiMessage *)
-{
- ami_gui_opts_open();
-}
-
-HOOKF(void, ami_menu_item_settings_snapshot, APTR, window, struct IntuiMessage *)
-{
- struct gui_window_2 *gwin;
- GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
-
- nsoption_set_int(window_x, gwin->win->LeftEdge);
- nsoption_set_int(window_y, gwin->win->TopEdge);
- nsoption_set_int(window_width, gwin->win->Width);
- nsoption_set_int(window_height, gwin->win->Height);
-}
-
-HOOKF(void, ami_menu_item_settings_save, APTR, window, struct IntuiMessage *)
-{
- ami_nsoption_write();
+ return checked;
}
-HOOKF(void, ami_menu_item_arexx_execute, APTR, window, struct IntuiMessage *)
-{
- char *temp;
- struct gui_window_2 *gwin;
- GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
-
- if(AslRequestTags(filereq,
- ASLFR_Window, gwin->win,
- ASLFR_SleepWindow, TRUE,
- ASLFR_TitleText, messages_get("NetSurf"),
- ASLFR_Screen, scrn,
- ASLFR_DoSaveMode, FALSE,
- ASLFR_InitialDrawer, nsoption_charp(arexx_dir),
- ASLFR_InitialPattern, "#?.nsrx",
- TAG_DONE)) {
- if((temp = AllocVecTagList(1024, NULL))) {
- strlcpy(temp, filereq->fr_Drawer, 1024);
- AddPart(temp, filereq->fr_File, 1024);
- ami_arexx_execute(temp);
- FreeVec(temp);
+/* menu creation code */
+void ami_menu_free_lab_item(struct ami_menu_data **md, int i)
+{
+ if(md[i] == NULL) return;
+ if(md[i]->menulab &&
+ (md[i]->menulab != NM_BARLABEL) &&
+ (md[i]->menulab != ML_SEPARATOR)) {
+ if(md[i]->menutype & MENU_IMAGE) {
+ if(md[i]->menuobj) DisposeObject(md[i]->menuobj);
}
- }
-}
-HOOKF(void, ami_menu_item_arexx_entries, APTR, window, struct IntuiMessage *)
-{
- char *script = hook->h_Data;
- char *temp;
- struct gui_window_2 *gwin;
- GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
-
- if(script) {
- if((temp = AllocVecTagList(1024, NULL))) {
- BPTR lock;
- if((lock = Lock(nsoption_charp(arexx_dir), SHARED_LOCK))) {
- DevNameFromLock(lock, temp, 1024, DN_FULLPATH);
- AddPart(temp, script, 1024);
- ami_arexx_execute(temp);
- FreeVec(temp);
- UnLock(lock);
- }
- }
+ ami_utf8_free(md[i]->menulab);
}
-}
+ if(md[i]->menukey != NULL) free(md[i]->menukey);
-/* menu creation code */
+ md[i]->menulab = NULL;
+ md[i]->menuobj = NULL;
+ md[i]->menukey = NULL;
+ md[i]->menutype = 0;
+ free(md[i]);
+ md[i] = NULL;
+}
-void ami_free_menulabs(struct gui_window_2 *gwin)
+static void ami_menu_free_labs(struct ami_menu_data **md, int max)
{
int i;
- for(i=0;i<AMI_MENU_AREXX_MAX;i++) {
- if(gwin->menulab[i] && (gwin->menulab[i] != NM_BARLABEL)) {
- if(gwin->menutype[i] & MENU_IMAGE) {
- if(gwin->menuobj[i]) DisposeObject(gwin->menuobj[i]);
- }
-
- ami_utf8_free(gwin->menulab[i]);
-
- if(i >= AMI_MENU_AREXX) {
- if(gwin->menu_hook[i].h_Data) free(gwin->menu_hook[i].h_Data);
- gwin->menu_hook[i].h_Data = NULL;
- }
- }
-
- gwin->menulab[i] = NULL;
- gwin->menuobj[i] = NULL;
- gwin->menukey[i] = 0;
+ for(i = 0; i <= max; i++) {
+ ami_menu_free_lab_item(md, i);
}
-
- FreeVec(gwin->menutype);
- gwin->menutype = NULL;
}
-static void ami_menu_alloc_item(struct gui_window_2 *gwin, int num, UBYTE type,
- const char *restrict label, char key, const char *restrict icon,
- void *restrict func, void *restrict hookdata)
+void ami_menu_alloc_item(struct ami_menu_data **md, int num, UBYTE type,
+ const char *restrict label, const char *restrict key, const char *restrict icon,
+ void *restrict func, void *restrict hookdata, UWORD flags)
{
- char menu_icon[1024];
-
- gwin->menutype[num] = type;
+ md[num] = calloc(1, sizeof(struct ami_menu_data));
+ md[num]->menutype = type;
+ md[num]->flags = flags;
+
+ if(type == NM_END) return;
if((label == NM_BARLABEL) || (strcmp(label, "--") == 0)) {
- gwin->menulab[num] = NM_BARLABEL;
- } else {
- if((num >= AMI_MENU_HOTLIST) && (num <= AMI_MENU_HOTLIST_MAX)) {
- utf8_from_local_encoding(label,
- (strlen(label) < NSA_MAX_HOTLIST_MENU_LEN) ? strlen(label) : NSA_MAX_HOTLIST_MENU_LEN,
- (char **)&gwin->menulab[num]);
- } else if((num >= AMI_MENU_AREXX) && (num < AMI_MENU_AREXX_MAX)) {
- gwin->menulab[num] = strdup(label);
+ md[num]->menulab = NM_BARLABEL;
+ icon = NULL;
+ } else { /* horrid non-generic stuff */
+ if((num >= AMI_MENU_AREXX) && (num < AMI_MENU_AREXX_MAX)) {
+ md[num]->menulab = strdup(label);
} else {
- gwin->menulab[num] = ami_utf8_easy(messages_get(label));
+ md[num]->menulab = ami_utf8_easy(messages_get(label));
}
}
- gwin->menuicon[num] = NULL;
- if(key) gwin->menukey[num] = key;
- if(func) gwin->menu_hook[num].h_Entry = (HOOKFUNC)func;
- if(hookdata) gwin->menu_hook[num].h_Data = hookdata;
+ md[num]->menuicon = NULL;
+ if(key) md[num]->menukey = strdup(key);
+ if(func) md[num]->menu_hook.h_Entry = (HOOKFUNC)func;
+ if(hookdata) md[num]->menu_hook.h_Data = hookdata;
#ifdef __amigaos4__
+ char menu_icon[1024];
+
if(LIB_IS_AT_LEAST((struct Library *)GadToolsBase, 53, 7)) {
if(icon) {
if(ami_locate_resource(menu_icon, icon) == true) {
- gwin->menuicon[num] = (char *)strdup(menu_icon);
+ md[num]->menuicon = (char *)strdup(menu_icon);
} else {
/* If the requested icon can't be found, put blank space in instead */
- gwin->menuicon[num] = (char *)strdup(NSA_SPACE);
+ md[num]->menuicon = (char *)strdup(NSA_SPACE);
}
}
}
#endif
}
-static void ami_init_menulabs(struct gui_window_2 *gwin)
-{
- int i;
-
- gwin->menutype = ami_misc_allocvec_clear(sizeof(UBYTE) * (AMI_MENU_AREXX_MAX + 1), 0);
-
- for(i=0;i <= AMI_MENU_AREXX_MAX;i++)
- {
- gwin->menutype[i] = NM_IGNORE;
- gwin->menulab[i] = NULL;
- gwin->menuobj[i] = NULL;
- gwin->menuicon[i] = NULL;
- }
-
- ami_menu_alloc_item(gwin, M_PROJECT, NM_TITLE, "Project", 0, NULL, NULL, NULL);
- ami_menu_alloc_item(gwin, M_NEWWIN, NM_ITEM, "NewWindowNS", 'N', "TBImages:list_app",
- ami_menu_item_project_newwin, NULL);
- ami_menu_alloc_item(gwin, M_NEWTAB, NM_ITEM, "NewTab", 'T', "TBImages:list_tab",
- ami_menu_item_project_newtab, NULL);
- ami_menu_alloc_item(gwin, M_BAR_P1, NM_ITEM, NM_BARLABEL, 0, NULL, NULL, NULL);
- ami_menu_alloc_item(gwin, M_OPEN, NM_ITEM, "OpenFile", 'O', "TBImages:list_folder_misc",
- ami_menu_item_project_open, NULL);
- ami_menu_alloc_item(gwin, M_SAVEAS, NM_ITEM, "SaveAsNS", 0, "TBImages:list_saveas", NULL, NULL);
- ami_menu_alloc_item(gwin, M_SAVESRC, NM_SUB, "Source", 'S', NULL,
- ami_menu_item_project_save, (void *)AMINS_SAVE_SOURCE);
- ami_menu_alloc_item(gwin, M_SAVETXT, NM_SUB, "TextNS", 0, NULL,
- ami_menu_item_project_save, (void *)AMINS_SAVE_TEXT);
- ami_menu_alloc_item(gwin, M_SAVECOMP, NM_SUB, "SaveCompNS", 0, NULL,
- ami_menu_item_project_save, (void *)AMINS_SAVE_COMPLETE);
-#ifdef WITH_PDF_EXPORT
- ami_menu_alloc_item(gwin, M_SAVEPDF, NM_SUB, "PDFNS", 0, NULL,
- ami_menu_item_project_save, (void *)AMINS_SAVE_PDF);
-#endif
- ami_menu_alloc_item(gwin, M_SAVEIFF, NM_SUB, "IFF", 0, NULL,
- ami_menu_item_project_save, (void *)AMINS_SAVE_IFF);
- ami_menu_alloc_item(gwin, M_BAR_P2, NM_ITEM, NM_BARLABEL, 0, NULL, NULL, NULL);
- ami_menu_alloc_item(gwin, M_PRINT, NM_ITEM, "PrintNS", 'P', "TBImages:list_print",
- ami_menu_item_project_print, NULL);
- ami_menu_alloc_item(gwin, M_BAR_P3, NM_ITEM, NM_BARLABEL, 0, NULL, NULL, NULL);
- ami_menu_alloc_item(gwin, M_CLOSETAB, NM_ITEM, "CloseTab", 'K', "TBImages:list_remove",
- ami_menu_item_project_closetab, NULL);
- ami_menu_alloc_item(gwin, M_CLOSEWIN, NM_ITEM, "CloseWindow", 0, "TBImages:list_cancel",
- ami_menu_item_project_closewin, NULL);
- ami_menu_alloc_item(gwin, M_BAR_P4, NM_ITEM, NM_BARLABEL, 0, NULL, NULL, NULL);
- ami_menu_alloc_item(gwin, M_ABOUT, NM_ITEM, "About", '?', "TBImages:list_info",
- ami_menu_item_project_about, NULL);
- ami_menu_alloc_item(gwin, M_BAR_P5, NM_ITEM, NM_BARLABEL, 0, NULL, NULL, NULL);
- ami_menu_alloc_item(gwin, M_QUIT, NM_ITEM, "Quit", 'Q', "TBImages:list_warning",
- ami_menu_item_project_quit, NULL);
-
- ami_menu_alloc_item(gwin, M_EDIT, NM_TITLE, "Edit", 0, NULL, NULL, NULL);
- ami_menu_alloc_item(gwin, M_CUT, NM_ITEM, "CutNS", 'X', "TBImages:list_cut",
- ami_menu_item_edit_cut, NULL);
- ami_menu_alloc_item(gwin, M_COPY, NM_ITEM, "CopyNS", 'C', "TBImages:list_copy",
- ami_menu_item_edit_copy, NULL);
- ami_menu_alloc_item(gwin, M_PASTE, NM_ITEM, "PasteNS", 'V', "TBImages:list_paste",
- ami_menu_item_edit_paste, NULL);
- ami_menu_alloc_item(gwin, M_BAR_E1, NM_ITEM, NM_BARLABEL, 0, NULL, NULL, NULL);
- ami_menu_alloc_item(gwin, M_SELALL, NM_ITEM, "SelectAllNS", 'A', NSA_SPACE,
- ami_menu_item_edit_selectall, NULL);
- ami_menu_alloc_item(gwin, M_CLEAR, NM_ITEM, "ClearNS", 0, NSA_SPACE,
- ami_menu_item_edit_clearsel, NULL);
- ami_menu_alloc_item(gwin, M_BAR_E2, NM_ITEM, NM_BARLABEL, 0, NULL, NULL, NULL);
- ami_menu_alloc_item(gwin, M_UNDO, NM_ITEM, "Undo", 'Z', "TBImages:list_undo",
- ami_menu_item_edit_undo, NULL);
- ami_menu_alloc_item(gwin, M_REDO, NM_ITEM, "Redo", 'Y', "TBImages:list_redo",
- ami_menu_item_edit_redo, NULL);
-
- ami_menu_alloc_item(gwin, M_BROWSER, NM_TITLE, "Browser", 0, NULL, NULL, NULL);
- ami_menu_alloc_item(gwin, M_FIND, NM_ITEM, "FindTextNS", 'F', "TBImages:list_search",
- ami_menu_item_browser_find, NULL);
- ami_menu_alloc_item(gwin, M_BAR_B1, NM_ITEM, NM_BARLABEL, 0, NULL, NULL, NULL);
- ami_menu_alloc_item(gwin, M_HISTLOCL, NM_ITEM, "HistLocalNS", 0, "TBImages:list_history",
- ami_menu_item_browser_localhistory, NULL);
- ami_menu_alloc_item(gwin, M_HISTGLBL, NM_ITEM, "HistGlobalNS", 0, "TBImages:list_history",
- ami_menu_item_browser_globalhistory, NULL);
- ami_menu_alloc_item(gwin, M_BAR_B2, NM_ITEM, NM_BARLABEL, 0, NULL, NULL, NULL);
- ami_menu_alloc_item(gwin, M_COOKIES, NM_ITEM, "ShowCookiesNS", 0, "TBImages:list_internet",
- ami_menu_item_browser_cookies, NULL);
- ami_menu_alloc_item(gwin, M_BAR_B3, NM_ITEM, NM_BARLABEL, 0, NULL, NULL, NULL);
- ami_menu_alloc_item(gwin, M_SCALE, NM_ITEM, "ScaleNS", 0, "TBImages:list_preview", NULL, NULL);
- ami_menu_alloc_item(gwin, M_SCALEDEC, NM_SUB, "ScaleDec", '-', "TBImages:list_zoom_out",
- ami_menu_item_browser_scale_decrease, NULL);
- ami_menu_alloc_item(gwin, M_SCALENRM, NM_SUB, "ScaleNorm", '=', "TBImages:list_zoom_100",
- ami_menu_item_browser_scale_normal, NULL);
- ami_menu_alloc_item(gwin, M_SCALEINC, NM_SUB, "ScaleInc", '+', "TBImages:list_zoom_in",
- ami_menu_item_browser_scale_increase, NULL);
- ami_menu_alloc_item(gwin, M_IMAGES, NM_ITEM, "Images", 0, "TBImages:list_image", NULL, NULL);
- ami_menu_alloc_item(gwin, M_IMGFORE, NM_SUB, "ForeImg", 0, NULL,
- ami_menu_item_browser_foreimg, NULL);
- ami_menu_alloc_item(gwin, M_IMGBACK, NM_SUB, "BackImg", 0, NULL,
- ami_menu_item_browser_backimg, NULL);
- ami_menu_alloc_item(gwin, M_JS, NM_ITEM, "EnableJS", 0, NULL,
- ami_menu_item_browser_enablejs, NULL);
- ami_menu_alloc_item(gwin, M_BAR_B4, NM_ITEM, NM_BARLABEL, 0, NULL, NULL, NULL);
- ami_menu_alloc_item(gwin, M_REDRAW, NM_ITEM, "Redraw", 0, "TBImages:list_wand",
- ami_menu_item_browser_redraw, NULL);
-
- ami_menu_alloc_item(gwin, M_HOTLIST, NM_TITLE, "Hotlist", 0, NULL, NULL, NULL);
- ami_menu_alloc_item(gwin, M_HLADD, NM_ITEM, "HotlistAdd", 'B', "TBImages:list_favouriteadd",
- ami_menu_item_hotlist_add, NULL);
- ami_menu_alloc_item(gwin, M_HLSHOW, NM_ITEM,"HotlistShowNS",'H', "TBImages:list_favourite",
- ami_menu_item_hotlist_show, NULL);
- ami_menu_alloc_item(gwin, M_BAR_H1, NM_ITEM, NM_BARLABEL, 0, NULL, NULL, NULL);
-
- ami_menu_alloc_item(gwin, M_PREFS, NM_TITLE, "Settings", 0, NULL, NULL, NULL);
- ami_menu_alloc_item(gwin, M_PREDIT, NM_ITEM, "SettingsEdit", 0, "TBImages:list_prefs",
- ami_menu_item_settings_edit, NULL);
- ami_menu_alloc_item(gwin, M_BAR_S1, NM_ITEM, NM_BARLABEL, 0, NULL, NULL, NULL);
- ami_menu_alloc_item(gwin, M_SNAPSHOT, NM_ITEM, "SnapshotWindow",0, "TBImages:list_hold",
- ami_menu_item_settings_snapshot, NULL);
- ami_menu_alloc_item(gwin, M_PRSAVE, NM_ITEM, "SettingsSave", 0, "TBImages:list_use",
- ami_menu_item_settings_save, NULL);
-
- ami_menu_alloc_item(gwin, M_AREXX, NM_TITLE, "ARexx", 0, NULL, NULL, NULL);
- ami_menu_alloc_item(gwin, M_AREXXEX, NM_ITEM, "ARexxExecute",'E', "TBImages:list_arexx",
- ami_menu_item_arexx_execute, NULL);
- ami_menu_alloc_item(gwin, M_BAR_A1, NM_ITEM, NM_BARLABEL, 0, NULL, NULL, NULL);
- gwin->menutype[AMI_MENU_AREXX_MAX] = NM_END;
-}
-
-/* Menu refresh for hotlist */
-void ami_menu_refresh(struct gui_window_2 *gwin)
-{
- return; /**\todo fix this after migrating to menuclass */
-
- struct Menu *menu;
-
- LOG("Clearing MenuStrip");
- SetAttrs(gwin->objects[OID_MAIN],
- WINDOW_MenuStrip, NULL,
- TAG_DONE);
-
- LOG("Freeing menu");
- ami_menu_free(gwin);
-
- LOG("Freeing menu labels");
- ami_free_menulabs(gwin);
-
- LOG("Creating new menu");
- menu = ami_menu_create(gwin);
-
- LOG("Attaching MenuStrip %p to %p", menu, gwin->objects[OID_MAIN]);
- SetAttrs(gwin->objects[OID_MAIN],
- WINDOW_MenuStrip, menu,
- TAG_DONE);
-}
-
static void ami_menu_load_glyphs(struct DrawInfo *dri)
{
#ifdef __amigaos4__
@@ -794,16 +196,16 @@ void ami_menu_free_glyphs(void)
#endif
}
-static int ami_menu_calc_item_width(struct gui_window_2 *gwin, int j, struct RastPort *rp)
+static int ami_menu_calc_item_width(struct ami_menu_data **md, int j, struct RastPort *rp)
{
int space_width = TextLength(rp, " ", 1);
int item_size;
- item_size = TextLength(rp, gwin->menulab[j], strlen(gwin->menulab[j]));
+ item_size = TextLength(rp, md[j]->menulab, strlen(md[j]->menulab));
item_size += space_width;
- if(gwin->menukey[j]) {
- item_size += TextLength(rp, &gwin->menukey[j], 1);
+ if(md[j]->menukey) {
+ item_size += TextLength(rp, md[j]->menukey, 1);
item_size += menu_glyph_width[NSA_GLYPH_AMIGAKEY];
/**TODO: take account of the size of other imagery too
*/
@@ -813,19 +215,87 @@ static int ami_menu_calc_item_width(struct gui_window_2 *gwin, int j, struct Ras
item_size += menu_glyph_width[NSA_GLYPH_AMIGAKEY];
}
- if(gwin->menuicon[j]) {
+ if(md[j]->menuicon) {
item_size += 16;
}
return item_size;
}
+#ifdef __amigaos4__
+static int ami_menu_layout_mc_recursive(Object *menu_parent, struct ami_menu_data **md, int level, int i, int max)
+{
+ int j;
+ Object *menu_item = menu_parent;
+
+ for(j = i; j < max; j++) {
+ /* skip empty entries */
+ if(md[j] == NULL) continue;
+ if(md[j]->menutype == NM_IGNORE) continue;
+
+ if(md[j]->menutype == level) {
+ if(md[j]->menulab == NM_BARLABEL)
+ md[j]->menulab = ML_SEPARATOR;
+
+ if(level == NM_TITLE) {
+ menu_item = NewObject(NULL, "menuclass",
+ MA_Type, T_MENU,
+ MA_ID, j,
+ MA_Label, md[j]->menulab,
+ TAG_DONE);
+ } else {
+ menu_item = NewObject(NULL, "menuclass",
+ MA_Type, T_ITEM,
+ MA_ID, j,
+ MA_Label, md[j]->menulab,
+ MA_Image,
+ BitMapObj,
+ IA_Scalable, TRUE,
+ BITMAP_Screen, scrn,
+ BITMAP_SourceFile, md[j]->menuicon,
+ BITMAP_Masking, TRUE,
+ BitMapEnd,
+ MA_Key, md[j]->menukey,
+ MA_UserData, &md[j]->menu_hook, /* NB: Intentionally UserData */
+ MA_Disabled, (md[j]->flags & NM_ITEMDISABLED),
+ MA_Selected, (md[j]->flags & CHECKED),
+ MA_Toggle, (md[j]->flags & MENUTOGGLE),
+ TAG_DONE);
+ }
+
+ //LOG("Adding item %p ID %d (%s) to parent %p", menu_item, j, md[j]->menulab, menu_parent);
+ IDoMethod(menu_parent, OM_ADDMEMBER, menu_item);
+ continue;
+ } else if (md[j]->menutype > level) {
+ j = ami_menu_layout_mc_recursive(menu_item, md, md[j]->menutype, j, max);
+ } else {
+ break;
+ }
+ }
+ return (j - 1);
+}
+
+static struct Menu *ami_menu_layout_mc(struct ami_menu_data **md, int max)
+{
+ Object *menu_root = NewObject(NULL, "menuclass",
+ MA_Type, T_ROOT,
+ MA_EmbeddedKey, FALSE,
+ TAG_DONE);
+
+ ami_menu_layout_mc_recursive(menu_root, md, NM_TITLE, 0, max);
+
+ return (struct Menu *)menu_root;
+}
+#endif
-static struct gui_window_2 *ami_menu_layout(struct gui_window_2 *gwin)
+static struct Menu *ami_menu_layout_gt(struct ami_menu_data **md, int max)
{
int i, j;
int txtlen = 0;
int left_posn = 0;
+ struct NewMenu *nm;
+ struct Menu *imenu = NULL;
+ struct VisualInfo *vi;
struct RastPort *rp = &scrn->RastPort;
struct DrawInfo *dri = GetScreenDrawInfo(scrn);
int space_width = TextLength(rp, " ", 1);
@@ -833,34 +303,41 @@ static struct gui_window_2 *ami_menu_layout(struct gui_window_2 *gwin)
if(menu_glyphs_loaded == false)
ami_menu_load_glyphs(dri);
- for(i=0; i < AMI_MENU_AREXX_MAX; i++)
- {
- if(gwin->menutype[i] == NM_TITLE) {
+ nm = calloc(1, sizeof(struct NewMenu) * (max + 1));
+ if(nm == NULL) return NULL;
+
+ for(i = 0; i < max; i++) {
+ if(md[i] == NULL) {
+ nm[i].nm_Type = NM_IGNORE;
+ continue;
+ }
+
+ if(md[i]->menutype == NM_TITLE) {
j = i + 1;
txtlen = 0;
do {
- if(gwin->menulab[j] != NM_BARLABEL) {
- if(gwin->menutype[j] == NM_ITEM) {
- int item_size = ami_menu_calc_item_width(gwin, j, rp);
+ if(md[j]->menulab != NM_BARLABEL) {
+ if(md[j]->menutype == NM_ITEM) {
+ int item_size = ami_menu_calc_item_width(md, j, rp);
if(item_size > txtlen) {
txtlen = item_size;
}
}
}
j++;
- } while((gwin->menutype[j] != NM_TITLE) && (gwin->menutype[j] != 0));
+ } while((j <= max) && (md[j] != NULL) && (md[j]->menutype != NM_TITLE) && (md[j]->menutype != 0));
}
#ifdef __amigaos4__
if(LIB_IS_AT_LEAST((struct Library *)GadToolsBase, 53, 7)) {
/* GadTools 53.7+ only. For now we will only create the menu
using label.image if there's a bitmap associated with the item. */
- if((gwin->menuicon[i] != NULL) && (gwin->menulab[i] != NM_BARLABEL)) {
+ if((md[i]->menuicon != NULL) && (md[i]->menulab != NM_BARLABEL)) {
int icon_width = 0;
Object *restrict submenuarrow = NULL;
Object *restrict icon = BitMapObj,
IA_Scalable, TRUE,
BITMAP_Screen, scrn,
- BITMAP_SourceFile, gwin->menuicon[i],
+ BITMAP_SourceFile, md[i]->menuicon,
BITMAP_Masking, TRUE,
BitMapEnd;
@@ -872,15 +349,15 @@ static struct gui_window_2 *ami_menu_layout(struct gui_window_2 *gwin)
GetAttr(IA_Width, icon, (ULONG *)&icon_width);
- if(gwin->menutype[i] != NM_SUB) {
+ if(md[i]->menutype != NM_SUB) {
left_posn = txtlen;
}
left_posn = left_posn -
- TextLength(rp, gwin->menulab[i], strlen(gwin->menulab[i])) -
+ TextLength(rp, md[i]->menulab, strlen(md[i]->menulab)) -
icon_width - space_width;
- if((gwin->menutype[i] == NM_ITEM) && (gwin->menutype[i+1] == NM_SUB)) {
+ if((md[i]->menutype == NM_ITEM) && md[i+1] && (md[i+1]->menutype == NM_SUB)) {
left_posn -= menu_glyph_width[NSA_GLYPH_SUBMENU];
submenuarrow = NewObject(NULL, "sysiclass",
@@ -890,278 +367,105 @@ static struct gui_window_2 *ami_menu_layout(struct gui_window_2 *gwin)
TAG_DONE);
}
- gwin->menuobj[i] = LabelObj,
+ md[i]->menuobj = LabelObj,
LABEL_MenuMode, TRUE,
LABEL_DrawInfo, dri,
LABEL_DisposeImage, TRUE,
LABEL_Image, icon,
LABEL_Text, " ",
- LABEL_Text, gwin->menulab[i],
+ LABEL_Text, md[i]->menulab,
LABEL_DisposeImage, TRUE,
LABEL_Image, submenuarrow,
LabelEnd;
- if(gwin->menuobj[i]) gwin->menutype[i] |= MENU_IMAGE;
+ if(md[i]->menuobj) md[i]->menutype |= MENU_IMAGE;
}
}
#endif
- gwin->menu[i].nm_Type = gwin->menutype[i];
+ nm[i].nm_Type = md[i]->menutype;
- if(gwin->menuobj[i])
- gwin->menu[i].nm_Label = (void *)gwin->menuobj[i];
+ if(md[i]->menuobj)
+ nm[i].nm_Label = (void *)md[i]->menuobj;
else
- gwin->menu[i].nm_Label = gwin->menulab[i];
+ nm[i].nm_Label = md[i]->menulab;
- if(gwin->menukey[i]) gwin->menu[i].nm_CommKey = &gwin->menukey[i];
- gwin->menu[i].nm_Flags = 0;
- if(gwin->menu_hook[i].h_Entry) gwin->menu[i].nm_UserData = &gwin->menu_hook[i];
+ if((md[i]->menukey) && (strlen(md[i]->menukey) > 1)) {
+ nm[i].nm_CommKey = md[i]->menukey;
+ }
+ nm[i].nm_Flags = md[i]->flags;
+ if(md[i]->menu_hook.h_Entry) nm[i].nm_UserData = &md[i]->menu_hook;
- if(gwin->menuicon[i]) {
- free(gwin->menuicon[i]);
- gwin->menuicon[i] = NULL;
+ if(md[i]->menuicon) {
+ free(md[i]->menuicon);
+ md[i]->menuicon = NULL;
}
}
FreeScreenDrawInfo(scrn, dri);
-
- return gwin;
-}
-
-void ami_menu_free(struct gui_window_2 *gwin)
-{
- FreeMenus(gwin->imenu);
- FreeVisualInfo(gwin->vi);
-}
-struct Menu *ami_menu_create(struct gui_window_2 *gwin)
-{
- gwin->menu = ami_misc_allocvec_clear(sizeof(struct NewMenu) * (AMI_MENU_AREXX_MAX + 1), 0);
- ami_init_menulabs(gwin);
- ami_menu_scan(ami_tree_get_tree(hotlist_window), gwin);
- ami_menu_arexx_scan(gwin);
- gwin = ami_menu_layout(gwin);
-
- gwin->menu[M_JS].nm_Flags = CHECKIT | MENUTOGGLE;
- if(nsoption_bool(enable_javascript) == true)
- gwin->menu[M_JS].nm_Flags |= CHECKED;
-
- gwin->menu[M_PRINT].nm_Flags = NM_ITEMDISABLED;
-
- gwin->menu[M_IMGFORE].nm_Flags = CHECKIT | MENUTOGGLE;
- if(nsoption_bool(foreground_images) == true)
- gwin->menu[M_IMGFORE].nm_Flags |= CHECKED;
- gwin->menu[M_IMGBACK].nm_Flags = CHECKIT | MENUTOGGLE;
- if(nsoption_bool(background_images) == true)
- gwin->menu[M_IMGBACK].nm_Flags |= CHECKED;
-
- gwin->vi = GetVisualInfo(scrn, TAG_DONE);
- gwin->imenu = CreateMenus(gwin->menu, TAG_DONE);
- LayoutMenus(gwin->imenu, gwin->vi,
+ vi = GetVisualInfo(scrn, TAG_DONE);
+ imenu = CreateMenus(nm, TAG_DONE);
+ LayoutMenus(imenu, vi,
GTMN_NewLookMenus, TRUE, TAG_DONE);
- FreeVec(gwin->menu); /**\todo this should be local to this function */
- gwin->menu = NULL;
-
- return gwin->imenu;
+ free(nm);
+ FreeVisualInfo(vi); /* Not using GadTools after layout so shouldn't need this */
+
+ return imenu;
}
-void ami_menu_arexx_scan(struct gui_window_2 *gwin)
+struct Menu *ami_menu_layout(struct ami_menu_data **md, int max)
{
- /**\todo Rewrite this to not use ExAll() **/
- int item = AMI_MENU_AREXX;
- BPTR lock = 0;
- UBYTE *buffer;
- struct ExAllControl *ctrl;
- char matchpatt[16];
- LONG cont;
- struct ExAllData *ead;
- char *menu_lab;
-
- if((lock = Lock(nsoption_charp(arexx_dir), SHARED_LOCK))) {
- if((buffer = AllocVecTagList(1024, NULL))) {
- if((ctrl = AllocDosObject(DOS_EXALLCONTROL,NULL))) {
- ctrl->eac_LastKey = 0;
-
- if(ParsePatternNoCase("#?.nsrx",(char *)&matchpatt,16) != -1) {
- ctrl->eac_MatchString = (char *)&matchpatt;
- }
-
- do {
- cont = ExAll(lock,(struct ExAllData *)buffer,1024,ED_COMMENT,ctrl);
- if((!cont) && (IoErr() != ERROR_NO_MORE_ENTRIES)) break;
- if(!ctrl->eac_Entries) continue;
-
- for(ead = (struct ExAllData *)buffer; ead; ead = ead->ed_Next) {
- if(item >= AMI_MENU_AREXX_MAX) continue;
- if(EAD_IS_FILE(ead)) {
- gwin->menu[item].nm_Type = NM_ITEM;
- if(ead->ed_Comment[0] != '\0')
- menu_lab = ead->ed_Comment;
- else
- menu_lab = ead->ed_Name;
-
- ami_menu_alloc_item(gwin, item, NM_ITEM, menu_lab, 0, NSA_SPACE,
- ami_menu_item_arexx_entries, (void *)strdup(ead->ed_Name));
-
- item++;
- }
- }
- } while(cont);
- FreeDosObject(DOS_EXALLCONTROL,ctrl);
- }
- FreeVec(buffer);
- }
- UnLock(lock);
+ if(LIB_IS_AT_LEAST((struct Library *)IntuitionBase, 54, 6)) {
+#ifdef __amigaos4__
+ return ami_menu_layout_mc(md, max);
+#endif
+ } else {
+ return ami_menu_layout_gt(md, max);
}
-
- gwin->menu[item].nm_Type = NM_END;
- gwin->menu[item].nm_Label = NULL;
}
-static bool ami_menu_hotlist_add(void *userdata, int level, int item, const char *title, nsurl *url, bool is_folder)
+void ami_menu_free_menu(struct ami_menu_data **md, int max, struct Menu *imenu)
{
- UBYTE type;
- STRPTR icon;
- struct gui_window_2 *gw = (struct gui_window_2 *)userdata;
-
- if(item >= AMI_MENU_HOTLIST_MAX) return false;
-
- switch(level) {
- case 1:
- type = NM_ITEM;
- break;
- case 2:
- type = NM_SUB;
- break;
- default:
- /* entries not at level 1 or 2 are not able to be added
- * \todo construct menus using menuclass instead! */
- return false;
- break;
- }
-
- if(is_folder == true) {
- icon = ASPrintf("icons/directory.png");
+ ami_menu_free_labs(md, max);
+ if(LIB_IS_AT_LEAST((struct Library *)IntuitionBase, 54, 6)) {
+ DisposeObject((Object *)imenu); // if we detach our menu from the window we need to do this manually
} else {
- icon = ami_gui_get_cache_favicon_name(url, true);
- if (icon == NULL) icon = ASPrintf("icons/content.png");
+ FreeMenus(imenu);
}
-
- ami_menu_alloc_item(gw, item, type, title,
- 0, icon, ami_menu_item_hotlist_entries, (void *)url);
- if((is_folder == true) && (type == NM_SUB))
- gw->menu[item].nm_Flags = NM_ITEMDISABLED;
-
- if(icon) FreeVec(icon);
-
- return true;
-}
-
-static nserror ami_menu_scan(struct tree *tree, struct gui_window_2 *gwin)
-{
- return ami_hotlist_scan((void *)gwin, AMI_MENU_HOTLIST, messages_get("HotlistMenu"), ami_menu_hotlist_add);
}
-void ami_menu_update_checked(struct gui_window_2 *gwin)
+void ami_menu_refresh(struct Menu *menu, struct ami_menu_data **md, int menu_item, int max,
+ nserror (*cb)(struct ami_menu_data **md))
{
- struct Menu *menustrip;
-
- GetAttr(WINDOW_MenuStrip, gwin->objects[OID_MAIN], (ULONG *)&menustrip);
- if(!menustrip) return;
- if(nsoption_bool(enable_javascript) == true) {
- if((ItemAddress(menustrip, AMI_MENU_JS)->Flags & CHECKED) == 0)
- ItemAddress(menustrip, AMI_MENU_JS)->Flags ^= CHECKED;
- } else {
- if(ItemAddress(menustrip, AMI_MENU_JS)->Flags & CHECKED)
- ItemAddress(menustrip, AMI_MENU_JS)->Flags ^= CHECKED;
- }
- if(nsoption_bool(foreground_images) == true) {
- if((ItemAddress(menustrip, AMI_MENU_FOREIMG)->Flags & CHECKED) == 0)
- ItemAddress(menustrip, AMI_MENU_FOREIMG)->Flags ^= CHECKED;
- } else {
- if(ItemAddress(menustrip, AMI_MENU_FOREIMG)->Flags & CHECKED)
- ItemAddress(menustrip, AMI_MENU_FOREIMG)->Flags ^= CHECKED;
- }
-
- if(nsoption_bool(background_images) == true) {
- if((ItemAddress(menustrip, AMI_MENU_BACKIMG)->Flags & CHECKED) == 0)
- ItemAddress(menustrip, AMI_MENU_BACKIMG)->Flags ^= CHECKED;
- } else {
- if(ItemAddress(menustrip, AMI_MENU_BACKIMG)->Flags & CHECKED)
- ItemAddress(menustrip, AMI_MENU_BACKIMG)->Flags ^= CHECKED;
- }
+#ifdef __amigaos4__
+ Object *restrict obj;
+ Object *restrict menu_item_obj;
+ int i;
- ResetMenuStrip(gwin->win, menustrip);
-}
+ if(menu == NULL) return;
-void ami_menu_update_disabled(struct gui_window *g, struct hlcache_handle *c)
-{
- struct Window *win = g->shared->win;
+ if(LIB_IS_AT_LEAST((struct Library *)IntuitionBase, 54, 6)) {
+ /* find the address of the menu */
+ menu_item_obj = (Object *)IDoMethod((Object *)menu, MM_FINDID, 0, menu_item);
- if(nsoption_bool(kiosk_mode) == true) return;
+ /* remove all children */
+ while((obj = (Object *)IDoMethod(menu_item_obj, MM_NEXTCHILD, 0, NULL)) != NULL) {
+ IDoMethod(menu_item_obj, OM_REMMEMBER, obj);
+ DisposeObject(obj);
+ }
- if(content_get_type(c) <= CONTENT_CSS)
- {
- OnMenu(win,AMI_MENU_SAVEAS_TEXT);
- OnMenu(win,AMI_MENU_SAVEAS_COMPLETE);
-#ifdef WITH_PDF_EXPORT
- OnMenu(win,AMI_MENU_SAVEAS_PDF);
-#endif
-#if 0
- if(browser_window_get_editor_flags(g->bw) & BW_EDITOR_CAN_COPY) {
- OnMenu(win,AMI_MENU_COPY);
- OnMenu(win,AMI_MENU_CLEAR);
- } else {
- OffMenu(win,AMI_MENU_COPY);
- OffMenu(win,AMI_MENU_CLEAR);
+ /* free associated data */
+ for(i = (menu_item + 1); i <= max; i++) {
+ if(md[i] == NULL) continue;
+ ami_menu_free_lab_item(md, i);
}
- if(browser_window_get_editor_flags(g->bw) & BW_EDITOR_CAN_CUT)
- OnMenu(win,AMI_MENU_CUT);
- else
- OffMenu(win,AMI_MENU_CUT);
-
- if(browser_window_get_editor_flags(g->bw) & BW_EDITOR_CAN_PASTE)
- OnMenu(win,AMI_MENU_PASTE);
- else
- OffMenu(win,AMI_MENU_PASTE);
-#else
- OnMenu(win,AMI_MENU_CUT);
- OnMenu(win,AMI_MENU_COPY);
- OnMenu(win,AMI_MENU_PASTE);
- OnMenu(win,AMI_MENU_CLEAR);
-#endif
- OnMenu(win,AMI_MENU_SELECTALL);
- OnMenu(win,AMI_MENU_FIND);
- OffMenu(win,AMI_MENU_SAVEAS_IFF);
- }
- else
- {
- OffMenu(win,AMI_MENU_CUT);
- OffMenu(win,AMI_MENU_PASTE);
- OffMenu(win,AMI_MENU_CLEAR);
-
- OffMenu(win,AMI_MENU_SAVEAS_TEXT);
- OffMenu(win,AMI_MENU_SAVEAS_COMPLETE);
-#ifdef WITH_PDF_EXPORT
- OffMenu(win,AMI_MENU_SAVEAS_PDF);
-#endif
- OffMenu(win,AMI_MENU_SELECTALL);
- OffMenu(win,AMI_MENU_FIND);
+ /* get current data */
+ cb(md);
-#ifdef WITH_NS_SVG
- if(content_get_bitmap(c) || (ami_mime_compare(c, "svg") == true))
-#else
- if(content_get_bitmap(c))
-#endif
- {
- OnMenu(win,AMI_MENU_COPY);
- OnMenu(win,AMI_MENU_SAVEAS_IFF);
- }
- else
- {
- OffMenu(win,AMI_MENU_COPY);
- OffMenu(win,AMI_MENU_SAVEAS_IFF);
- }
+ /* re-add items to menu */
+ ami_menu_layout_mc_recursive(menu_item_obj, md, NM_ITEM, (menu_item + 1), max);
}
+#endif
}
diff --git a/frontends/amiga/menu.h b/frontends/amiga/menu.h
old mode 100755
new mode 100644
index ac74f38..358faa4
--- a/frontends/amiga/menu.h
+++ b/frontends/amiga/menu.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008,2009,2013 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
+ * Copyright 2017 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -23,142 +23,37 @@
#include <intuition/intuition.h>
#include <libraries/gadtools.h>
-struct hlcache_handle;
-
-/** Maximum number of hotlist items (somewhat arbitrary value) */
-#define AMI_HOTLIST_ITEMS 60
-
-/** Maximum number of ARexx menu items (somewhat arbitrary value) */
-#define AMI_MENU_AREXX_ITEMS 20
-
-/** enum menu structure, has to be here as we need it below. */
-enum {
- /* Project menu */
- M_PROJECT = 0,
- M_NEWWIN,
- M_NEWTAB,
- M_BAR_P1,
- M_OPEN,
- M_SAVEAS,
- M_SAVESRC,
- M_SAVETXT,
- M_SAVECOMP,
- M_SAVEIFF,
-#ifdef WITH_PDF_EXPORT
- M_SAVEPDF,
-#endif
- M_BAR_P2,
- M_PRINT,
- M_BAR_P3,
- M_CLOSETAB,
- M_CLOSEWIN,
- M_BAR_P4,
- M_ABOUT,
- M_BAR_P5,
- M_QUIT,
- /* Edit menu */
- M_EDIT,
- M_CUT,
- M_COPY,
- M_PASTE,
- M_BAR_E1,
- M_SELALL,
- M_CLEAR,
- M_BAR_E2,
- M_UNDO,
- M_REDO,
- /* Browser menu */
- M_BROWSER,
- M_FIND,
- M_BAR_B1,
- M_HISTLOCL,
- M_HISTGLBL,
- M_BAR_B2,
- M_COOKIES,
- M_BAR_B3,
- M_SCALE,
- M_SCALEDEC,
- M_SCALENRM,
- M_SCALEINC,
- M_IMAGES,
- M_IMGFORE,
- M_IMGBACK,
- M_JS,
- M_BAR_B4,
- M_REDRAW,
- /* Hotlist menu */
- M_HOTLIST,
- M_HLADD,
- M_HLSHOW,
- M_BAR_H1, // 47
- AMI_MENU_HOTLIST, /* Where the hotlist entries start */
- AMI_MENU_HOTLIST_MAX = AMI_MENU_HOTLIST + AMI_HOTLIST_ITEMS,
- /* Settings menu */
- M_PREFS,
- M_PREDIT,
- M_BAR_S1,
- M_SNAPSHOT,
- M_PRSAVE,
- /* ARexx menu */
- M_AREXX,
- M_AREXXEX,
- M_BAR_A1,
- AMI_MENU_AREXX,
- AMI_MENU_AREXX_MAX = AMI_MENU_AREXX + AMI_MENU_AREXX_ITEMS
+struct ami_menu_data {
+ char *restrict menulab;
+ Object *restrict menuobj;
+ char *restrict menukey;
+ char *restrict menuicon;
+ struct Hook menu_hook;
+ UBYTE menutype;
+ UWORD flags;
};
-/* We can get away with AMI_MENU_MAX falling short as it is
- * only used for freeing the UTF-8 converted menu labels */
-#define AMI_MENU_MAX AMI_MENU_AREXX
-
-/* The Intuition menu numbers of some menus we might need to modify */
-#define AMI_MENU_SAVEAS_TEXT FULLMENUNUM(0,4,1)
-#define AMI_MENU_SAVEAS_COMPLETE FULLMENUNUM(0,4,2)
-#define AMI_MENU_SAVEAS_IFF FULLMENUNUM(0,4,3)
-#define AMI_MENU_SAVEAS_PDF FULLMENUNUM(0,4,4)
-#define AMI_MENU_CLOSETAB FULLMENUNUM(0,8,0)
-#define AMI_MENU_CUT FULLMENUNUM(1,0,0)
-#define AMI_MENU_COPY FULLMENUNUM(1,1,0)
-#define AMI_MENU_PASTE FULLMENUNUM(1,2,0)
-#define AMI_MENU_SELECTALL FULLMENUNUM(1,4,0)
-#define AMI_MENU_CLEAR FULLMENUNUM(1,5,0)
-#define AMI_MENU_UNDO FULLMENUNUM(1,8,0)
-#define AMI_MENU_REDO FULLMENUNUM(1,9,0)
-#define AMI_MENU_FIND FULLMENUNUM(2,0,0)
-#define AMI_MENU_FOREIMG FULLMENUNUM(2,8,0)
-#define AMI_MENU_BACKIMG FULLMENUNUM(2,8,1)
-#define AMI_MENU_JS FULLMENUNUM(2,9,0)
-
-struct gui_window;
-struct gui_window_2;
+/** empty space */
+#define NSA_SPACE "blankspace.png"
-void ami_free_menulabs(struct gui_window_2 *gwin);
-struct Menu *ami_menu_create(struct gui_window_2 *gwin);
-void ami_menu_refresh(struct gui_window_2 *gwin);
-void ami_menu_update_checked(struct gui_window_2 *gwin);
-void ami_menu_update_disabled(struct gui_window *g, struct hlcache_handle *c);
+/* cleanup */
void ami_menu_free_glyphs(void);
-void ami_menu_free(struct gui_window_2 *gwin);
-/**
- * Sets that an item linked to a toggle menu item has been changed.
- */
-void ami_menu_set_check_toggled(void);
+/* generic menu alloc/free/layout */
+void ami_menu_alloc_item(struct ami_menu_data **md, int num, UBYTE type,
+ const char *restrict label, const char *restrict key, const char *restrict icon,
+ void *restrict func, void *restrict hookdata, UWORD flags);
+struct Menu *ami_menu_layout(struct ami_menu_data **md, int max);
+void ami_menu_free_menu(struct ami_menu_data **md, int max, struct Menu *imenu);
+void ami_menu_free_lab_item(struct ami_menu_data **md, int i);
-/**
- * Gets if the menu needs updating because an item linked
- * to a toggle menu item has been changed.
- * NB: This also *clears* the state
- *
- * \return true if the menus need refreshing
- */
-bool ami_menu_get_check_toggled(void);
+/* refresh a menu's children */
+void ami_menu_refresh(struct Menu *menu, struct ami_menu_data **md, int menu_item, int max,
+ nserror (*cb)(struct ami_menu_data **md));
/**
- * Gets if NetSurf has been quit from the menu
- *
- * \return true if NetSurf has been quit
+ * Get the selected state of a menu item
*/
-bool ami_menu_quit_selected(void);
+bool ami_menu_get_selected(struct Menu *menu, struct IntuiMessage *msg);
#endif
diff --git a/frontends/amiga/misc.c b/frontends/amiga/misc.c
index c09b283..5ca4f90 100755
--- a/frontends/amiga/misc.c
+++ b/frontends/amiga/misc.c
@@ -42,58 +42,6 @@
#include "amiga/misc.h"
#include "amiga/utf8.h"
-void *ami_misc_allocvec_clear(int size, UBYTE value)
-{
-#ifdef __amigaos4__
- return AllocVecTags(size, AVT_ClearWithValue, value, TAG_DONE);
-#else
- void *mem = AllocVec(size, MEMF_ANY);
- if (mem) memset(mem, value, size);
- return mem;
-#endif
-}
-
-APTR ami_misc_itempool_create(int size)
-{
-#ifdef __amigaos4__
- return AllocSysObjectTags(ASOT_ITEMPOOL,
- ASOITEM_MFlags, MEMF_PRIVATE,
- ASOITEM_ItemSize, size,
- ASOITEM_GCPolicy, ITEMGC_AFTERCOUNT,
- ASOITEM_GCParameter, 100,
- TAG_DONE);
-#else
- return CreatePool(MEMF_ANY, 20 * size, size);
-#endif
-}
-
-void ami_misc_itempool_delete(APTR pool)
-{
-#ifdef __amigaos4__
- FreeSysObject(ASOT_ITEMPOOL, pool);
-#else
- DeletePool(pool);
-#endif
-}
-
-APTR ami_misc_itempool_alloc(APTR pool, int size)
-{
-#ifdef __amigaos4__
- return ItemPoolAlloc(pool);
-#else
- return AllocPooled(pool, size);
-#endif
-}
-
-void ami_misc_itempool_free(APTR restrict pool, APTR restrict item, int size)
-{
-#ifdef __amigaos4__
- ItemPoolFree(pool, item);
-#else
- FreePooled(pool, item, size);
-#endif
-}
-
static LONG ami_misc_req(const char *message, uint32 type)
{
LONG ret = 0;
diff --git a/frontends/amiga/misc.h b/frontends/amiga/misc.h
index c7ae5af..a749794 100644
--- a/frontends/amiga/misc.h
+++ b/frontends/amiga/misc.h
@@ -35,15 +35,6 @@ struct Window;
* faliure displaying the message to the user.
*/
nserror amiga_warn_user(const char *warning, const char *detail);
-
-void *ami_misc_allocvec_clear(int size, UBYTE value);
-
-/* Itempool cross-compatibility */
-APTR ami_misc_itempool_create(int size);
-void ami_misc_itempool_delete(APTR pool);
-APTR ami_misc_itempool_alloc(APTR pool, int size);
-void ami_misc_itempool_free(APTR pool, APTR item, int size);
-
char *translate_escape_chars(const char *s);
void ami_misc_fatal_error(const char *message);
int32 amiga_warn_user_multi(const char *body,
diff --git a/frontends/amiga/object.c b/frontends/amiga/object.c
index 6459d63..37fc724 100755
--- a/frontends/amiga/object.c
+++ b/frontends/amiga/object.c
@@ -26,7 +26,7 @@
#include <exec/lists.h>
#include <exec/nodes.h>
-#include "amiga/misc.h"
+#include "amiga/memory.h"
#include "amiga/object.h"
#ifdef __amigaos4__
@@ -41,7 +41,7 @@ static APTR pool_nsobj = NULL;
bool ami_object_init(void)
{
- pool_nsobj = ami_misc_itempool_create(sizeof(struct nsObject));
+ pool_nsobj = ami_memory_itempool_create(sizeof(struct nsObject));
if(pool_nsobj == NULL) return false;
else return true;
@@ -49,7 +49,7 @@ bool ami_object_init(void)
void ami_object_fini(void)
{
- ami_misc_itempool_delete(pool_nsobj);
+ ami_memory_itempool_delete(pool_nsobj);
}
/* Slightly abstract MinList initialisation */
@@ -62,7 +62,7 @@ static void ami_NewMinList(struct MinList *list)
/* Allocate and initialise a new MinList */
struct MinList *ami_AllocMinList(void)
{
- struct MinList *objlist = (struct MinList *)AllocVecTagList(sizeof(struct nsList), NULL);
+ struct MinList *objlist = (struct MinList *)malloc(sizeof(struct nsList));
if(objlist == NULL) return NULL;
ami_NewMinList(objlist);
return objlist;
@@ -78,7 +78,7 @@ struct nsObject *AddObject(struct MinList *objlist, ULONG otype)
{
struct nsObject *dtzo;
- dtzo = (struct nsObject *)ami_misc_itempool_alloc(pool_nsobj, sizeof(struct nsObject));
+ dtzo = (struct nsObject *)ami_memory_itempool_alloc(pool_nsobj, sizeof(struct nsObject));
if(dtzo == NULL) return NULL;
memset(dtzo, 0, sizeof(struct nsObject));
@@ -98,9 +98,9 @@ static void DelObjectInternal(struct nsObject *dtzo, BOOL free_obj)
{
Remove((struct Node *)dtzo);
if(dtzo->callback != NULL) dtzo->callback(dtzo->objstruct);
- if(dtzo->objstruct && free_obj) FreeVec(dtzo->objstruct);
+ if(dtzo->objstruct && free_obj) free(dtzo->objstruct);
if(dtzo->dtz_Node.ln_Name) free(dtzo->dtz_Node.ln_Name);
- ami_misc_itempool_free(pool_nsobj, dtzo, sizeof(struct nsObject));
+ ami_memory_itempool_free(pool_nsobj, dtzo, sizeof(struct nsObject));
dtzo = NULL;
}
@@ -119,18 +119,18 @@ void FreeObjList(struct MinList *objlist)
struct nsObject *node;
struct nsObject *nnode;
- if(IsMinListEmpty((struct MinList *)objlist)) return;
- node = (struct nsObject *)GetHead((struct List *)objlist);
-
- do {
- nnode=(struct nsObject *)GetSucc((struct Node *)node);
- if(node->Type == AMINS_RECT) {
- DelObjectNoFree(node);
- } else {
- DelObject(node);
- }
- } while((node=nnode));
-
- FreeVec(objlist);
+ if(IsMinListEmpty((struct MinList *)objlist) == FALSE) {
+ node = (struct nsObject *)GetHead((struct List *)objlist);
+
+ do {
+ nnode = (struct nsObject *)GetSucc((struct Node *)node);
+ if(node->Type == AMINS_RECT) {
+ DelObjectNoFree(node);
+ } else {
+ DelObject(node);
+ }
+ } while((node = nnode));
+ }
+ free(objlist);
}
diff --git a/frontends/amiga/object.h b/frontends/amiga/object.h
index be96504..70bb550 100755
--- a/frontends/amiga/object.h
+++ b/frontends/amiga/object.h
@@ -33,6 +33,7 @@ enum
AMINS_HISTORYWINDOW,
AMINS_GUIOPTSWINDOW,
AMINS_PRINTWINDOW,
+ AMINS_COREWINDOW,
AMINS_FONT,
AMINS_MIME,
AMINS_RECT
diff --git a/frontends/amiga/options.h b/frontends/amiga/options.h
index 3aa8451..b5b2b3b 100644
--- a/frontends/amiga/options.h
+++ b/frontends/amiga/options.h
@@ -89,8 +89,11 @@ NSOPTION_INTEGER(monitor_aspect_x, 0)
NSOPTION_INTEGER(monitor_aspect_y, 0)
NSOPTION_BOOL(accept_lang_locale, true)
NSOPTION_STRING(local_charset, "ISO-8859-1")
+#ifdef __amigaos4__
+/* Options relevant for OS4 only */
+NSOPTION_BOOL(use_extmem, true)
+#else
/* Options relevant for OS3 only */
-#ifndef __amigaos4__
NSOPTION_BOOL(friend_bitmap, false)
#endif
diff --git a/frontends/amiga/os3support.c b/frontends/amiga/os3support.c
index 6722ca8..c082602 100644
--- a/frontends/amiga/os3support.c
+++ b/frontends/amiga/os3support.c
@@ -46,7 +46,154 @@
#define FAILURE (FALSE)
#define NO !
-ULONG __slab_max_size = 8192; /* Enable clib2's slab allocator */
+/* Utility */
+struct FormatContext
+{
+ STRPTR Index;
+ LONG Size;
+ BOOL Overflow;
+};
+
+STATIC VOID ASM
+StuffChar(
+ REG(a3, struct FormatContext * Context),
+ REG(d0, UBYTE Char))
+{
+ /* Is there still room? */
+ if(Context->Size > 0)
+ {
+ (*Context->Index) = Char;
+
+ Context->Index++;
+ Context->Size--;
+
+ /* Is there only a single character left? */
+ if(Context->Size == 1)
+ {
+ /* Provide null-termination. */
+ (*Context->Index) = '\0';
+
+ /* Don't store any further characters. */
+ Context->Size = 0;
+ }
+ }
+ else
+ {
+ Context->Overflow = TRUE;
+ }
+}
+
+BOOL
+VSPrintfN(
+ LONG MaxLen,
+ STRPTR Buffer,
+ const STRPTR FormatString,
+ const va_list VarArgs)
+{
+ BOOL result = FAILURE;
+
+ /* format a text, but place only up to MaxLen
+ * characters in the output buffer (including
+ * the terminating NUL)
+ */
+
+ if (Buffer == NULL || FormatString == NULL) return(result);
+
+ if(MaxLen > 1)
+ {
+ struct FormatContext Context;
+
+ Context.Index = Buffer;
+ Context.Size = MaxLen;
+ Context.Overflow = FALSE;
+
+ RawDoFmt(FormatString,(APTR)VarArgs,(VOID (*)())StuffChar,(APTR)&Context);
+
+ if(NO Context.Overflow)
+ result = SUCCESS;
+ }
+
+ return(result);
+}
+
+BOOL
+SPrintfN(
+ LONG MaxLen,
+ STRPTR Buffer,
+ const STRPTR FormatString,
+ ...)
+{
+ va_list VarArgs;
+ BOOL result = FAILURE;
+
+ /* format a text, varargs version */
+
+ if (Buffer == NULL && FormatString == NULL) return result;
+
+ va_start(VarArgs,FormatString);
+ result = VSPrintfN(MaxLen,Buffer,FormatString,VarArgs);
+ va_end(VarArgs);
+
+ return(result);
+}
+
+char *ASPrintf(const char *fmt, ...)
+{
+ int r;
+ va_list ap;
+ static char buffer[2048];
+ char *rbuf;
+
+ va_start(ap, fmt);
+ r = VSPrintfN(2048, buffer, (const STRPTR)fmt, ap);
+ va_end(ap);
+
+ r = strlen(buffer);
+ rbuf = AllocVec(r+1, MEMF_CLEAR);
+ if (rbuf != NULL)
+ {
+ strncpy(rbuf, buffer, r);
+ }
+ return rbuf;
+}
+
+/* C */
+char *strlwr(char *str)
+{
+ size_t i;
+ size_t len = strlen(str);
+
+ for(i=0; i<len; i++)
+ str[i] = tolower((unsigned char)str[i]);
+
+ return str;
+}
+
+char *strsep(char **s1, const char *s2)
+{
+ char *const p1 = *s1;
+
+ if (p1 != NULL) {
+ *s1 = strpbrk(p1, s2);
+ if (*s1 != NULL) {
+ *(*s1)++ = '\0';
+ }
+ }
+ return p1;
+}
+
+int scandir(const char *dir, struct dirent ***namelist,
+ int (*filter)(const struct dirent *),
+ int (*compar)(const struct dirent **, const struct dirent **))
+{
+ /*\todo stub function, needs writing, preferably into clib2 */
+ return 0;
+}
+
+long long int strtoll(const char *nptr, char **endptr, int base)
+{
+ return (long long int)strtol(nptr, endptr, base);
+}
/* Diskfont */
struct OutlineFont *OpenOutlineFont(STRPTR fileName, struct List *list, ULONG flags)
@@ -101,7 +248,7 @@ struct OutlineFont *OpenOutlineFont(STRPTR fileName, struct List *list, ULONG fl
}
size = GetFileSize(fh);
- buffer = (UBYTE *)AllocVec(size, MEMF_ANY);
+ buffer = (UBYTE *)malloc(size);
if(buffer == NULL) {
LOG("Unable to allocate memory");
Close(fh);
@@ -116,7 +263,7 @@ struct OutlineFont *OpenOutlineFont(STRPTR fileName, struct List *list, ULONG fl
struct TagItem *tag = (struct TagItem *)buffer;
if((tag->ti_Tag != OT_FileIdent) || (tag->ti_Data != (ULONG)size)) {
LOG("Invalid OTAG file");
- FreeVec(buffer);
+ free(buffer);
FreeVec(otagpath);
return NULL;
}
@@ -134,7 +281,7 @@ struct OutlineFont *OpenOutlineFont(STRPTR fileName, struct List *list, ULONG fl
fname = ASPrintf("%s.library", ti->ti_Data);
} else {
LOG("Cannot find OT_Engine tag");
- FreeVec(buffer);
+ free(buffer);
FreeVec(otagpath);
return NULL;
}
@@ -143,7 +290,7 @@ struct OutlineFont *OpenOutlineFont(STRPTR fileName, struct List *list, ULONG fl
if(BulletBase == NULL) {
LOG("Unable to open font engine %s", fname);
- FreeVec(buffer);
+ free(buffer);
FreeVec(fname);
FreeVec(otagpath);
}
@@ -157,7 +304,7 @@ struct OutlineFont *OpenOutlineFont(STRPTR fileName, struct List *list, ULONG fl
OT_OTagList, (ULONG)buffer,
TAG_DONE);
- of = AllocVec(sizeof(struct OutlineFont), MEMF_CLEAR);
+ of = calloc(1, sizeof(struct OutlineFont));
if(of == NULL) return NULL;
of->BulletBase = BulletBase;
@@ -176,8 +323,8 @@ void CloseOutlineFont(struct OutlineFont *of, struct List *list)
CloseLibrary((struct Library *)BulletBase);
FreeVec(of->OTagPath);
- FreeVec(of->olf_OTagList);
- FreeVec(of);
+ free(of->olf_OTagList);
+ free(of);
}
@@ -185,13 +332,13 @@ void CloseOutlineFont(struct OutlineFont *of, struct List *list)
int64 GetFileSize(BPTR fh)
{
int32 size = 0;
- struct FileInfoBlock *fib = AllocVec(sizeof(struct FileInfoBlock), MEMF_ANY);
+ struct FileInfoBlock *fib = malloc(sizeof(struct FileInfoBlock));
if(fib == NULL) return 0;
ExamineFH(fh, fib);
size = fib->fib_Size;
- FreeVec(fib);
+ free(fib);
return (int64)size;
}
@@ -282,155 +429,5 @@ APTR NewObject(struct IClass * classPtr, CONST_STRPTR classID, ULONG tagList, ..
{
return NewObjectA(classPtr, classID, (const struct TagItem *) &tagList);
}
-
-/* Utility */
-struct FormatContext
-{
- STRPTR Index;
- LONG Size;
- BOOL Overflow;
-};
-
-STATIC VOID ASM
-StuffChar(
- REG(a3, struct FormatContext * Context),
- REG(d0, UBYTE Char))
-{
- /* Is there still room? */
- if(Context->Size > 0)
- {
- (*Context->Index) = Char;
-
- Context->Index++;
- Context->Size--;
-
- /* Is there only a single character left? */
- if(Context->Size == 1)
- {
- /* Provide null-termination. */
- (*Context->Index) = '\0';
-
- /* Don't store any further characters. */
- Context->Size = 0;
- }
- }
- else
- {
- Context->Overflow = TRUE;
- }
-}
-
-BOOL
-VSPrintfN(
- LONG MaxLen,
- STRPTR Buffer,
- const STRPTR FormatString,
- const va_list VarArgs)
-{
- BOOL result = FAILURE;
-
- /* format a text, but place only up to MaxLen
- * characters in the output buffer (including
- * the terminating NUL)
- */
-
- if (Buffer == NULL || FormatString == NULL) return(result);
-
- if(MaxLen > 1)
- {
- struct FormatContext Context;
-
- Context.Index = Buffer;
- Context.Size = MaxLen;
- Context.Overflow = FALSE;
-
- RawDoFmt(FormatString,(APTR)VarArgs,(VOID (*)())StuffChar,(APTR)&Context);
-
- if(NO Context.Overflow)
- result = SUCCESS;
- }
-
- return(result);
-}
-
-BOOL
-SPrintfN(
- LONG MaxLen,
- STRPTR Buffer,
- const STRPTR FormatString,
- ...)
-{
- va_list VarArgs;
- BOOL result = FAILURE;
-
- /* format a text, varargs version */
-
- if (Buffer == NULL && FormatString == NULL) return result;
-
- va_start(VarArgs,FormatString);
- result = VSPrintfN(MaxLen,Buffer,FormatString,VarArgs);
- va_end(VarArgs);
-
- return(result);
-}
-
-char *ASPrintf(const char *fmt, ...)
-{
- int r;
- va_list ap;
- static char buffer[2048];
- char *rbuf;
-
- va_start(ap, fmt);
- r = VSPrintfN(2048, buffer, (const STRPTR)fmt, ap);
- va_end(ap);
-
- r = strlen(buffer);
- rbuf = AllocVec(r+1, MEMF_CLEAR);
- if (rbuf != NULL)
- {
- strncpy(rbuf, buffer, r);
- }
- return rbuf;
-}
-
-/* C */
-char *strlwr(char *str)
-{
- size_t i;
- size_t len = strlen(str);
-
- for(i=0; i<len; i++)
- str[i] = tolower((unsigned char)str[i]);
-
- return str;
-}
-
-char *strsep(char **s1, const char *s2)
-{
- char *const p1 = *s1;
-
- if (p1 != NULL) {
- *s1 = strpbrk(p1, s2);
- if (*s1 != NULL) {
- *(*s1)++ = '\0';
- }
- }
- return p1;
-}
-
-int scandir(const char *dir, struct dirent ***namelist,
- int (*filter)(const struct dirent *),
- int (*compar)(const struct dirent **, const struct dirent **))
-{
- /*\todo stub function, needs writing, preferably into clib2 */
- return 0;
-}
-
-long long int strtoll(const char *nptr, char **endptr, int base)
-{
- return (long long int)strtol(nptr, endptr, base);
-}
-
#endif
diff --git a/frontends/amiga/os3support.h b/frontends/amiga/os3support.h
index 94d1d58..856439b 100644
--- a/frontends/amiga/os3support.h
+++ b/frontends/amiga/os3support.h
@@ -152,7 +152,6 @@
#define DevNameFromLock(A,B,C,D) NameFromLock(A,B,C)
/* Exec */
-#define AllocVecTagList(SZ,TAG) AllocVec(SZ,MEMF_ANY) /* AllocVecTagList with no tags */
#define FindIName FindName
/* Intuition */
diff --git a/frontends/amiga/plotters.c b/frontends/amiga/plotters.c
index 1917171..6bae634 100644
--- a/frontends/amiga/plotters.c
+++ b/frontends/amiga/plotters.c
@@ -33,6 +33,7 @@
#include <math.h>
#include <assert.h>
+#include <stdlib.h>
#include "utils/nsoption.h"
#include "utils/utils.h"
@@ -45,6 +46,7 @@
#include "amiga/bitmap.h"
#include "amiga/font.h"
#include "amiga/gui.h"
+#include "amiga/memory.h"
#include "amiga/misc.h"
#include "amiga/rtg.h"
#include "amiga/utf8.h"
@@ -145,14 +147,10 @@ void ami_init_layers(struct gui_globals *gg, ULONG width, ULONG height, bool for
gg->height = height;
gg->layerinfo = NewLayerInfo();
- gg->areabuf = AllocVecTagList(AREA_SIZE, NULL);
+ gg->areabuf = malloc(AREA_SIZE);
-#ifdef __amigaos4__
- gg->tmprasbuf = AllocVecTagList(width * height, NULL);
-#else
/* OS3/AGA requires this to be in chip mem. RTG would probably rather it wasn't. */
- gg->tmprasbuf = AllocVec(width * height, MEMF_CHIP);
-#endif
+ gg->tmprasbuf = ami_memory_chip_alloc(width * height);
if(gg->palette_mapped == true) {
gg->bm = AllocBitMap(width, height, depth, 0, friend);
@@ -171,7 +169,7 @@ void ami_init_layers(struct gui_globals *gg, ULONG width, ULONG height, bool for
if(!gg->bm) amiga_warn_user("NoMemory","");
- gg->rp = AllocVecTagList(sizeof(struct RastPort), NULL);
+ gg->rp = malloc(sizeof(struct RastPort));
if(!gg->rp) amiga_warn_user("NoMemory","");
InitRastPort(gg->rp);
@@ -184,18 +182,18 @@ void ami_init_layers(struct gui_globals *gg, ULONG width, ULONG height, bool for
InstallLayerHook(gg->rp->Layer,LAYERS_NOBACKFILL);
- gg->rp->AreaInfo = AllocVecTagList(sizeof(struct AreaInfo), NULL);
+ gg->rp->AreaInfo = malloc(sizeof(struct AreaInfo));
if((!gg->areabuf) || (!gg->rp->AreaInfo)) amiga_warn_user("NoMemory","");
- InitArea(gg->rp->AreaInfo,gg->areabuf, AREA_SIZE/5);
+ InitArea(gg->rp->AreaInfo, gg->areabuf, AREA_SIZE/5);
- gg->rp->TmpRas = AllocVecTagList(sizeof(struct TmpRas), NULL);
+ gg->rp->TmpRas = malloc(sizeof(struct TmpRas));
if((!gg->tmprasbuf) || (!gg->rp->TmpRas)) amiga_warn_user("NoMemory","");
InitTmpRas(gg->rp->TmpRas, gg->tmprasbuf, width*height);
if((gg->palette_mapped == true) && (pool_pens == NULL)) {
- pool_pens = ami_misc_itempool_create(sizeof(struct ami_plot_pen));
+ pool_pens = ami_memory_itempool_create(sizeof(struct ami_plot_pen));
}
gg->apen = 0x00000000;
@@ -212,19 +210,19 @@ void ami_free_layers(struct gui_globals *gg)
init_layers_count--;
if((init_layers_count == 0) && (pool_pens != NULL)) {
- ami_misc_itempool_delete(pool_pens);
+ ami_memory_itempool_delete(pool_pens);
pool_pens = NULL;
}
if(gg->rp) {
DeleteLayer(0,gg->rp->Layer);
- FreeVec(gg->rp->TmpRas);
- FreeVec(gg->rp->AreaInfo);
- FreeVec(gg->rp);
+ free(gg->rp->TmpRas);
+ free(gg->rp->AreaInfo);
+ free(gg->rp);
}
- FreeVec(gg->tmprasbuf);
- FreeVec(gg->areabuf);
+ ami_memory_chip_free(gg->tmprasbuf);
+ free(gg->areabuf);
DisposeLayerInfo(gg->layerinfo);
if(gg->palette_mapped == false) {
if(gg->bm) ami_rtg_freebitmap(gg->bm);
@@ -258,7 +256,7 @@ static ULONG ami_plot_obtain_pen(struct MinList *shared_pens, ULONG colr)
if(pen == -1) LOG("WARNING: Cannot allocate pen for ABGR:%lx", colr);
if((shared_pens != NULL) && (pool_pens != NULL)) {
- if((node = (struct ami_plot_pen *)ami_misc_itempool_alloc(pool_pens, sizeof(struct ami_plot_pen)))) {
+ if((node = (struct ami_plot_pen *)ami_memory_itempool_alloc(pool_pens, sizeof(struct ami_plot_pen)))) {
node->pen = pen;
AddTail((struct List *)shared_pens, (struct Node *)node);
}
@@ -282,7 +280,7 @@ void ami_plot_release_pens(struct MinList *shared_pens)
nnode = (struct ami_plot_pen *)GetSucc((struct Node *)node);
ReleasePen(scrn->ViewPort.ColorMap, node->pen);
Remove((struct Node *)node);
- ami_misc_itempool_free(pool_pens, node, sizeof(struct ami_plot_pen));
+ ami_memory_itempool_free(pool_pens, node, sizeof(struct ami_plot_pen));
} while((node = nnode));
glob->apen = 0x00000000;
@@ -712,7 +710,7 @@ static bool ami_bitmap_tile(int x, int y, int width, int height,
bfbm.offsetx = ox;
bfbm.offsety = oy;
bfbm.mask = ami_bitmap_get_mask(bitmap, width, height, tbm);
- bfh = ami_misc_allocvec_clear(sizeof(struct Hook), 0); /* NB: Was not MEMF_PRIVATE */
+ bfh = calloc(1, sizeof(struct Hook));
bfh->h_Entry = (HOOKFUNC)ami_bitmap_tile_hook;
bfh->h_SubEntry = 0;
bfh->h_Data = &bfbm;
@@ -726,7 +724,7 @@ static bool ami_bitmap_tile(int x, int y, int width, int height,
if(amiga_bitmap_get_opaque(bitmap)) DeleteBackFillHook(bfh);
else
#endif
- FreeVec(bfh);
+ free(bfh);
if((ami_bitmap_is_nativebm(bitmap, tbm) == false)) {
/**\todo is this logic logical? */
diff --git a/frontends/amiga/print.c b/frontends/amiga/print.c
index 6926647..5fab0f9 100644
--- a/frontends/amiga/print.c
+++ b/frontends/amiga/print.c
@@ -96,6 +96,14 @@ struct ami_printer_info
struct Window *win;
};
+struct ami_print_window {
+ struct ami_generic_window w;
+ struct Window *win;
+ Object *objects[OID_LAST];
+ Object *gadgets[GID_LAST];
+ struct hlcache_handle *c;
+};
+
enum
{
PGID_MAIN=0,
@@ -119,6 +127,13 @@ static struct ami_printer_info ami_print_info;
static CONST_STRPTR gadlab[PGID_LAST];
static STRPTR printers[11];
+static BOOL ami_print_event(void *w);
+
+static const struct ami_win_event_table ami_print_table = {
+ ami_print_event,
+ NULL, /* we don't explicitly close the print window on quit (or at all???) */
+};
+
static void ami_print_ui_setup(void)
{
gadlab[PGID_PRINTER] = (char *)ami_utf8_easy((char *)messages_get("Printer"));
@@ -133,11 +148,11 @@ static void ami_print_ui_free(void)
int i;
for(i = 0; i < PGID_LAST; i++) {
- if(gadlab[i]) FreeVec((APTR)gadlab[i]);
+ if(gadlab[i]) free((APTR)gadlab[i]);
}
for(i = 0; i < 10; i++) {
- if(printers[i]) FreeVec(printers[i]);
+ if(printers[i]) free(printers[i]);
}
}
@@ -227,21 +242,21 @@ void ami_print_ui(struct hlcache_handle *c)
char filename[30];
int i;
- struct ami_print_window *pw = ami_misc_allocvec_clear(sizeof(struct ami_print_window), 0);
+ struct ami_print_window *pw = calloc(1, sizeof(struct ami_print_window));
pw->c = c;
- printers[0] = ami_misc_allocvec_clear(50, 0);
+ printers[0] = calloc(1, 50);
ami_print_readunit("ENV:Sys/printer.prefs", printers[0], 50, 0);
strcpy(filename,"ENV:Sys/printerN.prefs");
for (i = 1; i < 10; i++)
{
filename[15] = '0' + i;
- printers[i] = AllocVecTagList(50, NULL);
+ printers[i] = malloc(50);
if(!ami_print_readunit(filename, printers[i], 50, i))
{
- FreeVec(printers[i]);
+ free(printers[i]);
printers[i] = NULL;
break;
}
@@ -325,22 +340,21 @@ void ami_print_ui(struct hlcache_handle *c)
EndWindow;
pw->win = (struct Window *)RA_OpenWindow(pw->objects[OID_MAIN]);
-
- pw->node = AddObject(window_list, AMINS_PRINTWINDOW);
- pw->node->objstruct = pw;
+ ami_gui_win_list_add(pw, AMINS_PRINTWINDOW, &ami_print_table);
}
static void ami_print_close(struct ami_print_window *pw)
{
DisposeObject(pw->objects[OID_MAIN]);
- DelObject(pw->node);
+ ami_gui_win_list_remove(pw);
ami_print_ui_free();
}
-BOOL ami_print_event(struct ami_print_window *pw)
+static BOOL ami_print_event(void *w)
{
/* return TRUE if window destroyed */
+ struct ami_print_window *pw = (struct ami_print_window *)w;
ULONG result;
uint16 code;
struct hlcache_handle *c;
@@ -482,7 +496,7 @@ struct MsgPort *ami_print_get_msgport(void)
bool ami_print_begin(struct print_settings *ps)
{
- ami_print_info.gg = ami_misc_allocvec_clear(sizeof(struct gui_globals), 0);
+ ami_print_info.gg = calloc(1, sizeof(struct gui_globals));
if(!ami_print_info.gg) return false;
ami_init_layers(ami_print_info.gg,
@@ -509,7 +523,7 @@ bool ami_print_next_page(void)
void ami_print_end(void)
{
ami_free_layers(ami_print_info.gg);
- FreeVec(ami_print_info.gg);
+ free(ami_print_info.gg);
DisposeObject(ami_print_info.objects[OID_MAIN]);
ami_gui_set_default_gg();
diff --git a/frontends/amiga/print.h b/frontends/amiga/print.h
index bdd409b..0d6b4f5 100755
--- a/frontends/amiga/print.h
+++ b/frontends/amiga/print.h
@@ -21,18 +21,10 @@
#include <proto/exec.h>
struct content;
-
-struct ami_print_window {
- struct nsObject *node;
- struct Window *win;
- Object *objects[OID_LAST];
- Object *gadgets[GID_LAST];
- struct hlcache_handle *c;
-};
+struct ami_print_window;
void ami_print(struct hlcache_handle *c, int copies);
void ami_print_ui(struct hlcache_handle *c);
-BOOL ami_print_event(struct ami_print_window *pw);
bool ami_print_cont(void);
struct MsgPort *ami_print_init(void);
void ami_print_free(void);
diff --git a/frontends/amiga/schedule.c b/frontends/amiga/schedule.c
index 707d7bb..bfafe9c 100644
--- a/frontends/amiga/schedule.c
+++ b/frontends/amiga/schedule.c
@@ -30,7 +30,7 @@
#include "utils/errors.h"
#include "utils/log.h"
-#include "amiga/misc.h"
+#include "amiga/memory.h"
#include "amiga/schedule.h"
struct nscallback
diff --git a/frontends/amiga/schedule.h b/frontends/amiga/schedule.h
index fb648ea..199e6db 100755
--- a/frontends/amiga/schedule.h
+++ b/frontends/amiga/schedule.h
@@ -19,6 +19,7 @@
#ifndef AMIGA_SCHEDULE_H
#define AMIGA_SCHEDULE_H
#include "amiga/os3support.h"
+#include "utils/errors.h"
/**
* Schedule a callback.
diff --git a/frontends/amiga/search.c b/frontends/amiga/search.c
index 429545e..99ee5b4 100755
--- a/frontends/amiga/search.c
+++ b/frontends/amiga/search.c
@@ -27,6 +27,7 @@
#include "utils/config.h"
#include <ctype.h>
#include <string.h>
+#include <stdlib.h>
#include <proto/intuition.h>
#include <proto/exec.h>
@@ -56,7 +57,7 @@
#include "amiga/libs.h"
#include "amiga/gui.h"
-#include "amiga/misc.h"
+#include "amiga/memory.h"
#include "amiga/search.h"
#include "amiga/object.h"
#include "amiga/theme.h"
@@ -68,7 +69,7 @@
static bool search_insert;
struct find_window {
- struct nsObject *node;
+ struct ami_generic_window w;
struct Window *win;
Object *objects[GID_LAST];
struct gui_window *gwin;
@@ -83,6 +84,7 @@ static void ami_search_set_hourglass(bool active, void *p);
static void ami_search_add_recent(const char *string, void *p);
static void ami_search_set_forward_state(bool active, void *p);
static void ami_search_set_back_state(bool active, void *p);
+static BOOL ami_search_event(void *w);
static struct gui_search_table search_table = {
ami_search_set_status,
@@ -92,6 +94,11 @@ static struct gui_search_table search_table = {
ami_search_set_back_state,
};
+static const struct ami_win_event_table ami_search_table = {
+ ami_search_event,
+ NULL, /* we don't explicitly close the search window on quit */
+};
+
struct gui_search_table *amiga_search_table = &search_table;
struct gui_window *ami_search_get_gwin(struct find_window *fw)
@@ -122,7 +129,7 @@ void ami_search_open(struct gui_window *gwin)
return;
}
- fwin = ami_misc_allocvec_clear(sizeof(struct find_window), 0);
+ fwin = calloc(1, sizeof(struct find_window));
fwin->objects[OID_MAIN] = WindowObj,
WA_ScreenTitle, ami_gui_get_screen_title(),
@@ -183,8 +190,7 @@ void ami_search_open(struct gui_window *gwin)
fwin->win = (struct Window *)RA_OpenWindow(fwin->objects[OID_MAIN]);
fwin->gwin = gwin;
- fwin->node = AddObject(window_list,AMINS_FINDWINDOW);
- fwin->node->objstruct = fwin;
+ ami_gui_win_list_add(fwin, AMINS_FINDWINDOW, &ami_search_table);
gwin->shared->searchwin = fwin;
ActivateLayoutGadget((struct Gadget *)fwin->objects[GID_MAIN], fwin->win,
@@ -196,11 +202,11 @@ void ami_search_close(void)
browser_window_search_clear(fwin->gwin->bw);
fwin->gwin->shared->searchwin = NULL;
DisposeObject(fwin->objects[OID_MAIN]);
- DelObject(fwin->node);
- fwin=NULL;
+ ami_gui_win_list_remove(fwin);
+ fwin = NULL;
}
-BOOL ami_search_event(void)
+static BOOL ami_search_event(void *w)
{
/* return TRUE if window destroyed */
ULONG result;
diff --git a/frontends/amiga/search.h b/frontends/amiga/search.h
index c0c6f01..f30352c 100755
--- a/frontends/amiga/search.h
+++ b/frontends/amiga/search.h
@@ -32,11 +32,6 @@ struct gui_search_table *amiga_search_table;
void ami_search_open(struct gui_window *gwin);
/**
- * Process search events
- */
-BOOL ami_search_event(void);
-
-/**
* Close search
*/
void ami_search_close(void);
diff --git a/frontends/amiga/sslcert.c b/frontends/amiga/sslcert.c
index 83798f2..5929f7e 100644
--- a/frontends/amiga/sslcert.c
+++ b/frontends/amiga/sslcert.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2009 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
+ * Copyright 2017 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -16,39 +16,358 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <proto/exec.h>
+/**
+ * \file
+ * Implementation of Amiga certificate viewing using core windows.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <proto/intuition.h>
+
+#include <classes/window.h>
+#include <gadgets/button.h>
+#include <gadgets/layout.h>
+#include <gadgets/scroller.h>
+#include <gadgets/space.h>
+#include <images/label.h>
+
+#include <intuition/icclass.h>
+#include <reaction/reaction_macros.h>
-#include "utils/nsurl.h"
-#include "content/llcache.h"
-#include "netsurf/mouse.h"
-#include "netsurf/window.h"
+#include "utils/log.h"
+#include "netsurf/keypress.h"
+#include "netsurf/plotters.h"
#include "desktop/sslcert_viewer.h"
+#include "utils/messages.h"
+#include "utils/nsoption.h"
-#include "amiga/tree.h"
+#include "amiga/corewindow.h"
+#include "amiga/libs.h"
#include "amiga/sslcert.h"
+#include "amiga/utf8.h"
+
+
+/**
+ * Amiga certificate viewing window context
+ */
+enum {
+ GID_SSLCERT_ACCEPT = GID_CW_LAST,
+ GID_SSLCERT_REJECT,
+ GID_SSLCERT_LAST
+};
+
+#define GID_SSLCERT_SIZE GID_SSLCERT_LAST - GID_CW_LAST
+
+struct ami_crtvrfy_window {
+ /** Amiga core window context */
+ struct ami_corewindow core;
-nserror gui_cert_verify(nsurl *url,
- const struct ssl_cert_info *certs, unsigned long num,
- nserror (*cb)(bool proceed, void *pw), void *cbpw)
+ /** Amiga GUI stuff */
+ Object *sslcert_objects[GID_SSLCERT_LAST]; // technically wasting a few bytes here
+
+ char *sslerr;
+ char *sslaccept;
+ char *sslreject;
+
+ /** SSL certificate viewer context data */
+ struct sslcert_session_data *ssl_data;
+};
+
+/**
+ * destroy a previously created certificate view
+ */
+static nserror
+ami_crtvrfy_destroy(struct ami_crtvrfy_window *crtvrfy_win)
+{
+ nserror res;
+
+ res = sslcert_viewer_fini(crtvrfy_win->ssl_data);
+ if (res == NSERROR_OK) {
+ ami_utf8_free(crtvrfy_win->sslerr);
+ ami_utf8_free(crtvrfy_win->sslaccept);
+ ami_utf8_free(crtvrfy_win->sslreject);
+ res = ami_corewindow_fini(&crtvrfy_win->core); /* closes the window for us */
+ }
+ return res;
+}
+
+static void
+ami_crtvrfy_accept(struct ami_corewindow *ami_cw)
{
- struct sslcert_session_data *data;
- struct treeview_window *ssl_window;
+ struct ami_crtvrfy_window *crtvrfy_win;
+ /* technically degenerate container of */
+ crtvrfy_win = (struct ami_crtvrfy_window *)ami_cw;
- sslcert_viewer_create_session_data(num, url, cb, cbpw,
- certs, &data);
- ssl_current_session = data;
+ sslcert_viewer_accept(crtvrfy_win->ssl_data);
- ssl_window = ami_tree_create(TREE_SSLCERT, data);
- if (!ssl_window) {
- return NSERROR_INIT_FAILED;
+ ami_crtvrfy_destroy(crtvrfy_win);
+}
+
+static void
+ami_crtvrfy_reject(struct ami_corewindow *ami_cw)
+{
+ struct ami_crtvrfy_window *crtvrfy_win;
+ /* technically degenerate container of */
+ crtvrfy_win = (struct ami_crtvrfy_window *)ami_cw;
+
+ sslcert_viewer_reject(crtvrfy_win->ssl_data);
+
+ ami_crtvrfy_destroy(crtvrfy_win);
+}
+
+/**
+ * callback for unknown events on Amiga core window
+ * eg. buttons in the ssl cert window
+ * (result & WMHI_CLASSMASK) gives the class of event (eg. WMHI_GADGETUP)
+ * (result & WMHI_GADGETMASK) gives the gadget ID (eg. GID_SSLCERT_ACCEPT)
+ *
+ * \param ami_cw The Amiga core window structure.
+ * \param result event as returned by RA_HandleInput()
+ * \return TRUE if window closed during event processing
+ */
+static BOOL
+ami_crtvrfy_event(struct ami_corewindow *ami_cw, ULONG result)
+{
+ if((result & WMHI_CLASSMASK) == WMHI_GADGETUP) {
+ switch(result & WMHI_GADGETMASK) {
+ case GID_SSLCERT_ACCEPT:
+ ami_crtvrfy_accept(ami_cw);
+ return TRUE;
+ break;
+
+ case GID_SSLCERT_REJECT:
+ ami_crtvrfy_reject(ami_cw);
+ return TRUE;
+ break;
+ }
}
+ return FALSE;
+}
+
+/**
+ * callback for mouse action for certificate verify on core window
+ *
+ * \param ami_cw The Amiga core window structure.
+ * \param mouse_state netsurf mouse state on event
+ * \param x location of event
+ * \param y location of event
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+ami_crtvrfy_mouse(struct ami_corewindow *ami_cw,
+ browser_mouse_state mouse_state,
+ int x, int y)
+{
+ struct ami_crtvrfy_window *crtvrfy_win;
+ /* technically degenerate container of */
+ crtvrfy_win = (struct ami_crtvrfy_window *)ami_cw;
- ami_tree_open(ssl_window, AMI_TREE_SSLCERT);
+ sslcert_viewer_mouse_action(crtvrfy_win->ssl_data, mouse_state, x, y);
return NSERROR_OK;
}
-void ami_ssl_free(struct treeview_window *twin)
+/**
+ * callback for keypress for certificate verify on core window
+ *
+ * \param example_cw The Amiga core window structure.
+ * \param nskey The netsurf key code
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+ami_crtvrfy_key(struct ami_corewindow *ami_cw, uint32_t nskey)
{
- ami_tree_destroy(twin);
+ struct ami_crtvrfy_window *crtvrfy_win;
+
+ /* technically degenerate container of */
+ crtvrfy_win = (struct ami_crtvrfy_window *)ami_cw;
+
+ if (sslcert_viewer_keypress(crtvrfy_win->ssl_data, nskey)) {
+ return NSERROR_OK;
+ }
+ return NSERROR_NOT_IMPLEMENTED;
+}
+
+/**
+ * callback on draw event for certificate verify on core window
+ *
+ * \param ami_cw The Amiga core window structure.
+ * \param r The rectangle of the window that needs updating.
+ * \param ctx The drawing context
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+ami_crtvrfy_draw(struct ami_corewindow *ami_cw, int x, int y, struct rect *r, struct redraw_context *ctx)
+{
+ struct ami_crtvrfy_window *crtvrfy_win;
+
+ /* technically degenerate container of */
+ crtvrfy_win = (struct ami_crtvrfy_window *)ami_cw;
+
+ sslcert_viewer_redraw(crtvrfy_win->ssl_data, x, y, r, ctx);
+
+ return NSERROR_OK;
+}
+
+static nserror
+ami_crtvrfy_create_window(struct ami_crtvrfy_window *crtvrfy_win)
+{
+ struct ami_corewindow *ami_cw = (struct ami_corewindow *)&crtvrfy_win->core;
+ ULONG refresh_mode = WA_SmartRefresh;
+
+ if(nsoption_bool(window_simple_refresh) == true) {
+ refresh_mode = WA_SimpleRefresh;
+ }
+
+ ami_cw->objects[GID_CW_WIN] = WindowObj,
+ WA_ScreenTitle, ami_gui_get_screen_title(),
+ WA_Title, ami_cw->wintitle,
+ WA_Activate, TRUE,
+ WA_DepthGadget, TRUE,
+ WA_DragBar, TRUE,
+ WA_CloseGadget, FALSE,
+ WA_SizeGadget, TRUE,
+ WA_SizeBBottom, TRUE,
+ WA_Height, scrn->Height / 2,
+ WA_PubScreen, scrn,
+ WA_ReportMouse, TRUE,
+ refresh_mode, TRUE,
+ WA_IDCMP, IDCMP_MOUSEMOVE | IDCMP_MOUSEBUTTONS | IDCMP_NEWSIZE |
+ IDCMP_RAWKEY | IDCMP_GADGETUP | IDCMP_IDCMPUPDATE |
+ IDCMP_EXTENDEDMOUSE | IDCMP_SIZEVERIFY | IDCMP_REFRESHWINDOW,
+ WINDOW_IDCMPHook, &ami_cw->idcmp_hook,
+ WINDOW_IDCMPHookBits, IDCMP_IDCMPUPDATE | IDCMP_EXTENDEDMOUSE |
+ IDCMP_SIZEVERIFY | IDCMP_REFRESHWINDOW,
+ WINDOW_SharedPort, sport,
+ WINDOW_UserData, crtvrfy_win,
+ /* WINDOW_NewMenu, twin->menu, -> No menu for SSL Cert */
+ WINDOW_IconifyGadget, FALSE,
+ WINDOW_Position, WPOS_CENTERSCREEN,
+ WINDOW_ParentGroup, ami_cw->objects[GID_CW_MAIN] = LayoutVObj,
+ LAYOUT_AddImage, LabelObj,
+ LABEL_Text, crtvrfy_win->sslerr,
+ LabelEnd,
+ LAYOUT_AddChild, ami_cw->objects[GID_CW_HSCROLLLAYOUT] = LayoutVObj,
+ LAYOUT_AddChild, ami_cw->objects[GID_CW_VSCROLLLAYOUT] = LayoutHObj,
+ LAYOUT_AddChild, ami_cw->objects[GID_CW_DRAW] = SpaceObj,
+ GA_ID, GID_CW_DRAW,
+ SPACE_Transparent, TRUE,
+ SPACE_BevelStyle, BVS_DISPLAY,
+ GA_RelVerify, TRUE,
+ SpaceEnd,
+ LAYOUT_AddChild, ami_cw->objects[GID_CW_VSCROLL] = ScrollerObj,
+ GA_ID, GID_CW_VSCROLL,
+ GA_RelVerify, TRUE,
+ ICA_TARGET, ICTARGET_IDCMP,
+ ScrollerEnd,
+ LayoutEnd,
+ LAYOUT_AddChild, ami_cw->objects[GID_CW_HSCROLL] = ScrollerObj,
+ GA_ID, GID_CW_HSCROLL,
+ GA_RelVerify, TRUE,
+ ICA_TARGET, ICTARGET_IDCMP,
+ SCROLLER_Orientation, SORIENT_HORIZ,
+ ScrollerEnd,
+ LayoutEnd,
+ LAYOUT_AddChild, LayoutHObj,
+ LAYOUT_AddChild, crtvrfy_win->sslcert_objects[GID_SSLCERT_ACCEPT] = ButtonObj,
+ GA_ID, GID_SSLCERT_ACCEPT,
+ GA_Text, crtvrfy_win->sslaccept,
+ GA_RelVerify, TRUE,
+ ButtonEnd,
+ LAYOUT_AddChild, crtvrfy_win->sslcert_objects[GID_SSLCERT_REJECT] = ButtonObj,
+ GA_ID, GID_SSLCERT_REJECT,
+ GA_Text, crtvrfy_win->sslreject,
+ GA_RelVerify, TRUE,
+ ButtonEnd,
+ EndGroup,
+ CHILD_WeightedHeight, 0,
+ EndGroup,
+ EndWindow;
+
+ if(ami_cw->objects[GID_CW_WIN] == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ return NSERROR_OK;
}
+
+/* exported interface documented in amiga/ssl_cert.h */
+nserror ami_cert_verify(struct nsurl *url,
+ const struct ssl_cert_info *certs,
+ unsigned long num,
+ nserror (*cb)(bool proceed, void *pw),
+ void *cbpw)
+{
+ struct ami_crtvrfy_window *ncwin;
+ nserror res;
+
+ ncwin = calloc(1, sizeof(struct ami_crtvrfy_window));
+ if (ncwin == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ ncwin->core.wintitle = ami_utf8_easy((char *)messages_get("SSLCerts"));
+ ncwin->sslerr = ami_utf8_easy((char *)messages_get("SSLError"));
+ ncwin->sslaccept = ami_utf8_easy((char *)messages_get("SSL_Certificate_Accept"));
+ ncwin->sslreject = ami_utf8_easy((char *)messages_get("SSL_Certificate_Reject"));
+
+ res = ami_crtvrfy_create_window(ncwin);
+ if (res != NSERROR_OK) {
+ LOG("SSL UI builder init failed");
+ ami_utf8_free(ncwin->core.wintitle);
+ ami_utf8_free(ncwin->sslerr);
+ ami_utf8_free(ncwin->sslaccept);
+ ami_utf8_free(ncwin->sslreject);
+ free(ncwin);
+ return res;
+ }
+
+ /* initialise Amiga core window */
+ ncwin->core.draw = ami_crtvrfy_draw;
+ ncwin->core.key = ami_crtvrfy_key;
+ ncwin->core.mouse = ami_crtvrfy_mouse;
+ ncwin->core.close = ami_crtvrfy_reject;
+ ncwin->core.event = ami_crtvrfy_event;
+
+ res = ami_corewindow_init(&ncwin->core);
+ if (res != NSERROR_OK) {
+ ami_utf8_free(ncwin->core.wintitle);
+ ami_utf8_free(ncwin->sslerr);
+ ami_utf8_free(ncwin->sslaccept);
+ ami_utf8_free(ncwin->sslreject);
+ DisposeObject(ncwin->core.objects[GID_CW_WIN]);
+ free(ncwin);
+ return res;
+ }
+
+ /* initialise certificate viewing interface */
+ res = sslcert_viewer_create_session_data(num, url, cb, cbpw, certs,
+ &ncwin->ssl_data);
+ if (res != NSERROR_OK) {
+ ami_utf8_free(ncwin->core.wintitle);
+ ami_utf8_free(ncwin->sslerr);
+ ami_utf8_free(ncwin->sslaccept);
+ ami_utf8_free(ncwin->sslreject);
+ DisposeObject(ncwin->core.objects[GID_CW_WIN]);
+ free(ncwin);
+ return res;
+ }
+
+ res = sslcert_viewer_init(ncwin->core.cb_table,
+ (struct core_window *)ncwin,
+ ncwin->ssl_data);
+ if (res != NSERROR_OK) {
+ ami_utf8_free(ncwin->core.wintitle);
+ ami_utf8_free(ncwin->sslerr);
+ ami_utf8_free(ncwin->sslaccept);
+ ami_utf8_free(ncwin->sslreject);
+ DisposeObject(ncwin->core.objects[GID_CW_WIN]);
+ free(ncwin);
+ return res;
+ }
+
+ return NSERROR_OK;
+}
+
diff --git a/frontends/amiga/sslcert.h b/frontends/amiga/sslcert.h
index 86ce9c4..392989f 100644
--- a/frontends/amiga/sslcert.h
+++ b/frontends/amiga/sslcert.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2009 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
+ * Copyright 2017 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -18,11 +18,21 @@
#ifndef AMIGA_SSLCERT_H
#define AMIGA_SSLCERT_H
+struct nsurl;
+struct ssl_cert_info;
-nserror gui_cert_verify(nsurl *url,
+/**
+ * Prompt the user to verify a certificate with issues.
+ *
+ * \param url The URL being verified.
+ * \param certs The certificate to be verified
+ * \param num The number of certificates to be verified.
+ * \param cb Callback upon user decision.
+ * \param cbpw Context pointer passed to cb
+ * \return NSERROR_OK or error code if prompt creation failed.
+ */
+nserror ami_cert_verify(struct nsurl *url,
const struct ssl_cert_info *certs, unsigned long num,
- nserror (*cb)(bool proceed, void *pw), void *cbpw);
-
-void ami_ssl_free(struct treeview_window *twin);
-
+ nserror (*cb)(bool proceed, void *pw), void *cbpw);
#endif
+
diff --git a/frontends/amiga/theme.c b/frontends/amiga/theme.c
index 4042d1d..496fc54 100644
--- a/frontends/amiga/theme.c
+++ b/frontends/amiga/theme.c
@@ -363,13 +363,13 @@ void ami_init_mouse_pointers(void)
if((ptrfile = Open(ptrfname,MODE_OLDFILE)))
{
int mx,my;
- UBYTE *pprefsbuf = AllocVecTagList(1061, NULL);
- Read(ptrfile,pprefsbuf,1061);
+ UBYTE *pprefsbuf = malloc(1061);
+ Read(ptrfile, pprefsbuf, 1061);
- mouseptrbm[i]=AllocVecTagList(sizeof(struct BitMap), NULL);
- InitBitMap(mouseptrbm[i],2,32,32);
- mouseptrbm[i]->Planes[0] = AllocRaster(32,32);
- mouseptrbm[i]->Planes[1] = AllocRaster(32,32);
+ mouseptrbm[i] = malloc(sizeof(struct BitMap));
+ InitBitMap(mouseptrbm[i], 2, 32, 32);
+ mouseptrbm[i]->Planes[0] = AllocRaster(32, 32);
+ mouseptrbm[i]->Planes[1] = AllocRaster(32, 32);
mouseptr.BitMap = mouseptrbm[i];
for(my=0;my<32;my++)
@@ -393,7 +393,7 @@ void ami_init_mouse_pointers(void)
POINTERA_YResolution,POINTERYRESN_SCREENRESASPECT,
TAG_DONE);
- FreeVec(pprefsbuf);
+ free(pprefsbuf);
Close(ptrfile);
}
@@ -414,7 +414,7 @@ void ami_mouse_pointers_free(void)
{
FreeRaster(mouseptrbm[i]->Planes[0],32,32);
FreeRaster(mouseptrbm[i]->Planes[1],32,32);
- FreeVec(mouseptrbm[i]);
+ free(mouseptrbm[i]);
}
}
}
diff --git a/frontends/amiga/tree.c b/frontends/amiga/tree.c
deleted file mode 100644
index 8328194..0000000
--- a/frontends/amiga/tree.c
+++ /dev/null
@@ -1,1474 +0,0 @@
-/*
- * Copyright 2008 - 2013 Chris Young <chris(a)unsatisfactorysoftware.co.uk>
- *
- * This file is part of NetSurf, http://www.netsurf-browser.org/
- *
- * NetSurf is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * NetSurf is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "amiga/os3support.h"
-
-#include <stdlib.h>
-#include <proto/window.h>
-#include <proto/layout.h>
-#include <proto/space.h>
-#include <proto/label.h>
-#include <proto/scroller.h>
-#include <proto/exec.h>
-#include <proto/intuition.h>
-#include <proto/button.h>
-#include <proto/bitmap.h>
-#include <proto/graphics.h>
-#include <proto/asl.h>
-#include <proto/utility.h>
-#include <proto/dos.h>
-
-#include <libraries/gadtools.h>
-#include <gadgets/button.h>
-#include <classes/window.h>
-#include <gadgets/space.h>
-#include <images/label.h>
-#include <images/bitmap.h>
-#include <gadgets/layout.h>
-#include <gadgets/scroller.h>
-#include <reaction/reaction_macros.h>
-#include <intuition/icclass.h>
-#ifdef __amigaos4__
-#include <graphics/blitattr.h>
-#endif
-
-#include <assert.h>
-#include <string.h>
-
-#include "utils/nsoption.h"
-#include "utils/utils.h"
-#include "utils/messages.h"
-#include "netsurf/browser_window.h"
-#include "netsurf/window.h"
-#include "netsurf/keypress.h"
-#include "content/llcache.h"
-#include "desktop/cookie_manager.h"
-#include "desktop/global_history.h"
-#include "desktop/hotlist.h"
-#include "desktop/sslcert_viewer.h"
-
-#include "amiga/gui.h"
-#include "amiga/tree.h"
-#include "amiga/file.h"
-#include "amiga/libs.h"
-#include "amiga/misc.h"
-#include "amiga/utf8.h"
-#include "amiga/sslcert.h"
-#include "amiga/drag.h" /* drag icon stuff */
-#include "amiga/theme.h" /* pointers */
-#include "amiga/filetype.h"
-#include "amiga/schedule.h"
-#include "amiga/plotters.h"
-
-#define AMI_TREE_MENU_ITEMS 26
-#define AMI_TREE_MENU_NEWDIR FULLMENUNUM(1,0,0)
-#define AMI_TREE_MENU_NEWURL FULLMENUNUM(1,1,0)
-#define AMI_TREE_MENU_EDIT FULLMENUNUM(1,3,0)
-#define AMI_TREE_MENU_DELETE FULLMENUNUM(1,5,0)
-#define AMI_TREE_MENU_CLEAR FULLMENUNUM(1,8,0)
-
-enum {
- GID_OPEN = GID_LAST,
- GID_TREE_LAST
-};
-
-
-struct treeview_window {
- struct nsObject *node;
- struct Window *win;
- Object *objects[GID_TREE_LAST];
- int type;
- struct NewMenu *menu;
- char *menu_name[AMI_TREE_MENU_ITEMS];
- struct tree *tree;
- struct Hook scrollerhook;
- uint32 key_state;
- uint32 mouse_state;
- int drag_x;
- int drag_y;
- struct timeval lastclick;
- int max_width;
- int max_height;
- struct gui_globals globals;
- struct sslcert_session_data *ssl_data;
- char *wintitle;
- char *sslerr;
- char *sslaccept;
- char *sslreject;
- struct MinList *shared_pens;
-};
-
-struct ami_tree_redraw_req {
- int x;
- int y;
- int width;
- int height;
- struct treeview_window *twin;
-};
-
-#if 0
-void ami_tree_draw(struct treeview_window *twin);
-static void ami_tree_resized(struct tree *tree, int width,
- int height, void *data);
-static void ami_tree_scroll_visible(int y, int height, void *data);
-static void ami_tree_get_window_dimensions(int *width, int *height, void *data);
-#endif
-
-void ami_tree_destroy(struct treeview_window *twin)
-{
- tree_delete(twin->tree);
- FreeVec(twin->shared_pens);
- FreeVec(twin);
-}
-
-struct tree *ami_tree_get_tree(struct treeview_window *twin)
-{
- return twin->tree;
-}
-
-static void ami_tree_resized(struct tree *tree, int width, int height, void *data)
-{
- struct treeview_window *twin = data;
- struct IBox *bbox;
-
- twin->max_height = height;
- twin->max_width = width;
-
- if(twin->win)
- {
- if(ami_gui_get_space_box(twin->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
- amiga_warn_user("NoMemory", "");
- return;
- }
-
- if(height == -1) {
- SetAttrs((APTR)twin->objects[OID_MAIN],
- WINDOW_VertProp, -1,
- TAG_DONE);
- } else {
- RefreshSetGadgetAttrs((APTR)twin->objects[OID_VSCROLL], twin->win, NULL,
- SCROLLER_Total, height,
- SCROLLER_Visible, bbox->Height,
- TAG_DONE);
- }
-
- if(width == -1) {
- SetAttrs((APTR)twin->objects[OID_MAIN],
- WINDOW_HorizProp, -1,
- TAG_DONE);
- } else {
- RefreshSetGadgetAttrs((APTR)twin->objects[OID_HSCROLL], twin->win, NULL,
- SCROLLER_Total, width,
- SCROLLER_Visible, bbox->Width,
- TAG_DONE);
- }
- ami_gui_free_space_box(bbox);
- }
-}
-
-/**
- * Retrieves the dimensions of the window with the tree
- *
- * \param data user data assigned to the tree on tree creation
- * \param width will be updated to window width if not NULL
- * \param height will be updated to window height if not NULL
- */
-static void ami_tree_get_window_dimensions(int *width, int *height, void *data)
-{
- struct treeview_window *twin = data;
- struct IBox *bbox;
-
- if(ami_gui_get_space_box(twin->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
- amiga_warn_user("NoMemory", "");
- return;
- }
-
- if(width) *width = bbox->Width;
- if(height) *height = bbox->Height;
-
- ami_gui_free_space_box(bbox);
-}
-
-static void ami_tree_redraw_req_dr(void *p)
-{
- struct ami_tree_redraw_req *atrr_data = (struct ami_tree_redraw_req *)p;
- int x = atrr_data->x;
- int y = atrr_data->y;
- int width = atrr_data->width;
- int height = atrr_data->height;
- struct treeview_window *twin = atrr_data->twin;
- struct IBox *bbox;
- int pos_x, pos_y;
- struct RastPort *temprp;
- struct redraw_context ctx = {
- .interactive = true,
- .background_images = true,
- .plot = &amiplot
- };
-
- if(!twin->win) return;
-
- ami_update_pointer(twin->win, GUI_POINTER_WAIT);
-
- glob = &twin->globals;
- temprp = glob->rp;
- glob->rp = twin->win->RPort;
-
- GetAttr(SCROLLER_Top, twin->objects[OID_HSCROLL], (ULONG *)&pos_x);
- GetAttr(SCROLLER_Top, twin->objects[OID_VSCROLL], (ULONG *)&pos_y);
-
- if(ami_gui_get_space_box(twin->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
- amiga_warn_user("NoMemory", "");
- return;
- }
-
- x += bbox->Left;
- y += bbox->Top;
-
- if(x - pos_x + width > bbox->Width) width = bbox->Width - (x - pos_x);
- if(y - pos_y + height > bbox->Height) height = bbox->Height - (y - pos_y);
-
- if(x < pos_x) {
- width -= pos_x - x;
- x = pos_x;
- }
-
- if(y < pos_y) {
- height -= pos_y - y;
- y = pos_y;
- }
-
- tree_draw(twin->tree, bbox->Left - pos_x, bbox->Top - pos_y,
- atrr_data->x, atrr_data->y,
- atrr_data->width, atrr_data->height, &ctx);
-
- FreeVec(atrr_data);
- ami_gui_free_space_box(bbox);
- ami_update_pointer(twin->win, GUI_POINTER_DEFAULT);
- ami_clearclipreg(glob);
- glob->rp = temprp;
- ami_gui_set_default_gg();
-}
-
-static void ami_tree_redraw_req(void *p)
-{
- struct ami_tree_redraw_req *atrr_data = (struct ami_tree_redraw_req *)p;
- int x = atrr_data->x;
- int y = atrr_data->y;
- int width = atrr_data->width;
- int height = atrr_data->height;
- struct treeview_window *twin = atrr_data->twin;
- struct IBox *bbox;
- int pos_x, pos_y;
- int tile_x, tile_y, tile_w, tile_h;
- struct redraw_context ctx = {
- .interactive = true,
- .background_images = true,
- .plot = &amiplot
- };
-
- if(!twin->win) return;
-
- ami_update_pointer(twin->win, GUI_POINTER_WAIT);
-
- glob = &twin->globals;
-
- GetAttr(SCROLLER_Top, twin->objects[OID_HSCROLL], (ULONG *)&pos_x);
- GetAttr(SCROLLER_Top, twin->objects[OID_VSCROLL], (ULONG *)&pos_y);
-
- if(ami_gui_get_space_box(twin->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
- amiga_warn_user("NoMemory", "");
- return;
- }
-
- if(x - pos_x + width > bbox->Width) width = bbox->Width - (x - pos_x);
- if(y - pos_y + height > bbox->Height) height = bbox->Height - (y - pos_y);
-
- if(x < pos_x) {
- width -= pos_x - x;
- x = pos_x;
- }
-
- if(y < pos_y) {
- height -= pos_y - y;
- y = pos_y;
- }
-
- for(tile_y = y; tile_y < (y + height); tile_y += nsoption_int(redraw_tile_size_y)) {
- tile_h = nsoption_int(redraw_tile_size_y);
- if(((y + height) - tile_y) < nsoption_int(redraw_tile_size_y))
- tile_h = (y + height) - tile_y;
-
- for(tile_x = x; tile_x < (x + width); tile_x += nsoption_int(redraw_tile_size_x)) {
- tile_w = nsoption_int(redraw_tile_size_x);
- if(((x + width) - tile_x) < nsoption_int(redraw_tile_size_x))
- tile_w = (x + width) - tile_x;
-
- tree_draw(twin->tree, - tile_x, - tile_y,
- tile_x, tile_y, tile_w, tile_h, &ctx);
-#ifdef __amigaos4__
- BltBitMapTags(BLITA_SrcType, BLITT_BITMAP,
- BLITA_Source, twin->globals.bm,
- BLITA_SrcX, 0,
- BLITA_SrcY, 0,
- BLITA_DestType, BLITT_RASTPORT,
- BLITA_Dest, twin->win->RPort,
- BLITA_DestX, bbox->Left + tile_x - pos_x,
- BLITA_DestY, bbox->Top + tile_y - pos_y,
- BLITA_Width, tile_w,
- BLITA_Height, tile_h,
- TAG_DONE);
-#else
- BltBitMapRastPort(twin->globals.bm, 0, 0,
- twin->win->RPort, bbox->Left + tile_x - pos_x, bbox->Top + tile_y - pos_y,
- tile_w, tile_h, 0xC0);
-#endif
- }
- }
-
- FreeVec(atrr_data);
- ami_gui_free_space_box(bbox);
- ami_update_pointer(twin->win, GUI_POINTER_DEFAULT);
- ami_clearclipreg(glob);
- ami_gui_set_default_gg();
-}
-
-static void ami_tree_redraw_request(int x, int y, int width, int height, void *data)
-{
- struct ami_tree_redraw_req *atrr_data = AllocVecTagList(sizeof(struct ami_tree_redraw_req), NULL);
-
- atrr_data->x = x;
- atrr_data->y = y;
- atrr_data->width = width;
- atrr_data->height = height;
- atrr_data->twin = (struct treeview_window *)data;
-
- /** /todo Queue these requests properly like the main browser code does
- **/
-
- if(nsoption_bool(direct_render) == false)
- ami_schedule(0, ami_tree_redraw_req, atrr_data);
- else
- ami_schedule(0, ami_tree_redraw_req_dr, atrr_data);
-}
-
-static void ami_tree_draw(struct treeview_window *twin)
-{
- struct IBox *bbox;
- int x, y;
-
- if(!twin) return;
-
- GetAttr(SCROLLER_Top, twin->objects[OID_HSCROLL], (ULONG *)&x);
- GetAttr(SCROLLER_Top, twin->objects[OID_VSCROLL], (ULONG *)&y);
-
- if(ami_gui_get_space_box(twin->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
- amiga_warn_user("NoMemory", "");
- return;
- }
-
- ami_tree_redraw_request(x, y, bbox->Width, bbox->Height, twin);
-
- ami_gui_free_space_box(bbox);
-}
-
-/**
- * Scrolls the tree to make an element visible
- *
- * \param y Y coordinate of the element
- * \param height height of the element
- * \param data user data assigned to the tree on tree creation
- */
-static void ami_tree_scroll_visible(int y, int height, void *data)
-{
- int sy, scrollset;
- struct IBox *bbox;
- struct treeview_window *twin = data;
-
- GetAttr(SCROLLER_Top, twin->objects[OID_VSCROLL], (ULONG *)&sy);
- if(ami_gui_get_space_box(twin->objects[GID_BROWSER], &bbox) != NSERROR_OK) {
- amiga_warn_user("NoMemory", "");
- return;
- }
-
- if((y > sy) && ((y + height) < (sy + bbox->Height))) {
- ami_gui_free_space_box(bbox);
- return;
- }
-
- if((y <= sy) || (height > bbox->Height)) scrollset = (ULONG)y;
- else scrollset = sy + (y + height) - (sy + bbox->Height);
-
- RefreshSetGadgetAttrs((APTR)twin->objects[OID_VSCROLL], twin->win, NULL,
- SCROLLER_Top, scrollset,
- TAG_DONE);
-
- ami_gui_free_space_box(bbox);
- ami_tree_draw(twin);
-}
-
-static void ami_tree_scroll(struct treeview_window *twin, int sx, int sy)
-{
- int x, y;
-
- if(!twin) return;
-
- GetAttr(SCROLLER_Top, twin->objects[OID_HSCROLL], (ULONG *)&x);
- GetAttr(SCROLLER_Top, twin->objects[OID_VSCROLL], (ULONG *)&y);
-
- x += sx;
- y += sy;
-
- if(y < 0) y = 0;
- if(x < 0) x = 0;
-
- RefreshSetGadgetAttrs((APTR)twin->objects[OID_VSCROLL], twin->win, NULL,
- SCROLLER_Top, y,
- TAG_DONE);
-
- RefreshSetGadgetAttrs((APTR)twin->objects[OID_HSCROLL], twin->win, NULL,
- SCROLLER_Top, x,
- TAG_DONE);
-
- ami_tree_draw(twin);
-}
-
-static void ami_tree_drag_icon_show(struct treeview_window *twin)
-{
- const char *type = "project";
- nsurl *url = NULL;
- const char *title = NULL;
-
- if((twin->type == AMI_TREE_COOKIES) ||
- (twin->type == AMI_TREE_SSLCERT)) return; /* No permissable drag operations */
-
- if((tree_drag_status(twin->tree) == TREE_SELECT_DRAG) ||
- (tree_drag_status(twin->tree) == TREE_TEXTAREA_DRAG))
- return;
-
- if((twin->type == AMI_TREE_HOTLIST) && (hotlist_has_selection())) {
- hotlist_get_selection(&url, &title);
- } else if((twin->type == AMI_TREE_HISTORY) && (global_history_has_selection())) {
- global_history_get_selection(&url, &title);
- }
-
- if(title && (url == NULL))
- {
- ami_drag_icon_show(twin->win, "drawer");
- }
- else
- {
- ami_drag_icon_show(twin->win, type);
- }
-}
-
-static void ami_tree_drag_end(struct treeview_window *twin, int x, int y)
-{
- struct gui_window_2 *gwin;
- struct treeview_window *tw;
- BOOL drag;
- nsurl *url = NULL;
- const char *title = NULL;
- bool ok = false;
-
- if((drag = ami_drag_in_progress())) ami_drag_icon_close(twin->win);
-
- if(drag && (twin != ami_window_at_pointer(AMINS_TVWINDOW)))
- {
- if((twin->type == AMI_TREE_HOTLIST) && (hotlist_has_selection())) {
- ok = hotlist_get_selection(&url, &title);
- } else if((twin->type == AMI_TREE_HISTORY) && (global_history_has_selection())) {
- ok = global_history_get_selection(&url, &title);
- }
-
- if((ok == false) || (url == NULL)) {
- DisplayBeep(scrn);
- } else if(url) {
- if((gwin = ami_window_at_pointer(AMINS_WINDOW))) {
- browser_window_navigate(gwin->gw->bw,
- url,
- NULL,
- BW_NAVIGATE_HISTORY,
- NULL,
- NULL,
- NULL);
- } else if((tw = ami_window_at_pointer(AMINS_TVWINDOW)) &&
- (tw != twin) && (tw->type == AMI_TREE_HOTLIST)) {
- hotlist_add_entry(url, title, true, y);
- }
- }
- tree_mouse_action(twin->tree, twin->mouse_state | twin->key_state,
- twin->drag_x, twin->drag_y); /* Keep the tree happy */
- tree_drag_end(twin->tree, twin->mouse_state,
- twin->drag_x, twin->drag_y,
- twin->drag_x, twin->drag_y); /* Keep the tree happier */
- } else {
- if(tree_drag_status(twin->tree) == TREE_UNKNOWN_DRAG)
- DisplayBeep(scrn);
-
- tree_drag_end(twin->tree, twin->mouse_state,
- twin->drag_x, twin->drag_y, x, y);
- }
-}
-
-HOOKF(void, ami_tree_scroller_hook, Object *, object, struct IntuiMessage *)
-{
- ULONG gid;
- struct treeview_window *twin = hook->h_Data;
- struct IntuiWheelData *wheel;
-
- switch(msg->Class)
- {
- case IDCMP_IDCMPUPDATE:
- gid = GetTagData( GA_ID, 0, msg->IAddress );
-
- switch( gid )
- {
- case OID_HSCROLL:
- case OID_VSCROLL:
- ami_tree_draw(twin);
- break;
- }
- break;
-#ifdef __amigaos4__
- case IDCMP_EXTENDEDMOUSE:
- if(msg->Code == IMSGCODE_INTUIWHEELDATA)
- {
- wheel = (struct IntuiWheelData *)msg->IAddress;
-
- ami_tree_scroll(twin, (wheel->WheelX * 20), (wheel->WheelY * 20));
- }
- break;
-#endif
- }
-}
-
-static void ami_tree_menu(struct treeview_window *twin)
-{
- if(twin->menu) return;
-
- if((twin->menu = ami_misc_allocvec_clear(sizeof(struct NewMenu) * AMI_TREE_MENU_ITEMS, 0))) {
- twin->menu[0].nm_Type = NM_TITLE;
- twin->menu_name[0] = ami_utf8_easy((char *)messages_get("Tree"));
- twin->menu[0].nm_Label = twin->menu_name[0];
-
- twin->menu[1].nm_Type = NM_ITEM;
- twin->menu_name[1] = ami_utf8_easy((char *)messages_get("TreeExport"));
- twin->menu[1].nm_Label = twin->menu_name[1];
- if(twin->type == AMI_TREE_COOKIES)
- twin->menu[1].nm_Flags = NM_ITEMDISABLED;
- twin->menu[1].nm_CommKey = "S";
-
- twin->menu[2].nm_Type = NM_ITEM;
- twin->menu[2].nm_Label = NM_BARLABEL;
-
- twin->menu[3].nm_Type = NM_ITEM;
- twin->menu_name[3] = ami_utf8_easy((char *)messages_get("Expand"));
- twin->menu[3].nm_Label = twin->menu_name[3];
-
- twin->menu[4].nm_Type = NM_SUB;
- twin->menu_name[4] = ami_utf8_easy((char *)messages_get("All"));
- twin->menu[4].nm_Label = twin->menu_name[4];
- twin->menu[4].nm_CommKey = "+";
-
- if(twin->type == AMI_TREE_COOKIES)
- {
- twin->menu_name[5] = ami_utf8_easy((char *)messages_get("Domains"));
- twin->menu_name[6] = ami_utf8_easy((char *)messages_get("Cookies"));
- }
- else
- {
- twin->menu_name[5] = ami_utf8_easy((char *)messages_get("Folders"));
- twin->menu_name[6] = ami_utf8_easy((char *)messages_get("Links"));
- }
-
- twin->menu[5].nm_Type = NM_SUB;
- twin->menu[5].nm_Label = twin->menu_name[5]; // tree-specific title
-
- twin->menu[6].nm_Type = NM_SUB;
- twin->menu[6].nm_Label = twin->menu_name[6]; // tree-specific title
-
- twin->menu[7].nm_Type = NM_ITEM;
- twin->menu_name[7] = ami_utf8_easy((char *)messages_get("Collapse"));
- twin->menu[7].nm_Label = twin->menu_name[7];
-
- twin->menu[8].nm_Type = NM_SUB;
- twin->menu[8].nm_Label = twin->menu_name[4];
- twin->menu[8].nm_CommKey = "-";
-
- twin->menu[9].nm_Type = NM_SUB;
- twin->menu[9].nm_Label = twin->menu_name[5]; // tree-specific title
-
- twin->menu[10].nm_Type = NM_SUB;
- twin->menu[10].nm_Label = twin->menu_name[6]; // tree-specific title
-
- twin->menu[11].nm_Type = NM_ITEM;
- twin->menu[11].nm_Label = NM_BARLABEL;
-
- twin->menu[12].nm_Type = NM_ITEM;
- twin->menu_name[12] = ami_utf8_easy((char *)messages_get("SnapshotWindow"));
- twin->menu[12].nm_Label = twin->menu_name[12];
-
- twin->menu[13].nm_Type = NM_ITEM;
- twin->menu[13].nm_Label = NM_BARLABEL;
-
- twin->menu[14].nm_Type = NM_ITEM;
- twin->menu_name[14] = ami_utf8_easy((char *)messages_get("CloseWindow"));
- twin->menu[14].nm_Label = twin->menu_name[14];
- twin->menu[14].nm_CommKey = "K";
-
- twin->menu[15].nm_Type = NM_TITLE;
- twin->menu_name[15] = ami_utf8_easy((char *)messages_get("Edit"));
- twin->menu[15].nm_Label = twin->menu_name[15];
-
- twin->menu[16].nm_Type = NM_ITEM;
- twin->menu_name[16] = ami_utf8_easy((char *)messages_get("TreeNewFolder"));
- twin->menu[16].nm_Label = twin->menu_name[16];
- twin->menu[16].nm_CommKey = "N";
-
- twin->menu[17].nm_Type = NM_ITEM;
- twin->menu_name[17] = ami_utf8_easy((char *)messages_get("TreeNewLink"));
- twin->menu[17].nm_Label = twin->menu_name[17];
-
- twin->menu[18].nm_Type = NM_ITEM;
- twin->menu[18].nm_Label = NM_BARLABEL;
-
- twin->menu[19].nm_Type = NM_ITEM;
- twin->menu_name[19] = ami_utf8_easy((char *)messages_get("TreeEdit"));
- twin->menu[19].nm_Label = twin->menu_name[19];
- twin->menu[19].nm_CommKey = "E";
-
- twin->menu[20].nm_Type = NM_ITEM;
- twin->menu[20].nm_Label = NM_BARLABEL;
-
- twin->menu[21].nm_Type = NM_ITEM;
- twin->menu_name[21] = ami_utf8_easy((char *)messages_get("TreeDelete"));
- twin->menu[21].nm_Label = twin->menu_name[21];
- twin->menu[21].nm_CommKey = "D";
-
- twin->menu[22].nm_Type = NM_ITEM;
- twin->menu[22].nm_Label = NM_BARLABEL;
-
- twin->menu[23].nm_Type = NM_ITEM;
- twin->menu_name[23] = ami_utf8_easy((char *)messages_get("SelectAllNS"));
- twin->menu[23].nm_Label = twin->menu_name[23];
- twin->menu[23].nm_CommKey = "A";
-
- twin->menu[24].nm_Type = NM_ITEM;
- twin->menu_name[24] = ami_utf8_easy((char *)messages_get("ClearNS"));
- twin->menu[24].nm_Label = twin->menu_name[24];
-
- twin->menu