From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1KZiTL-0008QN-2Q for mharc-grub-devel@gnu.org; Sun, 31 Aug 2008 04:39:47 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KZiTI-0008PD-DR for grub-devel@gnu.org; Sun, 31 Aug 2008 04:39:44 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KZiTF-0008Ni-1x for grub-devel@gnu.org; Sun, 31 Aug 2008 04:39:42 -0400 Received: from [199.232.76.173] (port=59057 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KZiTE-0008Ne-Tj for grub-devel@gnu.org; Sun, 31 Aug 2008 04:39:40 -0400 Received: from gateway07.websitewelcome.com ([69.56.142.25]:60041) by monty-python.gnu.org with smtp (Exim 4.60) (envelope-from ) id 1KZiTE-0000n3-1v for grub-devel@gnu.org; Sun, 31 Aug 2008 04:39:40 -0400 Received: (qmail 26251 invoked from network); 31 Aug 2008 07:03:58 -0000 Received: from gator297.hostgator.com (74.53.228.114) by gateway07.websitewelcome.com with SMTP; 31 Aug 2008 07:03:58 -0000 Received: from c-67-185-142-228.hsd1.wa.comcast.net ([67.185.142.228]:35316 helo=gamma.lan) by gator297.hostgator.com with esmtpsa (TLSv1:AES128-SHA:128) (Exim 4.68) (envelope-from ) id 1KZgnu-0005NQ-Rt for grub-devel@gnu.org; Sun, 31 Aug 2008 01:52:55 -0500 Date: Sat, 30 Aug 2008 23:52:54 -0700 From: Colin D Bennett To: grub-devel@gnu.org Message-ID: <20080830235254.7cc5ad80@gamma.lan> X-Mailer: Claws Mail 3.5.0 (GTK+ 2.12.11; i686-pc-linux-gnu) Mime-Version: 1.0 Content-Type: multipart/signed; boundary="Sig_/2Mn5IOUHwp+rMpSqDydkXlv"; protocol="application/pgp-signature"; micalg=PGP-SHA1 X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - gator297.hostgator.com X-AntiAbuse: Original Domain - gnu.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - gibibit.com X-detected-kernel: by monty-python.gnu.org: Linux 2.6 (newer, 3) Subject: [PATCH] GSoC #05 Menu entry class attribute X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: The development of GRUB 2 List-Id: The development of GRUB 2 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 31 Aug 2008 08:39:45 -0000 --Sig_/2Mn5IOUHwp+rMpSqDydkXlv Content-Type: multipart/mixed; boundary="MP_/9.4tdz9xFoN6MaZHtg8_Mwr" --MP_/9.4tdz9xFoN6MaZHtg8_Mwr Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable Content-Disposition: inline This patch adds support for a 'class' attribute on menu entries. It is somewhat of a kludge, however since currently you just append "|class=3Dthis,that" to the menu entry title to specify the classes. Classes are used to provide a simple and flexible way for the best available icon to be used in a graphical menu, but there are other possible uses for them as well. The idea originates from the CSS (cascading style sheets) and HTML 'class' concept. Regards, Colin --MP_/9.4tdz9xFoN6MaZHtg8_Mwr Content-Type: text/plain; name=05_ChangeLog.txt Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename=05_ChangeLog.txt 2008-08-30 Colin D Bennett Support classes for menu entries by adding '|classes=3Dx,y' to the title. * include/grub/menu.h (grub_menu_entry_class): New struct type. (grub_menu_entry): Added 'classes' field. * normal/main.c (free_menu_entry_classes): New function. (entry_class_attr_tag): New string constant. (ENTRY_ATTR_SEPARATOR_CHAR): New macro. (get_classes_from_entry_title): New function. (grub_normal_menu_addentry): Parse '|classes=3Dx,y' from entry titles. --MP_/9.4tdz9xFoN6MaZHtg8_Mwr Content-Type: text/x-patch; name=05_menu-entry-class.patch Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename=05_menu-entry-class.patch =3D=3D=3D modified file 'include/grub/menu.h' --- include/grub/menu.h 2008-08-30 19:20:13 +0000 +++ include/grub/menu.h 2008-08-31 05:47:00 +0000 @@ -20,12 +20,24 @@ #ifndef GRUB_MENU_HEADER #define GRUB_MENU_HEADER 1 =20 +struct grub_menu_entry_class +{ + char *name; + struct grub_menu_entry_class *next; +}; + /* The menu entry. */ struct grub_menu_entry { /* The title name. */ const char *title; =20 + /* The classes associated with the menu entry: + used to choose an icon or other style attributes. + This is a dummy head node for the linked list, so for an entry E, + E.classes->next is the first class if it is not NULL. */ + struct grub_menu_entry_class *classes; + /* The commands associated with this menu entry. */ struct grub_script *commands; =20 =3D=3D=3D modified file 'normal/main.c' --- normal/main.c 2008-08-30 19:20:13 +0000 +++ normal/main.c 2008-08-31 05:47:00 +0000 @@ -148,14 +148,132 @@ grub_env_unset_data_slot ("menu"); } =20 +static void +free_menu_entry_classes (struct grub_menu_entry_class *head) +{ + /* Free all the classes. */ + while (head) + { + struct grub_menu_entry_class *next; + + grub_free (head->name); + next =3D head->next; + grub_free (head); + head =3D next; + } +} + +/* The tag that can be added to a menu entry's title to specify a class + for the UI to use in selecting an icon or other visual attributes. */ +static const char entry_class_attr_tag[] =3D "|class=3D"; + +#define ENTRY_ATTR_SEPARATOR_CHAR ',' + +/* Parse and strip a possible "class" attribute in the title. + This code is not designed to support other attributes than "class" + in the title since, we are planning to use a better method of + specifying this information in the future. The parameter TITLE is + modified by storing a '\0' at the appropriate location to strip the + class information, if it exists. The class list is stored into *HEAD. = */ +static struct grub_menu_entry_class * +get_classes_from_entry_title (char *title) +{ + struct grub_menu_entry_class *head; + char *attr_start; + + head =3D grub_malloc (sizeof (struct grub_menu_entry_class)); + if (! head) + return 0; + head->name =3D 0; + head->next =3D 0; + + attr_start =3D grub_strstr (title, entry_class_attr_tag); + if (attr_start) + { + struct grub_menu_entry_class *tail; + const char *p; + + /* Trim the properties off of the title. */ + *attr_start =3D '\0'; + + /* Move the pointer to the beginning of the first class name. */ + attr_start +=3D grub_strlen (entry_class_attr_tag); + + tail =3D head; + p =3D attr_start; + while (p && *p) + { + const char *q; + const char *end; + const char *next_start; + + /* Skip any leading whitespace. */ + while (*p && grub_isspace (*p)) + p++; + + /* Find the comma terminating this one ... */ + q =3D grub_strchr (p, ENTRY_ATTR_SEPARATOR_CHAR); + /* ... or if it's the last one, find the '\0' terminator. */ + if (q) + { + end =3D q - 1; + next_start =3D q + 1; + } + else + { + /* For the last class, extend it to the end. */ + end =3D p + grub_strlen (p); + next_start =3D 0; + } + + /* Trim any trailing whitespace. */ + while (end > p && grub_isspace (*end)) + end--; + + grub_size_t len =3D end - p + 1; + /* Copy the class name into a new string. */ + char *class_name =3D grub_malloc (len + 1); + if (! class_name) + { + free_menu_entry_classes (head); + return 0; + } + grub_memcpy (class_name, p, len); + class_name[len] =3D '\0'; + + /* Create a new class and add it at the tail of the list. */ + struct grub_menu_entry_class *new_class; + new_class =3D grub_malloc (sizeof (struct grub_menu_entry_class)= ); + if (! new_class) + { + grub_free (class_name); + free_menu_entry_classes (head); + return 0; + } + /* Fill in the new class node. */ + new_class->name =3D class_name; + new_class->next =3D 0; + /* Link the tail to it, and make it the new tail. */ + tail->next =3D new_class; + tail =3D new_class; + + /* Advance the character pointer. */ + p =3D next_start; + } + } + + return head; +} + grub_err_t grub_normal_menu_addentry (const char *title, struct grub_script *script, const char *sourcecode) { - const char *menutitle; + char *menutitle; const char *menusourcecode; grub_menu_t menu; grub_menu_entry_t *last; + struct grub_menu_entry_class *classes; =20 menu =3D grub_env_get_data_slot("menu"); if (! menu) @@ -174,6 +292,14 @@ return grub_errno; } =20 + classes =3D get_classes_from_entry_title (menutitle); + if (! classes) + { + grub_free ((void *) menutitle); + grub_free ((void *) menusourcecode); + return grub_errno; + } + /* Add the menu entry at the end of the list. */ while (*last) last =3D &(*last)->next; @@ -181,6 +307,7 @@ *last =3D grub_malloc (sizeof (**last)); if (! *last) { + free_menu_entry_classes (classes); grub_free ((void *) menutitle); grub_free ((void *) menusourcecode); return grub_errno; @@ -188,6 +315,7 @@ =20 (*last)->commands =3D script; (*last)->title =3D menutitle; + (*last)->classes =3D classes; (*last)->next =3D 0; (*last)->sourcecode =3D menusourcecode; =20 --MP_/9.4tdz9xFoN6MaZHtg8_Mwr-- --Sig_/2Mn5IOUHwp+rMpSqDydkXlv Content-Type: application/pgp-signature; name=signature.asc Content-Disposition: attachment; filename=signature.asc -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.9 (GNU/Linux) iEYEARECAAYFAki6P8kACgkQokx8fzcGbYfuaACgkJG1b+i5toIKkatSkc/dac43 nFUAoI2C5uUBlaabYtUSFFllvHQmKc8u =cTtB -----END PGP SIGNATURE----- --Sig_/2Mn5IOUHwp+rMpSqDydkXlv--