.comment-link {margin-left:.6em;}

David @ Tokyo

Perspective from Japan on whaling and whale meat, a spot of gourmet news, and monthly updates of whale meat stockpile statistics

11/28/2005

 

IWC: And here's Captain Watson...

All the anti-whalers in the world need to sit back and think that they are on the same side as a scumbag like this guy.

Interesting that he criticises Greenpeace for their "non-confrontational" approach. One wonders how anyone could consider what Greenpeace does as constructive, but then considering Watson boasts about having sunk the vessels of private citizens, I guess he's on a totally different level.

 

IWC: Sealord gets dragged into it!!

Hahaha, great stuff here!

Earth Island Institute, a large money sucking "environmental" group has criticised NZ fisheries company Sealord for it's 50% ownership by Japanese fisheries enterprise Nissui. The other half is owned by Maori groups, which are also sympathetic to whaling interests given their shared belief in the principle of sustainable resource use.

But the good stuff was the response from Sealord's Chief Executive Doug Mckay. Calling the "environmental" groups anti-use campaigns "commercial terrorism", he noted that "(Nissui) are one of the industry participants in their Japanese government's scientific research programme on whaling, which is well-canvassed, well-debated (and) well-understood through the International Whaling Commission".

Indeed it is! It would be fantastic to see a homegrown kiwi company in Sealord go toe to toe with the donation thirsty "conservationists". They had better too - because if they ever succeed in getting whales off the menu, guess what's next?

11/26/2005

 

E17: Module Internationalization

Enlightenment DR17 has had internationalization support for the best part of a year now. Thus, providing a appropriate translation is available, it's possible to have the entire window manager's interface displayed in almost any given language.

However, due to the underlying gettext-based implementation that e17's internationalization support is built on, there are issues for module developers wishing to include internationalization as a feature of their 3rd party modules.

First a quick word about how the gettext-based internationalization support works.
1) Strings throughout the e17 code base that require translation are marked accordingly. Enlightenment uses a common method of wrapping strings to be translated in _(). For example:
e_dialog_title_set(exit_dialog, _("Are you sure you want to exit?"));
e_dialog_text_set(exit_dialog,
_("You requested to exit Enlightenment.<br>"
"<br>"
"Are you sure you want to exit?"
));
2) This _() technique isn't magic of course - it's actually a macro, which is defined in e17/apps/e/src/bin/e_intl.h as follows:
#include <libintl.h>

#define _(str) gettext(str)
#define d_(str, dom) dgettext(PACKAGE dom, str)
So when the C pre-processor runs over the code before compiliation, all those _("string") occurances are replaced with gettext("string") calls. gettext and other related functions (like dgettext, which we'll see more of later) are declared in libintl.h.

What does gettext do? It takes the input string, and uses it as a key to search in a message catalog for a translation. Which catalog is searched in is determined by the users locale / language environment settings. If it doesn't find a translation, then it just returns the key string as the result.

3) How are the message catalogs created? There are three steps:
a) When the autogen.sh script runs it executes the command xgettext to extract all the marked strings from the source code out in to a message catalog template.
b) Next, a translator copies the template, and creates a PO file, and does the translation exercise
c) When make is run to build e, msgfmt is used to compile the text based translation catalog into a binary format for use during run-time.

4) This isn't quite enough yet. In a basic program, the following needs to be done to trigger gettext operations.
setlocale (LC_ALL, "");
bindtextdomain (domain-name, path);
textdomain (domain-name);

Enlightenment actually does things a bit differently (see e_intl.c) but basically there has to be a setlocale call of some kind. The next two function calls are more interesting for module writers. bindtextdomain is used to specify the base directory for which message catalogs should be searched from, for a given domain (or namespace). For Enlightenment the domain would be "enlightenment", and for a module, we would just use whatever our module is called, i.e., "mymodule".
The path specified should be the path up to "locale". For example, Enlightenment would use "<prefix>/lib/locale"
The binary message catalogs are later to be installed to <path>/<locale>/LC_MESSAGES/domain-name.mo
For example, a Japanese (locale = ja) catalog for the "moon" module, installed to the user's home directory would be located under ~/.e/e/locale/ja/LC_MESSAGES/moon.mo
The final function, textdomain sets the domain-name as the domain to be used for all subsequent calls to the gettext function. Using this saves the programmer from having to specify the domain to be used for every single gettext call throughout the entire source code.

So how do modules fit in?

Issue 1: As 3rd party modules are developed, maintained and distributed independently of e17 itself, they can't be translated in the same message catalog as what enlightenment itself uses. Modules therefore will have to use their own message catalogs.
-> Modules must include a call to bindtextdomain to specify the path where the modules' message catalogs are stored
Issue 2: As 3rd party modules can't use enlightenment's message catalog, but the modules are dynamically loaded as part of the enlightenment, modules can't use textdomain and gettext. If they do, all the message translations in enlightenment that rely on the default domain being "enlightenment" will stop working. This would not be a popular module!
-> Modules must use dgettext, which is the same as gettext except that the domain is specified explicitly along with the string to translate.

