📄 display.c
字号:
if(!case_img_) { (void)fprintf(stderr, "E - XCreateImage (case) Failed\n"); return(NULL); } for(i=0;i<casewidth / MagFactor;++i) for(j=0;j<caseheight / MagFactor;++j) { pixel = XGetPixel(case_img, i, j); for(k=0;k<MagFactor;++k) for(l=0;l<MagFactor;++l) XPutPixel(case_img_, i*MagFactor+k, j*MagFactor+l, pixel); } XDestroyImage(case_img); case_img = case_img_; sbuf = (char *)malloc(((casewidth+7)&(~7)) * caseheight); case_img_mask_ = XCreateImage(xcpDisplay, DefaultVisual(xcpDisplay, xcpScreenNum), 1, ZPixmap, 0, sbuf, casewidth, caseheight, 8, (casewidth+7)&(~7)); if(!case_img_) { (void)fprintf(stderr, "E - XCreateImage (case) Failed\n"); return(NULL); } for(i=0;i<casewidth / MagFactor;++i) for(j=0;j<caseheight / MagFactor;++j) { pixel = XGetPixel(case_img_mask, i, j); for(k=0;k<MagFactor;++k) for(l=0;l<MagFactor;++l) XPutPixel(case_img_mask_, i*MagFactor+k, j*MagFactor+l, pixel); } XDestroyImage(case_img_mask); case_img_mask = case_img_mask_; } case_bitmap = XCreatePixmap(xcpDisplay, DefaultRootWindow(xcpDisplay), casewidth, caseheight, xcpDepth);#if 1 XPutImage(xcpDisplay, case_bitmap, DefaultGC(xcpDisplay, xcpScreenNum), case_img, 0, 0, 0, 0, casewidth, caseheight);#endif case_mask = XCreatePixmap(xcpDisplay, DefaultRootWindow(xcpDisplay), casewidth, caseheight, 1); if (case_img_mask) { XGCValues values; GC maskgc = XCreateGC(xcpDisplay, case_mask, 0, &values);#if 1 XPutImage(xcpDisplay, case_mask, maskgc, case_img_mask, 0, 0, 0, 0, casewidth, caseheight);#endif XFreeGC(xcpDisplay, maskgc); XShapeCombineMask(xcpDisplay, XtWindow(topWidget), ShapeBounding, 0, 0, case_mask, ShapeSet); XDestroyImage(case_img_mask); /* Free XImage since we're done */ } XtVaSetValues(Case, XtNbackgroundPixmap, case_bitmap, NULL); XDestroyImage(case_img); /* Free XImage since we're done */ XFreePixmap(xcpDisplay, case_bitmap); /* Free Pixmap since we're done */ XFreePixmap(xcpDisplay, case_mask); } } XtMapWidget(topWidget); CreateKeys(Case); xcpCaseWindow = XtWindow(Case); if(!xcpCaseWindow) { (void)fprintf(stderr, "E - create case window failed\n"); return(NULL); }#ifdef USE_XSHM /* * try to use XShm */ if (!no_x_shm) { if (xcpCheckXshm(xcpDisplay) == 2) { /* fprintf(stderr, "X - Shared mem available, using Shared Mem Images...\n"); */ xcpLCDImage = XShmCreateImage(xcpDisplay, DefaultVisual(xcpDisplay, xcpScreenNum), depth, ZPixmap, NULL, &xcpSHMInfo, lcdwidth, lcdheight); if (xcpLCDImage) { xcpSHMInfo.shmid = shmget(IPC_PRIVATE, xcpLCDImage->bytes_per_line * xcpLCDImage->height, IPC_CREAT | 0777); screen_size = xcpLCDImage->bytes_per_line * xcpLCDImage->height; if (xcpSHMInfo.shmid) { sbuf = xcpLCDImage->data = xcpSHMInfo.shmaddr = shmat(xcpSHMInfo.shmid, NULL, 0); hitError = 0; oldErrorfunc = XSetErrorHandler(shmError); XShmAttach(xcpDisplay, &xcpSHMInfo); XSync(xcpDisplay, False); xcpUsingShm = !hitError; XSetErrorHandler(oldErrorfunc); } if (!xcpUsingShm) { XDestroyImage(xcpLCDImage); shmdt(xcpSHMInfo.shmaddr); shmctl(xcpSHMInfo.shmid, IPC_RMID, 0); } } } }#endif if (!xcpUsingShm) {#ifdef USE_XSHM if (!no_x_shm) fprintf(stderr, "X - Shared memory unavailable, using regular images\n");#endif pad = ((depth == 24) ? 32 : depth); screen_size = (((pad + 7) / 8) * lcdwidth * lcdheight); sbuf = (char *)malloc(screen_size); xcpLCDImage = XCreateImage(xcpDisplay, DefaultVisual(xcpDisplay, xcpScreenNum), depth, ZPixmap, 0, sbuf, lcdwidth, lcdheight, pad, lcdwidth * ((pad + 7) / 8)); if(!xcpLCDImage) { fprintf(stderr, "E - XCreateImage Failed\n"); return(NULL); } } xcpLCDWindow = XtWindow(LCD); if(!xcpLCDWindow) { (void)fprintf(stderr, "E - create LCD window failed\n"); return(NULL); } /* * Build the LCD GC (for rendering in the LCD window) */ { XGCValues gc_values; gc_values.foreground = xcpOffPixel; gc_values.background = xcpOnPixel; xcpLCDgc = XCreateGC(xcpDisplay, xcpLCDWindow, GCForeground|GCBackground, &gc_values); } /* Trap WM_DELETE_WINDOW */ xcpDeleteWindow = XInternAtom(XtDisplay(topWidget), "WM_DELETE_WINDOW", False); if (xcpDeleteWindow != (Atom)0) { XSetWMProtocols(XtDisplay(topWidget), XtWindow(topWidget), &xcpDeleteWindow, 1); XtAddEventHandler(topWidget, NoEventMask, True, HandleClientMessage, (XtPointer)xcpDeleteWindow); } /* * Install signal handlers * and flag xcpStarted */ signal(SIGHUP, xcpSignalQuit); signal(SIGINT, xcpSignalQuit); signal(SIGQUIT, xcpSignalQuit); signal(SIGTERM, xcpSignalQuit); xcpStarted = 1; return sbuf;}/********************************************** * Update the LCD screen * * sbuf is the pointer to the XImage storage, * * screenmap is a pointer to the screen ram * * area of the Pilot. * **********************************************/static void xcpUpdateLCD(char *sbuf, const unsigned char *screenmap, const shared_img *shptr){ const unsigned char VPW = shptr->VPW; const unsigned char POSR = shptr->POSR; const unsigned char PICF = shptr->PICF; const int depth = xcpDepth / 8 + (xcpDepth == 24); int backlight = shptr->Backlight ? 7 : 0; int twobit = PICF & 0x01; const unsigned char *srcstart = screenmap + ((POSR & (0x04 | !twobit << 3)) ? 1 : 0); int shiftstart = (6 | !twobit) - (twobit + 1) * (POSR & (0x03 | !twobit << 2)); int maskstart = (1 | twobit << 1) << shiftstart; unsigned char *dststart = (unsigned char *)sbuf; int row; int min_x = lcdwidth, min_y = lcdheight, max_x = 0, max_y = 0;#ifdef WORDS_BIGENDIAN#define GOOD_ENDIAN(x) (x)#else/* Wonk: sizeof(unsigned char *) must be == sizeof(uint32) - Ian */#define GOOD_ENDIAN(x) ((unsigned char *)(((uint32)(x))^1UL))#endif#define PUTPIXEL(type, dstptr, x) { \ int i, j; \ for (i = 0; i < MagFactor; i++) { \ for (j = 0; j < MagFactor; j++) { \ type *pixdest = (type *)(dstptr + j * lcdwidth * sizeof(type)); \ if (*pixdest != x) { \ *pixdest = x; \ if (bit < min_x) \ min_x = bit; \ if (bit > max_x) \ max_x = bit; \ if (row < min_y) \ min_y = row; \ if (row > max_y) \ max_y = row; \ } \ } \ dstptr += sizeof(type); \ } \ } for (row = 0; row < lcdheight; row += MagFactor) { const unsigned char *src = srcstart; unsigned char *dst = dststart; int shift = shiftstart; int mask = maskstart; int bit; for (bit = 0; bit < lcdwidth; bit += MagFactor) { unsigned int grey; unsigned long pixel; grey = twobit ? shptr->grpalette[(*(GOOD_ENDIAN(src)) & mask) >> shift] : ((*(GOOD_ENDIAN(src)) & mask) ? 6 : 0); pixel = xcpGreys[grey + backlight].pixel; switch(depth) { case 1: PUTPIXEL(uint8, dst, pixel); break; case 2: PUTPIXEL(uint16, dst, pixel); break; case 4: PUTPIXEL(uint32, dst, pixel); break; } if (shift) { shift -= 1 + twobit; mask >>= 1 + twobit; } else { shift = 6 | !twobit; mask = (1 | twobit << 1) << (6 | !twobit); ++src; } } if ((min_x <= max_x) && (row == lcdheight - MagFactor || !(row + 1 % 10))) { xcpPutImage(min_x, min_y, max_x - min_x + MagFactor, max_y - min_y + MagFactor); min_x = lcdwidth; min_y = lcdheight; max_x = 0; max_y = 0; } srcstart += 2 * VPW; dststart += MagFactor * lcdwidth * depth; } XFlush(xcpDisplay);}#define UTIMER 50 /* how long between updates (milliseconds) */extern void *CPU_getmemptr(CPTR addr);static void RingBell(int percent, int pitch, int duration){ XKeyboardState old; XKeyboardControl new; new.bell_percent = percent; new.bell_pitch = pitch; new.bell_duration = duration; XGetKeyboardControl(xcpDisplay, &old); XChangeKeyboardControl(xcpDisplay, KBBellPercent | KBBellPitch | KBBellDuration, &new); XBell(xcpDisplay, 0); new.bell_percent = old.bell_percent; new.bell_pitch = old.bell_pitch; new.bell_duration = old.bell_duration; XChangeKeyboardControl(xcpDisplay, KBBellPercent | KBBellPitch | KBBellDuration, &new); XFlush(xcpDisplay);}static void CreateMenus(void){ extern char *id_version; app = mx_appearance_create(xcpDisplay, xcpScreenNum, xcpCaseWindow, "lucidasans-14", 2, 3, 0, 0, NULL, xcpHandleExpose); panel_main = mx_panel_create(xcpDisplay, app, XtNumber(main_items), main_items); about_items[0].text = id_version; panel_about = mx_panel_create(xcpDisplay, app, XtNumber(about_items), about_items); panel_ok = mx_panel_create(xcpDisplay, app, XtNumber(ok_items), ok_items); panel_appok = mx_panel_create(xcpDisplay, app, XtNumber(appok_items), appok_items); panel_appfail = mx_panel_create(xcpDisplay, app, XtNumber(appfail_items), appfail_items);}static void tick_LCD(void){ static int cleared = 0; if (shared->LcdPower == lcdOff) { /* When screen is turned off, make everything "black". */ if (cleared == 0) { XClearWindow (xcpDisplay, xcpLCDWindow); XFlush(xcpDisplay); cleared = 1; } } else { unsigned char *scrnmap; if (cleared) { /* The display was turned back on */ xcpPutImage(0, 0, lcdwidth, lcdheight); XFlush(xcpDisplay); } /* Get current location of screen ram from dragonball register * LSSA, then update LCD */ scrnmap = (unsigned char *)CPU_getmemptr(shared->lssa & ~1); xcpUpdateLCD(new_sbuf, scrnmap, shared); cleared = 0; } /* maybe ring the bell */ if (shared->LcdReq == lcdBell) { RingBell(shared->BellAmp, shared->BellFreq, shared->BellDur); shared->LcdReq = lcdNone; }}static void tick_LCD2(XtPointer closure, XtIntervalId *id){ XtAppContext context = (XtAppContext) closure; tick_LCD(); XtAppAddTimeOut(context, UTIMER, tick_LCD2, context);}/*********************************************** * This is the main event loop * * We loop in here updating the LCD screen * * while mapping mouse events to xcpPenEvent's * ***********************************************/void xcpEventLoop(XtAppContext context, Widget topWidget, char *sbuf, shared_img *shptr){ CreateMenus(); /* Once we drop out of the event loop it means we are quitting.. */ new_sbuf = sbuf; tick_LCD2(context, NULL); XtAppMainLoop(context); shptr->CpuReq = cpuExit; xcpCleanup(); return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -