|
@@ -42,8 +42,6 @@ enum {
|
|
|
|
|
|
Tft = 0x60,
|
|
|
|
|
|
-// Pcd = HOWMANY(432000, pixelclock), /* a bit too magic */
|
|
|
-
|
|
|
Loadmode = 2 << 1,
|
|
|
Fifosize = 0x400,
|
|
|
|
|
@@ -160,13 +158,11 @@ Cursor arrow = {
|
|
|
};
|
|
|
|
|
|
OScreen oscreen;
|
|
|
-OScreen settings[] = {
|
|
|
-[Res800x600] { 0, 800, 600, 60, RGB16, 40000,
|
|
|
- 87<<20, 39<<8, 127, 23<<20, 1<<8, 4, },
|
|
|
-[Res1024x768] { 0, 1024, 768, 60, RGB16, 65000,
|
|
|
- 159<<20, 23<<8, 135, 29<<20, 3<<8, 6, },
|
|
|
-[Res1280x1024] { 0, 1280, 1024, 60, RGB16, 108000,
|
|
|
- 247<<20, 47<<8, 111, 38<<20, 1<<8, 3, },
|
|
|
+Settings settings[] = {
|
|
|
+[Res800x600] { 800, 600, 60, RGB16, 40000, 88, 40, 128, 23, 1, 5, },
|
|
|
+[Res1024x768] { 1024, 768, 60, RGB16, 65000, 160, 24, 136, 29, 3, 7, },
|
|
|
+[Res1280x1024] { 1280, 1024, 60, RGB16, 108000, 248, 48, 112, 38, 1, 4, },
|
|
|
+[Res1400x1050] { 1400, 1050, 50, RGB16, 108000, 248, 48, 112, 38, 1, 4, }, // TODO
|
|
|
};
|
|
|
Omap3fb *framebuf;
|
|
|
Memimage *gscreen;
|
|
@@ -209,6 +205,24 @@ static ulong rep(ulong, int);
|
|
|
static void screenputc(char *buf);
|
|
|
static void screenwin(void);
|
|
|
|
|
|
+/*
|
|
|
+ * Software cursor.
|
|
|
+ */
|
|
|
+int swvisible; /* is the cursor visible? */
|
|
|
+int swenabled; /* is the cursor supposed to be on the screen? */
|
|
|
+Memimage* swback; /* screen under cursor */
|
|
|
+Memimage* swimg; /* cursor image */
|
|
|
+Memimage* swmask; /* cursor mask */
|
|
|
+Memimage* swimg1;
|
|
|
+Memimage* swmask1;
|
|
|
+
|
|
|
+Point swoffset;
|
|
|
+Rectangle swrect; /* screen rectangle in swback */
|
|
|
+Point swpt; /* desired cursor location */
|
|
|
+Point swvispt; /* actual cursor location */
|
|
|
+int swvers; /* incremented each time cursor image changes */
|
|
|
+int swvisvers; /* the version on the screen */
|
|
|
+
|
|
|
static void
|
|
|
lcdoff(void)
|
|
|
{
|
|
@@ -235,9 +249,13 @@ dssstart(void)
|
|
|
coherence();
|
|
|
}
|
|
|
|
|
|
+/* see spruf98i §15.6.7.4.2 */
|
|
|
static void
|
|
|
configdispc(void)
|
|
|
{
|
|
|
+ Settings *sp;
|
|
|
+
|
|
|
+ sp = oscreen.settings;
|
|
|
dss->ctrl &= 0x78; /* choose dss clock */
|
|
|
dispc->sysconf = Midlemode | Sidlemode | EnableWakeup | Autoidle;
|
|
|
dispc->config = Loadmode;
|
|
@@ -249,13 +267,15 @@ configdispc(void)
|
|
|
dispc->transcolor[0] = 0; /* set transparency to full */
|
|
|
dispc->transcolor[1] = 0;
|
|
|
|
|
|
- dispc->timing_h = oscreen.hbp | oscreen.hfp | oscreen.hsw;
|
|
|
- dispc->timing_v = oscreen.vbp | oscreen.vfp | oscreen.vsw;
|
|
|
+ dispc->timing_h = (sp->hbp-1) << 20 | (sp->hfp-1) << 8 |
|
|
|
+ (sp->hsw-1);
|
|
|
+ dispc->timing_v = sp->vbp << 20 | sp->vfp << 8 |
|
|
|
+ (sp->vsw-1);
|
|
|
|
|
|
dispc->pol_req = Ipc | Ihs | Ivs | Acb;
|
|
|
- dispc->divisor = 1 << 16 | HOWMANY(432000, oscreen.pixelclock);
|
|
|
+ dispc->divisor = 1 << 16 | HOWMANY(432000, sp->pixelclock);
|
|
|
|
|
|
- dispc->lcdsize = (oscreen.ht - 1) << 16 | (oscreen.wid - 1);
|
|
|
+ dispc->lcdsize = (sp->ht - 1) << 16 | (sp->wid - 1);
|
|
|
coherence();
|
|
|
|
|
|
dispc->base[0] = PADDR(framebuf->pixel);
|
|
@@ -263,7 +283,7 @@ configdispc(void)
|
|
|
|
|
|
dispc->pos = 0; /* place screen in the left corner */
|
|
|
/* use the whole screen */
|
|
|
- dispc->size = (oscreen.ht - 1) << 16 | (oscreen.wid - 1);
|
|
|
+ dispc->size = (sp->ht - 1) << 16 | (sp->wid - 1);
|
|
|
|
|
|
/* what mode does plan 9 use for fb? */
|
|
|
dispc->attrib = Burstsize | Format | Gfxenable;
|
|
@@ -326,25 +346,174 @@ screenpower(int on)
|
|
|
blankscreen(on == 0);
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * called with drawlock locked for us, most of the time.
|
|
|
+ * kernel prints at inopportune times might mean we don't
|
|
|
+ * hold the lock, but memimagedraw is now reentrant so
|
|
|
+ * that should be okay: worst case we get cursor droppings.
|
|
|
+ */
|
|
|
+void
|
|
|
+swcursorhide(void)
|
|
|
+{
|
|
|
+ if(swvisible == 0)
|
|
|
+ return;
|
|
|
+ if(swback == nil)
|
|
|
+ return;
|
|
|
+ swvisible = 0;
|
|
|
+ memimagedraw(gscreen, swrect, swback, ZP, memopaque, ZP, S);
|
|
|
+ flushmemscreen(swrect);
|
|
|
+}
|
|
|
+
|
|
|
+void
|
|
|
+swcursoravoid(Rectangle r)
|
|
|
+{
|
|
|
+ if(swvisible && rectXrect(r, swrect))
|
|
|
+ swcursorhide();
|
|
|
+}
|
|
|
+
|
|
|
+void
|
|
|
+swcursordraw(void)
|
|
|
+{
|
|
|
+ if(swvisible)
|
|
|
+ return;
|
|
|
+ if(swenabled == 0)
|
|
|
+ return;
|
|
|
+ if(swback == nil || swimg1 == nil || swmask1 == nil)
|
|
|
+ return;
|
|
|
+// assert(!canqlock(&drawlock)); // assertion fails on omap
|
|
|
+ swvispt = swpt;
|
|
|
+ swvisvers = swvers;
|
|
|
+ swrect = rectaddpt(Rect(0,0,16,16), swvispt);
|
|
|
+ memimagedraw(swback, swback->r, gscreen, swpt, memopaque, ZP, S);
|
|
|
+ memimagedraw(gscreen, swrect, swimg1, ZP, swmask1, ZP, SoverD);
|
|
|
+ flushmemscreen(swrect);
|
|
|
+ swvisible = 1;
|
|
|
+}
|
|
|
+
|
|
|
+int
|
|
|
+cursoron(int dolock)
|
|
|
+{
|
|
|
+ if (dolock)
|
|
|
+ lock(&oscreen);
|
|
|
+ cursoroff(0);
|
|
|
+ swcursordraw();
|
|
|
+ if (dolock)
|
|
|
+ unlock(&oscreen);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+void
|
|
|
+cursoroff(int dolock)
|
|
|
+{
|
|
|
+ if (dolock)
|
|
|
+ lock(&oscreen);
|
|
|
+ swcursorhide();
|
|
|
+ if (dolock)
|
|
|
+ unlock(&oscreen);
|
|
|
+}
|
|
|
+
|
|
|
+void
|
|
|
+swload(Cursor *curs)
|
|
|
+{
|
|
|
+ uchar *ip, *mp;
|
|
|
+ int i, j, set, clr;
|
|
|
+
|
|
|
+ if(!swimg || !swmask || !swimg1 || !swmask1)
|
|
|
+ return;
|
|
|
+ /*
|
|
|
+ * Build cursor image and mask.
|
|
|
+ * Image is just the usual cursor image
|
|
|
+ * but mask is a transparent alpha mask.
|
|
|
+ *
|
|
|
+ * The 16x16x8 memimages do not have
|
|
|
+ * padding at the end of their scan lines.
|
|
|
+ */
|
|
|
+ ip = byteaddr(swimg, ZP);
|
|
|
+ mp = byteaddr(swmask, ZP);
|
|
|
+ for(i=0; i<32; i++){
|
|
|
+ set = curs->set[i];
|
|
|
+ clr = curs->clr[i];
|
|
|
+ for(j=0x80; j; j>>=1){
|
|
|
+ *ip++ = set&j ? 0x00 : 0xFF;
|
|
|
+ *mp++ = (clr|set)&j ? 0xFF : 0x00;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ swoffset = curs->offset;
|
|
|
+ swvers++;
|
|
|
+ memimagedraw(swimg1, swimg1->r, swimg, ZP, memopaque, ZP, S);
|
|
|
+ memimagedraw(swmask1, swmask1->r, swmask, ZP, memopaque, ZP, S);
|
|
|
+}
|
|
|
+
|
|
|
+/* called from devmouse */
|
|
|
+void
|
|
|
+setcursor(Cursor* curs)
|
|
|
+{
|
|
|
+ cursoroff(1);
|
|
|
+ oscreen.Cursor = *curs;
|
|
|
+ swload(curs);
|
|
|
+ cursoron(1);
|
|
|
+}
|
|
|
+
|
|
|
int
|
|
|
-cursoron(int) // TODO
|
|
|
+swmove(Point p)
|
|
|
{
|
|
|
+ swpt = addpt(p, swoffset);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
void
|
|
|
-cursoroff(int)
|
|
|
+swcursorclock(void)
|
|
|
{
|
|
|
+ int x;
|
|
|
+
|
|
|
+ if(!swenabled)
|
|
|
+ return;
|
|
|
+ swmove(mousexy());
|
|
|
+ if(swvisible && eqpt(swpt, swvispt) && swvers==swvisvers)
|
|
|
+ return;
|
|
|
+
|
|
|
+ x = splhi();
|
|
|
+ if(swenabled)
|
|
|
+ if(!swvisible || !eqpt(swpt, swvispt) || swvers!=swvisvers)
|
|
|
+ if(canqlock(&drawlock)){
|
|
|
+ swcursorhide();
|
|
|
+ swcursordraw();
|
|
|
+ qunlock(&drawlock);
|
|
|
+ }
|
|
|
+ splx(x);
|
|
|
}
|
|
|
|
|
|
void
|
|
|
-setcursor(Cursor* curs) // TODO
|
|
|
+swcursorinit(void)
|
|
|
{
|
|
|
-// VGAscr *scr;
|
|
|
+ static int init;
|
|
|
+
|
|
|
+ if(!init){
|
|
|
+ init = 1;
|
|
|
+ addclock0link(swcursorclock, 10);
|
|
|
+ }
|
|
|
+ if(swback){
|
|
|
+ freememimage(swback);
|
|
|
+ freememimage(swmask);
|
|
|
+ freememimage(swmask1);
|
|
|
+ freememimage(swimg);
|
|
|
+ freememimage(swimg1);
|
|
|
+ }
|
|
|
+
|
|
|
+ swback = allocmemimage(Rect(0,0,32,32), gscreen->chan);
|
|
|
+ swmask = allocmemimage(Rect(0,0,16,16), GREY8);
|
|
|
+ swmask1 = allocmemimage(Rect(0,0,16,16), GREY1);
|
|
|
+ swimg = allocmemimage(Rect(0,0,16,16), GREY8);
|
|
|
+ swimg1 = allocmemimage(Rect(0,0,16,16), GREY1);
|
|
|
+ if(swback==nil || swmask==nil || swmask1==nil || swimg==nil || swimg1 == nil){
|
|
|
+ print("software cursor: allocmemimage fails\n");
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- USED(curs);
|
|
|
-// scr = &vgascreen[0];
|
|
|
-// cursorload(scr, curs);
|
|
|
+ memfillcolor(swmask, DOpaque);
|
|
|
+ memfillcolor(swmask1, DOpaque);
|
|
|
+ memfillcolor(swimg, DBlack);
|
|
|
+ memfillcolor(swimg1, DBlack);
|
|
|
}
|
|
|
|
|
|
/* called from main and possibly later from devdss to change resolution */
|
|
@@ -355,7 +524,7 @@ screeninit(void)
|
|
|
|
|
|
if (first) {
|
|
|
iprint("screeninit...");
|
|
|
- oscreen = settings[Res1280x1024];
|
|
|
+ oscreen.settings = &settings[Res1280x1024];
|
|
|
|
|
|
lcdstop();
|
|
|
if (framebuf)
|
|
@@ -382,19 +551,22 @@ screeninit(void)
|
|
|
gscreen->width = Wid * (Depth / BI2BY) / BY2WD;
|
|
|
flushmemscreen(gscreen->r);
|
|
|
|
|
|
+ blanktime = 3; /* minutes */
|
|
|
+
|
|
|
if (first) {
|
|
|
iprint("on: blue for 3 seconds...");
|
|
|
delay(3*1000);
|
|
|
iprint("\n");
|
|
|
- }
|
|
|
-
|
|
|
- blanktime = 3; /* minutes */
|
|
|
|
|
|
- if (first) {
|
|
|
screenwin(); /* draw border & top orange bar */
|
|
|
screenputs = omapscreenputs;
|
|
|
iprint("screen: frame buffer at %#p for %dx%d\n",
|
|
|
- framebuf, oscreen.wid, oscreen.ht);
|
|
|
+ framebuf, oscreen.settings->wid, oscreen.settings->ht);
|
|
|
+
|
|
|
+ swenabled = 1;
|
|
|
+ swcursorinit(); /* needs gscreen set */
|
|
|
+ setcursor(&arrow);
|
|
|
+
|
|
|
first = 0;
|
|
|
}
|
|
|
}
|