Now for an example of module internationalization, using the moon module.
NOTE THAT THIS IS JUST "Proof of concept" QUALITY, NOT THE FINAL VERSION
$ cd ~/src/moon/trunk
$ mkdir po
$ cp ~/src/e17/apps/e/po/Makefile.am po
$ vi Makefile.am

--- Makefile.am ( 31)
+++ Makefile.am (篏キ)
@@ -1,4 +1,4 @@
-SUBDIRS = src data
+SUBDIRS = src data po

$ vi configure.ac

--- configure.ac ( 31)
+++ configure.ac (篏キ)
@@ -18,6 +18,15 @@
fi
AC_PROG_LIBTOOL

+ALL_LINGUAS="ja"
+AC_SUBST(ALL_LINGUAS)
+
+AM_GNU_GETTEXT([external])
+AM_GNU_GETTEXT_VERSION(0.12.1)
+if test "x$LIBINTL" = "x"; then
+ LIBINTL="$INTLLIBS"
+fi
+
# Checks for libraries.
AC_PATH_GENERIC(eet, 0.9.10, [
AC_SUBST(eet_libs)
@@ -110,5 +119,6 @@
data/Makefile
data/themes/Makefile
data/themes/images/Makefile
- src/Makefile])
+ src/Makefile
+ po/Makefile])
AC_OUTPUT

$ vi autogen.sh
--- autogen.sh ( 31)
+++ autogen.sh (篏キ)
@@ -11,6 +11,22 @@
echo "Running libtoolize..." ; (libtoolize --copy --automake || glibtoolize --automake) || exit 1
echo "Running automake..." ; automake --add-missing --copy --gnu || exit 1

+echo "Generating gettext moon.pot template";
+xgettext +--output moon.pot +--output-dir=po +--language=C +--add-location +--keyword=d_ +--indent +--sort-by-file +--copyright-holder="Your N. Here" +--foreign-user +`find . -name "*.[ch]" -print` || exit 1
+
if [ -z "$NOCONFIGURE" ]; then
./configure "$@"
fi

$ vi src/e_mod_main.c

--- src/e_mod_main.c ( 31)
+++ src/e_mod_main.c (篏キ)
@@ -43,9 +43,12 @@
{
Moon *moon;

+ bindtextdomain(PACKAGE, "/home//.e/e/modules/share/locale");
+ bind_textdomain_codeset(PACKAGE, "UTF-8");

moon = _moon_new(module);


@@ -89,8 +92,8 @@
/*
* FIXME - need to gettextise this properly
*/
- e_module_dialog_show("Moon Clock Module",
- "Display current phase of the moon ala e16 E-MoonClock");
+ e_module_dialog_show(d_("Moon Clock Module", ""),
+ d_("Display current phase of the moon ala e16 E-MoonClock", ""));
return 1;
}


$ cp ~/src/e17/apps/e/ABOUT-NLS .
$ ./autogen.sh
$ cp po/moon.pot po/ja.po
$ vi po/ja.po

--- po/moon.pot 2005-11-26 17:47:09.903525000 +0900
+++ po/ja.po 2005-11-26 17:54:37.469484632 +0900
@@ -11,16 +11,16 @@
"Last-Translator: FULL NAME <email address="">\n"
"Language-Team: LANGUAGE <ll org="">\n"
"MIME-Version: 1.0\n"
- "Content-Type: text/plain; charset=CHARSET\n"
+ "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

#: src/e_mod_main.c:95
msgid "Moon Clock Module"
-msgstr ""
+msgstr "月の相モジュール"

#: src/e_mod_main.c:96
msgid "Display current phase of the moon ala e16 E-MoonClock"
-msgstr ""
+msgstr "e16のE-MoonClockのように月の満ち欠け状態を表示します"


$ make
...
$ make install
$ enlightenment_remote -module-load moon
$ enlightenment_remote -module-enable moon


And now if we pull up the About menu for the module...

Labels:


11/14/2005

 

E17: やった!僕の翻訳は使われている!

Enlightenment 17 ウィンドウマネージャのために作ってきた和訳は少なくとももう一人に使われているようだ。リンク先で見えるスクリーンショットで日本語のメニューが見えているのですが、それは僕が訳した。ネイティブスピーカーじゃないので、改善できるところはいっぱいあると思うけど。今後E17がリリースに向かって行くとともに日本でも興味のある人が増えて行くといいな。

Labels:


 

IWC 2005: Solomons position further clarified

http://www.solomonstarnews.com/drupal-4.4.1/?q=node/view/5873

