--- .empty Thu Jan 1 00:00:00 1970 +++ NEW/xc/programs/Xserver/hw/cg14.2screen/cg14.c Thu Jan 1 00:00:00 1970 @@ -0,0 +1,760 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cg14.h" +#include "vars.h" + +/* This song-and-dance is here because of interface botches in cfb: it is + not possible to use two different depths of cfb in the same file, at + least not unless you declare the routines yourself. cfb.h depends on + a global cpp define PSZ.... + + So what we do is to push all the cfb-calling code out into cg14-8.c + and cg14-24.c. */ + +#include "cg14-8.h" +#include "cg14-24.h" + +/* XXX xalloc should return void * in the first place! */ +#define vxalloc(x) (void *)xalloc((x)) + +/* XXX this should be in an include file! */ +extern Bool noXkbExtension; + +static int ar_t1 = 400; +static int ar_t2 = 50; +static const char *dev_fb = "/dev/cgfourteen0"; +static const char *dev_kb = "/dev/kbd"; +static const char *dev_ms = "/dev/mouse"; +static int zaphod = -1; +static int screen0_depth = 8; +static int screen1_depth = 24; + +static int fd_fb; +static int fd_kb; +static int fd_ms; +static int keycode_offset; +static int ar_key; +static int ar_first; +static struct timeval ar_when; +static int ms_state; + +void *fbregs; +volatile struct cg14ctl *ctl; +volatile struct cg14xlut *xlut; +volatile struct cg14clut *clut1; +void *vram_cbgr; +void *vram_px32; + +ColormapRec *instmap_8; +ColormapRec *instmap_24; + +static unsigned long int server_gen = 0; +static int spix; + +#define MIN_KEYCODE 8 /* protocol constant */ + +#define BASE_KEYCODE_TYPE3 1 + +static KeySym keymap_type3[] + = { XK_F11, NoSymbol, /* 1 */ + NoSymbol, NoSymbol, /* 2 */ + XK_F12, NoSymbol, /* 3 */ + NoSymbol, NoSymbol, /* 4 */ + XK_F1, NoSymbol, /* 5 */ + XK_F2, NoSymbol, /* 6 */ + NoSymbol, NoSymbol, /* 7 */ + XK_F3, NoSymbol, /* 8 */ + NoSymbol, NoSymbol, /* 9 */ + XK_F4, NoSymbol, /* 10 */ + NoSymbol, NoSymbol, /* 11 */ + XK_F5, NoSymbol, /* 12 */ + NoSymbol, NoSymbol, /* 13 */ + XK_F6, NoSymbol, /* 14 */ + NoSymbol, NoSymbol, /* 15 */ + XK_F7, NoSymbol, /* 16 */ + XK_F8, NoSymbol, /* 17 */ + XK_F9, NoSymbol, /* 18 */ + XK_Alt_R, NoSymbol, /* 19 */ + NoSymbol, NoSymbol, /* 20 */ + XK_F21, NoSymbol, /* 21 */ + XK_F22, NoSymbol, /* 22 */ + XK_F23, NoSymbol, /* 23 */ + NoSymbol, NoSymbol, /* 24 */ + XK_F13, NoSymbol, /* 25 */ + XK_F14, NoSymbol, /* 26 */ + NoSymbol, NoSymbol, /* 27 */ + NoSymbol, NoSymbol, /* 28 */ + XK_Escape, NoSymbol, /* 29 */ + XK_1, XK_exclam, /* 30 */ + XK_2, XK_at, /* 31 */ + XK_3, XK_numbersign, /* 32 */ + XK_4, XK_dollar, /* 33 */ + XK_5, XK_percent, /* 34 */ + XK_6, XK_asciicircum, /* 35 */ + XK_7, XK_ampersand, /* 36 */ + XK_8, XK_asterisk, /* 37 */ + XK_9, XK_parenleft, /* 38 */ + XK_0, XK_parenright, /* 39 */ + XK_minus, XK_underscore, /* 40 */ + XK_equal, XK_plus, /* 41 */ + XK_grave, XK_asciitilde, /* 42 */ + XK_BackSpace, NoSymbol, /* 43 */ + NoSymbol, NoSymbol, /* 44 */ + XK_F24, NoSymbol, /* 45 */ + XK_F25, NoSymbol, /* 46 */ + XK_F26, NoSymbol, /* 47 */ + NoSymbol, NoSymbol, /* 48 */ + XK_F15, NoSymbol, /* 49 */ + NoSymbol, NoSymbol, /* 50 */ + XK_F16, NoSymbol, /* 51 */ + NoSymbol, NoSymbol, /* 52 */ + XK_Tab, NoSymbol, /* 53 */ + XK_Q, NoSymbol, /* 54 */ + XK_W, NoSymbol, /* 55 */ + XK_E, NoSymbol, /* 56 */ + XK_R, NoSymbol, /* 57 */ + XK_T, NoSymbol, /* 58 */ + XK_Y, NoSymbol, /* 59 */ + XK_U, NoSymbol, /* 60 */ + XK_I, NoSymbol, /* 61 */ + XK_O, NoSymbol, /* 62 */ + XK_P, NoSymbol, /* 63 */ + XK_bracketleft, XK_braceleft, /* 64 */ + XK_bracketright, XK_braceright, /* 65 */ + XK_Delete, NoSymbol, /* 66 */ + NoSymbol, NoSymbol, /* 67 */ + XK_F27, NoSymbol, /* 68 */ + XK_Up, XK_F28, /* 69 */ + XK_F29, NoSymbol, /* 70 */ + NoSymbol, NoSymbol, /* 71 */ + XK_F17, NoSymbol, /* 72 */ + XK_F18, NoSymbol, /* 73 */ + NoSymbol, NoSymbol, /* 74 */ + NoSymbol, NoSymbol, /* 75 */ + XK_Control_L, NoSymbol, /* 76 */ + XK_A, NoSymbol, /* 77 */ + XK_S, NoSymbol, /* 78 */ + XK_D, NoSymbol, /* 79 */ + XK_F, NoSymbol, /* 80 */ + XK_G, NoSymbol, /* 81 */ + XK_H, NoSymbol, /* 82 */ + XK_J, NoSymbol, /* 83 */ + XK_K, NoSymbol, /* 84 */ + XK_L, NoSymbol, /* 85 */ + XK_semicolon, XK_colon, /* 86 */ + XK_apostrophe, XK_quotedbl, /* 87 */ + XK_backslash, XK_bar, /* 88 */ + XK_Return, NoSymbol, /* 89 */ + NoSymbol, NoSymbol, /* 90 */ + XK_Left, XK_F30, /* 91 */ + XK_F31, NoSymbol, /* 92 */ + XK_Right, XK_F32, /* 93 */ + NoSymbol, NoSymbol, /* 94 */ + XK_F19, NoSymbol, /* 95 */ + NoSymbol, NoSymbol, /* 96 */ + XK_F20, NoSymbol, /* 97 */ + NoSymbol, NoSymbol, /* 98 */ + XK_Shift_L, NoSymbol, /* 99 */ + XK_Z, NoSymbol, /* 100 */ + XK_X, NoSymbol, /* 101 */ + XK_C, NoSymbol, /* 102 */ + XK_V, NoSymbol, /* 103 */ + XK_B, NoSymbol, /* 104 */ + XK_N, NoSymbol, /* 105 */ + XK_M, NoSymbol, /* 106 */ + XK_comma, XK_less, /* 107 */ + XK_period, XK_greater, /* 108 */ + XK_slash, XK_question, /* 109 */ + XK_Shift_R, NoSymbol, /* 110 */ + XK_Linefeed, NoSymbol, /* 111 */ + XK_F33, NoSymbol, /* 112 */ + XK_Down, XK_F34, /* 113 */ + XK_F35, NoSymbol, /* 114 */ + NoSymbol, NoSymbol, /* 115 */ + NoSymbol, NoSymbol, /* 116 */ + NoSymbol, NoSymbol, /* 117 */ + NoSymbol, NoSymbol, /* 118 */ + XK_Caps_Lock, NoSymbol, /* 119 */ + XK_Meta_L, NoSymbol, /* 120 */ + XK_space, NoSymbol, /* 121 */ + XK_Meta_R, NoSymbol, /* 122 */ }; + +static int modifiers_type3[] + = { 99, ShiftMask, + 110, ShiftMask, + 76, ControlMask, + 119, LockMask, + 120, Mod1Mask, + 122, Mod1Mask, + -1 }; + +static KeySymsRec keysyms_type3 = { &keymap_type3[0], 1, 122, 2 }; + +#ifdef DPMSExtension + +void DPMSSet(int level __attribute__((__unused__))) +{ +} + +Bool DPMSSupported(void) +{ + return(FALSE); +} + +#endif + +Bool LegalModifier(unsigned int key, DeviceRec *dev) +{ + return(TRUE); +} + +static void config_screens(const char *s) +{ + const char *s0; + char *e; + long int v; + + screen0_depth = 0; + screen1_depth = 0; + s0 = s; + while (1) + { v = strtol(s,&e,0); + if (e == s) FatalError("malformed screen depths list (%.*s <<>> %s)",(int)(s-s0),s0,s); + switch (v) + { case 8: + case 24: + break; + default: + FatalError("invalid depth %ld in screen depths list",v); + break; + } + do + { if (! screen0_depth) + { screen0_depth = v; + break; + } + if (v == screen0_depth) FatalError("depth %ld specified twice",v); + if (! screen1_depth) + { screen1_depth = v; + break; + } + FatalError("too many depths in screens list"); + } while (0); + switch (*e) + { case ',': + s = e + 1; + break; + case '\0': + if (screen0_depth == 0) FatalError("no depths in screens list"); + return; + break; + default: + FatalError("syntax error in screen depths list (non-comma %c after number)",*e); + break; + } + } +} + +int ddxProcessArgument(int ac, char **av, int x) +{ + if (!strcmp(av[x],"-ar1")) + { if (++x >= ac) UseMsg(); + ar_t1 = atoi(av[x]); + return(2); + } + if (!strcmp(av[x],"-ar2")) + { if (++x >= ac) UseMsg(); + ar_t2 = atoi(av[x]); + return(2); + } + if (!strcmp(av[x],"-fb")) + { if (++x >= ac) UseMsg(); + dev_fb = av[x]; + return(2); + } + if (!strcmp(av[x],"-kbd")) + { if (++x >= ac) UseMsg(); + dev_kb = av[x]; + return(2); + } + if (!strcmp(av[x],"-ms")) + { if (++x >= ac) UseMsg(); + dev_ms = av[x]; + return(2); + } + if (!strcmp(av[x],"-screens")) + { if (++x >= ac) UseMsg(); + config_screens(av[x]); + return(2); + } + if (!strcmp(av[x],"-zaphod")) + { zaphod = 0; + return(1); + } + if (!strcmp(av[x],"+zaphod")) + { zaphod = 1; + return(1); + } + return(0); +} + +void ddxUseMsg(void) +{ + ErrorF("-ar1 int set autorepeat initiate delay (ms)\n"); + ErrorF("-ar2 int set autorepeat interval delay (ms)\n"); + ErrorF("-fb device name of framebuffer device\n"); + ErrorF("-kbd device name of keyboard device\n"); + ErrorF("-ms device name of mouse device\n"); + ErrorF("-screens N[,N] declare what screens exist and in what order\n"); + ErrorF(" N values are 8 or 24, giving screen depths\n"); + ErrorF("-zaphod suppress screen-flipping by mouse movement\n"); + ErrorF("+zaphod enable screen-flipping by mouse movement (default)\n"); +} + +static int open_it(const char *path, const char *what) +{ + int fd; + + fd = open(path,O_RDWR,0); + if (fd < 0) FatalError("Can't open %s %s: %s",what,path,strerror(errno)); + return(fd); +} + +static void *map_cg14(unsigned int offset, unsigned int len, const char *tag) +{ + void *mrv; + + mrv = mmap(0,len,PROT_READ|PROT_WRITE,MAP_FILE|MAP_SHARED,fd_fb,offset); + if (mrv == MAP_FAILED) FatalError("mmap framebuffer (%s): %s",tag,strerror(errno)); + return(mrv); +} + +void OsVendorInit(void) +{ + static int first = 1; + struct rlimit rl; + + if (! first) return; + if (getrlimit(RLIMIT_NOFILE,&rl) == 0) + { rl.rlim_cur = rl.rlim_max; + setrlimit(RLIMIT_NOFILE,&rl); + fd_kb = open_it(dev_kb,"keyboard"); + fd_ms = open_it(dev_ms,"mouse"); + fd_fb = open_it(dev_fb,"framebuffer"); + vram_cbgr = map_cg14(0x01000000,0x00400000,"vram cbgr"); + vram_px32 = map_cg14(0x03000000,0x00100000,"vram px32"); + fbregs = map_cg14(0x10000000,0x00010000,"regs"); + ctl = (void *)((char *)fbregs + CG14_REGS_CTL); + xlut = (void *)((char *)fbregs + CG14_REGS_XLUT); + clut1 = (void *)((char *)fbregs + CG14_REGS_CLUT1); + } + first = 0; +} + +static void bell(int pct, DeviceIntRec *d, void *ctl, int unused __attribute__((__unused__))) +{ + KeybdCtrl *kc; + int v; + + kc = ctl; + if ((pct == 0) || (kc->bell == 0)) return; + v = kc->bell_duration; + ioctl(fd_kb,KIOCBELL,&v); +} + +static void kb_ctl(DeviceIntRec *d __attribute__((__unused__)), KeybdCtrl *ctl __attribute__((__unused__))) +{ +} + +static int kb_proc(DeviceIntRec *d, int op) +{ + static KeySymsRec *ks = 0; + static CARD8 *mm = 0; + + switch (op) + { case DEVICE_INIT: +#ifdef XKB + if (! noXkbExtension) FatalError("XKB not supported"); +#endif + if (&d->public != LookupKeyboardDevice()) + { ErrorF("Opening non-system keyboard\n"); + return(!Success); + } + if (! ks) + { int i; + ks = &keysyms_type3; + if (ks->minKeyCode < MIN_KEYCODE) + { keycode_offset = MIN_KEYCODE - ks->minKeyCode; + ks->minKeyCode += keycode_offset; + ks->maxKeyCode += keycode_offset; + } + else + { keycode_offset = 0; + } + mm = vxalloc(MAP_LENGTH*sizeof(CARD8)); + bzero(mm,MAP_LENGTH*sizeof(CARD8)); + for (i=0;modifiers_type3[i]>=0;i+=2) + { mm[modifiers_type3[i]+keycode_offset] = modifiers_type3[i+1]; + } + } + memset(&defaultKeyboardControl.autoRepeats[0],~0,sizeof(defaultKeyboardControl.autoRepeats)); + ar_key = -1; + d->public.devicePrivate = 0; + d->public.on = FALSE; + InitKeyboardDeviceStruct(&d->public,ks,mm,bell,kb_ctl); + break; + case DEVICE_ON: + AddEnabledDevice(fd_kb); + d->public.on = TRUE; + break; + case DEVICE_CLOSE: + case DEVICE_OFF: + RemoveEnabledDevice(fd_kb); + d->public.on = FALSE; + break; + default: + FatalError("Unknown keyboard operation"); + break; + } + return(Success); +} + +static void ms_ctl(DeviceIntRec *d __attribute__((__unused__)), PtrCtrl *ctl __attribute__((__unused__))) +{ +} + +static int ms_proc(DeviceIntRec *d, int op) +{ + switch (op) + { case DEVICE_INIT: + if (&d->public != LookupPointerDevice()) + { ErrorF("Opening non-system mouse\n"); + return(!Success); + } + d->public.devicePrivate = 0; + d->public.on = FALSE; + { BYTE map[4]; + map[0] = 0; + map[1] = 1; + map[2] = 2; + map[3] = 3; + InitPointerDeviceStruct(&d->public,&map[0],3,miPointerGetMotionEvents,ms_ctl,miPointerGetMotionBufferSize()); + } + break; + case DEVICE_ON: + AddEnabledDevice(fd_ms); + d->public.on = TRUE; + ms_state = 0; + break; + case DEVICE_CLOSE: + case DEVICE_OFF: + RemoveEnabledDevice(fd_ms); + d->public.on = FALSE; + break; + default: + FatalError("Unknown keyboard operation"); + break; + } + return(Success); +} + +static int accel(DeviceIntRec *d, int delta) +{ + PtrCtrl *pc; + + pc = &d->ptrfeed->ctrl; + if (delta < 0) + { if (-delta > pc->threshold) + { return(-(pc->threshold+(((-delta-pc->threshold)*pc->num)/pc->den))); + } + } + else + { if (delta > pc->threshold) + { return(pc->threshold+(((delta-pc->threshold)*pc->num)/pc->den)); + } + } + return(delta); +} + +static __inline__ unsigned long int tv_to_ms(struct timeval) __attribute__((__const__)); +static __inline__ unsigned long int tv_to_ms(struct timeval tv) +{ + return((tv.tv_sec*1000UL)+(tv.tv_usec/1000)); +} + +static void handle_sigio(int sig __attribute__((__unused__))) +{ + typedef struct evbuf EVBUF; + struct evbuf { + struct firm_event evs[64]; + int fd; + void (*qfn)(struct firm_event *); + int fill; + int ptr; + int none; + } ; + int e; + DeviceIntRec *pd; + DeviceIntRec *kd; + EVBUF k; + EVBUF m; + + static void evbuf_init(EVBUF *b, int fd, void (*qfn)(struct firm_event *)) + { b->fd = fd; + b->qfn = qfn; + b->fill = 0; + b->ptr = 0; + b->none = 0; + } + + static int mayberead(EVBUF *b) + { int nb; + if (b->none || (b->ptr < b->fill)) return(0); + b->ptr = 0; + b->fill = 0; + nb = read(b->fd,&b->evs[0],sizeof(b->evs)); + if (nb < 0) + { if (errno == EWOULDBLOCK) + { b->none = 1; + return(0); + } + if (errno == EINTR) return(0); + FatalError("Input device read: %s\n",strerror(errno)); + } + if (nb == 0) + { b->none = 1; + return(0); + } + if (nb % sizeof(struct firm_event)) FatalError("Input device read size wrong: %d %% %d != 0\n",nb,sizeof(struct firm_event)); + b->fill = nb / sizeof(struct firm_event); + return(1); + } + + static void q_kb(struct firm_event *e) + { xEvent xe; + int kc; + CARD8 mod; + kc = (e->id & 0x7f) + keycode_offset; + mod = kd->key->modifierMap[kc]; + /* maybe kill autorepeater */ + xe.u.keyButtonPointer.time = tv_to_ms(e->time); + xe.u.u.type = (e->value == VKEY_UP) ? KeyRelease : KeyPress; + xe.u.u.detail = kc; + /* check for special stuff - autorepeat, locking keys, etc */ + mieqEnqueue(&xe); + } + + static void q_ms(struct firm_event *e) + { xEvent xe; + unsigned long int t; + int m; + t = tv_to_ms(e->time); + xe.u.keyButtonPointer.time = t; + switch (e->id) + { case MS_LEFT: + xe.u.u.detail = 1; + m = 1; + if (0) + { + case MS_MIDDLE: + xe.u.u.detail = 2; + m = 2; + } + if (0) + { + case MS_RIGHT: + xe.u.u.detail = 3; + m = 4; + } + if (e->value == VKEY_UP) + { if (! (ms_state & m)) return; + ms_state &= ~m; + xe.u.u.type = ButtonRelease; + } + else + { if (ms_state & m) return; + ms_state |= m; + xe.u.u.type = ButtonPress; + } + mieqEnqueue(&xe); + break; + case LOC_X_DELTA: + miPointerDeltaCursor(accel(pd,e->value),0,t); + break; + case LOC_Y_DELTA: + miPointerDeltaCursor(0,-accel(pd,e->value),t); + break; + } + } + + e = errno; + /* XXX interface botch - shouldn't depend on pointer casting + between DeviceIntRec * and DeviceRec *! */ + kd = (DeviceIntRec *) LookupKeyboardDevice(); + pd = (DeviceIntRec *) LookupPointerDevice(); + if (!kd->public.on || !pd->public.on) return; + evbuf_init(&k,fd_kb,q_kb); + evbuf_init(&m,fd_ms,q_ms); + while (1) + { EVBUF *q; + if (mayberead(&k)) m.none = 0; + if (mayberead(&m)) k.none = 0; + q = (m.none || (m.ptr >= m.fill)) + ? (k.none || (k.ptr >= k.fill)) + ? 0 + : &k + : (k.none || (k.ptr >= k.fill)) + ? &m + : timercmp(&k.evs[k.ptr].time,&m.evs[m.ptr].time,<) ? &k : &m; + if (! q) + { if (m.none && k.none) break; + continue; + } + if (q->none || (q->ptr >= q->fill)) *(volatile char *)0; + (*q->qfn)(&q->evs[q->ptr]); + q->ptr ++; + } + errno = e; +} + +void InitInput(int ac __attribute__((__unused__)), char **av __attribute__((__unused__))) +{ + DeviceRec *p; + DeviceRec *k; + + k = AddInputDevice(kb_proc,TRUE); + p = AddInputDevice(ms_proc,TRUE); + if (!k || !p) FatalError("Can't create input devices"); + RegisterKeyboardDevice(k); + RegisterPointerDevice(p); + miRegisterPointerDevice(screenInfo.screens[0],p); + mieqInit(k,p); + OsSignal(SIGIO,handle_sigio); + fcntl(fd_kb,F_SETFL,fcntl(fd_kb,F_GETFL,0)|O_NONBLOCK|O_ASYNC); + fcntl(fd_ms,F_SETFL,fcntl(fd_ms,F_GETFL,0)|O_NONBLOCK|O_ASYNC); +} + +static void show_screen(int showdepth) +{ + int i; + unsigned char v; + + fprintf(stderr,"show_screen(%d)\n",showdepth); + v = (showdepth == 8) ? 0x10 : 0x00; + for (i=0;i<256;i++) xlut->lut[i] = v; +} + +static Bool offscreen(ScreenRec **sp, int *x, int *y) +{ + int n; + + if (PointerConfinedToScreen()) return(TRUE); + if (!zaphod || ((zaphod < 0) && (screen1_depth == 0))) return(FALSE); + if (*x < 0) + { n = -1; + *x += 1152; + } + else if (*x >= (*sp)->width) + { n = 1; + *x -= 1152; + } + else + { return(FALSE); + } + n += (*sp)->myNum; + if (n < 0) n = screenInfo.numScreens - 1; else if (n >= screenInfo.numScreens) n = 0; + *sp = screenInfo.screens[n]; + return(TRUE); +} + +static void cross_screen(ScreenRec *s, Bool enter) +{ + if (enter) show_screen(s->rootDepth); +} + +static void warp_cursor(ScreenRec *s, int x, int y) +{ + sigset_t m; + sigset_t om; + + sigemptyset(&m); + sigemptyset(&om); + sigaddset(&m,SIGIO); + sigprocmask(SIG_BLOCK,&m,&om); + miPointerWarpCursor(s,x,y); + sigprocmask(SIG_SETMASK,&om,0); +} + +miPointerScreenFuncRec cg14_psfuncs + = { offscreen, cross_screen, warp_cursor }; + +void InitOutput(ScreenInfo *si, int ac, char **av) +{ + ctl->mctl = CG14_MCTL_ENABLEVID | CG14_MCTL_PIXMODE_32 | CG14_MCTL_POWERCTL; + si->imageByteOrder = IMAGE_BYTE_ORDER; + si->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT; + si->bitmapScanlinePad = BITMAP_SCANLINE_PAD; + si->bitmapBitOrder = BITMAP_BIT_ORDER; + si->numPixmapFormats = 3; + si->formats[0].depth = 1; + si->formats[0].bitsPerPixel = 1; + si->formats[0].scanlinePad = BITMAP_SCANLINE_PAD; + si->formats[1].depth = 8; + si->formats[1].bitsPerPixel = 8; + si->formats[1].scanlinePad = BITMAP_SCANLINE_PAD; + si->formats[2].depth = 24; + si->formats[2].bitsPerPixel = 32; + si->formats[2].scanlinePad = BITMAP_SCANLINE_PAD; + show_screen(screen0_depth); + switch (screen0_depth) + { case 8: + AddScreen(cg14_init8,ac,av); + break; + case 24: + AddScreen(cg14_init24,ac,av); + break; + } + switch (screen1_depth) + { case 8: + AddScreen(cg14_init8,ac,av); + break; + case 24: + AddScreen(cg14_init24,ac,av); + break; + } +} + +void AbortDDX(void) +{ +} + +void ddxGiveUp(void) +{ +} + +void ProcessInputEvents(void) +{ + mieqProcessInputEvents(); + miPointerUpdate(); +}