// Copyright 2020 The Wuffs Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// ----------------

/*
imageviewer is a simple GUI program for viewing images. On Linux, GUI means
X11. To run:

$CXX imageviewer.cc -lxcb -lxcb-image -lxcb-render -lxcb-render-util && \
  ./a.out ../../test/data/bricks-*.gif; rm -f a.out

for a C++ compiler $CXX, such as clang++ or g++.

The Space and BackSpace keys cycle through the files, if more than one was
given as command line arguments. If none were given, the program reads from
stdin.

The Return key is equivalent to the Space key.

The ',' Comma and '.' Period keys cycle through background colors, which
matters if the image has fully or partially transparent pixels.

The '1' to '8' keys change the magnification zoom (or minification zoom with
the shift key). The '0' key toggles nearest neighbor and bilinear filtering.

The arrow keys (or hjkl keys) scroll the image. The '`' key resets.

The Escape key quits.
*/

#include <inttypes.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

// Wuffs ships as a "single file C library" or "header file library" as per
// https://github.com/nothings/stb/blob/master/docs/stb_howto.txt
//
// To use that single file as a "foo.c"-like implementation, instead of a
// "foo.h"-like header, #define WUFFS_IMPLEMENTATION before #include'ing or
// compiling it.
#define WUFFS_IMPLEMENTATION

// Defining the WUFFS_CONFIG__STATIC_FUNCTIONS macro is optional, but when
// combined with WUFFS_IMPLEMENTATION, it demonstrates making all of Wuffs'
// functions have static storage.
//
// This can help the compiler ignore or discard unused code, which can produce
// faster compiles and smaller binaries. Other motivations are discussed in the
// "ALLOW STATIC IMPLEMENTATION" section of
// https://raw.githubusercontent.com/nothings/stb/master/docs/stb_howto.txt
#define WUFFS_CONFIG__STATIC_FUNCTIONS

// Defining the WUFFS_CONFIG__MODULE* macros are optional, but it lets users of
// release/c/etc.c choose which parts of Wuffs to build. That file contains the
// entire Wuffs standard library, implementing a variety of codecs and file
// formats. Without this macro definition, an optimizing compiler or linker may
// very well discard Wuffs code for unused codecs, but listing the Wuffs
// modules we use makes that process explicit. Preprocessing means that such
// code simply isn't compiled.
#define WUFFS_CONFIG__MODULES
#define WUFFS_CONFIG__MODULE__ADLER32
#define WUFFS_CONFIG__MODULE__AUX__BASE
#define WUFFS_CONFIG__MODULE__AUX__IMAGE
#define WUFFS_CONFIG__MODULE__BASE
#define WUFFS_CONFIG__MODULE__BMP
#define WUFFS_CONFIG__MODULE__CRC32
#define WUFFS_CONFIG__MODULE__DEFLATE
#define WUFFS_CONFIG__MODULE__GIF
#define WUFFS_CONFIG__MODULE__LZW
#define WUFFS_CONFIG__MODULE__NIE
#define WUFFS_CONFIG__MODULE__PNG
#define WUFFS_CONFIG__MODULE__TGA
#define WUFFS_CONFIG__MODULE__WBMP
#define WUFFS_CONFIG__MODULE__ZLIB

// If building this program in an environment that doesn't easily accommodate
// relative includes, you can use the script/inline-c-relative-includes.go
// program to generate a stand-alone C file.
#include "../../release/c/wuffs-unsupported-snapshot.c"

// X11 limits its image dimensions to uint16_t and some coordinates to int16_t.
#define MAX_INCL_DIMENSION 32767

#define NUM_BACKGROUND_COLORS 3
#define NUM_ZOOMS 8
#define SRC_BUFFER_ARRAY_SIZE (64 * 1024)

wuffs_base__color_u32_argb_premul g_background_colors[NUM_BACKGROUND_COLORS] = {
    0xFF000000,
    0xFFFFFFFF,
    0xFFA9009A,
};

uint32_t g_width = 0;
uint32_t g_height = 0;
wuffs_aux::MemOwner g_pixbuf_mem_owner(nullptr, &free);
wuffs_base__pixel_buffer g_pixbuf = {0};
uint32_t g_background_color_index = 0;
int32_t g_zoom = 0;
int32_t g_pos_x = 0;
int32_t g_pos_y = 0;
bool g_filter = false;