SOLOMON Islands will remain neutral and abstain from voting on the issue of the commercialization of whaling and it supports the sustainable harvesting of whales for the purpose of scientific research
Minister of Fisheries and Marine Resources, Mathias Taro explained the Government’s position following a question from the MP for East Malaita, Joses Sanga in Parliament on Wednesday.
Mr Sanga wanted to know the Government’s position on whale harvesting.
In his explanation, Mr Taro told Parliament that “any decision on this issue is the decision taken as a sovereign nation and that we should not be easily persuaded, or be influenced into taking a position that undermines our sovereignty.”
“Given the recent sensitivity surrounding this issue, and our desire not to upset two of our major development partners, it makes a lot more sense that we maintain a neutral position in future,” Mr Taro said.
At the same time Mr Taro said: “We need to back to the initial decision as to why we actually became a member of the International Whaling Commission, as it is quite clear that Solomon Islands, does not benefit directly for its membership.”
Following several supplementary questions by MPs, Prime Minister Sir Allan Kemakeza explained to Parliament that the Government had taken the neutral stand on the issue of commercialization of whaling because it wanted to see the results of the scientific research into the assumption that whales are helping to deplete fish stocks.
“Until the time when we see the results of the research, this Government will maintain the current policy,” Sir Allan said.
He also assured the people of Solomon Islands that the Government’s stand on the harvesting of whales will not affect the harvesting of dolphins for local consumption and porpoise teeth in certain parts of the country.

 

IWC 2005: Aussie media getting suspicious?

The Advertiser has an interesting article today.

A law professor in Sydney has suggested that "International Tribunal for the Law of the Sea had the power to issue an immediate injunction to stop the Japanese whaling research program".

Having read a bit about UNCLOS before, I really can't guess on what grounds the professor is putting his reputation on the line.

But what is telling here is this:
the Australian Government is unwilling to take the matter to the courts – fearing the cost and a backlash if the case was unsuccessful.

Environment Minister Senator Ian Campbell will not give reasons why the Government believes a legal challenge would fail.

"If the Australian Government – or any other international governments – thought that taking legal action would help to save whales, we would have done it by now," a spokeswoman said.


Senior Government sources said a failed challenge would enshrine "scientific" whaling in international law – ending the bid to stop it.


I've noted this before. The politicians from the big three, Australia, New Zealand and Britain are big on political rhetoric but incredibly soft on action. They know too well that Japan's programmes are absolutely legal, and that any attempts internationally to prove otherwise would result in a massive PR disaster.

The result - they do nothing but splash nonsense all through the media, and a barely interested public listens happily, not bothering to educate themselves about the details.

Unfortunately though, while the media has the brains to ask "why aren't you taking this to an international court?", they are failing to follow up on the "because we'd lose" response. It's clear that Japan's position is totally legal. In light of this, it's a moral imperitive that Australia reconsiders its own stance. Failing to do this indicates a lack of respect for international law. Laws are meant to be honoured even when they don't work in one's favour.

By the way, the cost that the government "fears" is only 500,000. This isn't much!

Labels: ,


11/12/2005

 

Off to Yamagata

Up early in the morning to head to the mountains for this year's Yamagata Independant Image Festival (http://www.yii.jp).
Last year was quite a blast:
http://david-in-tokyo.blogspot.com/2004_12_01_david-in-tokyo_archive.html
And no doubt this year is gonna be a cracker too :-)

Having lots of fun lately actually - a few weeks back I sat down on the train next to a student who was talking to his mate about travelling to Fiji via New Zealand, and he also happens to live at the same station as me. We met up again last week, and had Yakitori (grilled chicken meat etc) in a cosy little place down the road from where I live, and hooked up with some local girls. Went out with them two nights later, and then again last night (plus some billiards for the first time in a while). All of this ain't good for the liver, but it IS exactly why I wanted to move over to this side of town - lots more youth and action!

Back on Monday.

11/09/2005

 

IWC 2005: Another thing Chris doesn't seem to get

Here's Chris Carter again:
“Most of the global community accepts that killing whales is not necessary to study whale populations. Yet Japan continues to do so.
Leaving aside his baseless statement about what "most of the global community" thinks, Carter needs to grasp the reality of Japan's programmes.

The Japanese have been at this for 18 years now. This isn't just a flash in the pan. Japan's research programmes are part of a long term strategy to enable Japan to kill whales for all eternity. Killing whales is what whaling is all about.
The scientific studies themselves are not the end, they are one of the means. Japan believes that without scientific research, good management decisions regarding whaling can not be made.

Management here means - not what Chris Carter would have us do - that is to do absolutely nothing - but to adjust whale catch quotas in a way that can achieve favourable outcomes for both the people who wish to utilise those resources, but also the environment as a whole.

The anti-whaling nations make much about their whale watching industries and talk as if whaling activities will drive them out of business. They talk about "reasserting the rights" of their coastal communities "to benefit from the non-lethal use of whales". It should be noted that the IWC's function is the regulation of whaling - to ensure stocks are conserved and whaling industry is made possible - but this goal is not at all incompatible with the goals of those who wish to benefit from non-lethal uses of whales.

