#include <minix/devio.h>
#include <minix/syslib.h>
#include <minix/utils.h>
+#include <minix/bitmap.h>
#include <ibm/interrupt.h> /* IRQ vectors and miscellaneous ports */
#include <ibm/bios.h> /* BIOS index numbers */
*===========================================================================*/
void main(void)
{
+ int fkeys, sfkeys;
int i, r;
re_t *rep;
long v;
eth_ign_proto= htons((u16_t) v);
/* Observe some function key for debug dumps. */
- if ((r=fkey_enable(SF9)) != OK)
+ fkeys = sfkeys = 0; bit_set(sfkeys, 9);
+ if ((r=fkey_map(&fkeys, &sfkeys)) != OK)
printf("Warning: RTL8139 couldn't observe Shift+F9 key: %d\n",r);
/* Claim buffer memory now under Minix, before MM takes it all. */
{'H', 'Y', 'A', 'B', 'D', 'C', 'V', 'U', 'G', 'S', 'T', '@'};
/* Variables and definition for observed function keys. */
-PRIVATE int fkey_obs[12]; /* observers for F1-F12 */
-PRIVATE int sfkey_obs[12]; /* observers for SHIFT F1-F12 */
+typedef struct observer { int proc_nr; int events; } obs_t;
+PRIVATE obs_t fkey_obs[12]; /* observers for F1-F12 */
+PRIVATE obs_t sfkey_obs[12]; /* observers for SHIFT F1-F12 */
FORWARD _PROTOTYPE( int kb_ack, (void) );
FORWARD _PROTOTYPE( int kb_wait, (void) );
/* Clear the function key observers array. Also see func_key(). */
for (i=0; i<12; i++) {
- fkey_obs[i] = NONE; /* F1-F12 observers */
- sfkey_obs[i] = NONE; /* Shift F1-F12 observers */
+ fkey_obs[i].proc_nr = NONE; /* F1-F12 observers */
+ fkey_obs[i].events = 0; /* F1-F12 observers */
+ sfkey_obs[i].proc_nr = NONE; /* Shift F1-F12 observers */
+ sfkey_obs[i].events = 0; /* Shift F1-F12 observers */
}
/* Set interrupt handler and enable keyboard IRQ. */
/* This procedure allows processes to register a function key to receive
* notifications if it is pressed. At most one binding per key can exist.
*/
- int fkey = m_ptr->FKEY_CODE; /* get function key code */
- unsigned code;
- int *observers = NULL;
- int index = -1;
+ int i;
int result;
- /* See if this key can be observed; get the observers array and index. */
- if (F1 <= fkey && fkey <= F12) { /* F1-F12 */
- observers = fkey_obs;
- index = fkey - F1;
- } else if (SF1 <= fkey && fkey <= SF12) { /* Shift F1-F12 */
- observers = sfkey_obs;
- index = fkey - SF1;
- }
-
- /* Handle the request if an observers array was set above. */
- if (observers) {
- if (m_ptr->FKEY_ENABLE) { /* try to register an observer */
- if (observers[index] == NONE) {
- observers[index] = m_ptr->m_source;
- result = OK; /* done, new observer registered */
- } else {
- result = EBUSY; /* function key already bound */
- }
- } else { /* unregister an observer */
- if (observers[index] == m_ptr->m_source) {
- observers[index] = NONE;
- result = OK; /* done, observer unregistered */
- } else {
- result = EPERM; /* can only remove own binding */
+ switch (m_ptr->FKEY_REQUEST) { /* see what we must do */
+ case FKEY_MAP: /* request for new mapping */
+ for (i=0; i < 12; i++) { /* check F1-F12 keys */
+ if (bit_isset(m_ptr->FKEY_FKEYS, i+1) ) {
+ if (fkey_obs[i].proc_nr == NONE) {
+ fkey_obs[i].proc_nr = m_ptr->m_source;
+ fkey_obs[i].events = 0;
+ bit_unset(m_ptr->FKEY_FKEYS, i+1);
+ } else {
+ printf("WARNING, fkey_map failed F%d\n", i);
+ result = EBUSY;
+ break;
+ }
+ }
+ }
+ for (i=0; i < 12; i++) { /* check Shift+F1-F12 keys */
+ if (bit_isset(m_ptr->FKEY_SFKEYS, i+1) ) {
+ if (sfkey_obs[i].proc_nr == NONE) {
+ sfkey_obs[i].proc_nr = m_ptr->m_source;
+ sfkey_obs[i].events = 0;
+ bit_unset(m_ptr->FKEY_SFKEYS, i+1);
+ } else {
+ printf("WARNING, fkey_map failed Shift F%d\n", i);
+ result = EBUSY;
+ break;
+ }
+ }
+ }
+ result = OK; /* done, new observer registered */
+ break;
+ case FKEY_UNMAP:
+ result = ENOSYS; /* not yet supported (not needed) */
+ break;
+ case FKEY_EVENTS:
+ m_ptr->FKEY_FKEYS = m_ptr->FKEY_SFKEYS = 0;
+ for (i=0; i < 12; i++) { /* check (Shift+) F1-F12 keys */
+ if (fkey_obs[i].proc_nr == m_ptr->m_source) {
+ if (fkey_obs[i].events) {
+ bit_set(m_ptr->FKEY_FKEYS, i+1);
+ fkey_obs[i].events = 0;
+ }
+ }
+ if (sfkey_obs[i].proc_nr == m_ptr->m_source) {
+ if (sfkey_obs[i].events) {
+ bit_set(m_ptr->FKEY_SFKEYS, i+1);
+ sfkey_obs[i].events = 0;
+ }
}
}
- } else {
- result = EINVAL; /* key cannot be observed */
+ break;
+ default:
+ result = EINVAL; /* key cannot be observed */
}
/* Almost done, return result to caller. */
* Returns FALSE on a key release or if the key is not observable.
*/
message m;
- int *observers = NULL;
- unsigned fkey;
- int index = -1;
+ int key;
+ int proc_nr;
int i,s;
/* Ignore key releases. If this is a key press, get full key code. */
if (scode & KEY_RELEASE) return(FALSE); /* key release */
- fkey = map_key(scode); /* include modifiers */
+ key = map_key(scode); /* include modifiers */
/* Key pressed, now see if there is an observer for the pressed key.
* F1-F12 observers are in fkey_obs array.
* CTRL F1-F12 reserved (see kb_read)
* ALT F1-F12 reserved (see kb_read)
* Other combinations are not in use. Note that Alt+Shift+F1-F12 is yet
- * defined in <minix/keymap.h>, but other modifier combinations are not.
+ * defined in <minix/keymap.h>, and thus is easy for future extensions.
*/
- if (F1 <= fkey && fkey <= F12) { /* F1-F12 */
- observers = &fkey_obs[0];
- index = fkey - F1;
- } else if (SF1 <= fkey && fkey <= SF12) { /* Shift F2-F12 */
- observers = &sfkey_obs[0];
- index = fkey - SF1;
+ if (F1 <= key && key <= F12) { /* F1-F12 */
+ proc_nr = fkey_obs[key - F1].proc_nr;
+ fkey_obs[key - F1].events ++ ;
+ } else if (SF1 <= key && key <= SF12) { /* Shift F2-F12 */
+ proc_nr = sfkey_obs[key - SF1].proc_nr;
+ sfkey_obs[key - SF1].events ++;
+ }
+ else {
+ return(FALSE); /* not observable */
}
- if (! observers) return(FALSE); /* not observable */
/* See if an observer is registered and send it a message. */
- if (observers[index] != NONE) {
-#if DEAD_CODE
- m.m_type = FKEY_PRESSED;
- m.FKEY_NUM = index+1;
- m.FKEY_CODE = fkey;
- if (OK != (s=nb_send(observers[index], &m))) {
- printf("WARNING: F%d key nb_send to process %d failed: %d.\n",
- index+1, observers[index], s);
- }
-#else
+ if (proc_nr != NONE) {
m.NOTIFY_TYPE = FKEY_PRESSED;
- m.NOTIFY_ARG = fkey;
- m.NOTIFY_FLAGS = index+1;
- if (OK != (s=notify(observers[index], &m))) {
- printf("WARNING: F%d key notify to process %d failed: %d.\n",
- index+1, observers[index], s);
- }
-#endif
+ notify(proc_nr, &m);
}
return(TRUE);
}
PRIVATE void show_key_mappings()
{
int i,s;
- struct proc proc;
+ struct proc proc;
printf("\n");
printf("System information. Known function key mappings to request debug dumps:\n");
for (i=0; i<12; i++) {
printf(" %sF%d: ", i+1<10? " ":"", i+1);
- if (fkey_obs[i] != NONE) {
- if ((s=sys_getproc(&proc, fkey_obs[i]))!=OK)
+ if (fkey_obs[i].proc_nr != NONE) {
+ if ((s=sys_getproc(&proc, fkey_obs[i].proc_nr))!=OK)
printf("sys_getproc: %d\n", s);
printf("%-14.14s", proc.p_name);
} else {
}
printf(" %sShift-F%d: ", i+1<10? " ":"", i+1);
- if (i==0) {
- printf("%-14.14s", "<reserved by TTY>");
- } else if (sfkey_obs[i] != NONE) {
- if ((s=sys_getproc(&proc, sfkey_obs[i]))!=OK)
+ if (sfkey_obs[i].proc_nr != NONE) {
+ if ((s=sys_getproc(&proc, sfkey_obs[i].proc_nr))!=OK)
printf("sys_getproc: %d\n", s);
printf("%-14.14s", proc.p_name);
} else {
#define PZ_MEM_PTR m1_p1 /* base */
#define PZ_COUNT m1_i1 /* count */
-/* Field names for SELECT (FS) */
+/* Field names for SELECT (FS). */
#define SEL_NFDS m8_i1
#define SEL_READFDS m8_p1
#define SEL_WRITEFDS m8_p2
#define PANIC_DUMPS 97 /* debug dumps at the TTY on RBT_PANIC */
#define FKEY_CONTROL 98 /* control a function key at the TTY */
#define FKEY_PRESSED 99 /* notify process of function key event */
-# define FKEY_NUM m2_l1 /* fkey number excluding modifiers */
-# define FKEY_CODE m2_l2 /* fkey code including modifiers */
-# define FKEY_ENABLE m2_i1 /* enable or disable mapping */
+# define FKEY_REQUEST m2_i1 /* request to perform at TTY */
+# define FKEY_MAP 10 /* observe function key */
+# define FKEY_UNMAP 11 /* stop observing function key */
+# define FKEY_EVENTS 12 /* request open key presses */
+# define FKEY_FKEYS m2_l1 /* F1-F12 keys pressed */
+# define FKEY_SFKEYS m2_l2 /* Shift-F1-F12 keys pressed */
#define DIAGNOSTICS 100 /* output a string without FS in between */
# define DIAG_PRINT_BUF m1_p1
# define DIAG_BUF_COUNT m1_i1
#define ENABLE_SWAP 1
/* Enable or disable kernel calls (allows for minimal kernel). */
-#define ENABLE_K_TRACING 1 /* process tracing can be disabled */
#define ENABLE_K_DEBUGGING 0 /* kernel debugging calls */
/* Include or exclude an image of /dev/boot in the boot image. */
_PROTOTYPE( int env_parse, (char *env, char *fmt, int field, long *param,
long min, long max) );
-#define fkey_enable(fkey) fkey_ctl(fkey, 1)
-#define fkey_disable(fkey) fkey_ctl(fkey, 0)
-_PROTOTYPE( int fkey_ctl, (int fkey_code, int enable_disable) );
-
+#define fkey_map(fkeys, sfkeys) fkey_ctl(FKEY_MAP, (fkeys), (sfkeys))
+#define fkey_unmap(fkeys, sfkeys) fkey_ctl(FKEY_UNMAP, (fkeys), (sfkeys))
+#define fkey_events(fkeys, sfkeys) fkey_ctl(FKEY_EVENTS, (fkeys), (sfkeys))
+_PROTOTYPE( int fkey_ctl, (int req, int *fkeys, int *sfkeys) );
_PROTOTYPE( int printf, (const char *fmt, ...));
_PROTOTYPE( void kputc, (int c));
#define SENDREC 3 /* function code for SEND + RECEIVE */
#define NOTIFY 4 /* function code for notifications */
-#if 0
-/* Bit map operations to manipulate bits of a simple mask variable. */
-#define set_bit(mask, n) ((mask) |= (1 << (n)))
-#define clear_bit(mask, n) ((mask) &= ~(1 << (n)))
-#define isset_bit(mask, n) ((mask) & (1 << (n)))
-#define empty_mask (0)
-#define filled_mask (~0)
-#endif
-
/* Call masks indicating which system calls a process can make. */
#define EMPTY_CALL_MASK (0)
#define USER_CALL_MASK (1 << SENDREC)
#define do_signalrm do_setalarm
#define do_syncalrm do_setalarm
-#if ENABLE_K_TRACING
_PROTOTYPE( int do_trace, (message *m_ptr) ); /* process tracing */
-#else
-#define do_trace do_unused
-#endif
#endif /* SYSTEM_H */
#include "../system.h"
#include <sys/ptrace.h>
-#if ENABLE_K_TRACING /* only include code if tracing is enabled */
/*==========================================================================*
* do_trace *
return(OK);
}
-#endif /* ENABLE_K_TRACING */
/*===========================================================================*
* fkey_ctl *
*===========================================================================*/
-PUBLIC int fkey_ctl(fkey_code, enable_disable)
-int fkey_code; /* function key code it concerns */
-int enable_disable; /* enable or disable notifications */
+PUBLIC int fkey_ctl(request, fkeys, sfkeys)
+int request; /* request to perform */
+int *fkeys; /* bit masks for F1-F12 keys */
+int *sfkeys; /* bit masks for Shift F1-F12 keys */
{
/* Send a message to the TTY server to request notifications for function
* key presses or to disable notifications. Enabling succeeds unless the key
* bound to the current process.
*/
message m;
- m.FKEY_CODE = fkey_code;
- m.FKEY_ENABLE = enable_disable;
- return(_taskcall(TTY, FKEY_CONTROL, &m));
+ int s;
+ m.FKEY_REQUEST = request;
+ m.FKEY_FKEYS = (fkeys) ? *fkeys : 0;
+ m.FKEY_SFKEYS = (sfkeys) ? *sfkeys : 0;
+ s = _taskcall(TTY, FKEY_CONTROL, &m);
+ if (fkeys) *fkeys = m.FKEY_FKEYS;
+ if (sfkeys) *sfkeys = m.FKEY_SFKEYS;
+ return(s);
}
/*===========================================================================*
* handle_fkey *
*===========================================================================*/
+#define pressed(k) ((F1<=(k) && (k)<=F12 && bit_isset(m->FKEY_FKEYS, ((k)-F1+1))) \
+ || (SF1<=(k) && (k)<=SF12 && bit_isset(m->FKEY_SFKEYS, ((k)-SF1+1))))
+
PUBLIC int do_fkey_pressed(message *m)
{
- if (F1 <= m->NOTIFY_ARG && m->NOTIFY_ARG <= F12) {
- switch(m->NOTIFY_ARG) {
- case F1: proctab_dmp(); break;
- case F2: memmap_dmp(); break;
- case F3: image_dmp(); break;
- case F4: sendmask_dmp(); break;
- case F5: monparams_dmp(); break;
- case F6: irqtab_dmp(); break;
- case F7: kmessages_dmp(); break;
-
- case F10: kenv_dmp(); break;
- case F11: timing_dmp(); break;
- case F12: sched_dmp(); break;
- default:
- printf("IS: unhandled notify for F%d (code %d)\n",
- m->NOTIFY_FLAGS, m->NOTIFY_ARG);
- }
- }
-
- if (SF1 <= m->NOTIFY_ARG && m->NOTIFY_ARG <= SF12) {
- switch(m->NOTIFY_ARG) {
-
- case SF1: mproc_dmp(); break;
-
- case SF3: fproc_dmp(); break;
- case SF4: dtab_dmp(); break;
-
- case SF6: diagnostics_dmp(); break;
- default:
- printf("IS: unhandled notify for Shift-F%d (code %d)\n",
- m->NOTIFY_FLAGS, m->NOTIFY_ARG);
- }
- }
- return(EDONTREPLY);
+ int s;
+
+ /* The notification message does not convey any information, other
+ * than that some function keys have been pressed. Ask TTY for details.
+ */
+ m->m_type = FKEY_CONTROL;
+ m->FKEY_REQUEST = FKEY_EVENTS;
+ if (OK != (s=sendrec(TTY, m)))
+ report("IS", "warning, sendrec to TTY failed", s);
+
+ /* Now check which keys were pressed: F1-F12. */
+ if (pressed(F1)) proctab_dmp();
+ if (pressed(F2)) memmap_dmp();
+ if (pressed(F3)) image_dmp();
+ if (pressed(F4)) sendmask_dmp();
+ if (pressed(F5)) monparams_dmp();
+ if (pressed(F6)) irqtab_dmp();
+ if (pressed(F7)) kmessages_dmp();
+
+ if (pressed(F10)) kenv_dmp();
+ if (pressed(F11)) timing_dmp();
+ if (pressed(F12)) sched_dmp();
+
+ /* Also check Shift F1-F6 keys. */
+ if (pressed(SF1)) mproc_dmp();
+
+ if (pressed(SF3)) fproc_dmp();
+ if (pressed(SF4)) dtab_dmp();
+ if (pressed(SF6)) diagnostics_dmp();
+
+ /* Inhibit sending a reply message. */
+ return(EDONTREPLY);
}
#include <minix/syslib.h>
#include <minix/utils.h>
#include <minix/keymap.h>
+#include <minix/bitmap.h>
#include <stdlib.h>
#include <stdio.h>
{
/* Initialize the information service. */
message m;
- int r;
- long key;
+ int i;
/* Set own process number. */
is_proc_nr = IS_PROC_NR;
/* Set key mappings. IS takes all of F1-F12 and Shift+F1-F6 . */
- for (key=F1; key<=F12; key++) {
- if ((r=fkey_enable(key)) != OK) {
- printf("IS: WARNING: couldn't register F%d key: %d\n",
- (key-F1+1), r);
- }
- }
- for (key=SF1; key<=SF6; key++) {
- if ((r=fkey_enable(key)) != OK) {
- printf("IS: WARNING: couldn't register SF%d key: %d\n",
- (key-SF1+1), r);
- }
- }
+ m.FKEY_FKEYS = m.FKEY_SFKEYS = 0;
+ for (i=1; i<=12; i++) bit_set(m.FKEY_FKEYS, i);
+ for (i=1; i<= 6; i++) bit_set(m.FKEY_SFKEYS, i);
+ m.m_type = FKEY_CONTROL;
+ m.FKEY_REQUEST = FKEY_MAP;
+ if (OK != (i=sendrec(TTY, &m)))
+ report("IS", "warning, sendrec failed:", i);
/* Display status message ... */
- printf("IS: information service is alive and kicking; press F1-F12 for dumps\n");
+ report("IS", "information service is alive and kicking", NO_NUM);
}
/*===========================================================================*