struct {
  int remaining_argc;
  char** remaining_argv;

  double screen_gamma;
} g_flags = {0};

static const char* g_usage =
    "Usage: imageviewer -flags input0.gif input1.png\n"
    "\n"
    "Flags:\n"
    "    -screen_gamma=N.N (default 2.2; 0 disables gamma correction)";

const char*  //
parse_flags(int argc, char** argv) {
  g_flags.screen_gamma = 2.2;

  int c = (argc > 0) ? 1 : 0;  // Skip argv[0], the program name.
  for (; c < argc; c++) {
    char* arg = argv[c];
    if (*arg++ != '-') {
      break;
    }

    // A double-dash "--foo" is equivalent to a single-dash "-foo". As special
    // cases, a bare "-" is not a flag (some programs may interpret it as
    // stdin) and a bare "--" means to stop parsing flags.
    if (*arg == '\x00') {
      break;
    } else if (*arg == '-') {
      arg++;
      if (*arg == '\x00') {
        c++;
        break;
      }
    }

    if (!strncmp(arg, "screen_gamma=", 13)) {
      g_flags.screen_gamma = atof(arg + 13);
      continue;
    }

    return g_usage;
  }

  g_flags.remaining_argc = argc - c;
  g_flags.remaining_argv = argv + c;
  return NULL;
}

class MyDecodeImageCallbacks : public wuffs_aux::DecodeImageCallbacks {
 public:
  MyDecodeImageCallbacks() : m_combined_gamma(1.0) {}

 private:
  std::string  //
  HandleMetadata(const wuffs_base__more_information& minfo,
                 wuffs_base__slice_u8 raw) override {
    if (minfo.flavor == WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_PARSED) {
      switch (minfo.metadata__fourcc()) {
        case WUFFS_BASE__FOURCC__GAMA:
          // metadata_parsed__gama returns the inverse gamma scaled by 1e5.
          m_combined_gamma =
              1e5 / (g_flags.screen_gamma * minfo.metadata_parsed__gama());
          break;
      }
    }
    return wuffs_aux::DecodeImageCallbacks::HandleMetadata(minfo, raw);
  }

  void  //
  Done(wuffs_aux::DecodeImageResult& result,
       wuffs_aux::sync_io::Input& input,
       wuffs_aux::IOBuffer& buffer,
       wuffs_base__image_decoder::unique_ptr image_decoder) override {
    // Apply basic color correction - gamma correction. Proper color correction
    // should also involve considering any CHRM, ICCP and SRGB metadata but
    // that requires a non-trivial amount of code (such as skcms, Skia's Color
    // Management System). To keep this example program simple, we only
    // consider GAMA metadata (and 8-bit color channels) here.
    //
    // This code also assumes that wuffs_aux::DecodeImageCallbacks defaults to
    // producing a WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL pixel buffer.
    if ((result.pixbuf.pixel_format().repr ==
         WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL) &&
        ((m_combined_gamma < 0.9999) || (1.0001 < m_combined_gamma))) {
      uint8_t lut[256];
      lut[0x00] = 0x00;
      lut[0xFF] = 0xFF;
      for (uint32_t i = 1; i < 0xFF; i++) {
        lut[i] =
            (uint8_t)(floor(255.0 * pow(i / 255.0, m_combined_gamma) + 0.5));
      }

      wuffs_base__table_u8 t = result.pixbuf.plane(0);
      size_t w4 = t.width / 4;
      for (size_t y = 0; y < t.height; y++) {
        uint8_t* ptr = t.ptr + (y * t.stride);
        for (size_t x = 0; x < w4; x++) {
          ptr[0] = lut[ptr[0]];
          ptr[1] = lut[ptr[1]];
          ptr[2] = lut[ptr[2]];
          ptr += 4;
        }
      }
    }
  }

  // m_combined_gamma holds the product of the screen gamma and the image
  // file's inverse gamma.
  double m_combined_gamma;
};