Clearly the reference is to whale watching activites. It doesn't take a whale scientist to figure out that sustainable whaling activities implies sustainable numbers of whales - and thus the needs of both groups can be met. This is not just an ideal, but a reality in whaling regions such as Iceland.

All that is required for this to be acheived is for the anti-whaling bloc in particular to genuinely accept that the whaling peoples of the world have a right to exist, and to work constructively to achieve the goal for the common good.

 

IWC 2005: More Chris Carter propaganda

Yet more propaganda from the New Zealand government and Greenpeace, and coincidently on the same day (obviously to create a larger media fuss)

"New Zealand is deeply alarmed at news Japan's whaling fleet has sailed to commence its newly expanded scientific whaling programme, Conservation Minister Chris Carter said today."

Chris Carter's feigned alarm is a joke considering he's known about this for months.

What's far far worse is his total lack of knowledge with regard to conservation issues. He's supposed to be the Minister for Conservation.

He is uninformed:

He compares hunting "whales" with hunting tigers, gorillas, or kiwi. It's time he showed that he understands his portfolio:
a) there is not a "whales" species, but 10's of them, of which very few are actually endangered (and not targetted by humans where this is the case, such as for the Blue whale)
b) the species targetted by Japan are in no way going to be at risk from the meagre numbers that the Japanese plan to take. Australian scientists have admitted as much, in addition to recognising the "booming" stock growth of 10%.

He is deceptive:

"New Zealand is very worried about the impact of further hunting on their numbers,"

he says of the Humpback species. Well sorry Chris, but "further" implies they are already being hunted, or that they are not replenishing, and clearly neither is the case.

He shouldn't be representing New Zealand internationally:

His lack of understanding of New Zealand's obligations as a responsible world citizen under the ICRW is shocking. He laments that the Japanese are hunting whales in the Southern Ocean - International waters. If Carter has a problem with this (as he does with other aspects of the ICRW), why doesn't he put his money where his mouth is and propose New Zealand's withdrawal from the convention instead of whinging about it all the time? He needs to wake up and recognise the ICRW with the importance that it deserves. International documents should not be footballed around like this.

He's plain dopey too:

Whoops! He even let this slip out:
"Scientific whaling is only legal because ... "

Exactly. It IS legal. So one wonders why Carter was mouthing off about taking Japan to the World Court earlier this year. Perhaps, just to get a headline?

He is just completely off his rocker:
"... because the provisions in the International Convention on the Regulation of Whaling (IWC) are out of step with modern conservation approaches. "

Since when have science based management methods of the ICRW such as the RMP been out of step with modern conservation approaches? Perhaps poor Chris is just confusing his protectionist position for a conservation position. There is a huge difference.


As I noted, Greenpeace also timed their propaganda with that of Mr Carter:
http://www.scoop.co.nz/stories/PO0511/S00071.htm
Too much nonsense here for me to bother to deal with - and it's bedtime :-)

11/06/2005

 

E17: Creation of a Moonclock module - Part 1

This article has been posted HERE at edevelop.org, and will be maintained at that location going forward. This article remains here for historical purposes (^_^)

