long FAR PASCAL _export ccc_win_proc(HWND hwnd, UINT message, UINT wParam, LONG lParam) { static int paint_flag = 1; // tells WinProc to call ccc_win_main() PAINTSTRUCT ps; // the display's paint struct HDC mainwin_hdc; HINSTANCE hInstance; switch (message) { case WM_PAINT: mainwin_hdc = BeginPaint(hwnd, &ps); if (paint_flag) { paint_flag = false; // flag must be set first in case cwin.open(hwnd, mainwin_hdc); ccc_win_main(); } else cwin.repaint(ps); EndPaint(hwnd, &ps); break; case WM_DESTROY: cwin.close(); exit(0); } return DefWindowProc(hwnd, message, wParam, lParam); }
int main(int argc, char** argv) { // The usual X overhead... unsigned int width, height; // window size unsigned int border_width = 4; char* window_name = argv[0]; char* icon_name = "GCT"; Pixmap icon_pixmap; XSizeHints* size_hints; XWMHints* wm_hints; XClassHint* class_hints; XTextProperty windowName; XTextProperty iconName; XEvent report; int window_size_ok = 1; char* display_name = 0; char* progname = argv[0]; Window win; Display* display; int screen_num; // check allocation of hints if (!(size_hints = XAllocSizeHints()) || !(wm_hints = XAllocWMHints()) || !(class_hints = XAllocClassHint())) { cerr << progname << " error: failure allocating memory" << endl; exit(-1); } progname = argv[0]; // connect to X server display = XOpenDisplay(display_name); if (display == NULL) { cerr << progname << " error: can't connect to server " << XDisplayName(display_name) << endl; exit(-1); } // get screen size from display structure macro screen_num = DefaultScreen(display); win = XCreateSimpleWindow(display, RootWindow(display, screen_num), 0, 0, DEF_WIDTH, DEF_HEIGHT, border_width, BlackPixel(display, screen_num), WhitePixel(display, screen_num)); if (XStringListToTextProperty(&window_name, 1, &windowName) == 0) { cerr << progname << " error: structure allocation for windowName failed." << endl; exit(-1); } if (XStringListToTextProperty(&icon_name, 1, &iconName) == 0) { cerr << progname << " error: structure allocation for iconName failed." << endl; exit(-1); } size_hints->flags = PPosition | PSize | PMinSize; size_hints->min_width = DEF_WIDTH; size_hints->min_height = DEF_HEIGHT; wm_hints->initial_state = NormalState; wm_hints->input = True; wm_hints->icon_pixmap = icon_pixmap; wm_hints->flags = StateHint | IconPixmapHint | InputHint; class_hints->res_name = progname; class_hints->res_class = "chigcx"; XSetWMProperties(display, win, &windowName, &iconName, argv, argc, size_hints, wm_hints, class_hints); // Select desired event types XSelectInput(display, win, ExposureMask | KeyPressMask | ButtonPressMask); // Highly intuitive way to state that we can process "delete window" Atom delete_atom = XInternAtom(display, "WM_DELETE_WINDOW", false); XSetWMProtocols(display, win, &delete_atom, 1); XMapWindow(display, win); cwin.open(display, win); // Event loop int draw_flag = 1; while (true) { XNextEvent(display, &report); switch ((int)report.type) { case Expose: if (report.xexpose.count == 0) { if (window_size_ok) { if (draw_flag) { ccc_win_main(); draw_flag = 0; } else cwin.repaint(); } } break; case ConfigureNotify: /* window has been resized, change width and height to send to draw_text and draw_graphics in next Expose */ width = report.xconfigure.width; height = report.xconfigure.height; window_size_ok = (width >= size_hints->min_width) && (height >= size_hints->min_height); break; case ClientMessage: if (report.xclient.data.l[0] == delete_atom) { cwin.close(); exit(0); } break; case ButtonPress: case KeyPress: default: break; } } return 0; }