bool  //
load_image(const char* filename) {
  FILE* file = stdin;
  const char* adj_filename = "<stdin>";
  if (filename) {
    FILE* f = fopen(filename, "rb");
    if (f == NULL) {
      printf("%s: could not open file\n", filename);
      return false;
    }
    file = f;
    adj_filename = filename;
  }

  g_width = 0;
  g_height = 0;
  g_pixbuf_mem_owner.reset();
  g_pixbuf = wuffs_base__null_pixel_buffer();

  uint64_t dia_flags = 0;
  if (g_flags.screen_gamma > 0) {
    dia_flags |= wuffs_aux::DecodeImageArgFlags::REPORT_METADATA_GAMA;
  }

  MyDecodeImageCallbacks callbacks;
  wuffs_aux::sync_io::FileInput input(file);
  wuffs_aux::DecodeImageResult res = wuffs_aux::DecodeImage(
      callbacks, input, wuffs_aux::DecodeImageArgQuirks::DefaultValue(),
      wuffs_aux::DecodeImageArgFlags(dia_flags),
      // Use PIXEL_BLEND__SRC_OVER, not the default PIXEL_BLEND__SRC, because
      // we also pass a background color.
      wuffs_aux::DecodeImageArgPixelBlend(WUFFS_BASE__PIXEL_BLEND__SRC_OVER),
      wuffs_aux::DecodeImageArgBackgroundColor(
          g_background_colors[g_background_color_index]),
      wuffs_aux::DecodeImageArgMaxInclDimension(MAX_INCL_DIMENSION));
  if (filename) {
    fclose(file);
  }

  // wuffs_aux::DecodeImageCallbacks's default implementation should give us an
  // interleaved (not multi-planar) pixel buffer, so that all of the pixel data
  // is in a single 2-dimensional table (plane 0). Later on, we re-interpret
  // that table as XCB image data, which isn't something we could do if we had
  // e.g. multi-planar YCbCr.
  if (!res.pixbuf.pixcfg.pixel_format().is_interleaved()) {
    printf("%s: non-interleaved pixbuf\n", adj_filename);
    return false;
  }
  wuffs_base__table_u8 tab = res.pixbuf.plane(0);
  if (tab.width != tab.stride) {
    // The xcb_image_create_native call, later on, assumes that (tab.height *
    // tab.stride) bytes are readable, which isn't quite the same as what
    // wuffs_base__table__flattened_length(tab.width, tab.height, tab.stride)
    // returns unless the table is tight (its width equals its stride).
    printf("%s: could not allocate tight pixbuf\n", adj_filename);
    return false;
  }

  g_width = res.pixbuf.pixcfg.width();
  g_height = res.pixbuf.pixcfg.height();
  g_pixbuf_mem_owner = std::move(res.pixbuf_mem_owner);
  g_pixbuf = res.pixbuf;

  if (res.error_message.empty()) {
    printf("%s: ok (%" PRIu32 " x %" PRIu32 ")\n", adj_filename, g_width,
           g_height);
  } else {
    printf("%s: %s\n", adj_filename, res.error_message.c_str());
  }
  return res.pixbuf.pixcfg.is_valid();
}

// ---------------------------------------------------------------------

#if defined(__linux__)
#define SUPPORTED_OPERATING_SYSTEM

#include <xcb/render.h>
#include <xcb/xcb.h>
#include <xcb/xcb_image.h>
#include <xcb/xcb_renderutil.h>

#define XK_BackSpace 0xFF08
#define XK_Escape 0xFF1B
#define XK_Return 0xFF0D
#define XK_Left 0xFF51
#define XK_Up 0xFF52
#define XK_Right 0xFF53
#define XK_Down 0xFF54

uint32_t g_maximum_request_length = 0;  // Measured in 4-byte units.
xcb_atom_t g_atom_net_wm_name = XCB_NONE;
xcb_atom_t g_atom_utf8_string = XCB_NONE;
xcb_atom_t g_atom_wm_protocols = XCB_NONE;
xcb_atom_t g_atom_wm_delete_window = XCB_NONE;
xcb_pixmap_t g_pixmap = XCB_NONE;
xcb_gcontext_t g_pixmap_gc = XCB_NONE;
xcb_render_picture_t g_pixmap_picture = XCB_NONE;
xcb_render_pictforminfo_t* g_pictforminfo = NULL;
xcb_keysym_t* g_keysyms = NULL;
xcb_get_keyboard_mapping_reply_t* g_keyboard_mapping = NULL;

void  //
init_keymap(xcb_connection_t* c, const xcb_setup_t* z) {
  xcb_get_keyboard_mapping_cookie_t cookie = xcb_get_keyboard_mapping(
      c, z->min_keycode, z->max_keycode - z->min_keycode + 1);
  g_keyboard_mapping = xcb_get_keyboard_mapping_reply(c, cookie, NULL);
  g_keysyms = (xcb_keysym_t*)(g_keyboard_mapping + 1);
}

