All of lore.kernel.org
 help / color / mirror / Atom feed
* Sendkey, activate, bash
@ 2005-08-01 18:38 Vladimir Serbinenko
  0 siblings, 0 replies; only message in thread
From: Vladimir Serbinenko @ 2005-08-01 18:38 UTC (permalink / raw)
  To: grub-devel

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

I send a new version of my patch. Sendkey is now a variable and also
there are
the variables kb_*. The disadvantages are that sendkey is not loaded
automatically, the
number of variables and unavailability to see the help. Could someone
propose how to fix it?
At hte same time I discovered that grub and bash parse quotes and
doublequotes differently.
Example to set sendkey to "h e l l o". it doesn't work if you write:
sendkey="h e l l o"
You must write:
"sendkey=h e l l o"
I changed the way that grub parses the " and '. And now it does like bash.

Also I wrote new module: activate. It's also pc-specific. It's analog of
makeactive but with
other syntax:

active PARTITION.

like:

activate (hd0,2)


                                          Vladimir Serbinenko
2005-08-01  Vladimir Serbinenko <phcoder@gmail.com>

    Sendkey and activate modules(pc) and preboots

    * commands/boot.c: Added support for preboot functions
    * conf/i386.rmk (sendkey): new module
    (activate): Likewise
    * commands/i386/pc/activate.c: new file
    * include/grub/normal.h: new headers and types for preboots
    * commands/i386/pc/activate.c: new file
    * kern/misc.c (grub_split_cmdline): more bash-like quotes and
    doublequotes handle




