unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* GDI+ take 3
@ 2020-04-04 21:25 Juan José García-Ripoll
  2020-04-05 12:58 ` Eli Zaretskii
  0 siblings, 1 reply; 86+ messages in thread
From: Juan José García-Ripoll @ 2020-04-04 21:25 UTC (permalink / raw)
  To: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1956 bytes --]

After some consideration and washing off the feeling that I am wasting
my time, I have reworked my previous patch to test at boot time whether
GDI+ is available (gdiplus_v3.diff). It implements a generic
"native-image-api" option which can be extended to OSX (I have a patch,
but I have no machines to test it so it is not attached).

It does not implement a new image type. Instead, it places the native
backends at the front and continues searching the image list when those
backends are not active. I find that treating the native backend as a
second class citizen, as ImageMagick, is not ok. But most important, I
find that the abstraction of backend = image-type is broken.

Regarding previous discussions, I believe the concerns about GDI+
becoming deprecated are irrelevant in comparison to the fact that Emacs
is using already a deprecated API, namely GDI, which is older and
equally prone to disappear in favor of Direct2d/WIC.

Regarding unicode, GDI+ requires WCHAR. Therefore the backend refuses to
initialize if w32-unicode-filenames is NIL, defaulting to other
backends. However, if the user changes this variable from T to NIL after
the backend has been initialized, the backend will remain active but
refuse to load images.

I have fixed the use of terminal hooks, due to insistance. However, that
meant one function declaration had to be added to w32term.h

I have not changed the use of SSDATA in the :data field of images. If
this is a problem, it is so in all of image.c.

I have touch my Emacs installation to avoid removing the double spaces
after a dot, but I am not 100% sure all is Kosher.

I go to bed. If you still find that this patch is not acceptable, I am
not going to work any more on it. I developed it to minimize the number
of dependencies of Emacs on the Windows platform, but that does not seem
to be a priority around here.

Best,

-- 
Juan José García Ripoll
http://juanjose.garciaripoll.com
http://quinfog.hbar.es

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: gdiplus_v3.diff --]
[-- Type: text/x-patch, Size: 13958 bytes --]

diff --git a/src/image.c b/src/image.c
index 65d59254f0..2ef51a87f2 100644
--- a/src/image.c
+++ b/src/image.c
@@ -751,7 +751,7 @@ x_create_bitmap_mask (struct frame *f, ptrdiff_t id)

   /* Check that SPEC is a valid image specification for the given
      image type.  Value is true if SPEC is valid.  */
-  bool (*valid_p) (Lisp_Object spec);
+  bool (*valid_p) (Lisp_Object spec, Lisp_Object type);

   /* Load IMG which is used on frame F from information contained in
      IMG->spec.  Value is true if successful.  */
@@ -807,7 +807,7 @@ valid_image_p (Lisp_Object object)
 	      {
 		struct image_type const *type = lookup_image_type (XCAR (tail));
 		if (type)
-		  return type->valid_p (object);
+		  return type->valid_p (object, builtin_lisp_symbol (type->type));
 	      }
 	    break;
 	  }
@@ -3144,12 +3144,12 @@ slurp_file (int fd, ptrdiff_t *size)
    displayed is used.  */

 static bool
-xbm_image_p (Lisp_Object object)
+xbm_image_p (Lisp_Object object, Lisp_Object type)
 {
   struct image_keyword kw[XBM_LAST];

   memcpy (kw, xbm_format, sizeof kw);
-  if (!parse_image_spec (object, kw, XBM_LAST, Qxbm))
+  if (!parse_image_spec (object, kw, XBM_LAST, type))
     return 0;

   eassert (EQ (kw[XBM_TYPE].value, Qxbm));
@@ -3697,7 +3697,7 @@ xbm_load (struct frame *f, struct image *img)
   bool success_p = 0;
   Lisp_Object file_name;

-  eassert (xbm_image_p (img->spec));
+  eassert (xbm_image_p (img->spec, Qxbm));

   /* If IMG->spec specifies a file name, create a non-file spec from it.  */
   file_name = image_spec_value (img->spec, QCfile, NULL);
@@ -4155,11 +4155,11 @@ xpm_valid_color_symbols_p (Lisp_Object color_symbols)
 /* Value is true if OBJECT is a valid XPM image specification.  */

 static bool
-xpm_image_p (Lisp_Object object)
+xpm_image_p (Lisp_Object object, Lisp_Object type)
 {
   struct image_keyword fmt[XPM_LAST];
   memcpy (fmt, xpm_format, sizeof fmt);
-  return (parse_image_spec (object, fmt, XPM_LAST, Qxpm)
+  return (parse_image_spec (object, fmt, XPM_LAST, type)
 	  /* Either `:file' or `:data' must be present.  */
 	  && fmt[XPM_FILE].count + fmt[XPM_DATA].count == 1
 	  /* Either no `:color-symbols' or it's a list of conses
@@ -5882,13 +5882,13 @@ image_build_heuristic_mask (struct frame *f, struct image *img,
 /* Return true if OBJECT is a valid PBM image specification.  */

 static bool
