Note: if you did not end up here from my N900 main page, then you might be interested to know that I have also written an updated version of this page for Emacs 23.1.93.
This page describes the port of Emacs 22.2 for Nokia N900. This is based on a previous work for the Nokia N810.
If you simply want to grab all the material to build emacs 22.2 for the N900, here are the few simple steps required to do that:
arno@small:~$ wget -q http://ftp.gnu.org/pub/gnu/emacs/emacs-22.2.tar.gz arno@small:~$ wget -q http://ftp.gnu.org/pub/gnu/emacs/emacs-22.2.tar.gz.sig arno@small:~$ gpg --verify emacs-22.2.tar.gz.sig gpg: Signature made Wed 26 Mar 2008 03:12:35 PM CET using DSA key ID BC40251C gpg: Good signature from "Chong Yidong <cyd@stupidchicken.com>" arno@small:~$ tar xzf emacs-22.2.tar.gz arno@small:~$ cd emacs-22.2 arno@small:~/emacs-22.2$ hg clone http://hg.natisbad.org/N900/emacs-22.2-debian-folder/ debian requesting all changes adding changesets adding manifests adding file changes added 1 changesets with 17 changes to 17 files updating to branch default 17 files updated, 0 files merged, 0 files removed, 0 files unresolved
Note that you need to be in your scratchbox environment if you want to go further and compile the package. You also need to satisfy all the build dependencies of the package.
The rest of this page provides additional information on the content of the debian folder to build emacs 22.2 for the N900. There are already various pages (here and here) on Maemo wiki providing information on how applications can be packaged and built for the N900. For that reason, I only document here things worth mentioning on the files of the debian folder:
arno@small:~/emacs-22.2/$ ls -l debian total 52 -rw-r--r-- 1 arno arno 132 2009-11-28 17:29 changelog -rw-r--r-- 1 arno arno 2 2009-11-28 17:29 compat -rw-r--r-- 1 arno arno 5142 2009-12-12 18:51 control -rw-r--r-- 1 arno arno 1391 2009-11-28 17:29 copyright drwxr-xr-x 3 arno arno 4096 2009-12-12 17:33 data drwxr-xr-x 2 arno arno 4096 2009-11-28 17:29 patches -rwxr-xr-x 1 arno arno 62 2009-12-12 17:49 postinst -rwxr-xr-x 1 arno arno 389 2009-12-12 18:10 preinst -rwxr-xr-x 1 arno arno 3319 2009-12-12 18:05 rules
Note that if you install the package, you might be interested by the additional notes on the purpose of the patch found in patches folder to allow passing emacs in fullscreen mode and the specific page on the keyboard remapping.
control file
The content of the control file is the following:
arno@small:~/emacs-22.2/debian$ cat control Source: emacs Section: user/utilities Priority: optional Maintainer: Arnaud Ebalard <arno@natisbad.org> Build-Depends: debhelper (>= 5), autotools-dev, quilt Standards-Version: 3.7.2 Package: emacs Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: The GNU Emacs editor GNU Emacs is the extensible self-documenting text editor. This package is intended for use on Nokia N900. XB-Maemo-Icon-26: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsSAAAL ... bf4Xw9L60MbC16UAAAAASUVORK5CYII=
There is almost nothing specific in it if you are already familiar with usual Debian control file, except the XB-Maemo-Icon-26 entry. It contains the application icon file encoded in base64. The Application Manager displays this icon next to the package name (when installing or removing the application). The icon file should be in a format understood by the N900 (PNG is fine) and should have a size of 48x48.
Encoding the PNG icon file in base64 and concatenating it to the control file after the XB-Maemo-Icon-26: entry cant be done in the following way:
arno@small:~/emacs22.2/debian$ openssl base64 -in emacs-48x48.png | sed -e 's/^/ /' >> control
The sed part is for adding a leading space to each line of the base64-encoded icon in the control file.
data folder
arno@small:~/emacs-22.2/debian/$ ls -l data -rw-r--r-- 1 arno arno 268 2009-12-12 17:33 emacs.desktop drwxr-xr-x 1 arno arno 4096 2009-11-28 17:29 icons
emacs.desktop file
arno@small:~/emacs-22.2/$ cat data/emacs.desktop [Desktop Entry] Encoding=UTF-8 Version=1.0 Type=Application Name=Emacs 22.2 Comment=The GNU Emacs editor Exec=/usr/bin/emacs Icon=emacs X-Window-Icon=emacs X-Window-Icon-Dimmed=emacs X-HildonDesk-ShowInToolBar=true X-Osso-Type=application/x-executable Terminal=false
icons folder
arno@small:~/emacs-22.2/debian$ find data/icons/ data/icons/ data/icons/hicolor data/icons/hicolor/40x40 data/icons/hicolor/40x40/apps data/icons/hicolor/40x40/apps/emacs.png data/icons/hicolor/48x48 data/icons/hicolor/48x48/apps data/icons/hicolor/48x48/apps/emacs.png data/icons/hicolor/64x64 data/icons/hicolor/64x64/apps data/icons/hicolor/64x64/apps/emacs.png data/icons/hicolor/scalable data/icons/hicolor/scalable/hildon data/icons/hicolor/scalable/hildon/emacs.png data/icons/hicolor/128x128 data/icons/hicolor/128x128/apps data/icons/hicolor/128x128/apps/emacs.png data/icons/hicolor/26x26 data/icons/hicolor/26x26/apps data/icons/hicolor/26x26/apps/emacs.png data/icons/scalable data/icons/scalable/apps data/icons/scalable/apps/emacs.png
preinst file
The N900 root filesystem is very limited in size (200Mo) and emacs has a lot of files to be installed under /usr/share/emacs (more precisely /usr/share/emacs/emacs-22.2).
For such packages, /home/opt/ can be used to store such files. In our specific case, I wrote a simple preinst script which creates /home/opt/emacs/ folder and then a link to it from /usr/share/emacs/.
arno@small:~/emacs/debian$ cat preinst #! /bin/sh # Emacs is fat. Because there is limited space available # directly in /usr/share/ for "emacs" directory, we just # create the folder in /home/opt/ on the 1.8GB partition # and then use a symbolic link from /usr/share/emacs if [ ! -d /usr/share/emacs ]; then if [ ! -d /home/opt/emacs ]; then mkdir -p /home/opt/emacs fi ln -s /home/opt/emacs /usr/share/emacs fi
postinst file
includes icons and an emacs.desktop file which are installed by the rule fileThe package deploys icons in /usr/share/icons/hicolor folder (those are copied from data folder by rules file). In order for the system to learn about those file, the gtk-update-icon-cache needs to be called after the package has been installed. This is the purpose of the postinst script:
arno@small:~/emacs/debian$ cat postinst #! /bin/sh gtk-update-icon-cache -f /usr/share/icons/hicolor
rules files
The rules files for building the package is pretty common. It is based on the one used in the upstream Debian package, with some changes:
- to configure call (--with-gtk)
- to remove various man files and docs to reduce the size of the resulting package
- to remove .el.gz files
- to copy icons and emacs.desktop file
- to support the use of quilt for applying a custom patch allowing switching to fullscreen mode on the N900.
arno@small:~/emacs/debian$ cat rules #!/usr/bin/make -f include /usr/share/quilt/quilt.make # These are used for cross-compiling and for saving the configure script # from having to guess our platform (since we know it already) DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) CFLAGS = -Wall -g ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) CFLAGS += -O0 else CFLAGS += -O2 endif config.status: configure dh_testdir # Add here commands to configure the package. ./configure --host=$(DEB_HOST_GNU_TYPE) \ --build=$(DEB_BUILD_GNU_TYPE) \ --prefix=/usr --mandir=\$${prefix}/share/man \ --infodir=\$${prefix}/share/info \ --with-gtk --with-toolkit-scroll-bars \ CFLAGS="$(CFLAGS)" LDFLAGS="-Wl,-z,defs" build: build-stamp build-stamp: $(QUILT_STAMPFN) config.status dh_testdir $(MAKE) touch $@ clean: unpatch dh_testdir dh_testroot rm -f build-stamp -$(MAKE) distclean ifneq "$(wildcard /usr/share/misc/config.sub)" "" cp -f /usr/share/misc/config.sub config.sub endif ifneq "$(wildcard /usr/share/misc/config.guess)" "" cp -f /usr/share/misc/config.guess config.guess endif dh_clean install: build dh_testdir dh_testroot dh_clean -k dh_installdirs $(MAKE) prefix=$(CURDIR)/debian/emacs/usr install # To save some Mo, we remove .el.gz files. We do it after they # have been installed to avoid patching various emacs Makefile # files. find $(CURDIR)/debian/emacs/usr -name '*.el.gz' -exec rm '{}' \; mkdir -p $(CURDIR)/debian/emacs/usr/share/applications/hildon/ cp $(CURDIR)/debian/data/emacs.desktop \ $(CURDIR)/debian/emacs/usr/share/applications/hildon/emacs.desktop # Install icons cp -R $(CURDIR)/debian/data/icons \ $(CURDIR)/debian/emacs/usr/share/ binary-indep: build install # We have nothing to do by default. # Build architecture-dependent files here. binary-arch: build install dh_testdir dh_testroot dh_link dh_strip dh_compress dh_fixperms dh_installdeb dh_shlibdeps dh_gencontrol dh_md5sums dh_builddeb binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install
patches folder
As discussed above, in order to support switching to fullscreen mode, I have written a small patch which is stored in patches folder under the debian folder and applied automatically during the build of the package.
arno@small:~/emacs-22.2/debian/$ cat patches/handle_fullscreen_using_gtk_window_fullscreen.patch Index: emacs-22.2/src/xterm.c =================================================================== --- emacs-22.2.orig/src/xterm.c 2008-06-01 20:10:26.000000000 +0200 +++ emacs-22.2/src/xterm.c 2008-06-01 20:11:39.000000000 +0200 @@ -8426,87 +8426,34 @@ return rc; } -/* Do fullscreen as specified in extended window manager hints */ +/* Some custom hack for N900. With the following in the .emacs + we get fullscreen done +(defun fullscreen () + (interactive) + (set-frame-parameter nil 'fullscreen + (if (frame-parameter nil 'fullscreen) nil 'fullboth))) +(global-set-key [f6] 'fullscreen) + + */ static int do_ewmh_fullscreen (f) struct frame *f; { - int have_net_atom = wm_supports (f, "_NET_WM_STATE"); - - /* Some window managers don't say they support _NET_WM_STATE, but they do say - they support _NET_WM_STATE_FULLSCREEN. Try that also. */ - if (!have_net_atom) - have_net_atom = wm_supports (f, "_NET_WM_STATE_FULLSCREEN"); - - if (have_net_atom) - { - Lisp_Object frame; - const char *atom = "_NET_WM_STATE"; - const char *fs = "_NET_WM_STATE_FULLSCREEN"; - const char *fw = "_NET_WM_STATE_MAXIMIZED_HORZ"; - const char *fh = "_NET_WM_STATE_MAXIMIZED_VERT"; - const char *what = NULL; - - XSETFRAME (frame, f); - - /* If there are _NET_ atoms we assume we have extended window manager - hints. */ - switch (f->want_fullscreen) - { - case FULLSCREEN_BOTH: - what = fs; - break; - case FULLSCREEN_WIDTH: - what = fw; - break; - case FULLSCREEN_HEIGHT: - what = fh; - break; - } - - if (what != NULL && !wm_supports (f, what)) return 0; + GtkWidget *wtop = FRAME_GTK_OUTER_WIDGET(f); + if (f->want_fullscreen == FULLSCREEN_BOTH || + f->want_fullscreen == FULLSCREEN_WIDTH || + f->want_fullscreen == FULLSCREEN_HEIGHT) { + gtk_window_fullscreen(GTK_WINDOW(wtop)); + f->want_fullscreen = FULLSCREEN_NONE; + } else + gtk_window_unfullscreen(GTK_WINDOW(wtop)); - Fx_send_client_event (frame, make_number (0), frame, - make_unibyte_string (atom, strlen (atom)), - make_number (32), - Fcons (make_number (0), /* Remove */ - Fcons - (make_unibyte_string (fs, - strlen (fs)), - Qnil))); - Fx_send_client_event (frame, make_number (0), frame, - make_unibyte_string (atom, strlen (atom)), - make_number (32), - Fcons (make_number (0), /* Remove */ - Fcons - (make_unibyte_string (fh, - strlen (fh)), - Qnil))); - Fx_send_client_event (frame, make_number (0), frame, - make_unibyte_string (atom, strlen (atom)), - make_number (32), - Fcons (make_number (0), /* Remove */ - Fcons - (make_unibyte_string (fw, - strlen (fw)), - Qnil))); - f->want_fullscreen = FULLSCREEN_NONE; - if (what != NULL) - Fx_send_client_event (frame, make_number (0), frame, - make_unibyte_string (atom, strlen (atom)), - make_number (32), - Fcons (make_number (1), /* Add */ - Fcons - (make_unibyte_string (what, - strlen (what)), - Qnil))); - } - - return have_net_atom; + return 1; } + static void XTfullscreen_hook (f) FRAME_PTR f;
emacs fullscreen toggling
There is a nice page on EmacsWiki discussing how to play with fullscreen mode in Emacs. This is basically achieved by adding something like the following in your .emacs
(defun fullscreen (&optional f) (interactive) (set-frame-parameter f 'fullscreen (if (frame-parameter f 'fullscreen) nil 'fullboth))) (global-set-key [f6] 'fullscreen) (add-hook 'after-make-frame-functions 'fullscreen)
You may wonder what the point is because there is no F6 key on the N900 keyboard. Well, we can simply correct that and spawn a F6 key on our N900 keyboard.