Blame app.c

452870
452870
#include "app.h"
452870
452870
452870
452870
452870
int appInit(App *app) {
452870
  LOGDBG("app: init");
843e7a
  app->run = 0;
061fcf
  app->x = app->y = app->w = app->h = 0;
843e7a
  app->irx = app->iry = app->irw = app->irh = 0;
452870
  
452870
  LOGDBG("app: init: connect to xcb");
452870
  app->xcb = xcb_connect(NULL, NULL);
452870
  if (!app->xcb)
452870
    return LOGERR("app: init: cannot connect to xcb");
452870
  
452870
  LOGDBG("app: init: get screen");
452870
  app->screen = xcb_setup_roots_iterator(xcb_get_setup(app->xcb)).data;
452870
  if (app->screen) {
452870
    LOGDBG("app: init: create window");
061fcf
    
061fcf
    app->x = 0;
061fcf
    app->w = app->screen->width_in_pixels;
061fcf
    app->h = app->screen->height_in_pixels/4;
061fcf
    app->y = app->screen->height_in_pixels - app->h;
061fcf
    
061fcf
    #ifdef NOBORDER
061fcf
    int noborder = 1;
061fcf
    #else
061fcf
    int noborder = 0;
061fcf
    #endif
061fcf
    
452870
    app->win = xcb_generate_id(app->xcb);
452870
    uint32_t mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK;
452870
    uint32_t values[] = {
061fcf
      noborder,                         // override redirect
452870
        XCB_EVENT_MASK_EXPOSURE         // event mask
452870
      | XCB_EVENT_MASK_STRUCTURE_NOTIFY
452870
      | XCB_EVENT_MASK_BUTTON_PRESS
63daec
      | XCB_EVENT_MASK_BUTTON_1_MOTION
452870
      | XCB_EVENT_MASK_BUTTON_RELEASE };
452870
    xcb_create_window(
452870
      app->xcb,                      // connection
452870
      XCB_COPY_FROM_PARENT,          // depth (same as root)
452870
      app->win,                      // window id
452870
      app->screen->root,             // parent window
843e7a
      app->x, app->y,                // origin
843e7a
      app->w, app->h,                // size
452870
      10,                            // border_width
452870
      XCB_WINDOW_CLASS_INPUT_OUTPUT, // class
452870
      app->screen->root_visual,      // visual
452870
      mask,                          // additional options mask
452870
      values );                      // additional options
452870
    
452870
    uint32_t hints[9] = {
452870
      1, // mask for input hints
452870
      0, // value of input hint
452870
    };
452870
    xcb_change_property_checked(
452870
      app->xcb,
452870
      XCB_PROP_MODE_REPLACE,
452870
      app->win,
452870
      XCB_ATOM_WM_HINTS,
452870
      XCB_ATOM_WM_HINTS,
452870
      32,
452870
      sizeof(hints)/sizeof(hints[0]), hints );
452870
    
452870
    // init submodules
452870
    if (graphInit(&app->graph, app)) {
061fcf
      graphResize(&app->graph);
452870
      if (inputInit(&app->input, app)) {
452870
        if (keyboardInit(&app->keyboard, app)) {
452870
          return 1;
452870
        }
452870
        inputDeinit(&app->input);
452870
      }
452870
      graphDeinit(&app->graph);
452870
    }
452870
  } else {
452870
    LOGERR("app: init: no screen found");
452870
  }
452870
  
452870
  xcb_disconnect(app->xcb);
452870
  return 0;
452870
}
452870
452870
452870
void appDeinit(App *app) {
452870
  LOGDBG("app: deinit");
452870
  keyboardDeinit(&app->keyboard);
452870
  inputDeinit(&app->input);
452870
  graphDeinit(&app->graph);
452870
  xcb_disconnect(app->xcb);
452870
}
452870
452870
452870
int appRun(App *app) {
452870
  LOGDBG("app: run");
452870
843e7a
  if (app->run)
843e7a
    return LOGERR("app: run: seems already run");
843e7a
  app->run = 1;
843e7a
  
452870
  LOGDBG("app: run: show window");
452870
  xcb_map_window(app->xcb, app->win);
452870
  xcb_flush(app->xcb);
452870
452870
  LOGDBG("app: run: event loop");
452870
  xcb_generic_event_t *event;
452870
  while ((event = xcb_wait_for_event(app->xcb))) {
452870
    switch (event->response_type & ~0x80) {
452870
    case XCB_EXPOSE: {
452870
      xcb_expose_event_t *e = (xcb_expose_event_t*)event;
452870
      LOGDBG("app: expose: x=%d, y=%d, w=%d, h=%d", e->x, e->y, e->width, e->height);
452870
      appInvalidateRect(app, e->x, e->y, e->width, e->height);
452870
      break;
452870
    }
452870
    case XCB_CONFIGURE_NOTIFY: {
452870
      xcb_configure_notify_event_t *e = (xcb_configure_notify_event_t*)event;
843e7a
      if ( e->width
843e7a
        && e->height
843e7a
        && ( app->x != e->x
843e7a
          || app->y != e->y
843e7a
          || app->w != e->width
843e7a
          || app->h != e->height ))
843e7a
      {
843e7a
        LOGDBG("app: moved: x=%d y=%d w=%d, h=%d", e->x, e->y, e->width, e->height);
843e7a
        int resized = app->w != e->width || app->h != e->height;
843e7a
        app->x = e->x;
843e7a
        app->y = e->y;
452870
        app->w = e->width;
452870
        app->h = e->height;
061fcf
        if (resized) graphResize(&app->graph);
452870
      }
452870
      break;
452870
    }
452870
    case XCB_BUTTON_PRESS: {
452870
      xcb_button_press_event_t *e = (xcb_button_press_event_t*)event;
452870
      if (e->detail == 1) {
452870
        LOGDBG("app: mouse down: x=%d, y=%d", e->event_x, e->event_y);
452870
        keyboardMouseDown(&app->keyboard, e->event_x, e->event_y);
452870
      }
452870
      break;
452870
    }
452870
    case XCB_BUTTON_RELEASE: {
452870
      xcb_button_press_event_t *e = (xcb_button_press_event_t*)event;
452870
      if (e->detail == 1) {
452870
        LOGDBG("app: mouse up");
452870
        keyboardMouseUp(&app->keyboard);
452870
      }
452870
      break;
452870
    }
63daec
    case XCB_MOTION_NOTIFY: {
63daec
      xcb_motion_notify_event_t *e = (xcb_motion_notify_event_t*)event;
63daec
      if (e->state & Button1Mask) {
63daec
        LOGDBG("app: mouse motion: x=%d, y=%d", e->event_x, e->event_y);
63daec
        keyboardMouseMotion(&app->keyboard, e->event_x, e->event_y);
63daec
      }
63daec
      break;
63daec
    }
452870
    default: 
452870
        break;
452870
    }
452870
    free(event);
452870
    
843e7a
    if (app->run != 1) break;
843e7a
    
061fcf
    inputUpdateModifiers(&app->input);
061fcf
    keyboardResize(&app->keyboard);
061fcf
    keyboardUpdateModifiers(&app->keyboard);
452870
    if (app->irw > 0 && app->irh > 0) {
452870
      LOGDBG("app: draw: x=%d, y=%d, w=%d, h=%d", app->irx, app->iry, app->irw, app->irh);
452870
      graphDrawBackgound(&app->graph, app->irx, app->iry, app->irw, app->irh);
452870
      keyboardDraw(&app->keyboard, app->irx, app->iry, app->irw, app->irh);
452870
      xcb_flush(app->xcb);
452870
      app->irw = 0;
452870
    }
452870
  }
452870
  
843e7a
  int err = app->run == -2;
843e7a
  app->run = 0;
843e7a
  LOGDBG("app: run: done err=%d", err);
843e7a
  return !err;
843e7a
}
843e7a
843e7a
843e7a
void appStop(App *app, int err) {
843e7a
  LOGDBG("app: stop: err=%d", err);
843e7a
  if (!app->run) {
843e7a
    LOGERR("app: stop: seems not started");
843e7a
    return;
843e7a
  }
843e7a
  if (app->run == 1) app->run = -1;
843e7a
  if (err) app->run = -2;
843e7a
}
843e7a
843e7a
843e7a
void appMove(App *app, int x, int y, int w, int h) {
843e7a
  LOGDBG("app: move: x=%d, y=%d, w=%d, h=%d", x, y, w, h);
843e7a
  if (w <= 0 || h <= 0) return;
843e7a
  if (app->x == x && app->y == y && app->w == w && app->h == h)
843e7a
    return;
843e7a
  uint32_t mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
843e7a
  uint32_t values[] = { x, y, w, h };
843e7a
  xcb_configure_window(app->xcb, app->win, mask, values);
63daec
  xcb_flush(app->xcb);
452870
}
452870
452870
452870
void appInvalidateRect(App *app, int x, int y, int w, int h) {
452870
  LOGDBG("app: invalidate rect: x=%d, y=%d, w=%d, h=%d", x, y, w, h);
452870
  rectIntersect(&x, &y, &w, &h, 0, 0, app->w, app->h);
452870
  rectMerge(&app->irx, &app->iry, &app->irw, &app->irh, x, y, w, h);
d3e9d7
  LOGDBG("app: invalidate rect: summary x=%d, y=%d, w=%d, h=%d", app->irx, app->iry, app->irw, app->irh);
452870
}
452870