LRESULT CALLBACK cursesWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { win32CursesCtx *ctx = (win32CursesCtx*)GetWindowLongPtr(hwnd,GWLP_USERDATA); #ifdef _WIN32 static int Scroll_Message; if (!Scroll_Message) { Scroll_Message = (int)RegisterWindowMessage("MSWHEEL_ROLLMSG"); if (!Scroll_Message) Scroll_Message=-1; } if (Scroll_Message > 0 && uMsg == (UINT)Scroll_Message) { uMsg=WM_MOUSEWHEEL; wParam<<=16; } #endif if (ctx)switch (uMsg) { case WM_DESTROY: ctx->m_hwnd=0; return 0; #ifdef WIN32_CONSOLE_KBQUEUE case WM_CHAR: case WM_KEYDOWN: { int a=xlateKey(uMsg,wParam,lParam); if (a != ERR && ctx->m_kbq) { ctx->m_kbq->Add(&a,sizeof(int)); } } case WM_KEYUP: return 0; #endif case WM_GETMINMAXINFO: { LPMINMAXINFO p=(LPMINMAXINFO)lParam; p->ptMinTrackSize.x = 160; p->ptMinTrackSize.y = 120; } return 0; case WM_SIZE: if (wParam != SIZE_MINIMIZED) { m_reinit_framebuffer(ctx); ctx->m_need_redraw=1; } return 0; case WM_RBUTTONDOWN: case WM_LBUTTONDOWN: SetFocus(hwnd); case WM_LBUTTONUP: case WM_RBUTTONUP: case WM_CAPTURECHANGED: case WM_MOUSEMOVE: case WM_MOUSEWHEEL: if (ctx && ctx->onMouseMessage) return ctx->onMouseMessage(ctx->user_data,hwnd,uMsg,wParam,lParam); return 0; #ifdef _WIN32 case WM_GETDLGCODE: if (GetParent(hwnd)) { return DLGC_WANTALLKEYS; } return 0; #endif case WM_TIMER: if (wParam==CURSOR_BLINK_TIMER && ctx) { int la = ctx->m_cursor_state; ctx->m_cursor_state= (ctx->m_cursor_state+1)%CURSOR_BLINK_TIMER_ZEROEVERY; if (!!ctx->m_cursor_state != !!la) __move(ctx,ctx->m_cursor_y,ctx->m_cursor_x,1);// refresh cursor } #ifdef WIN32_CONSOLE_KBQUEUE if (wParam == 1) { if (!ctx->m_intimer) { ctx->m_intimer=1; if (ctx->ui_run) ctx->ui_run(ctx); ctx->m_intimer=0; } } #endif return 0; case WM_CREATE: // this only is called on osx or from standalone, it seems, since on win32 ctx isnt set up yet ctx->m_hwnd=hwnd; #ifdef WIN32_CONSOLE_KBQUEUE SetTimer(hwnd,1,33,NULL); #endif #ifndef _WIN32 m_reinit_framebuffer(ctx); ctx->m_need_redraw=1; #endif SetTimer(hwnd,CURSOR_BLINK_TIMER,CURSOR_BLINK_TIMER_MS,NULL); return 0; case WM_ERASEBKGND: return 0; case WM_PAINT: { RECT r; #ifdef _WIN32 if (GetUpdateRect(hwnd,&r,FALSE)) #else GetClientRect(hwnd,&r); #endif { PAINTSTRUCT ps; HDC hdc=BeginPaint(hwnd,&ps); if (hdc) { doFontCalc(ctx,ps.hdc); HGDIOBJ oldf=SelectObject(hdc,ctx->mOurFont); int y,ypos; int lattr=-1; #ifdef _WIN32 SetTextAlign(hdc,TA_TOP|TA_LEFT); #endif const char *ptr=(const char*)ctx->m_framebuffer; RECT updr=r; r.left /= ctx->m_font_w; r.top /= ctx->m_font_h; r.bottom += ctx->m_font_h-1; r.bottom /= ctx->m_font_h; r.right += ctx->m_font_w-1; r.right /= ctx->m_font_w; ypos = r.top * ctx->m_font_h; ptr += 2*(r.top * ctx->cols); if (r.top < 0) r.top=0; if (r.bottom > ctx->lines) r.bottom=ctx->lines; if (r.left < 0) r.left=0; if (r.right > ctx->cols) r.right=ctx->cols; HBRUSH bgbrushes[COLOR_PAIRS << NUM_ATTRBITS]; for(y=0;y<sizeof(bgbrushes)/sizeof(bgbrushes[0]);y++) bgbrushes[y] = CreateSolidBrush(ctx->colortab[y][1]); int cstate=ctx->m_cursor_state; if (ctx->m_cursor_y != ctx->m_cursor_state_ly || ctx->m_cursor_x != ctx->m_cursor_state_lx) { ctx->m_cursor_state_lx=ctx->m_cursor_x; ctx->m_cursor_state_ly=ctx->m_cursor_y; ctx->m_cursor_state=0; cstate=1; } if (ctx->m_framebuffer) for (y = r.top; y < r.bottom; y ++, ypos+=ctx->m_font_h, ptr += ctx->cols*2) { int x = r.left,xpos = r.left * ctx->m_font_w; const char *p = ptr + r.left*2; int defer_blanks=0; for (;; x ++, xpos+=ctx->m_font_w, p += 2) { char c=' ',attr=0; if (x < r.right) { c=p[0]; attr=p[1]; } bool isCursor = cstate && y == ctx->m_cursor_y && x == ctx->m_cursor_x; bool isNotBlank = (isprint(c) && !isspace(c)); if (defer_blanks > 0 && (isNotBlank || isCursor || attr != lattr || x>=r.right)) { RECT tr={xpos - defer_blanks*ctx->m_font_w,ypos,xpos,ypos+ctx->m_font_h}; FillRect(hdc,&tr,bgbrushes[lattr&((COLOR_PAIRS << NUM_ATTRBITS)-1)]); defer_blanks=0; } if (x>=r.right) break; #if WIN32_CURSES_CURSORTYPE == 0 if (isCursor) { SetTextColor(hdc,ctx->colortab[attr&((COLOR_PAIRS << NUM_ATTRBITS)-1)][1]); SetBkColor(hdc,ctx->colortab[attr&((COLOR_PAIRS << NUM_ATTRBITS)-1)][0]); lattr = -1; } else #endif // WIN32_CURSES_CURSORTYPE == 0 if (attr != lattr) { SetTextColor(hdc,ctx->colortab[attr&((COLOR_PAIRS << NUM_ATTRBITS)-1)][0]); SetBkColor(hdc,ctx->colortab[attr&((COLOR_PAIRS << NUM_ATTRBITS)-1)][1]); lattr=attr; } if (isNotBlank||isCursor) { #ifdef _WIN32 int txpos = xpos; TextOut(hdc,txpos,ypos,isNotBlank ? p : " ",1); #else RECT tr={xpos,ypos,xpos+32,ypos+32}; HBRUSH br=bgbrushes[attr&((COLOR_PAIRS << NUM_ATTRBITS)-1)]; #if WIN32_CURSES_CURSORTYPE == 0 if (isCursor) { br = CreateSolidBrush(ctx->colortab[attr&((COLOR_PAIRS << NUM_ATTRBITS)-1)][0]); FillRect(hdc,&tr,br); DeleteObject(br); } else #endif { FillRect(hdc,&tr,br); } char tmp[2]={c,0}; DrawText(hdc,isprint(c) && !isspace(c) ?tmp : " ",-1,&tr,DT_LEFT|DT_TOP|DT_NOPREFIX|DT_NOCLIP); #endif #if WIN32_CURSES_CURSORTYPE > 0 if (isCursor) { #if WIN32_CURSES_CURSORTYPE == 1 RECT r={xpos,ypos,xpos+2,ypos+ctx->m_font_h}; #elif WIN32_CURSES_CURSORTYPE == 2 RECT r={xpos,ypos+ctx->m_font_h-2,xpos+ctx->m_font_w,ypos+ctx->m_font_h}; #endif HBRUSH br=CreateSolidBrush(ctx->colortab[attr&((COLOR_PAIRS << NUM_ATTRBITS)-1)][0]); FillRect(hdc,&r,br); DeleteObject(br); } #endif } else { defer_blanks++; } } } int rm=ctx->cols * ctx->m_font_w; int bm=ctx->lines * ctx->m_font_h; if (updr.right >= rm) { RECT tr={max(rm,updr.left),max(updr.top,0),updr.right,updr.bottom}; FillRect(hdc,&tr,bgbrushes[0]); } if (updr.bottom >= bm) { RECT tr={max(0,updr.left),max(updr.top,bm),updr.right,updr.bottom}; FillRect(hdc,&tr,bgbrushes[0]); } for(y=0;y<sizeof(bgbrushes)/sizeof(bgbrushes[0]);y++) DeleteObject(bgbrushes[y]); SelectObject(hdc,oldf); EndPaint(hwnd,&ps); } } } return 0; } return DefWindowProc(hwnd,uMsg,wParam,lParam); }
/* get edsilone - closure (subset) subset is return value. the tunction return is boolean. have end state in subset. */ static int _closure(struct reg_pattern* pattern, struct reg_list* subset){ int have_end_state = __move(pattern, subset, 0, subset); return have_end_state; }