I am trying to work on an x86 operating system and coding it in C. My OS uses GRUB-Multiboot and thus far I have been able to get a GDT working.
I am currently working on my IDT and have run into a problem. When my OS boots up, it receives one IRQ and no further ones. I do have the keyboard line enabled and I should be receiving IRQs from that whenever I click a key but this is not the case.
What comes up upon startup:
Here is the code for idt.c:
#include <stdint.h>
#include "idt.h"
#include "lib/stdio.h"
#include "include/io.h"
// Define the Interrupt Descriptor Table (IDT)
struct idt_entry_t idt[IDT_ENTRIES];
struct idt_entry_t idt_entries[IDT_ENTRIES];
// Load the IDT pointer
struct idt_ptr_t idt_ptr = {
.limit = sizeof(idt) - 1,
.base = (uint32_t)&idt
};
typedef struct registers {
uint32_t ds; // Data segment selector
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha
uint32_t int_no, err_code; // Interrupt number and error code (if applicable)
uint32_t eip, cs, eflags, useresp, ss; // Pushed by the processor automatically
} registers_t;
// Define an IRQ handler function
void irq_handler(registers_t *regs)
{
nanos_printf("Received an IRQ!\n");
// Send an EOI (end-of-interrupt) signal to the PICs
outb(0xA0, 0x20); // Send reset signal to slave
outb(0x20, 0x20); // Send reset signal to master
return;
}
void isr_handler()
{
nanos_printf("\n\nSTOP\n\nException occurred... halting...");
// Halt the CPU
for (;;);
}
void idt_load()
{
asm volatile("lidt %0" : : "m"(idt_ptr));
}
void idt_init(void)
{
// Disable interrupts
__asm__ __volatile__("cli");
// Setup the PIC(s)
outb(0x20, 0x11);
outb(0xA0, 0x11);
outb(0x21, 0x20);
outb(0xA1, 0x28);
outb(0x21, 0x04);
outb(0x21, 0x01);
outb(0x21, 0xFB);
outb(0xA1, 0xFF);
// Print a message to indicate that IDT is being loaded
nanos_printf("Loading IDT\n");
// Initialize the IDT pointer
idt_ptr.limit = sizeof(idt) - 1;
idt_ptr.base = (uint32_t)&idt;
// Set each IDT entry to the default handler
for (int i = 0; i < IDT_ENTRIES; i++)
{
idt_set_gate(i, (uint32_t)isr_handler, 0x08, 0x8E);
}
// Set the IRQ entries in the IDT
idt_set_gate(32, (uint32_t)irq_handler, 0x08, 0x8E);
idt_set_gate(33, (uint32_t)irq_handler, 0x08, 0x8E);
idt_set_gate(34, (uint32_t)irq_handler, 0x08, 0x8E);
idt_set_gate(35, (uint32_t)irq_handler, 0x08, 0x8E);
idt_set_gate(36, (uint32_t)irq_handler, 0x08, 0x8E);
idt_set_gate(37, (uint32_t)irq_handler, 0x08, 0x8E);
idt_set_gate(38, (uint32_t)irq_handler, 0x08, 0x8E);
idt_set_gate(39, (uint32_t)irq_handler, 0x08, 0x8E);
idt_set_gate(40, (uint32_t)irq_handler, 0x08, 0x8E);
idt_set_gate(41, (uint32_t)irq_handler, 0x08, 0x8E);
idt_set_gate(42, (uint32_t)irq_handler, 0x08, 0x8E);
idt_set_gate(43, (uint32_t)irq_handler, 0x08, 0x8E);
idt_set_gate(44, (uint32_t)irq_handler, 0x08, 0x8E);
idt_set_gate(45, (uint32_t)irq_handler, 0x08, 0x8E);
// Send initialization control word 1 and 2 to both PICs
outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); // Initialization Control Word 1
io_wait();
outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4);
io_wait();
// Send initialization control word 3 to both PICs
outb(PIC1_DATA, 0x20); // Initialization Control Word 3: IRQ 0-7 map to IDT entries 0x20-0x27
io_wait();
outb(PIC2_DATA, 0x28); // Initialization Control Word 3: IRQ 8-15 map to IDT entries 0x28-0x2F
io_wait();
// Send initialization control word 4 to both PICs
outb(PIC1_DATA, ICW4_8086);
io_wait();
outb(PIC2_DATA, ICW4_8086);
io_wait();
// Unmask IRQs
outb(PIC1_DATA, 0x0);
outb(PIC2_DATA, 0x0);
// Load IDT
idt_load();
// Enable interrupts
__asm__ __volatile__("sti");
nanos_printf("IDT loaded\n");
}
void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags)
{
// Set the base address
idt[num].base_lo = base & 0xFFFF;
idt[num].base_hi = (base >> 16) & 0xFFFF;
// Set the selector
idt[num].sel = sel;
// Set the always0 field
idt[num].always0 = 0;
// Set the flags
idt[num].flags = flags;
}
And here is idt.h:
#ifndef IDT_H
#define IDT_H
#include <stdint.h>
// Number of entries in the IDT
#define IDT_ENTRIES 256
// Struct for IDT entry
struct idt_entry_t {
uint16_t base_lo; // Lower 16 bits of handler function address
uint16_t sel; // Kernel segment selector
uint8_t always0; // Must always be zero
uint8_t flags; // Flags for entry (present, privilege level, type)
uint16_t base_hi; // Upper 16 bits of handler function address
} __attribute__((packed));
// Struct for IDT pointer
struct idt_ptr_t {
uint16_t limit; // Size of IDT
uint32_t base; // Base address of IDT
} __attribute__((packed));
// Define macros for setting flags in IDT entries
#define IDT_PRESENT_BIT 0x80
#define IDT_RING0 0x00
#define IDT_RING3 0x60
#define IDT_INT_GATE 0x0E
#define IDT_TRAP_GATE 0x0F
#define IDT_SIZE 0x08
// Define an IRQ handler function
void irq_handler();
// Define an ISR handler function
void isr_handler();
// Define a function to load the IDT
void idt_load();
// Define a function to initialize the IDT
void idt_init(void);
// Define a function to set a gate in the IDT
void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags);
#endif // IDT_H
The issue seems to lie within the IRQ handler itself not returning. I do send reset signals to both the master and slave PIC inside of irq_handler() which is inside of idt.c.
And yes, I do have an infinite loop at the end of my kernel_main():
void kernel_main(void)
{
clear_screen();
nanos_printf("Hello NanOS!\n");
gdt_init();
nanos_printf("Initialized Global Descriptor Table.\n");
idt_init();
nanos_printf("Initialized Interrupt Descriptor Table.\n");
while (true) {}
}
Problem:
I tried to click keys on the keyboard to receive a keyboard IRQ but I only receive one IRQ at the start. I dabbled in OSDEV a few years back and from what I remember the PICs receive more than one IRQ upon startup anyways.
I am having problems with calculating CRC-16 implementation of a byte array in java. Basically I am trying to send bytes to a RFID that starts writing to a tag. I can see the checksum value of array by looking tcpdump command on mac. But my goal is to generate it by myself. Here is my byte array which should generate 0xbe,0xd9:
byte[] bytes = new byte[]{(byte) 0x55,(byte) 0x08,(byte) 0x68, (byte) 0x14,
(byte) 0x93, (byte) 0x01, (byte) 0x00, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x06,
(byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00,
(byte) 0x13, (byte) 0x50, (byte) 0x00, (byte) 0x00,
(byte) 0x00, (byte) 0x22, (byte) 0x09, (byte) 0x11};
0x55 is the header. As the documentation says it will be excluded.
Whenever I try this array on java (with 0xbe,0xd9), RFID works. My problem is the generating of those checksum values. I searched almost entire web but no chance. I couldn't find any algorithm that produces 0xbe,0xd9.
Any idea is most welcome for me. Thanks in advance.
edit: here is the protocol that provided with rfid
I'm not really sure if this is the correct translation in Java of the C crc16 algorithm....
but it shows the correct result for your example!
Please compare other results with Mac's CRC16 and stress-test it before using it.
public class Crc16 {
public static void main(String... a) {
byte[] bytes = new byte[] { (byte) 0x08, (byte) 0x68, (byte) 0x14, (byte) 0x93, (byte) 0x01, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x01,
(byte) 0x00, (byte) 0x13, (byte) 0x50, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x22, (byte) 0x09,
(byte) 0x11 };
byte[] byteStr = new byte[4];
Integer crcRes = new Crc16().calculate_crc(bytes);
System.out.println(Integer.toHexString(crcRes));
byteStr[0] = (byte) ((crcRes & 0x000000ff));
byteStr[1] = (byte) ((crcRes & 0x0000ff00) >>> 8);
System.out.printf("%02X\n%02X", byteStr[0],byteStr[1]);
}
int calculate_crc(byte[] bytes) {
int i;
int crc_value = 0;
for (int len = 0; len < bytes.length; len++) {
for (i = 0x80; i != 0; i >>= 1) {
if ((crc_value & 0x8000) != 0) {
crc_value = (crc_value << 1) ^ 0x8005;
} else {
crc_value = crc_value << 1;
}
if ((bytes[len] & i) != 0) {
crc_value ^= 0x8005;
}
}
}
return crc_value;
}
}
There is a CRC16 implementation in the Java runtime (rt.jar) already.
Please see grepcode for the source.
You will probably be able to see it in your IDE if you search for CRC16:
Maybe are you looking for this?
Crc16 in java
I use the same array (variable "table") in this method:
public Integer computeCrc16(byte[] data) {
int crc = 0x0000;
for (byte b : data) {
crc = (crc >>> 8) ^ table[((crc ^ b) & 0xff)];
}
return (int) crc;
}
if you want ASCII character then change
byte[] bytes="02303131313233343031303345303903".getBytes();
Below is correct answer for HEX input ,
byte[] bytes = hexStringToByteArray("02303131313233343031303345303903");
public class CRC16 {
public static void main(String[] args) {
int[] table = {
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040,
};
byte[] bytes = hexStringToByteArray("02303131313233343031303345303903"); // for HEX
int crc16 = 0x0000;
for (byte b : bytes) {
crc16=table[(crc16 ^ b) & 0xff] ^ (crc16 >> 8);
}
crc16= crc16 & 0xFFFF;
System.out.println("CRC16 = " +Integer.toHexString(crc16));
}
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
}
I'm currently trying out the Git HEAD version of Emacs 24 on OS/X as described in this article:
http://www.viget.com/extend/emacs-24-rails-development-environment-from-scratch-to-productive-in-5-minu/
I'd like to bind some of the Macintosh extended keyboard numeric keypad keys to Emacs functions, but it doesn't seem to be working. When I do a "c-h k" to check the key details the key presses are not recognized. Ditto if I refer to them in a (global-set-key (kbd "kp-minus") ...) setting.
Is this an issue with using the development version of Emacs 24 or is it something about the Macintosh keyboard hardware and how Emacs sees it? Can anyone advise on the best way to go about this?
Thanks in advance,
Stu
I had the same issue with the keypad keys building emacs 24. The problem is the same with emacs 23. I patched the emacs 24 code as follows to correct the problem. Not sure this is a good solution but it works well enough for me.
index 91f0cbb..d537ee3 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
## -87,6 +87,7 ## static unsigned convert_ns_to_X_keysym[] =
NSBeginFunctionKey, 0x58,
NSSelectFunctionKey, 0x60,
NSPrintFunctionKey, 0x61,
+ NSClearLineFunctionKey, 0x0B,
NSExecuteFunctionKey, 0x62,
NSInsertFunctionKey, 0x63,
NSUndoFunctionKey, 0x65,
## -134,6 +135,35 ## static unsigned convert_ns_to_X_keysym[] =
0x1B, 0x1B /* escape */
};
+static unsigned convert_nskeypad_to_X_keysym[] =
+{
+ /* Arrow keys are both function and keypad keys */
+ NSLeftArrowFunctionKey, 0x51,
+ NSUpArrowFunctionKey, 0x52,
+ NSRightArrowFunctionKey, 0x53,
+ NSDownArrowFunctionKey, 0x54,
+
+ 0x41, 0xAE, /* KP_Decimal */
+ 0x43, 0xAA, /* KP_Multiply */
+ 0x45, 0xAB, /* KP_Add */
+ 0x4B, 0xAF, /* KP_Divide */
+ 0x4E, 0xAD, /* KP_Subtract */
+ 0x51, 0xBD, /* KP_Equal */
+ 0x52, 0xB0, /* KP_0 */
+ 0x53, 0xB1, /* KP_1 */
+ 0x54, 0xB2, /* KP_2 */
+ 0x55, 0xB3, /* KP_3 */
+ 0x56, 0xB4, /* KP_4 */
+ 0x57, 0xB5, /* KP_5 */
+ 0x58, 0xB6, /* KP_6 */
+ 0x59, 0xB7, /* KP_7 */
+ 0x5B, 0xB8, /* KP_8 */
+ 0x5C, 0xB9, /* KP_9 */
+
+ // The enter key is on the keypad but modifier isnt set
+ NSEnterCharacter, 0x8D
+};
+
static Lisp_Object Qmodifier_value;
Lisp_Object Qalt, Qcontrol, Qhyper, Qmeta, Qsuper, Qnone;
## -1924,13 +1954,33 ## ns_convert_key (unsigned code)
unsigned keysym;
/* An array would be faster, but less easy to read. */
for (keysym = 0; keysym < last_keysym; keysym += 2)
- if (code == convert_ns_to_X_keysym[keysym])
- return 0xFF00 | convert_ns_to_X_keysym[keysym+1];
+
+ if (code == convert_ns_to_X_keysym[keysym]) {
+ return 0xFF00 | convert_ns_to_X_keysym[keysym+1];
+ }
return 0;
/* if decide to use keyCode and Carbon table, use this line:
return code > 0xff ? 0 : 0xFF00 | ns_keycode_to_xkeysym_table[code]; */
}
+static unsigned
+ns_convert_keypad (unsigned code)
+/* --------------------------------------------------------------------------
+ Internal call used by NSView-keyDown.
+ -------------------------------------------------------------------------- */
+{
+ const unsigned last_keysym = (sizeof (convert_nskeypad_to_X_keysym)
+ / sizeof (convert_nskeypad_to_X_keysym[0]));
+ unsigned keysym;
+ /* An array would be faster, but less easy to read. */
+ for (keysym = 0; keysym < last_keysym; keysym += 2) {
+ if (code == convert_nskeypad_to_X_keysym[keysym]) {
+ return 0xFF00 | convert_nskeypad_to_X_keysym[keysym+1];
+ }
+ }
+ return 0;
+}
+
char *
x_get_keysym_name (int keysym)
## -4503,10 +4553,10 ## ns_term_shutdown (int sig)
Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (emacsframe);
int code;
unsigned fnKeysym = 0;
- int flags;
static NSMutableArray *nsEvArray;
static BOOL firstTime = YES;
int left_is_none;
+ unsigned int flags = [theEvent modifierFlags];
NSTRACE (keyDown);
## -4550,9 +4600,13 ## ns_term_shutdown (int sig)
code = ([[theEvent charactersIgnoringModifiers] length] == 0) ?
0 : [[theEvent charactersIgnoringModifiers] characterAtIndex: 0];
/* (Carbon way: [theEvent keyCode]) */
+
/* is it a "function key"? */
- fnKeysym = ns_convert_key (code);
+ if (code < 0x00ff && (flags & NSNumericPadKeyMask) )
+ fnKeysym = ns_convert_keypad([theEvent keyCode]);
+ else
+ fnKeysym = ns_convert_key(code);
if (fnKeysym)
{
/* COUNTERHACK: map 'Delete' on upper-right main KB to 'Backspace',
## -4565,7 +4619,6 ## ns_term_shutdown (int sig)
/* are there modifiers? */
emacs_event->modifiers = 0;
- flags = [theEvent modifierFlags];
if (flags & NSHelpKeyMask)
emacs_event->modifiers |= hyper_modifier;
I tried this with an older Emacs:
This is GNU Emacs 22.2.1 (powerpc-apple-darwin9.5.0, GTK+ Version 2.10.13)
Built from the ports collection with +gtk +x11 and used with the X11 server XQuartz 2.1.6 (xorg-server 1.4.2-apple33), when I look with C-h lI get
<kp-0> ... <kp-9>
for the numbers. and
<kp-enter> <kp-subtract> <kp-multiply> <kp-divide> <kp-equal>
For the other keys.
I'd suggest to build the latest Emacs from MacPorts with the options +gtk and +x11.
Then I'd get the latest XQuartz and run Emacs over X11 (I prefer this to the more native builds because then Emacs always behaves the same regardless if it runs remotely on another OS (usually via ssh -Y) or locally.
I'll upgrade my ports to the latest Emacs next week and add the result for these also.
The problem is exclusive to the Cocoa variant of emacs. The problem did not exist in the Carbon version, which is emacs22. I updated the patch I posted above, which now works better. It will likely work with the Emacs23 code base using XCode 3. If you are using XCode 4, like me you will need to use the Emacs24 code base which is currently only available in the GIT repository. Here is a very nice description on building Emacs24 via XCode 4
[http://mikbe.tk/2011/04/18/build-emacs-with-xcode-4/][1]
Here's an Emacs 23.3 translation of the Emacs 24 patch M. D. Marchionna's posted on this page.
--- nsterm-orig.m 2011-11-13 17:51:47.000000000 -0500
+++ nsterm.m 2011-11-13 17:39:56.000000000 -0500
## -87,6 +87,7 ##
NSBeginFunctionKey, 0x58,
NSSelectFunctionKey, 0x60,
NSPrintFunctionKey, 0x61,
+ NSClearLineFunctionKey, 0x0B,
NSExecuteFunctionKey, 0x62,
NSInsertFunctionKey, 0x63,
NSUndoFunctionKey, 0x65,
## -134,6 +135,33 ##
0x1B, 0x1B /* escape */
};
+static unsigned convert_nskeypad_to_X_keysym[] =
+{
+ /* Arrow keys are both function and keypad keys */
+ NSLeftArrowFunctionKey, 0x51,
+ NSUpArrowFunctionKey, 0x52,
+ NSRightArrowFunctionKey, 0x53,
+ NSDownArrowFunctionKey, 0x54,
+
+ 0x41, 0xAE, /* KP_Decimal */
+ 0x43, 0xAA, /* KP_Multiply */
+ 0x45, 0xAB, /* KP_Add */
+ 0x4B, 0xAF, /* KP_Divide */
+ 0x4E, 0xAD, /* KP_Subtract */
+ 0x51, 0xBD, /* KP_Equal */
+ 0x52, 0xB0, /* KP_0 */
+ 0x53, 0xB1, /* KP_1 */
+ 0x54, 0xB2, /* KP_2 */
+ 0x55, 0xB3, /* KP_3 */
+ 0x56, 0xB4, /* KP_4 */
+ 0x57, 0xB5, /* KP_5 */
+ 0x58, 0xB6, /* KP_6 */
+ 0x59, 0xB7, /* KP_7 */
+ 0x5B, 0xB8, /* KP_8 */
+ 0x5C, 0xB9, /* KP_9 */
+ // The enter key is on the keypad but modifier isnt set
+ NSEnterCharacter, 0x8D
+};
/* Lisp communications */
Lisp_Object ns_input_file, ns_input_font, ns_input_fontsize, ns_input_line;
## -1842,6 +1870,23 ##
return code > 0xff ? 0 : 0xFF00 | ns_keycode_to_xkeysym_table[code]; */
}
+static unsigned
+ns_convert_keypad (unsigned code)
+/* --------------------------------------------------------------------------
+ Internal call used by NSView-keyDown.
+ -------------------------------------------------------------------------- */
+{
+ const unsigned last_keysym = (sizeof (convert_nskeypad_to_X_keysym)
+ / sizeof (convert_nskeypad_to_X_keysym[0]));
+ unsigned keysym;
+ /* An array would be faster, but less easy to read. */
+ for (keysym = 0; keysym < last_keysym; keysym += 2) {
+ if (code == convert_nskeypad_to_X_keysym[keysym]) {
+ return 0xFF00 | convert_nskeypad_to_X_keysym[keysym+1];
+ }
+ }
+ return 0;
+}
char *
x_get_keysym_name (int keysym)
## -4349,7 +4394,7 ##
struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (emacsframe);
int code;
unsigned fnKeysym = 0;
- int flags;
+ unsigned int flags = [theEvent modifierFlags];
static NSMutableArray *nsEvArray;
static BOOL firstTime = YES;
## -4397,6 +4442,9 ##
/* (Carbon way: [theEvent keyCode]) */
/* is it a "function key"? */
+ if (code < 0x00ff && (flags & NSNumericPadKeyMask) )
+ fnKeysym = ns_convert_keypad([theEvent keyCode]);
+ else
fnKeysym = ns_convert_key (code);
if (fnKeysym)
{
## -4410,8 +4458,6 ##
/* are there modifiers? */
emacs_event->modifiers = 0;
- flags = [theEvent modifierFlags];
-
if (flags & NSHelpKeyMask)
emacs_event->modifiers |= hyper_modifier;