-pbm_image_p (Lisp_Object object)
+pbm_image_p (Lisp_Object object, Lisp_Object type)
 {
   struct image_keyword fmt[PBM_LAST];

   memcpy (fmt, pbm_format, sizeof fmt);

-  if (!parse_image_spec (object, fmt, PBM_LAST, Qpbm))
+  if (!parse_image_spec (object, fmt, PBM_LAST, type))
     return 0;

   /* Must specify either :data or :file.  */
@@ -6230,6 +6230,83 @@ pbm_load (struct frame *f, struct image *img)
   return 1;
 }

+\f
+/***********************************************************************
+			    NATIVE IMAGE HANDLING
+ ***********************************************************************/
+#if defined(HAVE_NATIVE_IMAGE_API) && defined(HAVE_NTGUI)
+/*
+ * These functions are actually defined in the OS-native implementation
+ * file.  Currently, for Windows GDI+ interface, w32image.c, but other
+ * operating systems can follow suit.
+ */
+
+static bool
+init_native_image_functions (void)
+{
+  return w32_gdiplus_startup ();
+}
+
+/* Indices of image specification fields in native format, below.  */
+
+enum native_image_keyword_index
+{
+  NATIVE_IMAGE_TYPE,
+  NATIVE_IMAGE_DATA,
+  NATIVE_IMAGE_FILE,
+  NATIVE_IMAGE_ASCENT,
+  NATIVE_IMAGE_MARGIN,
+  NATIVE_IMAGE_RELIEF,
+  NATIVE_IMAGE_ALGORITHM,
+  NATIVE_IMAGE_HEURISTIC_MASK,
+  NATIVE_IMAGE_MASK,
+  NATIVE_IMAGE_BACKGROUND,
+  NATIVE_IMAGE_INDEX,
+  NATIVE_IMAGE_LAST
+};
+
+/* Vector of image_keyword structures describing the format
+   of valid user-defined image specifications.  */
+
+static const struct image_keyword native_image_format[] =
+{
+  {":type",		IMAGE_SYMBOL_VALUE,			1},
+  {":data",		IMAGE_STRING_VALUE,			0},
+  {":file",		IMAGE_STRING_VALUE,			0},
+  {":ascent",		IMAGE_ASCENT_VALUE,			0},
+  {":margin",		IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
+  {":relief",		IMAGE_INTEGER_VALUE,			0},
+  {":conversion",	IMAGE_DONT_CHECK_VALUE_TYPE,		0},
+  {":heuristic-mask",	IMAGE_DONT_CHECK_VALUE_TYPE,		0},
+  {":mask",		IMAGE_DONT_CHECK_VALUE_TYPE,		0},
+  {":background",	IMAGE_STRING_OR_NIL_VALUE,		0},
+  {":index",		IMAGE_NON_NEGATIVE_INTEGER_VALUE,	0}
+};
+
+/* Return true if OBJECT is a valid native API image specification.  */
+
+static bool
+native_image_p (Lisp_Object object, Lisp_Object type)
+{
+  struct image_keyword fmt[NATIVE_IMAGE_LAST];
+  memcpy (fmt, native_image_format, sizeof fmt);
+
+  if (!parse_image_spec (object, fmt, 10, type))
+    return 0;
+
+  /* Must specify either the :data or :file keyword.  */
+  return fmt[NATIVE_IMAGE_FILE].count + fmt[NATIVE_IMAGE_DATA].count == 1;
+}
+
+static bool
+native_image_load (struct frame *f, struct image *img)
+{
+  return w32_load_image (f, img,
+                         image_spec_value (img->spec, QCfile, NULL),
+                         image_spec_value (img->spec, QCdata, NULL));
+}
+#endif
+
 \f
 /***********************************************************************
 				 PNG
@@ -6274,12 +6351,12 @@ pbm_load (struct frame *f, struct image *img)
 /* Return true if OBJECT is a valid PNG image specification.  */

 static bool
-png_image_p (Lisp_Object object)
+png_image_p (Lisp_Object object, Lisp_Object type)
 {
   struct image_keyword fmt[PNG_LAST];
   memcpy (fmt, png_format, sizeof fmt);

-  if (!parse_image_spec (object, fmt, PNG_LAST, Qpng))
+  if (!parse_image_spec (object, fmt, PNG_LAST, type))
     return 0;

   /* Must specify either the :data or :file keyword.  */
@@ -6889,7 +6966,6 @@ png_load (struct frame *f, struct image *img)
                         image_spec_value (img->spec, QCdata, NULL));
 }