xcb_window_t  //
make_window(xcb_connection_t* c, xcb_screen_t* s) {
  xcb_window_t w = xcb_generate_id(c);
  uint32_t value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
  uint32_t value_list[2];
  value_list[0] = s->black_pixel;
  value_list[1] = XCB_EVENT_MASK_KEY_PRESS |        //
                  XCB_EVENT_MASK_BUTTON_PRESS |     //
                  XCB_EVENT_MASK_BUTTON_1_MOTION |  //
                  XCB_EVENT_MASK_EXPOSURE;
  xcb_create_window(c, 0, w, s->root, 0, 0, 1024, 768, 0,
                    XCB_WINDOW_CLASS_INPUT_OUTPUT, s->root_visual, value_mask,
                    value_list);
  xcb_change_property(c, XCB_PROP_MODE_REPLACE, w, g_atom_net_wm_name,
                      g_atom_utf8_string, 8, 12, "Image Viewer");
  xcb_change_property(c, XCB_PROP_MODE_REPLACE, w, g_atom_wm_protocols,
                      XCB_ATOM_ATOM, 32, 1, &g_atom_wm_delete_window);
  xcb_map_window(c, w);
  return w;
}

void  //
apply_zoom_and_filter(xcb_connection_t* c) {
  static const xcb_render_fixed_t neg_zooms[NUM_ZOOMS] = {
      0x00010000,  // 1/1 as 16.16 fixed point
      0x00020000,  // 2/1
      0x00040000,  // 4/1
      0x00080000,  // 8/1
      0x00100000,  // 16/1
      0x00200000,  // 32/1
      0x00400000,  // 64/1
      0x00800000,  // 128/1
  };
  static const xcb_render_fixed_t pos_zooms[NUM_ZOOMS] = {
      0x00010000,  // 1/1 as 16.16 fixed point
      0x00008000,  // 1/2
      0x00004000,  // 1/4
      0x00002000,  // 1/8
      0x00001000,  // 1/16
      0x00000800,  // 1/32
      0x00000400,  // 1/64
      0x00000200,  // 1/128
  };

  xcb_render_fixed_t z = g_zoom < 0
                             ? neg_zooms[((uint32_t)(-g_zoom)) % NUM_ZOOMS]
                             : pos_zooms[((uint32_t)(+g_zoom)) % NUM_ZOOMS];
  xcb_render_set_picture_transform(c, g_pixmap_picture,
                                   ((xcb_render_transform_t){
                                       z, 0, 0,        //
                                       0, z, 0,        //
                                       0, 0, 0x10000,  //
                                   }));

  uint16_t f_len = 7;
  const char* f_ptr = "nearest";
  if (g_filter && (g_zoom != 0)) {
    f_len = 8;
    f_ptr = "bilinear";
  }
  xcb_render_set_picture_filter(c, g_pixmap_picture, f_len, f_ptr, 0, NULL);
}

// zoom_shift returns (a << g_zoom), roughly speaking, but saturates at an
// arbitrary value called M.
//
// The final two arguments to xcb_render_composite have uint16_t type (and
// UINT16_MAX is 65535), but in practice, values above M sometimes don't work
// in that the xcb_render_composite call has no visible effect.
//
// Some xrender debugging could potentially derive a more accurate maximum but
// for now, the M = 30000 round number will do.
uint16_t  //
zoom_shift(uint32_t a) {
  uint16_t M = 30000;
  uint64_t b = g_zoom < 0
                   ? (((uint64_t)a) >> (((uint32_t)(-g_zoom)) % NUM_ZOOMS))
                   : (((uint64_t)a) << (((uint32_t)(+g_zoom)) % NUM_ZOOMS));
  return (b < M) ? b : M;
}

int32_t  //
calculate_delta(uint16_t state) {
  if (state & XCB_MOD_MASK_SHIFT) {
    return 256;
  } else if (state & XCB_MOD_MASK_CONTROL) {
    return 1;
  }
  return 16;
}

