diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2015-01-09 22:23:25 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2015-01-09 22:23:25 +0100 |
commit | 15590e39c6be92d8a9ecb2f00b015dbb9a3dc0b0 (patch) | |
tree | 1ecc8859409aae2446f7cb23ca8ad672878846a3 /sys/src/9 | |
parent | cf76346b37ddbd54b8d1fe5580ab813a8165392b (diff) |
igfx: implement hardware cursor
this can even be used with the vesa driver, just
enable the cursor after mode switch like:
echo hwgc igfxhwgc >/dev/vgactl
Diffstat (limited to 'sys/src/9')
-rw-r--r-- | sys/src/9/pc/pccpuf | 2 | ||||
-rw-r--r-- | sys/src/9/pc/pcf | 2 | ||||
-rw-r--r-- | sys/src/9/pc/vgaigfx.c | 115 | ||||
-rw-r--r-- | sys/src/9/pc64/pc64 | 2 |
4 files changed, 117 insertions, 4 deletions
diff --git a/sys/src/9/pc/pccpuf b/sys/src/9/pc/pccpuf index 89d726b8c..0b06f4192 100644 --- a/sys/src/9/pc/pccpuf +++ b/sys/src/9/pc/pccpuf @@ -113,7 +113,7 @@ misc vgageode +cur vgahiqvideo +cur vgai81x +cur - vgaigfx + vgaigfx +cur vgamach64xx +cur vgamga2164w +cur vgamga4xx +cur diff --git a/sys/src/9/pc/pcf b/sys/src/9/pc/pcf index f4166027d..b05bf0cd6 100644 --- a/sys/src/9/pc/pcf +++ b/sys/src/9/pc/pcf @@ -114,7 +114,7 @@ misc vgageode +cur vgahiqvideo +cur vgai81x +cur - vgaigfx + vgaigfx +cur vgamach64xx +cur vgamga2164w +cur vgamga4xx +cur diff --git a/sys/src/9/pc/vgaigfx.c b/sys/src/9/pc/vgaigfx.c index a8184041a..17eede39f 100644 --- a/sys/src/9/pc/vgaigfx.c +++ b/sys/src/9/pc/vgaigfx.c @@ -28,11 +28,124 @@ igfxenable(VGAscr* scr) addvgaseg("igfxmmio", p->mem[0].bar&~0x0F, p->mem[1].size); if(scr->paddr == 0) vgalinearpci(scr); - if(scr->apsize) + if(scr->apsize){ addvgaseg("igfxscreen", scr->paddr, scr->apsize); + scr->storage = (scr->apsize - 64*64*4) & ~(BY2PG-1); + if(scr->storage > 0x1000000) + scr->storage = 0x1000000; + } } VGAdev vgaigfxdev = { "igfx", igfxenable, }; + +static void +igfxcurload(VGAscr* scr, Cursor* curs) +{ + uchar set, clr; + u32int *p; + int i, j; + + p = (u32int*)((uchar*)scr->vaddr + scr->storage); + memset(p, 0, 64*64*4); + for(i=0;i<32;i++) { + set = curs->set[i]; + clr = curs->clr[i]; + for(j=0x80; j; j>>=1){ + if((set|clr)&j) + *p++ = (0xFF<<24) | (set&j ? 0x000000 : 0xFFFFFF); + else + *p++ = 0; + } + if(i & 1) + p += 64-16; + } + scr->offset = curs->offset; +} + +enum { + CURCTL = 0, + CURBASE, + CURPOS, + + NPIPE = 3, +}; + +static u32int* +igfxcurregs(VGAscr* scr, int pipe) +{ + u32int o; + + if(scr->mmio == nil || scr->storage == 0) + return nil; + o = pipe*0x1000; + /* check PIPExCONF if enabled */ + if((scr->mmio[(0x70008 | o)/4] & (1<<31)) == 0) + return nil; + if(scr->pci->did == 0x2a42){ /* G45 */ + if(pipe > 1) + return nil; + o = pipe*0x40; + } + return (u32int*)((uchar*)scr->mmio + (0x70080 + o)); +} + +static int +igfxcurmove(VGAscr* scr, Point p) +{ + int i, x, y; + u32int *r; + + for(i=0; i<NPIPE; i++){ + if((r = igfxcurregs(scr, i)) != nil){ + x = p.x + scr->offset.x; + if(x < 0) x = -x | 0x8000; + y = p.y + scr->offset.y; + if(y < 0) y = -y | 0x8000; + r[CURPOS] = (y << 16) | x; + } + } + return 0; +} + +static void +igfxcurenable(VGAscr* scr) +{ + u32int *r; + int i; + + igfxenable(scr); + igfxcurload(scr, &arrow); + igfxcurmove(scr, ZP); + + for(i=0; i<NPIPE; i++){ + if((r = igfxcurregs(scr, i)) != nil){ + r[CURCTL] = (r[CURCTL] & ~(3<<28 | 1<<5)) | (i<<28) | 7; + r[CURBASE] = scr->storage; + } + } +} + +static void +igfxcurdisable(VGAscr* scr) +{ + u32int *r; + int i; + + for(i=0; i<NPIPE; i++){ + if((r = igfxcurregs(scr, i)) != nil){ + r[CURCTL] &= ~(1<<5 | 7); + r[CURBASE] = 0; + } + } +} + +VGAcur vgaigfxcur = { + "igfxhwgc", + igfxcurenable, + igfxcurdisable, + igfxcurload, + igfxcurmove, +}; diff --git a/sys/src/9/pc64/pc64 b/sys/src/9/pc64/pc64 index f61c10beb..a5f971967 100644 --- a/sys/src/9/pc64/pc64 +++ b/sys/src/9/pc64/pc64 @@ -112,6 +112,7 @@ misc # vgageode +cur # vgahiqvideo +cur # vgai81x +cur + vgaigfx +cur # vgamach64xx +cur # vgamga2164w +cur # vgamga4xx +cur @@ -124,7 +125,6 @@ misc # vgatvp3020 =cur # vgatvp3026 =cur vgavesa - vgaigfx # vgavmware +cur ip |