-
 #endif /* HAVE_NS */


@@ -6937,13 +7013,13 @@ png_load (struct frame *f, struct image *img)
 /* Return true if OBJECT is a valid JPEG image specification.  */

 static bool
-jpeg_image_p (Lisp_Object object)
+jpeg_image_p (Lisp_Object object, Lisp_Object type)
 {
   struct image_keyword fmt[JPEG_LAST];

   memcpy (fmt, jpeg_format, sizeof fmt);

-  if (!parse_image_spec (object, fmt, JPEG_LAST, Qjpeg))
+  if (!parse_image_spec (object, fmt, JPEG_LAST, type))
     return 0;

   /* Must specify either the :data or :file keyword.  */
@@ -7513,12 +7589,12 @@ jpeg_load (struct frame *f, struct image *img)
 /* Return true if OBJECT is a valid TIFF image specification.  */

 static bool
-tiff_image_p (Lisp_Object object)
+tiff_image_p (Lisp_Object object, Lisp_Object type)
 {
   struct image_keyword fmt[TIFF_LAST];
   memcpy (fmt, tiff_format, sizeof fmt);

-  if (!parse_image_spec (object, fmt, TIFF_LAST, Qtiff))
+  if (!parse_image_spec (object, fmt, TIFF_LAST, type))
     return 0;

   /* Must specify either the :data or :file keyword.  */
@@ -7961,19 +8037,19 @@ gif_clear_image (struct frame *f, struct image *img)
 /* Return true if OBJECT is a valid GIF image specification.  */

 static bool
-gif_image_p (Lisp_Object object)
+gif_image_p (Lisp_Object object, Lisp_Object type)
 {
   struct image_keyword fmt[GIF_LAST];
   memcpy (fmt, gif_format, sizeof fmt);

-  if (!parse_image_spec (object, fmt, GIF_LAST, Qgif))
+  if (!parse_image_spec (object, fmt, GIF_LAST, type))
     return 0;

   /* Must specify either the :data or :file keyword.  */
   return fmt[GIF_FILE].count + fmt[GIF_DATA].count == 1;
 }

-#endif /* HAVE_GIF */
+#endif /* HAVE_GIF || HAVE_NS */

 #ifdef HAVE_GIF

@@ -8573,12 +8649,12 @@ imagemagick_clear_image (struct frame *f,
    identify the IMAGEMAGICK format.   */

 static bool
-imagemagick_image_p (Lisp_Object object)
+imagemagick_image_p (Lisp_Object object, Lisp_Object type)
 {
   struct image_keyword fmt[IMAGEMAGICK_LAST];
   memcpy (fmt, imagemagick_format, sizeof fmt);

-  if (!parse_image_spec (object, fmt, IMAGEMAGICK_LAST, Qimagemagick))
+  if (!parse_image_spec (object, fmt, IMAGEMAGICK_LAST, type))
     return 0;

   /* Must specify either the :data or :file keyword.  */
@@ -9368,12 +9444,12 @@ DEFUN ("imagemagick-types", Fimagemagick_types, Simagemagick_types, 0, 0, 0,
    identify the SVG format.   */

 static bool
-svg_image_p (Lisp_Object object)
+svg_image_p (Lisp_Object object, Lisp_Object type)
 {
   struct image_keyword fmt[SVG_LAST];
   memcpy (fmt, svg_format, sizeof fmt);

-  if (!parse_image_spec (object, fmt, SVG_LAST, Qsvg))
+  if (!parse_image_spec (object, fmt, SVG_LAST, type))
     return 0;

   /* Must specify either the :data or :file keyword.  */
@@ -9836,7 +9912,7 @@ #define HAVE_GHOSTSCRIPT 1
    specification.  */

 static bool
-gs_image_p (Lisp_Object object)
+gs_image_p (Lisp_Object object, Lisp_Object type)
 {
   struct image_keyword fmt[GS_LAST];
   Lisp_Object tem;
@@ -9844,7 +9920,7 @@ gs_image_p (Lisp_Object object)

   memcpy (fmt, gs_format, sizeof fmt);

-  if (!parse_image_spec (object, fmt, GS_LAST, Qpostscript))
+  if (!parse_image_spec (object, fmt, GS_LAST, type))
     return 0;

   /* Bounding box must be a list or vector containing 4 integers.  */
@@ -10131,13 +10207,20 @@ DEFUN ("init-image-library", Finit_image_library, Sinit_image_library, 1, 1, 0,
 initialize_image_type (struct image_type const *type)
 {
 #ifdef WINDOWSNT
-  Lisp_Object typesym = builtin_lisp_symbol (type->type);
-  Lisp_Object tested = Fassq (typesym, Vlibrary_cache);
+  Lisp_Object typesym, tested;
+  bool (*init) (void) = type->init;
+
+#ifdef HAVE_NATIVE_IMAGE_API
+  if (init == init_native_image_functions)
+    return init();
+#endif
+
+  typesym = builtin_lisp_symbol (type->type);
+  tested = Fassq (typesym, Vlibrary_cache);
   /* If we failed to load the library before, don't try again.  */
   if (CONSP (tested))
     return !NILP (XCDR (tested)) ? true : false;

-  bool (*init) (void) = type->init;
   if (init)
     {
       bool type_valid = init ();
@@ -10164,6 +10247,16 @@ initialize_image_type (struct image_type const *type)
  { SYMBOL_INDEX (Qsvg), svg_image_p, svg_load, image_clear_image,
    IMAGE_TYPE_INIT (init_svg_functions) },
 #endif
+#if defined HAVE_NATIVE_IMAGE_API
+ { SYMBOL_INDEX (Qjpeg), native_image_p, native_image_load, image_clear_image,
+   IMAGE_TYPE_INIT (init_native_image_functions) },
+ { SYMBOL_INDEX (Qpng), native_image_p, native_image_load, image_clear_image,
+   IMAGE_TYPE_INIT (init_native_image_functions) },
+ { SYMBOL_INDEX (Qgif), native_image_p, native_image_load, image_clear_image,
+   IMAGE_TYPE_INIT (init_native_image_functions) },
+ { SYMBOL_INDEX (Qtiff), native_image_p, native_image_load, image_clear_image,
+   IMAGE_TYPE_INIT (init_native_image_functions) },
+#endif
 #if defined HAVE_PNG || defined HAVE_NS
  { SYMBOL_INDEX (Qpng), png_image_p, png_load, image_clear_image,
    IMAGE_TYPE_INIT (init_png_functions) },
@@ -10198,7 +10291,13 @@ lookup_image_type (Lisp_Object type)
     {
       struct image_type const *r = &image_types[i];
       if (EQ (type, builtin_lisp_symbol (r->type)))
+#ifdef HAVE_NATIVE_IMAGE_API
+        /* We can have more than one backend for one image type.  */
+        if (initialize_image_type (r))
+          return r;
+#else
 	return initialize_image_type (r) ? r : NULL;
+#endif
     }
   return NULL;
 }
@@ -10315,22 +10414,22 @@ syms_of_image (void)
   add_image_type (Qxpm);
 #endif

-#if defined (HAVE_JPEG) || defined (HAVE_NS)
+#if defined (HAVE_JPEG) || defined (HAVE_NS) || defined (HAVE_NATIVE_IMAGE_API)
   DEFSYM (Qjpeg, "jpeg");
   add_image_type (Qjpeg);
 #endif

-#if defined (HAVE_TIFF) || defined (HAVE_NS)
+#if defined (HAVE_TIFF) || defined (HAVE_NS) || defined (HAVE_NATIVE_IMAGE_API)
   DEFSYM (Qtiff, "tiff");
   add_image_type (Qtiff);
 #endif

-#if defined (HAVE_GIF) || defined (HAVE_NS)
+#if defined (HAVE_GIF) || defined (HAVE_NS) || defined (HAVE_NATIVE_IMAGE_API)
   DEFSYM (Qgif, "gif");
   add_image_type (Qgif);
 #endif

-#if defined (HAVE_PNG) || defined (HAVE_NS)
+#if defined (HAVE_PNG) || defined (HAVE_NS) || defined(HAVE_NATIVE_IMAGE_API)
   DEFSYM (Qpng, "png");
   add_image_type (Qpng);
 #endif
diff --git a/src/w32.c b/src/w32.c
index 698e10e234..1d2a52b6df 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -10225,6 +10225,10 @@ term_ntproc (int ignored)
   term_winsock ();

   term_w32select ();
+
+#ifdef HAVE_GDIPLUS
+  w32_gdiplus_shutdown ();
+#endif
 }

 void
diff --git a/src/w32term.c b/src/w32term.c
index 5fa77d58e1..f19754df02 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -1529,7 +1529,7 @@ w32_query_colors (struct frame *f, Emacs_Color *colors, int ncolors)

 /* Store F's background color into *BGCOLOR.  */

-static void
+void
 w32_query_frame_background_color (struct frame *f, Emacs_Color *bgcolor)
 {
   bgcolor->pixel = FRAME_BACKGROUND_PIXEL (f);
diff --git a/src/w32term.h b/src/w32term.h
index f8a8a727e8..d44c6f9b83 100644
--- a/src/w32term.h
+++ b/src/w32term.h
@@ -75,7 +75,10 @@ #define CP_DEFAULT 1004
 extern void w32_regenerate_palette (struct frame *f);
 extern void w32_fullscreen_rect (HWND hwnd, int fsmode, RECT normal,
                                  RECT *rect);
-
+extern int w32_load_image (struct frame *f, struct image *img,
+                           Lisp_Object spec_file, Lisp_Object spec_data);
+extern bool w32_gdiplus_startup (void);
+extern void w32_gdiplus_shutdown (void);
 \f
 /* For each display (currently only one on w32), we have a structure that
    records information about it.  */
@@ -248,6 +251,8 @@ #define CP_DEFAULT 1004
 extern int w32_display_pixel_width (struct w32_display_info *);
 extern void initialize_frame_menubar (struct frame *);
 extern void w32_dialog_in_progress (Lisp_Object in_progress);
+extern void w32_query_frame_background_color (struct frame *f,
+                                              Emacs_Color *bgcolor);

 extern void w32_make_frame_visible (struct frame *f);
 extern void w32_make_frame_invisible (struct frame *f);

^ permalink raw reply related	[flat|nested] 86+ messages in thread
[parent not found: <617217672.240027.1586079490291@mail1.libero.it>]

end of thread, other threads:[~2020-04-26 15:14 UTC | newest]

Thread overview: 86+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-04 21:25 GDI+ take 3 Juan José García-Ripoll
2020-04-05 12:58 ` Eli Zaretskii
2020-04-13  6:19   ` Eli Zaretskii
2020-04-13 10:04     ` Juan José García-Ripoll
2020-04-14 15:33       ` Eli Zaretskii
2020-04-14 17:43         ` Eli Zaretskii
2020-04-14 22:19           ` Alan Third
2020-04-16 18:39             ` Eli Zaretskii
2020-04-14 18:38         ` Dmitry Gutov
2020-04-14 18:43           ` Eli Zaretskii
2020-04-14 19:38             ` Dmitry Gutov
2020-04-14 19:08         ` Basil L. Contovounesios
2020-04-14 19:24           ` Eli Zaretskii
2020-04-14 21:57             ` Basil L. Contovounesios
2020-04-15  6:18               ` Eli Zaretskii
2020-04-15 13:40                 ` Juanma Barranquero
2020-04-15 14:00                   ` Eli Zaretskii
2020-04-15 14:12                     ` Juanma Barranquero
2020-04-15 14:17                       ` Juanma Barranquero
2020-04-15 14:28                         ` Eli Zaretskii
2020-04-15 14:35                           ` Juanma Barranquero
2020-04-15 14:43                             ` Eli Zaretskii
2020-04-15 14:47                               ` Juanma Barranquero
2020-04-15 15:00                               ` Juanma Barranquero
2020-04-15 15:02                                 ` Juanma Barranquero
2020-04-15 15:10                                   ` Eli Zaretskii
2020-04-15 15:31                                     ` Juanma Barranquero
2020-04-15 15:46                                       ` Eli Zaretskii
2020-04-15 15:56                                         ` Eli Zaretskii
2020-04-15 16:08                                           ` Eli Zaretskii
2020-04-15 16:50                                         ` Juanma Barranquero
2020-04-15 16:59                                           ` Eli Zaretskii
2020-04-15 17:24                                             ` Juanma Barranquero
2020-04-15 17:34                                               ` Eli Zaretskii
2020-04-15 17:49                                                 ` Juanma Barranquero
2020-04-15 18:13                                                   ` Eli Zaretskii
2020-04-15 18:45                                                     ` Juanma Barranquero
2020-04-15 20:21                                                       ` Eli Zaretskii
2020-04-15 20:31                                                         ` Juanma Barranquero
2020-04-16 10:04                                                           ` Eli Zaretskii
2020-04-16 23:49                                                             ` Juanma Barranquero
2020-04-17  6:55                                                               ` Eli Zaretskii
2020-04-17  7:27                                                                 ` Juan José García-Ripoll
2020-04-17  8:36                                                                   ` Juanma Barranquero
2020-04-17  9:52                                                                   ` Eli Zaretskii
2020-04-18  8:41                                                                     ` Juan José García-Ripoll
2020-04-18 10:00                                                               ` Eli Zaretskii
2020-04-18 10:09                                                                 ` Juanma Barranquero
2020-04-18 12:38                                                                   ` Juan José García-Ripoll
2020-04-18 13:38                                                                     ` Eli Zaretskii
2020-04-18 15:56                                                                       ` Juanma Barranquero
2020-04-18 16:15                                                                         ` Eli Zaretskii
2020-04-18 17:51                                                                           ` Juan José García-Ripoll
2020-04-18 18:01                                                                             ` Eli Zaretskii
2020-04-18 18:04                                                                               ` Eli Zaretskii
2020-04-18 18:49                                                                                 ` Juanma Barranquero
2020-04-18 19:15                                                                                   ` Eli Zaretskii
2020-04-18 20:19                                                                       ` Alan Third
2020-04-19 10:20                                                                         ` Juan José García-Ripoll
2020-04-19 20:08                                                                           ` Juan José García-Ripoll
2020-04-20 13:37                                                                             ` Eli Zaretskii
2020-04-21  7:35                                                                               ` Juan José García-Ripoll
2020-04-21 14:15                                                                                 ` Eli Zaretskii
2020-04-21 18:17                                                                                 ` Alan Third
2020-04-21 18:34                                                                                   ` Eli Zaretskii
2020-04-25 16:51                                                                                     ` Alan Third
2020-04-20 20:16                                                                             ` Alan Third
2020-04-21  6:25                                                                               ` Juan José García-Ripoll
2020-04-25 16:23                                                                                 ` Alan Third
2020-04-25 13:42                                                                             ` Eli Zaretskii
2020-04-26 15:14                                                                               ` Juan José García-Ripoll
2020-04-19 18:16                                                                         ` Eli Zaretskii
2020-04-19 20:28                                                                           ` Juan José García-Ripoll
2020-04-20 13:54                                                                             ` Eli Zaretskii
2020-04-21  6:44                                                                               ` Juan José García-Ripoll
2020-04-21 14:13                                                                                 ` Eli Zaretskii
2020-04-21 16:20                                                                                   ` Juan José García-Ripoll
2020-04-15 16:50                                       ` Eli Zaretskii
2020-04-15 14:27                       ` Eli Zaretskii
     [not found] <617217672.240027.1586079490291@mail1.libero.it>
2020-04-15 14:07 ` Angelo Graziosi
2020-04-15 14:15   ` Eli Zaretskii
2020-04-15 14:22     ` Angelo Graziosi
2020-04-15 14:26       ` Eli Zaretskii
2020-04-15 15:25         ` Angelo Graziosi
2020-04-15 15:27           ` Eli Zaretskii
2020-04-15 15:46             ` Angelo Graziosi

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).