hotkey.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /*
  2. * hotkey.c
  3. */
  4. #include "private.h"
  5. #include "lub/string.h"
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <stdio.h>
  9. #include <assert.h>
  10. /* Symbolic key codes */
  11. const char *clish_hotkey_list[] = {
  12. "^@", /* 0 Null character */
  13. "^A", /* 1 Start of heading, = console interrupt */
  14. "^B", /* 2 Start of text, maintenance mode on HP console */
  15. "^C", /* 3 End of text */
  16. "^D", /* 4 End of transmission, not the same as ETB */
  17. "^E", /* 5 Enquiry, goes with ACK; old HP flow control */
  18. "^F", /* 6 Acknowledge, clears ENQ logon hand */
  19. "^G", /* 7 Bell, rings the bell... */
  20. "^H", /* 8 Backspace, works on HP terminals/computers */
  21. "^I", /* 9 Horizontal tab, move to next tab stop */
  22. "^J", /* 10 Line Feed */
  23. "^K", /* 11 Vertical tab */
  24. "^L", /* 12 Form Feed, page eject */
  25. "^M", /* 13 Carriage Return*/
  26. "^N", /* 14 Shift Out, alternate character set */
  27. "^O", /* 15 Shift In, resume defaultn character set */
  28. "^P", /* 16 Data link escape */
  29. "^Q", /* 17 XON, with XOFF to pause listings; "okay to send". */
  30. "^R", /* 18 Device control 2, block-mode flow control */
  31. "^S", /* 19 XOFF, with XON is TERM=18 flow control */
  32. "^T", /* 20 Device control 4 */
  33. "^U", /* 21 Negative acknowledge */
  34. "^V", /* 22 Synchronous idle */
  35. "^W", /* 23 End transmission block, not the same as EOT */
  36. "^X", /* 24 Cancel line, MPE echoes !!! */
  37. "^Y", /* 25 End of medium, Control-Y interrupt */
  38. "^Z", /* 26 Substitute */
  39. "^[", /* 27 Escape, next character is not echoed */
  40. "^\\", /* 28 File separator */
  41. "^]", /* 29 Group separator */
  42. "^^", /* 30 Record separator, block-mode terminator */
  43. "^_", /* 31 Unit separator */
  44. NULL
  45. };
  46. /*--------------------------------------------------------- */
  47. /* Search for the specified hotkey and return its hotkey structure */
  48. static clish_hotkey_t *find_hotkey(clish_hotkeyv_t *this, int code)
  49. {
  50. unsigned int i;
  51. clish_hotkey_t *result = NULL;
  52. if (!this)
  53. return NULL;
  54. /* Scan the hotkey entries in this instance */
  55. for (i = 0; i < this->num; i++) {
  56. clish_hotkey_t *hk = this->hotkeyv[i];
  57. if (code == hk->code) {
  58. result = hk;
  59. break;
  60. }
  61. }
  62. return result;
  63. }
  64. /*--------------------------------------------------------- */
  65. const char *clish_hotkeyv_cmd_by_code(clish_hotkeyv_t *this, int code)
  66. {
  67. clish_hotkey_t *hk;
  68. if (!this)
  69. return NULL;
  70. hk = find_hotkey(this, code);
  71. if (!hk)
  72. return NULL;
  73. return hk->cmd;
  74. }
  75. /*--------------------------------------------------------- */
  76. int clish_hotkeyv_insert(clish_hotkeyv_t *this,
  77. const char *key, const char *cmd)
  78. {
  79. int code = -1;
  80. int i;
  81. if (!this)
  82. return -1;
  83. /* Find out key code */
  84. i = 0;
  85. while (clish_hotkey_list[i]) {
  86. if (!strcmp(clish_hotkey_list[i], key))
  87. code = i;
  88. i++;
  89. }
  90. if (code < 0)
  91. return -1;
  92. /* Search for existance of such hotkey */
  93. clish_hotkey_t *hk = find_hotkey(this, code);
  94. if (hk) {
  95. /* release the current value */
  96. lub_string_free(hk->cmd);
  97. } else {
  98. size_t new_size = ((this->num + 1) * sizeof(clish_hotkey_t *));
  99. clish_hotkey_t **tmp;
  100. /* resize the hotkeys vector */
  101. tmp = realloc(this->hotkeyv, new_size);
  102. this->hotkeyv = tmp;
  103. /* insert reference to the parameter */
  104. hk = malloc(sizeof(*hk));
  105. this->hotkeyv[this->num++] = hk;
  106. hk->code = code;
  107. }
  108. hk->cmd = NULL;
  109. if (cmd)
  110. hk->cmd = lub_string_dup(cmd);
  111. return 0;
  112. }
  113. /*--------------------------------------------------------- */
  114. clish_hotkeyv_t *clish_hotkeyv_new(void)
  115. {
  116. clish_hotkeyv_t *this;
  117. this = malloc(sizeof(clish_hotkeyv_t));
  118. this->num = 0;
  119. this->hotkeyv = NULL;
  120. return this;
  121. }
  122. /*--------------------------------------------------------- */
  123. static void clish_hotkeyv_fini(clish_hotkeyv_t *this)
  124. {
  125. unsigned int i;
  126. for (i = 0; i < this->num; i++) {
  127. lub_string_free(this->hotkeyv[i]->cmd);
  128. free(this->hotkeyv[i]);
  129. }
  130. free(this->hotkeyv);
  131. }
  132. /*--------------------------------------------------------- */
  133. void clish_hotkeyv_delete(clish_hotkeyv_t *this)
  134. {
  135. if (!this)
  136. return;
  137. clish_hotkeyv_fini(this);
  138. free(this);
  139. }
  140. /*--------------------------------------------------------- */