1 x-face patch for Mutt 1.5.6
3 Copied from Debian's slrnface package:
5 http://dave.willfork.com/slrnface/
6 Upstream Author: Drazen Kacar <dave@arsdigita.com>
7 Copyright: /usr/share/common-licenses/GPL
10 --- mutt-1.4./README.xface Thu Jan 1 01:00:00 1970
11 +++ mutt-1.4/README.xface Sat Aug 24 02:29:23 2002
13 +This is slrnface, a small helper utility which displays X-Faces on behalf
14 +of programs like slrn and mutt when they are run in the X11 terminal
20 +b) Terminal emulator which sets WINDOWID environment variable. Most of the
21 + ones in common use will set it. If you're using some terminal emulator
22 + which doesn't have this capability, you'll have to set it yourself.
26 +a) Install libcompface. I recommend getting the source from the nearest
27 + Debian GNU/Linux mirror because there's a patch which adds the
28 + ability to output XBM image, as well as the historic brain dead
29 + format. Slrnface doesn't use that feature, but it might be handy for
36 +d) Install with "make install".
38 +Upgrading from version 1.x:
40 + If you have used one of the older versions of slrnface, you probably
41 + have .slrnface file in your home directory. You can delete it, because
42 + the new version doesn't use it any more. Instead, the pipes will be
43 + created in $HOME/.slrnfaces directory. There are no other user visible
46 +Using slrnface with slrn:
48 + This version requires S-Lang 1.4 or later and slrn 0.9.7.4. It might
49 + work with slrn 0.9.7.3, but I haven't tested that configuration. It
50 + will not work properly with older versions.
52 + In case you can't or won't upgrade, take a look at the slrnface home
53 + page. You'll find older versions which might work with what you have.
55 + Take a look at slrnface.sl, edit if you want and then include it in
56 + your .slrnrc, like this:
58 + interpret slrnface.sl
62 +Using slrnface with mutt:
64 + Mutt doesn't have a way to use some kind of embeded interpreter, like
65 + S-Lang. Since Mutt's current capabilities are not good enough for our
66 + purposes, a patch for the source is provided. It has been tested with
67 + mutt 1.4, but it should work with the 1.3.x series, if x is high
70 + Uncompress mutt 1.4 source and apply mutt.patch from the slrnface
73 + Compile mutt as usual.
75 + Edit your ~/.muttrc and add:
81 +If you think X-Faces are not placed at the appropriate location on your
82 +terminal emulator window or you don't like the colors, set some X resources.
83 +Read the man page for more information. Additional documentation is in the
86 +Licence: GPL. See file called COPYING.
88 +Special thanks to Mark R. Bowyer for proofreading the man page.
90 +Home page: http://dave.willfork.com/slrnface/
93 diff -urp ../MUTT/mutt/PATCHES mutt/PATCHES
94 --- ../MUTT/mutt/PATCHES 2002-12-09 18:44:54.000000000 +0100
95 +++ mutt/PATCHES 2004-07-21 16:02:16.000000000 +0200
97 +patch-1.5.6.cb.xface.1
98 diff -urp ../MUTT/mutt/globals.h mutt/globals.h
99 --- ../MUTT/mutt/globals.h.orig 2007-03-26 14:49:03.226880430 +0200
100 +++ mutt/globals.h 2007-03-26 14:51:13.227945753 +0200
102 WHERE ALIAS *Aliases INITVAL (0);
103 WHERE LIST *UserHeader INITVAL (0);
105 +WHERE int slrnface_fd INITVAL (-1);
107 /*-- formerly in pgp.h --*/
108 WHERE REGEXP PgpGoodSign;
109 WHERE char *PgpSignAs;
110 diff -urp ../MUTT/mutt/init.c mutt/init.c
111 --- ../MUTT/mutt/init.c 2004-07-18 01:25:28.000000000 +0200
112 +++ mutt/init.c 2004-07-21 13:33:47.000000000 +0200
115 #include <sys/utsname.h>
117 +#include <sys/types.h>
119 #include <sys/wait.h>
121 void toggle_quadoption (int opt)
122 @@ -2356,3 +2358,131 @@ int mutt_get_hook_type (const char *name
127 +void mutt_start_slrnface(void)
130 + int pathlen, status;
134 + if (!option(OPTXFACE))
138 + * If we don't have display, there's no point. The user probably knows,
139 + * so fail silently.
141 + if (!getenv("DISPLAY"))
143 + /* If there is no WINDOWID, complain. */
144 + if (!getenv ("WINDOWID"))
146 + mutt_error (_("Cannot run slrnface: WINDOWID not found in environment."));
151 + pathlen = strlen (Homedir) + sizeof("/.slrnfaces/")
152 + + strlen (u.nodename) + 30;
153 + fifo = safe_malloc (pathlen);
154 + sprintf (fifo, "%s/.slrnfaces", Homedir);
155 + if (mkdir (fifo, 0700))
157 + if (errno != EEXIST)
159 + mutt_error (_("Cannot run slrnface: failed to create %s: %s."),
160 + fifo, strerror(errno));
168 + /* We'll abuse fifo filename memory here. It's long enough. */
169 + sprintf (fifo, "%s/.slrnfaces/README", Homedir);
170 + if ((fp = fopen (fifo, "w")) != NULL)
173 +"This directory is used to create named pipes for communication between\n"
174 +"slrnface and its parent process. It should normally be empty because\n"
175 +"the pipe is deleted right after it has been opened by both processes.\n\n"
176 +"File names generated by slrnface have the form \"hostname.pid\". It is\n"
177 +"probably an error if they linger here longer than a fraction of a second.\n\n"
178 +"However, if the directory is mounted from an NFS server, you might see\n"
179 +"special files created by your NFS server while slrnface is running.\n"
180 +"Do not try to remove them.\n"), fp);
185 + status = snprintf (fifo, pathlen, "%s/.slrnfaces/%s.%ld", Homedir,
186 + u.nodename, (long)getpid());
191 + if (mkfifo (fifo, 0600) < 0)
193 + mutt_error (_("Cannot run slrnface, failed to create %s: %s."), fifo,
202 + case 0: execlp ("slrnface", "slrnface", fifo, (char *)0);
203 + /* This is child, exit on error. */
206 + pidst = waitpid (pid, &status, 0);
207 + } while (pidst == -1 && errno == EINTR);
209 + if (!WIFEXITED (status))
210 + mutt_error (_("Slrnface abnormaly exited, code %d."), status);
215 + switch (WEXITSTATUS (status))
217 + case 0: /* All fine, open the pipe */
218 + slrnface_fd = open (fifo, O_WRONLY, 0600);
219 + write (slrnface_fd, "start\n", sizeof "start");
221 + case 1: message = "couldn't connect to display";
223 + case 2: message = "WINDOWID not found in environment";
225 + case 3: message = "couldn't find controlling terminal";
227 + case 4: message = "terminal doesn't export width and height";
229 + case 5: message = "cannot open FIFO";
231 + case 6: message = "fork() failed";
233 + case 10: message = "executable not found";
235 + default: message = "unknown error";
237 + mutt_error (_("Slrnface failed: %s."), message);
246 +void mutt_stop_slrnface(void)
248 + if (slrnface_fd >= 0)
249 + close(slrnface_fd);
252 + /* FIFO has been unlinked in the startup function. */
254 diff -urp ../MUTT/mutt/init.h mutt/init.h
255 --- ../MUTT/mutt/init.h 2004-07-21 13:33:02.000000000 +0200
256 +++ mutt/init.h 2004-07-21 13:33:47.000000000 +0200
257 @@ -2736,6 +2736,12 @@ struct option_t MuttVars[] = {
258 ** Controls whether mutt writes out the Bcc header when preparing
259 ** messages to be sent. Exim users may wish to use this.
261 + { "xface", DT_BOOL, R_NONE, OPTXFACE, 0 },
264 + ** Controls whether mutt uses slrnface to display X-Faces when run
265 + ** in an X11 terminal emulator.
270 diff -urp ../MUTT/mutt/main.c mutt/main.c
271 --- ../MUTT/mutt/main.c 2004-06-18 17:24:22.000000000 +0200
272 +++ mutt/main.c 2004-07-21 13:33:47.000000000 +0200
273 @@ -905,6 +905,8 @@ int main (int argc, char **argv)
275 mutt_folder_hook (folder);
277 + mutt_start_slrnface();
279 if((Context = mx_open_mailbox (folder, ((flags & M_RO) || option (OPTREADONLY)) ? M_READONLY : 0, NULL))
282 @@ -913,6 +915,8 @@ int main (int argc, char **argv)
285 mutt_endwin (Errorbuf);
287 + mutt_stop_slrnface();
291 diff -urp ../MUTT/mutt/mutt.h mutt/mutt.h
292 --- ../MUTT/mutt/mutt.h 2004-07-21 13:33:02.000000000 +0200
293 +++ mutt/mutt.h 2004-07-21 13:33:47.000000000 +0200
294 @@ -435,6 +435,7 @@ enum
297 OPTWRITEBCC, /* write out a bcc header? */
302 @@ -577,6 +578,7 @@ typedef struct envelope
304 LIST *references; /* message references (in reverse order) */
305 LIST *in_reply_to; /* in-reply-to header content */
306 + LIST *x_face; /* X-Face header content */
307 LIST *userhdrs; /* user defined headers */
310 diff -urp ../MUTT/mutt/muttlib.c mutt/muttlib.c
311 --- ../MUTT/mutt/muttlib.c 2004-07-18 01:25:28.000000000 +0200
312 +++ mutt/muttlib.c 2004-07-21 13:33:47.000000000 +0200
313 @@ -651,6 +651,7 @@ void mutt_free_envelope (ENVELOPE **p)
315 mutt_free_list (&(*p)->references);
316 mutt_free_list (&(*p)->in_reply_to);
317 + mutt_free_list (&(*p)->x_face);
318 mutt_free_list (&(*p)->userhdrs);
321 diff -urp ../MUTT/mutt/pager.c mutt/pager.c
322 --- ../MUTT/mutt/pager.c 2004-07-18 01:25:28.000000000 +0200
323 +++ mutt/pager.c 2004-07-21 13:36:34.000000000 +0200
324 @@ -1527,6 +1527,66 @@ upNLines (int nlines, struct line_t *inf
329 +mutt_display_xface (HEADER *hdr)
334 + if (slrnface_fd < 0)
340 + face = hdr->env->x_face;
342 + if (face == NULL || face->data == NULL)
343 + write(slrnface_fd, "clear\n", sizeof "clear");
348 + len = snprintf (buf, sizeof (buf), "xface %s\n", face->data);
349 + if (len <= sizeof (buf))
351 + write (slrnface_fd, buf, len);
355 + * slrnface will ignore X-Faces larger than approx. 2000 chars, so
356 + * try the next one, if it exists.
358 + } while (face = face->next);
362 +mutt_clear_xface (void)
364 + if (slrnface_fd < 0)
367 + write(slrnface_fd, "clear\n", sizeof "clear");
371 +mutt_suppress_xface (void)
373 + if (slrnface_fd < 0)
376 + write(slrnface_fd, "suppress\n", sizeof "suppress");
380 +mutt_show_xface (void)
382 + if (slrnface_fd < 0)
385 + write(slrnface_fd, "show\n", sizeof "show");
388 static const struct mapping_t PagerHelp[] = {
389 { N_("Exit"), OP_EXIT },
390 { N_("PrevPg"), OP_PREV_PAGE },
391 @@ -1545,6 +1605,9 @@ mutt_pager (const char *banner, const ch
392 snprintf (helpstr, sizeof (helpstr), "%s %s", tmphelp, buffer);
395 + if (IsHeader (extra))
396 + mutt_display_xface(extra->hdr);
401 @@ -2067,7 +2130,9 @@ search_next:
405 + mutt_suppress_xface ();
406 mutt_help (MENU_PAGER);
407 + mutt_show_xface ();
408 redraw = REDRAW_FULL;
411 @@ -2383,59 +2448,71 @@ CHECK_IMAP_ACL(IMAP_ACL_WRITE);
413 CHECK_MODE(IsHeader (extra) && !IsAttach (extra));
415 + mutt_suppress_xface ();
416 ci_send_message (0, NULL, NULL, extra->ctx, NULL);
417 + mutt_show_xface ();
418 redraw = REDRAW_FULL;
422 CHECK_MODE(IsHeader (extra) || IsMsgAttach (extra));
424 + mutt_suppress_xface();
425 if (IsMsgAttach (extra))
426 mutt_attach_reply (extra->fp, extra->hdr, extra->idx,
427 extra->idxlen, extra->bdy,
430 ci_send_message (SENDREPLY, NULL, NULL, extra->ctx, extra->hdr);
431 + mutt_show_xface ();
432 redraw = REDRAW_FULL;
435 case OP_RECALL_MESSAGE:
436 CHECK_MODE(IsHeader (extra) && !IsAttach(extra));
438 + mutt_suppress_xface();
439 ci_send_message (SENDPOSTPONED, NULL, NULL, extra->ctx, extra->hdr);
440 + mutt_show_xface ();
441 redraw = REDRAW_FULL;
445 CHECK_MODE(IsHeader (extra) || IsMsgAttach (extra));
447 + mutt_suppress_xface();
448 if (IsMsgAttach (extra))
449 mutt_attach_reply (extra->fp, extra->hdr, extra->idx,
450 extra->idxlen, extra->bdy, SENDREPLY|SENDGROUPREPLY);
452 ci_send_message (SENDREPLY | SENDGROUPREPLY, NULL, NULL, extra->ctx, extra->hdr);
453 + mutt_suppress_xface ();
454 redraw = REDRAW_FULL;
458 CHECK_MODE(IsHeader (extra) || IsMsgAttach (extra));
460 + mutt_suppress_xface();
461 if (IsMsgAttach (extra))
462 mutt_attach_reply (extra->fp, extra->hdr, extra->idx,
463 extra->idxlen, extra->bdy, SENDREPLY|SENDLISTREPLY);
465 ci_send_message (SENDREPLY | SENDLISTREPLY, NULL, NULL, extra->ctx, extra->hdr);
466 + mutt_show_xface ();
467 redraw = REDRAW_FULL;
470 case OP_FORWARD_MESSAGE:
471 CHECK_MODE(IsHeader (extra) || IsMsgAttach (extra));
473 + mutt_suppress_xface();
474 if (IsMsgAttach (extra))
475 mutt_attach_forward (extra->fp, extra->hdr, extra->idx,
476 extra->idxlen, extra->bdy);
478 ci_send_message (SENDFORWARD, NULL, NULL, extra->ctx, extra->hdr);
479 + mutt_show_xface ();
480 redraw = REDRAW_FULL;
483 @@ -2485,7 +2562,9 @@ CHECK_IMAP_ACL(IMAP_ACL_WRITE);
486 case OP_SHELL_ESCAPE:
487 + mutt_suppress_xface ();
488 mutt_shell_escape ();
489 + mutt_show_xface ();
490 MAYBE_REDRAW (redraw);
493 @@ -2644,5 +2723,6 @@ CHECK_IMAP_ACL(IMAP_ACL_DELETE);
496 mutt_menuDestroy(&index);
497 + mutt_clear_xface ();
498 return (rc != -1 ? rc : 0);
500 diff -urp ../MUTT/mutt/parse.c mutt/parse.c
501 --- ../MUTT/mutt/parse.c 2004-07-21 13:33:02.000000000 +0200
502 +++ mutt/parse.c 2004-07-21 13:33:47.000000000 +0200
503 @@ -85,6 +85,27 @@ static char *read_rfc822_line (FILE *f,
507 +static LIST *mutt_add_x_face (LIST *lst, char *face)
511 + n = safe_malloc(sizeof(LIST));
512 + n->data = safe_strdup(face);
519 + for(l = lst; l->next; l = l->next);
528 static LIST *mutt_parse_references (char *s, int in_reply_to)
530 LIST *t, *lst = NULL;
531 @@ -1231,6 +1252,11 @@ int mutt_parse_rfc822_line (ENVELOPE *e,
532 e->x_label = safe_strdup(p);
535 + else if (ascii_strcasecmp (line+1, "-face") == 0)
537 + e->x_face = mutt_add_x_face (e->x_face, p);
543 diff -urp ../MUTT/mutt/sendlib.c mutt/sendlib.c
544 --- ../MUTT/mutt/sendlib.c 2004-07-21 13:33:02.000000000 +0200
545 +++ mutt/sendlib.c 2004-07-21 13:37:16.000000000 +0200
546 @@ -1697,6 +1697,15 @@ int mutt_write_rfc822_header (FILE *fp,
550 + /* Add X-Face headers */
555 + for (face = env->x_face; face; face = face->next)
556 + fprintf (fp, "X-Face: %s\n", face->data);
559 if (mode == 0 && !privacy && option (OPTXMAILER) && !has_agent)
561 /* Add a vanity header */