bool  //
load(xcb_connection_t* c, xcb_window_t w, const char* filename) {
  if (g_pixmap != XCB_NONE) {
    xcb_render_free_picture(c, g_pixmap_picture);
    xcb_free_gc(c, g_pixmap_gc);
    xcb_free_pixmap(c, g_pixmap);
  }

  if (!load_image(filename)) {
    return false;
  }
  wuffs_base__table_u8 tab = g_pixbuf.plane(0);

  xcb_create_pixmap(c, g_pictforminfo->depth, g_pixmap, w, g_width, g_height);
  xcb_create_gc(c, g_pixmap_gc, g_pixmap, 0, NULL);
  xcb_render_create_picture(c, g_pixmap_picture, g_pixmap, g_pictforminfo->id,
                            0, NULL);
  apply_zoom_and_filter(c);

  // Copy the pixels from the X11 client process (this process) to the X11
  // server process. For large images, this may involve multiple xcb_image_put
  // calls, each copying part of the pixels (a strip that has the same width
  // but smaller height), to avoid XCB_CONN_CLOSED_REQ_LEN_EXCEED.
  if (g_width > 0) {
    uint32_t max_strip_height = g_maximum_request_length / g_width;
    for (uint32_t y = 0; y < g_height;) {
      uint32_t h = g_height - y;
      if (h > max_strip_height) {
        h = max_strip_height;
      }

      // Make libxcb-image interpret WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL as
      // XCB_PICT_STANDARD_ARGB_32 with byte_order XCB_IMAGE_ORDER_LSB_FIRST.
      xcb_image_t* unconverted =
          xcb_image_create(g_width,                      // width
                           h,                            // height
                           XCB_IMAGE_FORMAT_Z_PIXMAP,    // format
                           32,                           // xpad
                           g_pictforminfo->depth,        // depth
                           32,                           // bpp
                           32,                           // unit
                           XCB_IMAGE_ORDER_LSB_FIRST,    // byte_order
                           XCB_IMAGE_ORDER_MSB_FIRST,    // bit_order
                           NULL,                         // base
                           h * tab.stride,               // bytes
                           tab.ptr + (y * tab.stride));  // data

      xcb_image_t* converted =
          xcb_image_native(c, unconverted, true);  // true means to convert.
      if (converted != unconverted) {
        xcb_image_destroy(unconverted);
      }
      xcb_image_put(c, g_pixmap, g_pixmap_gc, converted, 0, y, 0);
      xcb_image_destroy(converted);

      y += h;
    }
  }

  return true;
}

bool  //
intersects(int32_t old_x,
           int32_t old_y,
           int32_t width,
           int32_t height,
           int32_t new_x,
           int32_t new_y) {
  if ((width <= 0) || (height <= 0)) {
    return false;
  } else if ((old_x > new_x) && ((old_x - new_x) >= width)) {
    return false;
  } else if ((new_x > old_x) && ((new_x - old_x) >= width)) {
    return false;
  } else if ((old_y > new_y) && ((old_y - new_y) >= height)) {
    return false;
  } else if ((new_y > old_y) && ((new_y - old_y) >= height)) {
    return false;
  }
  return true;
}

// clear_area clears the L-shaped difference between old and new rectangles (of
// equal width and height). It does this in up to two xcb_clear_area calls,
// labeled A and B in the example below (with old_x=0, old_y=0, width=5,
// height=4, new_x=2, new_y=2).
//
// If the old and new rectangles do not intersect then the old rectangle (not
// an L-shape) will be cleared.
//
// AAAAA
// AAAAA
// BB+---+
// BB|   |
//   |   |
//   +---+
void  //
clear_area(xcb_connection_t* c,
           xcb_window_t w,
           int32_t old_x,
           int32_t old_y,
           int32_t width,
           int32_t height,
           int32_t new_x,
           int32_t new_y) {
  if ((width <= 0) || (height <= 0)) {
    return;
  } else if (!intersects(old_x, old_y, width, height, new_x, new_y)) {
    xcb_clear_area(c, 1, w, old_x, old_y, width, height);
    return;
  }

  int32_t dy = new_y - old_y;
  if (dy < 0) {
    xcb_clear_area(c, 1, w, old_x, old_y + height + dy, width, -dy);
  } else if (dy > 0) {
    xcb_clear_area(c, 1, w, old_x, old_y, width, dy);
  }

  int32_t y0 = wuffs_base__i32__max(old_y, new_y);
  int32_t y1 = wuffs_base__i32__min(old_y + height, new_y + height);

  int32_t dx = new_x - old_x;
  if (dx < 0) {
    xcb_clear_area(c, 1, w, old_x + width + dx, y0, -dx, y1 - y0);
  } else if (dx > 0) {
    xcb_clear_area(c, 1, w, old_x, y0, dx, y1 - y0);
  }
}

