grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Sendkey, activate, bash


From: Vladimir Serbinenko
Subject: Sendkey, activate, bash
Date: Mon, 01 Aug 2005 20:38:41 +0200
User-agent: Mozilla Thunderbird 1.0.2-1.3.2 (X11/20050324)

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 <address@hidden>

    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



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 <address@hidden>
+
+       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  <address@hidden>
 
        * 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
 
 
 
+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;
+}
+
+
+
+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;
+
+}
+
+
+
 #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 <address@hidden>
+ *
+ *  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 address@hidden
+ *
+ *  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);


reply via email to

[Prev in Thread] Current Thread [Next in Thread]