[-- Attachment #2: key.patch --]
[-- Type: text/x-patch, Size: 27805 bytes --]

diff -urpN grub2um/ChangeLog grub2m/ChangeLog
--- grub2um/ChangeLog	2005-08-01 11:44:43.000000000 +0200
+++ grub2m/ChangeLog	2005-08-01 19:58:18.000000000 +0200
@@ -1,3 +1,16 @@
+2005-08-01  Vladimir Serbinenko <phcoder@gmail.com>
+
+	Sendkey and activate modules(pc) and preboots
+	
+	* commands/boot.c: Added support for preboot functions
+	* conf/i386.rmk (sendkey): new module
+	(activate): Likewise
+	* commands/i386/pc/activate.c: new file
+	* include/grub/normal.h: new headers and types for preboots
+	* commands/i386/pc/activate.c: new file
+	* kern/misc.c (grub_split_cmdline): more bash-like quotes and
+	doublequotes handle
+
 2005-07-31  Yoshinori K. Okuji  <okuji@enbug.org>
 
 	* loader/i386/pc/multiboot.c (grub_multiboot_is_elf32): New
diff -urpN grub2um/commands/boot.c grub2m/commands/boot.c
--- grub2um/commands/boot.c	2005-07-25 15:23:26.000000000 +0200
+++ grub2m/commands/boot.c	2005-07-25 16:58:11.000000000 +0200
@@ -23,13 +23,23 @@
 #include <grub/arg.h>
 #include <grub/misc.h>
 #include <grub/loader.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+
+static grub_prebootfn_t *grub_preboots = 0;
+static int grub_preboot_cnt = 0;
 
 static grub_err_t
 grub_cmd_boot (struct grub_arg_list *state __attribute__ ((unused)),
 	       int argc, char **args __attribute__ ((unused)))
 {
+  int i;
+
   if (argc)
     return grub_error (GRUB_ERR_BAD_ARGUMENT, "too many arguments");
+
+  for (i = 0; i < grub_preboot_cnt; i++)
+    grub_preboots[i] ();
   
   grub_loader_boot ();
   
@@ -38,6 +48,46 @@ grub_cmd_boot (struct grub_arg_list *sta
 
 \f
 
+grub_err_t
+grub_preboot_add (grub_prebootfn_t fn)
+{
+  grub_prebootfn_t *tmp;
+  tmp = (grub_prebootfn_t *) grub_realloc (grub_preboots, (grub_preboot_cnt + 1) * sizeof(grub_prebootfn_t));
+  if (!tmp)
+    return grub_errno;
+  grub_preboots = tmp;
+  grub_preboots[grub_preboot_cnt] = fn;
+  grub_preboot_cnt++;
+
+  return 0;
+}
+
+\f
+
+grub_err_t
+grub_preboot_remove (grub_prebootfn_t fn)
+{
+  int i;
+  for (i = 0; i < grub_preboot_cnt; i++)
+    if (grub_preboots[i] == fn)
+      break;
+
+  if (i == grub_preboot_cnt)
+    {
+      return grub_error (GRUB_ERR_BAD_ARGUMENT, "fn not found");
+    }
+
+  for (; i < grub_preboot_cnt - 1; i++)
+    grub_preboots[i] = grub_preboots[i + 1];
+
+  grub_preboots = (grub_prebootfn_t *) grub_realloc (grub_preboots, (--grub_preboot_cnt) * sizeof(grub_prebootfn_t));
+
+  return 0;
+
+}
+
+\f
+
 #ifdef GRUB_UTIL
 void
 grub_boot_init (void)
diff -urpN grub2um/commands/i386/pc/activate.c grub2m/commands/i386/pc/activate.c
--- grub2um/commands/i386/pc/activate.c	1970-01-01 01:00:00.000000000 +0100
+++ grub2m/commands/i386/pc/activate.c	2005-08-01 18:55:15.000000000 +0200
@@ -0,0 +1,114 @@
+/* activate.c - activate pc partition */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2003  Free Software Foundation, Inc.
+ *  Copyright (C) 2003  NIIBE Yutaka <gniibe@m17n.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/normal.h>
+#include <grub/pc_partition.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/partition.h>
+
+static grub_err_t
+grub_cmd_activate (struct grub_arg_list *state __attribute__ ((unused)),
+		int argc, char **args)
+{
+
+  grub_device_t dev;
+  struct grub_pc_partition_mbr mbr;
+  grub_partition_t part;
+  
+  int i, index;
+
+  if (argc > 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "too many arguments");
+
+  if (!argc)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "too few arguments");
+
+  dev = grub_device_open (args[0]); 
+
+  if (!dev)
+    return grub_errno;
+
+  if (!dev->disk)
+    {
+      grub_device_close (dev);
+      return grub_error (GRUB_ERR_BAD_ARGUMENT, "not a disk");
+    }
+
+  if (!dev->disk->partition)
+    {
+      grub_device_close (dev);
+      return grub_error (GRUB_ERR_BAD_ARGUMENT, "not a partition");
+    }
+
+  if (grub_strcmp (dev->disk->partition->partmap->name, "pc_partition_map"))
+    {
+      grub_device_close (dev);
+      return grub_error (GRUB_ERR_BAD_ARGUMENT, "not a pc partition");
+    }
+
+  if (dev->disk->partition->offset)
+    {
+      grub_device_close (dev);
+      return grub_error (GRUB_ERR_BAD_ARGUMENT, "not a primary partition");
+    }
+
+  index = dev->disk->partition->index;
+  part = dev->disk->partition;
+  dev->disk->partition = 0;
+
+  /* Read the MBR.  */
+  if (grub_disk_read (dev->disk, 0, 0, sizeof (mbr), (char *) &mbr))
+    {
+      dev->disk->partition = part;
+      grub_device_close (dev);
+      return grub_errno;
+    }
+
+  for (i = 0; i < 4; i++)
+    mbr.entries[i].flag = 0x0;
+
+  mbr.entries[index].flag = 0x80;  
+
+   /* Write the MBR.  */
+  grub_disk_write (dev->disk, 0, 0, sizeof (mbr), (char *) &mbr);
+  dev->disk->partition = part;
+  grub_device_close (dev);
+  return grub_errno;
+  
+}
+
+GRUB_MOD_INIT
+{
+  (void)mod;			/* To stop warning. */
+  grub_register_command ("activate", grub_cmd_activate, GRUB_COMMAND_FLAG_BOTH,
+			 "activate PARTITION", "set active flag to PARTITION", 0);
+}
+
+GRUB_MOD_FINI
+{
+  grub_unregister_command ("activate");
+}
diff -urpN grub2um/commands/i386/pc/sendkey.c grub2m/commands/i386/pc/sendkey.c
--- grub2um/commands/i386/pc/sendkey.c	1970-01-01 01:00:00.000000000 +0100
+++ grub2m/commands/i386/pc/sendkey.c	2005-08-01 17:25:50.000000000 +0200
@@ -0,0 +1,394 @@
+/* keystroke.c - test module for dynamic loading */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2005  Free Software Foundation, Inc.
+ *  Copyright (C) 2005  Vladimir Serbinenko serbinenko.vova@bk.ru
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/normal.h>
+#include <grub/arg.h>
+#include <grub/env.h>
+
+#define RAW_ADDR(a) ((void *)(a))
+struct 
+keysym
+{
+  char *unshifted_name;			/* the name in unshifted state */
+  char *shifted_name;			/* the name in shifted state */
+  unsigned char unshifted_ascii;	/* the ascii code in unshifted state */
+  unsigned char shifted_ascii;		/* the ascii code in shifted state */
+  unsigned char keycode;		/* keyboard scancode */
+};
+
+/* The table for key symbols. If the "shifted" member of an entry is
+   NULL, the entry does not have shifted state. Copied from GRUB Legacy setkey fuction  */
+static struct keysym keysym_table[] =
+{
+  {"escape",		0,		0x1b,	0,	0x01},
+  {"1",			"exclam",	'1',	'!',	0x02},
+  {"2",			"at",		'2',	'@',	0x03},
+  {"3",			"numbersign",	'3',	'#',	0x04},
+  {"4",			"dollar",	'4',	'$',	0x05},
+  {"5",			"percent",	'5',	'%',	0x06},
+  {"6",			"caret",	'6',	'^',	0x07},
+  {"7",			"ampersand",	'7',	'&',	0x08},
+  {"8",			"asterisk",	'8',	'*',	0x09},
+  {"9",			"parenleft",	'9',	'(',	0x0a},
+  {"0",			"parenright",	'0',	')',	0x0b},
+  {"minus",		"underscore",	'-',	'_',	0x0c},
+  {"equal",		"plus",		'=',	'+',	0x0d},
+  {"backspace",		0,		'\b',	0,	0x0e},
+  {"tab",		0,		'\t',	0,	0x0f},
+  {"q",			"Q",		'q',	'Q',	0x10},
+  {"w",			"W",		'w',	'W',	0x11},
+  {"e",			"E",		'e',	'E',	0x12},
+  {"r",			"R",		'r',	'R',	0x13},
+  {"t",			"T",		't',	'T',	0x14},
+  {"y",			"Y",		'y',	'Y',	0x15},
+  {"u",			"U",		'u',	'U',	0x16},
+  {"i",			"I",		'i',	'I',	0x17},
+  {"o",			"O",		'o',	'O',	0x18},
+  {"p",			"P",		'p',	'P',	0x19},
+  {"bracketleft",	"braceleft",	'[',	'{',	0x1a},
+  {"bracketright",	"braceright",	']',	'}',	0x1b},
+  {"enter",		0,		'\r',	0,	0x1c},
+  {"control",		0,		0,	0,	0x1d},
+  {"a",			"A",		'a',	'A',	0x1e},
+  {"s",			"S",		's',	'S',	0x1f},
+  {"d",			"D",		'd',	'D',	0x20},
+  {"f",			"F",		'f',	'F',	0x21},
+  {"g",			"G",		'g',	'G',	0x22},
+  {"h",			"H",		'h',	'H',	0x23},
+  {"j",			"J",		'j',	'J',	0x24},
+  {"k",			"K",		'k',	'K',	0x25},
+  {"l",			"L",		'l',	'L',	0x26},
+  {"semicolon",		"colon",	';',	':',	0x27},
+  {"quote",		"doublequote",	'\'',	'"',	0x28},
+  {"backquote",		"tilde",	'`',	'~',	0x29},
+  {"shift",		0,		0,	0,	0x2a},
+  {"backslash",		"bar",		'\\',	'|',	0x2b},
+  {"z",			"Z",		'z',	'Z',	0x2c},
+  {"x",			"X",		'x',	'X',	0x2d},
+  {"c",			"C",		'c',	'C',	0x2e},
+  {"v",			"V",		'v',	'V',	0x2f},
+  {"b",			"B",		'b',	'B',	0x30},
+  {"n",			"N",		'n',	'N',	0x31},
+  {"m",			"M",		'm',	'M',	0x32},
+  {"comma",		"less",		',',	'<',	0x33},
+  {"period",		"greater",	'.',	'>',	0x34},
+  {"slash",		"question",	'/',	'?',	0x35},
+  {"rshift",		0,		0,	0,	0x36},
+  {"numasterisk",		0,		'*',	0,	0x37},
+  {"alt",		0,		0,	0,	0x38},
+  {"space",		0,		' ',	0,	0x39},
+  {"capslock",		0,		0,	0,	0x3a},
+  {"F1",		0,		0,	0,	0x3b},
+  {"F2",		0,		0,	0,	0x3c},
+  {"F3",		0,		0,	0,	0x3d},
+  {"F4",		0,		0,	0,	0x3e},
+  {"F5",		0,		0,	0,	0x3f},
+  {"F6",	 	0,		0,	0,	0x40},
+  {"F7",		0,		0,	0,	0x41},
+  {"F8",		0,		0,	0,	0x42},
+  {"F9",		0,		0,	0,	0x43},
+  {"F10",		0,		0,	0,	0x44},
+  {"num7",		"numhome",		'7',	0,	0x47},
+  {"num8",		"numup",		'8',	0,	0x48},
+  {"num9",		"numpgup",		'9',	0,	0x49},
+  {"numminus",		0,		'-',	0,	0x4a},
+  {"num4",		"numleft",		'4',	0,	0x4b},
+  {"num5",		"num5numlock",		'5',	0,	0x4c},
+  {"num6",		"numright",		'6',	0,	0x4d},
+  {"numplus",		0,		'-',	0,	0x4e},
+  {"num1",		"numend",		'1',	0,	0x4f},
+  {"num2",		"numdown",		'2',	0,	0x50},
+  {"num3",		"numpgdown",		'3',	0,	0x51},
+  {"num0",		"numinsert",		'0',	0,	0x52},
+  {"numperiod",	"numdelete", 0,	0x7f,		0x53},
+  {"F11",		0,		0,	0,	0x57},
+  {"F12",		0,		0,	0,	0x58},
+  {"numenter",		0,		'\r',	0,	0xe0},
+  {"numslash",		0,		'/',	0,	0xe0},
+  {"delete",		0,		0x7f,	0,	0xe0},
+  {"insert",		0,		0xe0,	0,	0x52},
+  {"home",		0,		0xe0,	0,	0x47},
+  {"end",		0,		0xe0,	0,	0x4f},
+  {"pgdown",		0,		0xe0,	0,	0x51},
+  {"pgup",		0,		0xe0,	0,	0x49},
+  {"down",		0,		0xe0,	0,	0x50},
+  {"up",		0,		0xe0,	0,	0x48},
+  {"left",		0,		0xe0,	0,	0x4b},
+  {"right",		0,		0xe0,	0,	0x4d}
+};
+
+/* Send a character VALUE to port PORT  */
+static void 
+outportb (char value, int port) {
+  asm volatile ("outb %%al,%%dx": :"a" (value),"d" (port));
+  return;
+}
+
+/* Read a byte from port PORT  */
+static unsigned char 
+inb (unsigned int port)
+{
+  unsigned char ret;
+  asm volatile ("inb %%dx,%%al":"=a" (ret):"d" (port));
+  return ret;
+
+}
+
+/* Set a simple flag in flags variable  
+   FLAGS - where to set,
+   OUTOFFSET - offset of flag in FLAGS,
+   OP - action id
+*/
+static void
+grub_sendkey_set_simple_flag (unsigned long *flags, int outoffset, int op)
+{
+  /* previous state of flag  */
+  int prevstat = (*flags >> outoffset) & 1;
+  /* new state */
+  int newstat = (op == 1) || (op == 2 && prevstat);
+  /* Set new state  */
+  *flags = (*flags & (~(1 << outoffset))) | (newstat << outoffset);
+}
+
+/* Set a double flag (ctrl/alt) in flags variable  
+   FLAGS - where to set,
+   OUTOFFSETR - offset of common flag in FLAGS,
+   OUTOFFSETL - offset of "left" flag in FLAGS,
+   OPR - operation for "right" flag,
+   OPL - operation for  "left" flag
+*/
+static void
+grub_sendkey_set_double_flag (unsigned long *flags, int outoffsetc, int outoffsetl, int opr, int opl)
+{
+  /* previous state of flag  */
+  int prevstatc = (*flags >> outoffsetc) & 1;
+  int prevstatl = (*flags >> outoffsetl) & 1;
+  int prevstatr = prevstatc && (!prevstatl);
+  /* new state */
+  int newstatl = (opl == 1) || (opl == 2 && prevstatl);
+  int newstatr = (opr == 1) || (opr == 2 && prevstatr);
+  int newstatc = newstatr || newstatr;
+  /* Set new state  */
+  *flags = (*flags & (~(1 << outoffsetl))) | (newstatl << outoffsetl);
+  *flags = (*flags & (~(1 << outoffsetc))) | (newstatc << outoffsetc);
+}
+
+static int
+grub_sendkey_parse_op (char *name)
+{
+  char *var;
+
+  var = grub_env_get (name);
+
+  if (!var)
+    return 2;
+
+  if (!grub_strcmp (var, "off") || !grub_strcmp (var, "0") || !grub_strcmp (var, "unpress"))
+    return 0;
+
+  if (!grub_strcmp (var, "on") || !grub_strcmp (var, "1") || !grub_strcmp (var, "press"))
+    return 1;
+
+  return 2;
+}
+
+/* Set keyboard buffer to our sendkey  */
+static void
+grub_sendkey_preboot (void)
+{
+
+  /* Length of sendkey  */
+  int keylen = 0;
+  char sendkey[0x20];
+  /* For convenion: pointer to flags  */
+  unsigned long *flags = (unsigned long *) RAW_ADDR (0x417);
+  char *next, ch, *sendkeyvar;
+  int noled = 0;
+
+  /* To stop warning  */ 
+  auto int find_key_code (char *key); 
+  auto int find_ascii_code (char *key);
+
+  auto int find_key_code (char *key)
+    {
+      unsigned i;
+
+      for (i = 0; i < sizeof (keysym_table) / sizeof (keysym_table[0]); i++)
+	{
+	  if (keysym_table[i].unshifted_name && grub_strcmp (key, keysym_table[i].unshifted_name) == 0)
+	    return keysym_table[i].keycode;
+	  else if (keysym_table[i].shifted_name && grub_strcmp (key, keysym_table[i].shifted_name) == 0)
+	    return keysym_table[i].keycode;
+	}
+
+      return 0;
+    }
+
+  auto int find_ascii_code (char *key)
+    {
+      unsigned i;
+
+      for (i = 0; i < sizeof (keysym_table) / sizeof (keysym_table[0]); i++)
+	{
+	  if (keysym_table[i].unshifted_name && grub_strcmp (key, keysym_table[i].unshifted_name) == 0)
+	    return keysym_table[i].unshifted_ascii;
+	  else if (keysym_table[i].shifted_name && grub_strcmp (key, keysym_table[i].shifted_name) == 0)
+	    return keysym_table[i].shifted_ascii;
+	}
+
+      return 0;
+    }
+
+  sendkeyvar = grub_env_get ("sendkey");
+
+  if (sendkeyvar)
+    do
+      {
+	next = grub_strchr (sendkeyvar, ' ');
+	if (next)
+	  {
+	    ch = *next;
+	    *next = 0;
+	  }
+	if (find_key_code (sendkeyvar))
+	  {
+	    sendkey[keylen++] = find_ascii_code (sendkeyvar);
+	    sendkey[keylen++] = find_key_code (sendkeyvar);
+	  }
+	if (next)
+	  {
+	    *next = ch;
+	    sendkeyvar = next + 1;
+	  }
+      }
+    while (next && keylen < 0x20);
+  
+  {
+    int i;
+    /* Set the sendkey  */
+    *((char *) RAW_ADDR (0x41a)) = 0x1e;
+    *((char *) RAW_ADDR (0x41c)) = keylen + 0x1e;
+    for(i = 0; i < 0x20; i++)
+      ((char *) RAW_ADDR (0x41e))[i] = sendkey[i];
+  }
+
+  /* Set the flags. For more information reffer to technical specification*/
+  grub_sendkey_set_simple_flag (flags,  5, grub_sendkey_parse_op("kb_num")); // numlock mode
+  grub_sendkey_set_simple_flag (flags,  6, grub_sendkey_parse_op("kb_caps")); // capslock mode
+  grub_sendkey_set_simple_flag (flags,  4, grub_sendkey_parse_op("kb_scroll")); // scrolllock mode
+  grub_sendkey_set_simple_flag (flags,  7, grub_sendkey_parse_op("kb_insert")); // insert mode
+  grub_sendkey_set_simple_flag (flags, 11, grub_sendkey_parse_op("kb_wait")); // wait mode
+  grub_sendkey_set_simple_flag (flags,  1, grub_sendkey_parse_op("kb_lshift")); // left shift
+  grub_sendkey_set_simple_flag (flags,  0, grub_sendkey_parse_op("kb_rshift")); // right shift
+  grub_sendkey_set_simple_flag (flags, 10, grub_sendkey_parse_op("kb_sysreq")); // sysreq
+  grub_sendkey_set_simple_flag (flags, 13, grub_sendkey_parse_op("kb_numkey")); // numlock key
+  grub_sendkey_set_simple_flag (flags, 14, grub_sendkey_parse_op("kb_capskey")); // capslock key
+  grub_sendkey_set_simple_flag (flags, 12, grub_sendkey_parse_op("kb_scrollkey")); // scrolllock key
+  grub_sendkey_set_simple_flag (flags, 15, grub_sendkey_parse_op("kb_insertkey")); // insert key
+
+  /*Set ctrl and alt*/
+  grub_sendkey_set_double_flag (flags, 2, 8, grub_sendkey_parse_op("kb_rctrl"), grub_sendkey_parse_op("kb_lctrl")); //Ctrl
+  grub_sendkey_set_double_flag (flags, 3, 9, grub_sendkey_parse_op("kb_ralt"),  grub_sendkey_parse_op("kb_lalt")); //Alt
+
+
+  /* Set noled */
+  {
+    char *var;
+
+    /* set 1 if set explicitely  */
+    if ((var = grub_env_get ("kb_noled")) && grub_strcmp (var, "0"))
+      noled = 1;
+    
+    /* implicit: when LEDs haven't changed  */
+    if (!var && grub_sendkey_parse_op("kb_num") == 2 && grub_sendkey_parse_op("kb_caps") == 2
+	&& grub_sendkey_parse_op("kb_scroll") == 2)
+      noled = 1;
+  }
+
+  /* Write new LED state  */
+  if (!noled)
+    {
+      int value = 0;
+      int failed;
+      /* Try 5 times  */
+      for (failed = 0; failed < 5; failed++)
+	{
+	  value = 0;
+	  /* Send command change LEDs  */
+	  outportb (0xed, 0x60);
+
+	  /* Wait */
+	  while ((value != 0xfa) && (value != 0xfe))
+	    value = inb (0x60);
+
+	  if (value == 0xfa)
+	    {
+	      /* Set new LEDs*/
+	      outportb ((flags[0] >> 4) & 7, 0x60);
+	      break;
+	    }
+	}
+    }
+
+}
+
+GRUB_MOD_INIT
+{
+  (void)mod;			/* To stop warning. */
+  unsigned i;
+  /* List of variables to set to "keep"  */
+  char list[16][12] = 
+    {
+      "kb_num", "kb_caps", "kb_scroll", "kb_insert", "kb_wait", "kb_lshift", "kb_rshift", "kb_sysreq", 
+      "kb_numkey", "kb_capskey", "kb_scrollkey", "kb_insertkey", "kb_lalt", "kb_ralt", "kb_lctrl", "kb_rctrl"
+    };
+
+  grub_env_set ("sendkey", "");
+  grub_env_set ("kb_noled", "0");
+
+  for (i = 0; i < sizeof (list) / sizeof (list[0]); i++)
+    grub_env_set (list[i], "keep");
+
+  grub_preboot_add (grub_sendkey_preboot);
+}
+
+GRUB_MOD_FINI
+{
+
+  unsigned i;
+  /* List of variables to unset  */
+  char list[19][12] = 
+    {
+      "kb_num", "kb_caps", "kb_scroll", "kb_insert", "kb_wait", "kb_lshift", "kb_rshift", "kb_sysreq", 
+      "kb_numkey", "kb_capskey", "kb_scrollkey", "kb_insertkey", "kb_lalt", "kb_ralt", "kb_lctrl", "kb_rctrl",
+      "sendkey", "kb_noled"
+    };
+
+  for (i = 0; i < sizeof (list) / sizeof (list[0]); i++)
+    grub_env_unset (list[i]);  
+  
+  grub_preboot_remove (grub_sendkey_preboot);
+}
diff -urpN grub2um/conf/i386-pc.mk grub2m/conf/i386-pc.mk
--- grub2um/conf/i386-pc.mk	2005-07-25 15:23:26.000000000 +0200
+++ grub2m/conf/i386-pc.mk	2005-08-01 18:56:23.000000000 +0200
@@ -989,7 +989,8 @@ pkgdata_MODULES = _chain.mod _linux.mod 
 	font.mod _multiboot.mod ls.mod boot.mod cmp.mod cat.mod		\
 	terminal.mod fshelp.mod chain.mod multiboot.mod amiga.mod	\
 	apple.mod pc.mod sun.mod loopback.mod reboot.mod halt.mod	\
-	help.mod default.mod timeout.mod configfile.mod
+	help.mod default.mod timeout.mod configfile.mod sendkey.mod     \
+	activate.mod
 
 # For _chain.mod.
 _chain_mod_SOURCES = loader/i386/pc/chainloader.c
@@ -1781,6 +1782,106 @@ fs-hello.lst: hello/hello.c genfslist.sh
 
 hello_mod_CFLAGS = $(COMMON_CFLAGS)
 
+# For sendkey.mod.
+sendkey_mod_SOURCES = commands/i386/pc/sendkey.c
+CLEANFILES += sendkey.mod mod-sendkey.o mod-sendkey.c pre-sendkey.o sendkey_mod-commands_i386_pc_sendkey.o def-sendkey.lst und-sendkey.lst
+MOSTLYCLEANFILES += sendkey_mod-commands_i386_pc_sendkey.d
+DEFSYMFILES += def-sendkey.lst
+UNDSYMFILES += und-sendkey.lst
+
+sendkey.mod: pre-sendkey.o mod-sendkey.o
+	-rm -f $@
+	$(LD) -r -d -o $@ $^
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment $@
+
+pre-sendkey.o: sendkey_mod-commands_i386_pc_sendkey.o
+	-rm -f $@
+	$(LD) -r -d -o $@ $^
+
+mod-sendkey.o: mod-sendkey.c
+	$(CC) $(CPPFLAGS) $(CFLAGS) $(sendkey_mod_CFLAGS) -c -o $@ $<
+
+mod-sendkey.c: moddep.lst genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'sendkey' $< > $@ || (rm -f $@; exit 1)
+
+def-sendkey.lst: pre-sendkey.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 sendkey/' > $@
+
+und-sendkey.lst: pre-sendkey.o
+	echo 'sendkey' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+sendkey_mod-commands_i386_pc_sendkey.o: commands/i386/pc/sendkey.c
+	$(CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(CPPFLAGS) $(CFLAGS) $(sendkey_mod_CFLAGS) -c -o $@ $<
+
+sendkey_mod-commands_i386_pc_sendkey.d: commands/i386/pc/sendkey.c
+	set -e; 	  $(CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(CPPFLAGS) $(CFLAGS) $(sendkey_mod_CFLAGS) -M $< 	  | sed 's,sendkey\.o[ :]*,sendkey_mod-commands_i386_pc_sendkey.o $@ : ,g' > $@; 	  [ -s $@ ] || rm -f $@
+
+-include sendkey_mod-commands_i386_pc_sendkey.d
+
+CLEANFILES += cmd-sendkey.lst fs-sendkey.lst
+COMMANDFILES += cmd-sendkey.lst
+FSFILES += fs-sendkey.lst
+
+cmd-sendkey.lst: commands/i386/pc/sendkey.c gencmdlist.sh
+	set -e; 	  $(CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(CPPFLAGS) $(CFLAGS) $(sendkey_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh sendkey > $@ || (rm -f $@; exit 1)
+
+fs-sendkey.lst: commands/i386/pc/sendkey.c genfslist.sh
+	set -e; 	  $(CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(CPPFLAGS) $(CFLAGS) $(sendkey_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh sendkey > $@ || (rm -f $@; exit 1)
+
+
+sendkey_mod_CFLAGS = $(COMMON_CFLAGS)
+
+# For activate.mod.
+activate_mod_SOURCES = commands/i386/pc/activate.c
+CLEANFILES += activate.mod mod-activate.o mod-activate.c pre-activate.o activate_mod-commands_i386_pc_activate.o def-activate.lst und-activate.lst
+MOSTLYCLEANFILES += activate_mod-commands_i386_pc_activate.d
+DEFSYMFILES += def-activate.lst
+UNDSYMFILES += und-activate.lst
+
+activate.mod: pre-activate.o mod-activate.o
+	-rm -f $@
+	$(LD) -r -d -o $@ $^
+	$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment $@
+
+pre-activate.o: activate_mod-commands_i386_pc_activate.o
+	-rm -f $@
+	$(LD) -r -d -o $@ $^
+
+mod-activate.o: mod-activate.c
+	$(CC) $(CPPFLAGS) $(CFLAGS) $(activate_mod_CFLAGS) -c -o $@ $<
+
+mod-activate.c: moddep.lst genmodsrc.sh
+	sh $(srcdir)/genmodsrc.sh 'activate' $< > $@ || (rm -f $@; exit 1)
+
+def-activate.lst: pre-activate.o
+	$(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 activate/' > $@
+
+und-activate.lst: pre-activate.o
+	echo 'activate' > $@
+	$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+activate_mod-commands_i386_pc_activate.o: commands/i386/pc/activate.c
+	$(CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(CPPFLAGS) $(CFLAGS) $(activate_mod_CFLAGS) -c -o $@ $<
+
+activate_mod-commands_i386_pc_activate.d: commands/i386/pc/activate.c
+	set -e; 	  $(CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(CPPFLAGS) $(CFLAGS) $(activate_mod_CFLAGS) -M $< 	  | sed 's,activate\.o[ :]*,activate_mod-commands_i386_pc_activate.o $@ : ,g' > $@; 	  [ -s $@ ] || rm -f $@
+
+-include activate_mod-commands_i386_pc_activate.d
+
+CLEANFILES += cmd-activate.lst fs-activate.lst
+COMMANDFILES += cmd-activate.lst
+FSFILES += fs-activate.lst
+
+cmd-activate.lst: commands/i386/pc/activate.c gencmdlist.sh
+	set -e; 	  $(CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(CPPFLAGS) $(CFLAGS) $(activate_mod_CFLAGS) -E $< 	  | sh $(srcdir)/gencmdlist.sh activate > $@ || (rm -f $@; exit 1)
+
+fs-activate.lst: commands/i386/pc/activate.c genfslist.sh
+	set -e; 	  $(CC) -Icommands/i386/pc -I$(srcdir)/commands/i386/pc $(CPPFLAGS) $(CFLAGS) $(activate_mod_CFLAGS) -E $< 	  | sh $(srcdir)/genfslist.sh activate > $@ || (rm -f $@; exit 1)
+
+
+activate_mod_CFLAGS = $(COMMON_CFLAGS)
+
 # For boot.mod.
 boot_mod_SOURCES = commands/boot.c
 CLEANFILES += boot.mod mod-boot.o mod-boot.c pre-boot.o boot_mod-commands_boot.o def-boot.lst und-boot.lst
diff -urpN grub2um/conf/i386-pc.rmk grub2m/conf/i386-pc.rmk
--- grub2um/conf/i386-pc.rmk	2005-07-25 15:23:26.000000000 +0200
+++ grub2m/conf/i386-pc.rmk	2005-08-01 18:56:16.000000000 +0200
@@ -102,7 +102,8 @@ pkgdata_MODULES = _chain.mod _linux.mod 
 	font.mod _multiboot.mod ls.mod boot.mod cmp.mod cat.mod		\
 	terminal.mod fshelp.mod chain.mod multiboot.mod amiga.mod	\
 	apple.mod pc.mod sun.mod loopback.mod reboot.mod halt.mod	\
-	help.mod default.mod timeout.mod configfile.mod
+	help.mod default.mod timeout.mod configfile.mod sendkey.mod     \
+	activate.mod
 
 # For _chain.mod.
 _chain_mod_SOURCES = loader/i386/pc/chainloader.c
@@ -163,6 +164,14 @@ normal_mod_ASFLAGS = $(COMMON_ASFLAGS)
 hello_mod_SOURCES = hello/hello.c
 hello_mod_CFLAGS = $(COMMON_CFLAGS)
 
+# For sendkey.mod.
+sendkey_mod_SOURCES = commands/i386/pc/sendkey.c
+sendkey_mod_CFLAGS = $(COMMON_CFLAGS)
+
+# For activate.mod.
+activate_mod_SOURCES = commands/i386/pc/activate.c
+activate_mod_CFLAGS = $(COMMON_CFLAGS)
+
 # For boot.mod.
 boot_mod_SOURCES = commands/boot.c
 boot_mod_CFLAGS = $(COMMON_CFLAGS)
diff -urpN grub2um/include/grub/normal.h grub2m/include/grub/normal.h
--- grub2um/include/grub/normal.h	2005-07-25 15:23:26.000000000 +0200
+++ grub2m/include/grub/normal.h	2005-07-25 15:25:29.000000000 +0200
@@ -44,6 +44,9 @@
 /* Not loaded yet. Used for auto-loading.  */
 #define GRUB_COMMAND_FLAG_NOT_LOADED	0x20
 
+/* Preboot function declaration.  */
+typedef void (*grub_prebootfn_t) (void); 
+
 /* The command description.  */
 struct grub_command
 {
@@ -178,6 +181,8 @@ grub_context_t grub_context_get (void);
 grub_menu_t grub_context_get_current_menu (void);
 grub_menu_t grub_context_push_menu (grub_menu_t menu);
 void grub_context_pop_menu (void);
+grub_err_t grub_preboot_add (grub_prebootfn_t fn);
+grub_err_t grub_preboot_remove (grub_prebootfn_t fn);
 
 #ifdef GRUB_UTIL
 void grub_normal_init (void);
diff -urpN grub2um/kern/misc.c grub2m/kern/misc.c
--- grub2um/kern/misc.c	2005-07-25 15:23:26.000000000 +0200
+++ grub2m/kern/misc.c	2005-08-01 19:01:39.000000000 +0200
@@ -911,41 +911,6 @@ grub_split_cmdline (const char *cmdline,
       do {
 	switch (c)
 	  {
-	  case '"':
-	    /* Double quote.  */
-	    while ((c = getchar ()))
-	      {
-		if (grub_errno)
-		  return 1;
-		/* Read in an escaped character.  */
-		if (c == '\\')
-		  {
-		    c = getchar ();
-		    *(bp++) = c;
-		    continue;
-		  }
-		else if (c == '"')
-		  break;
-		/* Read a variable.  */
-		if (c == '$')
-		  {
-		    getenvvar ();
-		    continue;
-		  }
-		*(bp++) = c;
-	      }
-	    break;
-
-	  case '\'':
-	    /* Single quote.  */
-	    while ((c = getchar ()) != '\'')
-	      {
-		if (grub_errno)
-		  return 1;
-
-		*(bp++) = c;
-	      }
-	    break;
 
 	  case '\n':
 	    /* This was not a argument afterall.  */
@@ -971,7 +936,43 @@ grub_split_cmdline (const char *cmdline,
 		    c = getchar ();
 		    continue;
 		  }
-		*(bp++) = c;
+
+		if (c == '\'')
+		  /* Single quote.  */
+		  while ((c = getchar ()) != '\'')
+		    {
+		      if (grub_errno)
+			return 1;
+
+		      *(bp++) = c;
+		    }
+
+		if (c == '"')
+		  /* Double quote.  */
+		  while ((c = getchar ()))
+		    {
+		      if (grub_errno)
+			return 1;
+		      /* Read in an escaped character.  */
+		      if (c == '\\')
+			{
+			  c = getchar ();
+			  *(bp++) = c;
+			  continue;
+			}
+		      else if (c == '"')
+			break;
+		      /* Read a variable.  */
+		      if (c == '$')
+			{
+			  getenvvar ();
+			  continue;
+			}
+		      *(bp++) = c;
+		    }
+
+		if (c != '"' && c != '\'')
+		  *(bp++) = c;
 		c = getchar ();
 	      }
 	    unputc (c);


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2005-08-01 19:16 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-08-01 18:38 Sendkey, activate, bash Vladimir Serbinenko

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.