int  //
main(int argc, char** argv) {
  const char* status = parse_flags(argc, argv);
  if (status) {
    fprintf(stderr, "%s\n", status);
    return 1;
  }

  xcb_connection_t* c = xcb_connect(NULL, NULL);

  g_maximum_request_length = xcb_get_maximum_request_length(c);
  // Our X11 requests (especially xcb_image_put) also need a header, in terms
  // of wire format. 256 4-byte units should be big enough.
  const uint32_t max_req_len_adjustment = 256;
  if (g_maximum_request_length < max_req_len_adjustment) {
    printf("XCB failure (maximum request length is too short)\n");
    exit(EXIT_FAILURE);
  }
  g_maximum_request_length -= max_req_len_adjustment;

  const xcb_setup_t* z = xcb_get_setup(c);
  xcb_screen_t* s = xcb_setup_roots_iterator(z).data;

  const xcb_render_query_pict_formats_reply_t* pict_formats =
      xcb_render_util_query_formats(c);
  g_pictforminfo = xcb_render_util_find_standard_format(
      pict_formats, XCB_PICT_STANDARD_ARGB_32);

  {
    xcb_intern_atom_cookie_t cookie0 =
        xcb_intern_atom(c, 1, 12, "_NET_WM_NAME");
    xcb_intern_atom_cookie_t cookie1 = xcb_intern_atom(c, 1, 11, "UTF8_STRING");
    xcb_intern_atom_cookie_t cookie2 =
        xcb_intern_atom(c, 1, 12, "WM_PROTOCOLS");
    xcb_intern_atom_cookie_t cookie3 =
        xcb_intern_atom(c, 1, 16, "WM_DELETE_WINDOW");
    xcb_intern_atom_reply_t* reply0 = xcb_intern_atom_reply(c, cookie0, NULL);
    xcb_intern_atom_reply_t* reply1 = xcb_intern_atom_reply(c, cookie1, NULL);
    xcb_intern_atom_reply_t* reply2 = xcb_intern_atom_reply(c, cookie2, NULL);
    xcb_intern_atom_reply_t* reply3 = xcb_intern_atom_reply(c, cookie3, NULL);
    g_atom_net_wm_name = reply0->atom;
    g_atom_utf8_string = reply1->atom;
    g_atom_wm_protocols = reply2->atom;
    g_atom_wm_delete_window = reply3->atom;
    free(reply0);
    free(reply1);
    free(reply2);
    free(reply3);
  }

  xcb_window_t w = make_window(c, s);
  xcb_render_picture_t p = xcb_generate_id(c);
  xcb_render_create_picture(
      c, p, w,
      xcb_render_util_find_visual_format(pict_formats, s->root_visual)->format,
      0, NULL);
  init_keymap(c, z);
  xcb_flush(c);

  g_pixmap = xcb_generate_id(c);
  g_pixmap_gc = xcb_generate_id(c);
  g_pixmap_picture = xcb_generate_id(c);

  int32_t button_x = 0;
  int32_t button_y = 0;

  bool loaded = load(
      c, w, (g_flags.remaining_argc > 0) ? g_flags.remaining_argv[0] : NULL);
  int arg = 0;

  while (true) {
    xcb_generic_event_t* event = xcb_wait_for_event(c);
    if (!event) {
      printf("XCB failure (error code %d)\n", xcb_connection_has_error(c));
      exit(EXIT_FAILURE);
    }

    bool reload = false;
    int32_t old_pos_x = g_pos_x;
    int32_t old_pos_y = g_pos_y;
    switch (event->response_type & 0x7F) {
      case XCB_EXPOSE: {
        xcb_expose_event_t* e = (xcb_expose_event_t*)event;
        if (loaded && (e->count == 0)) {
          xcb_render_composite(c, XCB_RENDER_PICT_OP_SRC, g_pixmap_picture,
                               XCB_NONE, p, 0, 0, 0, 0, g_pos_x, g_pos_y,
                               zoom_shift(g_width), zoom_shift(g_height));
          xcb_flush(c);
        }
        break;
      }

      case XCB_KEY_PRESS: {
        xcb_key_press_event_t* e = (xcb_key_press_event_t*)event;
        uint32_t i = e->detail;
        if ((z->min_keycode <= i) && (i <= z->max_keycode)) {
          i = g_keysyms[(i - z->min_keycode) *
                        g_keyboard_mapping->keysyms_per_keycode];
          switch (i) {
            case XK_Escape:
              return 0;

            case ' ':
            case XK_BackSpace:
            case XK_Return:
              if (g_flags.remaining_argc <= 1) {
                break;
              }
              arg += (i != XK_BackSpace) ? +1 : -1;
              if (arg < 0) {
                arg = g_flags.remaining_argc - 1;
              } else if (arg == g_flags.remaining_argc) {
                arg = 0;
              }
              reload = true;
              break;

            case ',':
            case '.':
              g_background_color_index +=
                  (i == ',') ? (NUM_BACKGROUND_COLORS - 1) : 1;
              g_background_color_index %= NUM_BACKGROUND_COLORS;
              reload = true;
              break;

            case '`':
              g_pos_x = 0;
              g_pos_y = 0;
              break;

            case XK_Left:
            case 'h':
              g_pos_x += calculate_delta(e->state);
              break;

            case XK_Down:
            case 'j':
              g_pos_y -= calculate_delta(e->state);
              break;

            case XK_Up:
            case 'k':
              g_pos_y += calculate_delta(e->state);
              break;

            case XK_Right:
            case 'l':
              g_pos_x -= calculate_delta(e->state);
              break;

            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
              if (i == '0') {
                g_filter = !g_filter;
              } else {
                int32_t z = i - '1';
                if (e->state & XCB_MOD_MASK_SHIFT) {
                  z = -z;
                }
                if (g_zoom == z) {
                  break;
                }
                g_zoom = z;
              }
              apply_zoom_and_filter(c);
              xcb_clear_area(c, 1, w, 0, 0, 0xFFFF, 0xFFFF);
              xcb_flush(c);
              break;
          }
        }
        break;
      }

      case XCB_BUTTON_PRESS: {
        xcb_button_press_event_t* e = (xcb_button_press_event_t*)event;
        switch (e->detail) {
          case 1:
            button_x = e->event_x;
            button_y = e->event_y;
            break;
          case 4:
            g_pos_y += calculate_delta(e->state);
            break;
          case 5:
            g_pos_y -= calculate_delta(e->state);
            break;
          case 6:
            g_pos_x += calculate_delta(e->state);
            break;
          case 7:
            g_pos_x -= calculate_delta(e->state);
            break;
        }
        break;
      }

      case XCB_MOTION_NOTIFY: {
        xcb_motion_notify_event_t* e = (xcb_motion_notify_event_t*)event;
        g_pos_x += e->event_x - button_x;
        g_pos_y += e->event_y - button_y;
        button_x = e->event_x;
        button_y = e->event_y;
        break;
      }

      case XCB_CLIENT_MESSAGE: {
        xcb_client_message_event_t* e = (xcb_client_message_event_t*)event;
        if (e->data.data32[0] == g_atom_wm_delete_window) {
          return 0;
        }
        break;
      }
    }

    free(event);

    if (reload) {
      loaded = load(c, w, g_flags.remaining_argv[arg]);
      xcb_clear_area(c, 1, w, 0, 0, 0xFFFF, 0xFFFF);
      xcb_flush(c);
    } else if (loaded &&  //
               ((old_pos_x != g_pos_x) || (old_pos_y != g_pos_y))) {
      clear_area(c, w, old_pos_x, old_pos_y, zoom_shift(g_width),
                 zoom_shift(g_height), g_pos_x, g_pos_y);
      xcb_render_composite(c, XCB_RENDER_PICT_OP_SRC, g_pixmap_picture,
                           XCB_NONE, p, 0, 0, 0, 0, g_pos_x, g_pos_y,
                           zoom_shift(g_width), zoom_shift(g_height));
      xcb_flush(c);
    }
  }
  return 0;
}

#endif  // defined(__linux__)

// ---------------------------------------------------------------------

#if !defined(SUPPORTED_OPERATING_SYSTEM)

int  //
main(int argc, char** argv) {
  printf("unsupported operating system\n");
  return 1;
}

#endif  // !defined(SUPPORTED_OPERATING_SYSTEM)
