You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

113 lines
2.7 KiB

  1. #include "dcs.h"
  2. #define LOG_MODULE "dcs"
  3. #define LOG_ENABLE_DBG 0
  4. #include "log.h"
  5. #include "sixel.h"
  6. #include "vt.h"
  7. static void
  8. bsu(struct terminal *term)
  9. {
  10. /* https://gitlab.com/gnachman/iterm2/-/wikis/synchronized-updates-spec */
  11. LOG_DBG("untested: BSU - Begin Synchronized Update (params: %.*s)",
  12. (int)term->vt.dcs.idx, term->vt.dcs.data);
  13. term_enable_app_sync_updates(term);
  14. }
  15. static void
  16. esu(struct terminal *term)
  17. {
  18. /* https://gitlab.com/gnachman/iterm2/-/wikis/synchronized-updates-spec */
  19. LOG_DBG("untested: ESU - End Synchronized Update (params: %.*s)",
  20. (int)term->vt.dcs.idx, term->vt.dcs.data);
  21. term_disable_app_sync_updates(term);
  22. }
  23. void
  24. dcs_hook(struct terminal *term, uint8_t final)
  25. {
  26. LOG_DBG("hook: %c (intermediate(s): %.2s, param=%d)", final, term->vt.private,
  27. vt_param_get(term, 0, 0));
  28. assert(term->vt.dcs.data == NULL);
  29. assert(term->vt.dcs.size == 0);
  30. assert(term->vt.dcs.put_handler == NULL);
  31. assert(term->vt.dcs.unhook_handler == NULL);
  32. switch (term->vt.private[0]) {
  33. case 0:
  34. switch (final) {
  35. case 'q':
  36. sixel_init(term);
  37. term->vt.dcs.put_handler = &sixel_put;
  38. term->vt.dcs.unhook_handler = &sixel_unhook;
  39. break;
  40. }
  41. break;
  42. case '=':
  43. switch (final) {
  44. case 's':
  45. switch (vt_param_get(term, 0, 0)) {
  46. case 1: term->vt.dcs.unhook_handler = &bsu; return;
  47. case 2: term->vt.dcs.unhook_handler = &esu; return;
  48. }
  49. break;
  50. }
  51. break;
  52. }
  53. }
  54. static bool
  55. ensure_size(struct terminal *term, size_t required_size)
  56. {
  57. if (required_size <= term->vt.dcs.size)
  58. return true;
  59. size_t new_size = (required_size + 127) / 128 * 128;
  60. assert(new_size > 0);
  61. uint8_t *new_data = realloc(term->vt.dcs.data, new_size);
  62. if (new_data == NULL) {
  63. LOG_ERRNO("failed to increase size of DCS buffer");
  64. return false;
  65. }
  66. term->vt.dcs.data = new_data;
  67. term->vt.dcs.size = new_size;
  68. return true;
  69. }
  70. void
  71. dcs_put(struct terminal *term, uint8_t c)
  72. {
  73. LOG_DBG("PUT: %c", c);
  74. if (term->vt.dcs.put_handler != NULL)
  75. term->vt.dcs.put_handler(term, c);
  76. else {
  77. if (!ensure_size(term, term->vt.dcs.idx + 1))
  78. return;
  79. term->vt.dcs.data[term->vt.dcs.idx++] = c;
  80. }
  81. }
  82. void
  83. dcs_unhook(struct terminal *term)
  84. {
  85. if (term->vt.dcs.unhook_handler != NULL)
  86. term->vt.dcs.unhook_handler(term);
  87. term->vt.dcs.unhook_handler = NULL;
  88. term->vt.dcs.put_handler = NULL;
  89. free(term->vt.dcs.data);
  90. term->vt.dcs.data = NULL;
  91. term->vt.dcs.size = 0;
  92. term->vt.dcs.idx = 0;
  93. }