What this is:

  • These are my notes about the creation of a module for e17, gathered together in an attempt to provide a semi-tutorial. This is not a step by step instruction guide on how to make a module - just points that I found pertinent while doing so myself. I do have a background in software (BSc Computer Science) and experience with C (in a kickass 3rd year networking paper), and expect anyone reading this and hoping to find this informative would have some C knowledge as well. In this article our focus is on the C source code for a module - we won't be going into the details of makefiles or edc's for edjes this time.
  • Also note that this is not the article of a seasoned e17-pro, just someone doing this in his free time for a bit of fun. Don't take anything written here as 100% truth.
  • Everything in this article with regard to CVS is up-to-date at the time of writing (to the best of my knowledge), but as development progresses this article will possibly fall out of date.
  • Finally, anything that happens to your computer as a result of your reading and using this information is your responsibility, not mine! If you start fiddling with your module source code it's quite likely that you'll crash the whole window manager and any open apps if you do something silly - I've done this numerous times myself :-)
  • That's the disclaimer out of the way...

    Motivation:

    After my initial pathetic contribution to E17, an actually useful patch more recently, as well as Japanese interface translation, I've now read enough cvs commits and emails to have a bit of a clue about how enlightenment 17 works. Thus I decided it was high time I hacked up a module of some sort to learn some more, and maybe even contribute something somebody else might like to use.

    But what should I make?

    The first time I used Enlightenment would have been around 2 and half years ago when I was trying out a range of "light weight" linux distros on a crappy old half (now almost completely) broken Pentium 166 with maybe 32Mb of RAM. My favourite distro at the time (visually, at least) was Peanut Linux (now aLinux) and that was due entirely to it having Enlightment 16 as it's default window manager. One of e16's features are small little mini applications known as "epplets", and my favourite was and still is E-MoonClock. All it does it sit on your desktop and display the current phase of the moon. Very simple, and pretty useless really, but I like it and happily grant it some of my RAM and CPU cycles.



    Alas, e17 doesn't have it's own moonclock. Yet with the source to e16's E-MoonClock available, plus a ready made set of phased moon images, there would be few modules simpler to slap together than this one. So, let's go.

    The e17 moon clock module source:
    Whether you plan to read this article or not, the source for the e17 moon clock module that I'm writing about in this article can be obtained from here:
    http://www.geocities.jp/david_at_tokyo/e17/moon/

    1) Prerequisite: The Enlightenment 17 Module API

    Enlightenment 17 has a pre-defined interface consisting of five C functions which modules are required to provide the definition for. This interface is very simple:

    EAPI void *e_modapi_init (E_Module *m);
    EAPI int e_modapi_shutdown (E_Module *m);
    EAPI int e_modapi_save (E_Module *m);
    EAPI int e_modapi_info (E_Module *m);
    EAPI int e_modapi_about (E_Module *m);


    An introduction to implementing the bare minimum for a module is available here at essiene's "Exploring E17 Modules - Part 1". Since the basic module API has good coverage at that tutorial already, I'm not going to write any more about it. If you haven't read that article already, you probably should before reading this one, unless you are happy just to plagarise these function definitions from an existing module.

    2) The User Interface - Edje (display only)

    I'd been reading about the concept of Edje based applications prior to commencing the e17 module fun, and found the concepts very appealing, so much so that I wanted to give it a blast for myself. The Edje library makes it possible to seperate your application's user interface from the less visible application code, rather than having them tightly integrated together. With Edje you have the freedom to ship details of the way your interface looks and behaves into an independant source file, which is made up of details of the interface layout, images, and mini programs to control what the interface does. To be honest I got sick of building interfaces when using Delphi previously, prefering to work on non-user visible internal source code, but so far the Edje learning experience has been enjoyable. Anyway, my goal was to try the Edje library out for myself, and see how the separation of UI details from the real source went.

    3) How to make a moonclock tick

    But that left the problem of figuring out what the phase of the moon is at a given instant... any takers? OK! I don't have a clue about how to calculate the current phase of the moon, and I'm guessing the majority of people who will read this aren't astronomers either. Thankfully, on brief examination of the E-MoonClock source, I found that in fact it's author had in turn borrowed a chunk of source code from a prior moonclock author, who was rightly credited with doing all the real work. Likewise, I am equally indebted, but let's continue.

    To create the moonclock all one needs to do is set up a couple of time & date arguments, call a library function, then use the resulting floating point value (between 0.0 and 1.0) to decide which moon image to display (and repeat the process periodically to keep the moon image up to date). The original E-MoonClock does all of this in one function (very simple).

    Images however are a feature of the user interface with nothing to do with the application code, and in the spirit of Edje, we'll be doing things a bit differently. E-MoonClock has 60 smallish moon images (and the epplet source code is specific to having 60 images), but if someone else out there had a larger set of higher quality images available that they wish to use, they'd have to recompile the entire source to do so. That's not cool - ideally we want to maintain the separation of moon phase calculation and other stuff from the UI details. So the ultimate goal is to slap together the C code for the module, define the interface details in an Edje source file (EDC) and somehow have the application code inform the Edje of the current phase of the moon as represented by a floating point value. Other than this floating point value, there's nothing else the Edje needs to determine how to represent the moon phase information on screen.

    4) Plagarising the skeleton

    So into the C code we go. But where to start? There's a saying about lazy programmers (and this whole module is a fine example), and in that tradition I went looking for a module that was similar enough to my own. Basically I just want to create a square moon clock like that in e16 - in some respects very similar to the e17's default clock module. Like the clock, the moon module just needs to sit there on the screen, maintaining it's aspect and so on, with the addition of sending moon phase information to the moon modules' Edje (this is the main difference to clock, and we'll cover how to make our module do this later). So, I followed the clock module source closely, copying stuff that I needed (and in some cases copying stuff just to figure out what it actually does). If you haven't read the e17 clock source before, now's a good time to open it up and have a squizz.

    The definitions of the moon module's five module API functions were basically copy and pastes of the clock module code with a few changes to refer to moons instead of clocks.

    The init function is the only function that does much in my case: the actual creation of a "Moon" data structure, which I eventually separated out into a helper function, "_moon_new" ala the clock module.

    5) The Moon data structure, _moon_new and _moon_free

    The Moon data structure in src/e_mod_main.h only contains three things:

    typedef struct _Moon Moon;
    struct _Moon
    {
    Evas_List *faces;
    E_Menu *config_menu;
    Ecore_Timer *moon_check_timer;
    };

    a) A list of moon "faces".
    The "Moon_Face" data structure holds information about which canvas it's to be included on etc. The Moon data structure has a list of these, as Enlightenment doesn't assume that you have only one screen for your computer (I only have one myself, so haven't bothered myself with the details, and could be only 50% on the mark about this - hopefully someone will confirm or correct me)

    b) A menu data structure.
    All modules have an entry in the "Modules" menu, so why not have one for the Moon module as well? We'll have a familiar use for this later anyway: configuration - but not in this article. At the time of writing the configuration menu in the e_modapi_init function is also disabled since we aren't using it yet.

    c) An Ecore_Timer.
    We need to periodically check the current phase of the moon so that we can keep our UI Edje up to date with the latest information. Rather than get dirty with SIGALRM's, the Ecore library already provides a simple and easy to use timer mechanism for us to take advantage of. The Ecore_Timer allows our module to receive a callback from the underlying Enlightenment infrastructure after a certain amount of time has expired. Callback's (often abbreviated as "cb"s) are something that pop up all over the place in Enlightenment - these are just event listeners. e17 overall follows an event-driven model. The EFL Cookbook has an example of one of how to use Ecore_Timers if you need some more detail, but in this case we are going to do this:
    moon->moon_check_timer = ecore_timer_add(60.0, _moon_cb_check, moon);
    This sets up our Ecore_Timer to call us (the moon) back via the _moon_cb_check function, every 60.0 seconds. I'll talk more about the _moon_cb_check function later, but for now I'll just note that the function must return a value of 1 in order for the timer to be renewed after each call to the callback function (or so I hear).

    The _moon_new function sets up these three items, and since this is C, we also write an accompanying shutdown function (_moon_free) to make sure we free'd all the memory we allocated in _moon_new.

    If you compare these moon functions with those in the clock, you'll notice the moon functions are simpler - first off I just want to get this thing working, so there is no code to save configuration information yet, and the Ecore_Timer time value is hardcoded to go off once every minute. Later on (not in this article though), we'll make this configurable, but for now once a minute should be acceptable.

    6) _moon_face_new and _moon_face_free

    The _moon_face_new function is more interesting than what we've seen already, with a range of EFL and Enlightenment functions being invoked. This time we're setting up a Moon_Face data structure that is defined something like this:

    typedef struct _Moon_Face Moon_Face;
    struct _Moon_Face
    {
    E_Container *con;
    Evas_Object *moon_object;
    E_Gadman_Client *gmc;
    };

    The first thing we do is allocate memory for the moon_face structure, and then assign the structure's Container value with the container that the moon_face is going to be added to. At this stage we don't actually need to record this container in the object, but (I think) we'll find it useful later when we add some configuration save / load code.

    Next up it's time to setup our moon's Edje object! This involves carving out a chunk of space on the background canvas for the moon module to display it's interface in. It's worth noting here that with the Enlightenment Foundation Libraries and evas in particular, the model used is of a "canvas" containing objects, which can then be manipulated (moved, resized etc). This is what we have with visual modules in E17 - they are basically objects etched into the desktop background. This is about as far as my rudimentary knowledge of evas goes, but as we'll soon see it's enough to get our module working.

    I presume there's a good reason for it, but we start this activity by first calling
    evas_event_freeze, passing the background canvas of the Container that this face will be added to as the required argument. At the end of the function, once we've finished setting up the Moon's interface, we'll call the corresponding function evas_event_thaw again specifying the same background canvas.

    evas_event_freeze(con->bg_evas);

    // make changes to background canvas (i.e., add new object to represent moon etc)

    evas_event_thaw(con->bg_evas);

    After calling evas_event_freeze and until evas_event_thaw is called, the background canvas specified puts all event processing on ice. This is the time to make changes to the canvas, that is, adding edje object's to it, positioning them and so forth (see below). Presumably bad unpredictable stuff could happen if the evas is processing events (maybe objects moving about etc) while we are making our own changes to the canvas at the same time - the mind boggles! I'm not sure about exactly what scenarios this functionality prevents - hopefully I'll get some more detail on this later, but for now, as the clock and various modules do this, we will too.

    Now that the events from the background canvas are on hold, we add a new edje object (our moon's "face" on the desktop) to the background:

    o = edje_object_add(con->bg_evas);
    face->moon_object = o;

    We then tell the new Evas object which user interface file to use. For the moon module we'll be using a file called "moon.edj", but we'll not be getting to that until we've finished writing the C code. In the meantime, let's just assume we have a dummy "moon.edc" file, which will be compiled into "moon.edj". Later on we need to write "moon.edc" properly so that it'll display moon images, but for starters we'll just use a plain black rectangle:

    collections {
    group {
    name: "moon/main";
    parts {
    part {
    name: "dummy";
    type: RECT;
    description {
    state: "default" 0.0;
    color: 0 0 0 255;
    rel1 {
    relative: 0.0 0.0;
    }
    rel2 {
    relative: 1.0 1.0;
    }
    }
    }
    }
    }
    }
    }

    We use edje_object_file_set to specify that the object we added to the background canvas should use the "moon.edj" file. If you look at other modules, you'll see them using a semi hardcoded path name to the edje file here. If you mimic such modules, you'll probably come up with something like:

    edje_object_file_set(face->moon_object, PACKAGE_LIB_DIR "/e_modules/moon/moon.edj", "moon/main");
    This is pretty bad actually (as I discovered myself), because we don't know that the module is going to be installed under "e_modules". e17 currently supports modules that have been installed into user home directories at ~/.e/e/modules/ as well. If the user chooses to install there instead of under the e_modules tree, when the user enables the module and it tries to load it's edje, it will not be able to find it, and will choke up errors all over your standard output. So, we really want to find our moon.edj object in a more dynamic fashion. The good news is that (as usual with e17 and the EFL) the hard work has already been done - there's a function in e_module.h that does exactly what we need:
    EAPI const char *e_module_dir_get(E_Module *m);
    With this function in our arsenal, we just need to have the E_Module available to get the path to where the module will be installed. As per esseine's tutorial you will recall that this infomation is passed to us when the e_modapi_init function is called, so I've just passed the E_Module to the _moon_face_new function as an argument:
    static Moon_Face *
    _moon_face_new(E_Container *con, E_Module *module)
    {
    char edje_path[PATH_MAX];
    ...
    snprintf(edje_path, sizeof(edje_path),
    "%s/moon.edj", e_module_dir_get(module));
    edje_object_file_set(face->moon_object, edje_path, "moon/main");
    ...
    That's better! Now we're only hardcoding the "moon.edj" name and the "moon/main" values, but for now we have no way of changing these, even if we wanted to, so it's sufficient for now (^_^).

    Next and importantly - we need to call evas_object_show with the new edje object as the argument. This is the function call that will actually make the edje visible on the screen.
    evas_object_show(face->moon_object);
    Subsequent to this I have some calls which I basically copied from the clock module:
    evas_object_resize(face->moon_object, 96, 96);
    edje_object_calc_force(face->moon_object);
    edje_object_part_geometry_get(face->moon_object, "moon", &x, &amp;amp;amp;amp;amp;amp;y, &w, &h);
    // blah blah

    The first of these, evas_object_resize, obviously resizes the moon_object to be 96 wide by 96 high. Using this function ensures that our module starts off with a reasonable size.
    The next call, edje_object_calc_force, somewhat
    less obviously forces the edje to recalculate it's layout (although at least with this module I've not seen the interface display itself incorrectly after resizing - I may be missing the point with this...)
    Thirdly we are grabbing the geometry of our edje object's "moon" part - but we haven't even discussed parts or edjes yet, so this is best skipped for now (and it's not actually required anyway).

    Now, we could stop here, but if we did so, our Moon module (displaying it's dummy black rectangle interface) would be stuck at a fixed location on our dekstop background. The user wouldn't be able to move or resize the moon module to their personal liking, as they can for other modules like the clock:

    That's not cool either. This is where we need to get our module set up as an client of the e_gadget manager. The e_gadget manager component of the e17 window manager will be familiar to anyone who's bothered to re-arrange the layout of modules on their desktop. By setting our module up as a gadget manager client we'll get all the nice animated module resizing / relocating capabilities for free. The e_gadman_client function calls are actually pretty self explanatory, and what you do here will depend on the characteristics of your particular module, so I'm not going to go into any great details on that. Suffice it to say we set various properties of our client, which will affect how the interface can be resized and moved. But at a minimum we need to create the E_Gadman_Client, create a "change" event handler callback that defines how our client will respond to move / resize actions from the user, and finally tell it to load.

    face->gmc = e_gadman_client_new(con->gadman);
    ...
    e_gadman_client_change_func_set(face->gmc, _moon_face_cb_gmc_change, face);
    e_gadman_client_load(face->gmc);

    In the case of the moon module, the callback function (_moon_face_cb_gmc_change) is basically identical to that of the clock module. This function gets called in response to the user moving or resizing the module while the gadget edit mode is on. After setting up our gadman client, now look what we can do:



    Wheeee! Our module now has all the shiny whizbangs available for resizing, and it's also relocatable now. Even our dummy edje looks pretty good with it registered with the gadget manager (^_^). This concludes the set up of a Moon_Face.

    Finally, after all this excitement in the _moon_face_new function, we teardown everything we've done / deallocate memory in the _moon_face_free function.

    7) And now back to that timer callback...

    So now we have plonked a module on the desktop. In fact, at this point you can't see it if you load and enable it as the user interface still doesn't exist yet. But, if you turn on the gadget edit mode, you'll see a empty border on your screen - this will be the moon's space.

    But before getting ahead of ourselves, we need to fill out the details of the _moon_cb_check callback for the Moon object that we defined back up in the _moon_new function. The Ecore_Timer is going to go off every 60 seconds, and when that happens we need the function we defined to calculate the current moon phase, and then somehow inform our yet to be created user interface what the value is.

    The callback is simple though because, as I mentioned earlier, the work has already been done for us previously in e16's E-MoonClock epplet and prior moon clock implementations. Here I created a new helper function, _moon_phase_calc, to return the moon phase. This helper function mimics the e16 epplet code, just cutting out some stuff that we don't need, and reformatting to my taste.
    static double
    _moon_phase_calc()
    {
    ...
    ... (blah blah blah, read the source if you are interested in astronomy!)
    ...
    return c.MoonPhase;
    }

    Now that we have the value representing the moon phase, we have to get this information to the edje of our moon_face (or faces, if you have a flasher setup than me).

    Hmmmmmmmm! This is about the first original thing we've had to do in this module - pretty much everything else we have done so far is plagarise from clock and other modules. So how do we get our moon phase value to our edje? Rest assured, the Rasterman has this base covered too.

    8) Application -> Edje communications

    So, we need our application code to be able to pass a message to our Edje interface, containing the float information representing the current phase of the moon.

    After some poking around here and there, I discovered that Edje has a message queue interface, allowing applications to send data of various types to their interfaces. This is of course exactly what is required for the moon module. The API call of particular interest here is this one (from Edje.h - currently undocumented other than in the source, although I'm going see what I can do about that):
       EAPI void         edje_object_message_send           (Evas_Object *obj, Edje_Message_Type type, int id, void *msg);
    To use this, first you need to determine what you want to send to your Edje. The various types currently available are declared in Edje.h:
    typedef struct _Edje_Message_String           Edje_Message_String;
    typedef struct _Edje_Message_Int Edje_Message_Int;
    typedef struct _Edje_Message_Float Edje_Message_Float;
    typedef struct _Edje_Message_String_Set Edje_Message_String_Set;
    typedef struct _Edje_Message_Int_Set Edje_Message_Int_Set;
    typedef struct _Edje_Message_Float_Set Edje_Message_Float_Set;
    typedef struct _Edje_Message_String_Int Edje_Message_String_Int;
    typedef struct _Edje_Message_String_Float Edje_Message_String_Float;
    typedef struct _Edje_Message_String_Int_Set Edje_Message_String_Int_Set;
    typedef struct _Edje_Message_String_Float_Set Edje_Message_String_Float_Set;
    In this case we'll assume we're happy to just send a single floating point value to our Edje, so we'll use Edje_Message_Float. The struct for one of these is ultra simple:
    struct _Edje_Message_Float
    {
    double val;
    };
    This is self-explanatory - Edje_Message_Float has just one element, a value, which we're going to assign to hold our moon phase information:

    Edje_Message_Float msg;
    ...
    msg.val = _moon_phase_calc();
    ...
    edje_object_message_send(face->moon_object, EDJE_MESSAGE_FLOAT, 1, &msg)
    But there's two more args defined there - EDJE_MESSAGE_FLOAT is also defined in a enum in Edje.h, but the '1' argument is less obvious. Later on when we look at how the Edje receives these messages, the use of this argument will become clear - but in brief, the problem is that the messaging interface doesn't cater for arbitrary function names to be called - there is only one function name. Additionally, it's only able to handle the predefined data types shown above. Now if you imagine that you had a module where you wanted to send two different messages containing two completely unrelated pieces of information - yet perhaps those different pieces of information were both represented using the same type of value (say float), the Edje needs a way to distinguish one float message from the next. This numeric id provides a means of making such a distinguishment between different messages that use the same Edje Message Type. In our example, we only have one float, so this id value doesn't actually matter for us, and thus we'll just choose '1' as our value - we could choose anything else though.

    With that, we're done with everything of interest in src/e_mod_main.h and src/e_mod_main.c.

    9) Next time

    In the second part of this article (under construction!) we'll take a look at the EDC for the moon, how it receives this floating point value from the application. and bring everything together by displaying appropriate moon images on screen. We'll also take a look at the embedded embyro scripting functionality as well.

    Labels:


    11/01/2005

     

    E17: Creation of a Moonclock module - Part 2

    The second part of my moon module creation effort is now online at edevelop.org.

    Labels:


    Archives

    June 2004   July 2004   August 2004   September 2004   October 2004   November 2004   December 2004   January 2005   March 2005   April 2005   May 2005   June 2005   July 2005   August 2005   September 2005   October 2005   November 2005   December 2005   January 2006   February 2006   March 2006   April 2006   May 2006   June 2006   July 2006   August 2006   September 2006   October 2006   November 2006   December 2006   January 2007   February 2007   March 2007   April 2007   May 2007   June 2007   July 2007   August 2007   September 2007   October 2007   November 2007   December 2007   January 2008   February 2008   April 2008   May 2008   June 2008   July 2008   August 2008   September 2008   October 2008   November 2008   December 2008   January 2009   February 2009   March 2009   April 2009   May 2009   June 2009   July 2009   August 2009   September 2009   October 2009   November 2009   January 2010   February 2010   April 2010   May 2010   June 2010   July 2010   August 2010   September 2010   February 2011   March 2011   May 2013   June 2013  

    This page is powered by Blogger. Isn't yours?