Source code of Windows XP (NT5)
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.

312 lines
7.3 KiB

  1. /*++
  2. Copyright (c) 1999 Intel Corporation
  3. Module Name:
  4. libClipboard.c
  5. Abstract:
  6. Implementation of the "clipboard"
  7. --*/
  8. #ifndef _LIB_CLIPBOARD
  9. #define _LIB_CLIPBOARD
  10. #include "libMisc.h"
  11. STATIC EFI_STATUS ClipboardInit (VOID);
  12. STATIC EFI_STATUS ClipboardCleanup(VOID);
  13. STATIC EFI_STATUS ClipboardClear (VOID);
  14. STATIC EFI_STATUS ClipboardCut (UINTN,UINTN);
  15. STATIC EFI_STATUS ClipboardCopy (UINTN,UINTN);
  16. STATIC EFI_STATUS ClipboardPaste (VOID);
  17. EE_CLIPBOARD Clipboard = {
  18. NULL,
  19. NULL,
  20. 0,
  21. ClipboardInit,
  22. ClipboardCleanup,
  23. ClipboardClear,
  24. ClipboardCut,
  25. ClipboardCopy,
  26. ClipboardPaste
  27. };
  28. STATIC
  29. EFI_STATUS
  30. ClipboardInit (
  31. VOID
  32. )
  33. {
  34. Clipboard.ListHead = AllocatePool(sizeof(LIST_ENTRY));
  35. InitializeListHead(Clipboard.ListHead);
  36. return EFI_SUCCESS;
  37. }
  38. STATIC
  39. EFI_STATUS
  40. ClipboardCleanup (
  41. VOID
  42. )
  43. {
  44. ClipboardClear();
  45. FreePool(Clipboard.ListHead);
  46. return EFI_SUCCESS;
  47. }
  48. STATIC
  49. EFI_STATUS
  50. ClipboardClear (
  51. VOID
  52. )
  53. {
  54. EE_LINE *Line;
  55. LIST_ENTRY *Link;
  56. LIST_ENTRY *Head;
  57. Head = Clipboard.ListHead;
  58. for ( Link = Head->Blink; Link != Head; Link = Head->Blink) {
  59. RemoveEntryList(Link);
  60. Line = CR(Link,EE_LINE,Link,EE_LINE_LIST);
  61. FreePool(Line);
  62. }
  63. Clipboard.NumLines = 0;
  64. return EFI_SUCCESS;
  65. }
  66. STATIC
  67. EFI_STATUS
  68. ClipboardFill (
  69. IN UINTN Start,
  70. IN UINTN End
  71. )
  72. {
  73. EE_LINE *Current;
  74. EE_LINE *NewLine;
  75. UINTN i;
  76. LIST_ENTRY *Link;
  77. UINTN StartRow = Start / 0x10;
  78. UINTN EndRow = End / 0x10;
  79. NewLine = AllocatePool (sizeof(EE_LINE));
  80. NewLine->Signature = EE_LINE_LIST;
  81. Link = MainEditor.BufferImage->ListHead->Flink;
  82. for (i = 0; i < StartRow; i++) {
  83. Link = Link->Flink;
  84. }
  85. Current = CR(Link,EE_LINE,Link,EE_LINE_LIST);
  86. InsertTailList(Clipboard.ListHead,&NewLine->Link);
  87. LineSplit(Current,(Start%0x10),NewLine);
  88. Clipboard.NumLines = 1;
  89. if ( StartRow == EndRow ) {
  90. NewLine->Size = End - Start + 1;
  91. } else {
  92. for ( i = StartRow; i < EndRow; i++ ) {
  93. Link = Current->Link.Flink;
  94. Current = CR(Link,EE_LINE,Link,EE_LINE_LIST);
  95. NewLine = LineDup(Current);
  96. InsertTailList(Clipboard.ListHead,&NewLine->Link);
  97. }
  98. NewLine->Size = 1 + (End % 0x10);
  99. ++Clipboard.NumLines;
  100. }
  101. return EFI_SUCCESS;
  102. }
  103. STATIC
  104. EFI_STATUS
  105. ClipboardCut (
  106. IN UINTN Start,
  107. IN UINTN End
  108. )
  109. {
  110. LIST_ENTRY *Link;
  111. UINTN i;
  112. UINTN StartRow = Start / 0x10;
  113. ClipboardClear ();
  114. ClipboardFill(Start,End);
  115. Link = MainEditor.BufferImage->ListHead->Flink;
  116. for ( i = 0; i < StartRow; i++ ) {
  117. Link = Link->Flink;
  118. }
  119. LineDeleteAt(Link,(Start%0x10),End-Start+1);
  120. if (Start < MainEditor.FileBuffer->LowVisibleOffset) {
  121. MainEditor.FileBuffer->LowVisibleOffset = (Start & 0xfffffff0);
  122. MainEditor.FileBuffer->HighVisibleOffset = (Start & 0xfffffff0) + MainEditor.FileBuffer->MaxVisibleBytes;
  123. } else if (Start > MainEditor.FileBuffer->HighVisibleOffset) {
  124. MainEditor.FileBuffer->LowVisibleOffset = (Start & 0xfffffff0);
  125. MainEditor.FileBuffer->HighVisibleOffset = (Start & 0xfffffff0) + MainEditor.FileBuffer->MaxVisibleBytes;
  126. }
  127. MainEditor.FileBuffer->DisplayPosition.Row = (Start - MainEditor.FileBuffer->LowVisibleOffset) % 0x10 + DISP_START_ROW;
  128. MainEditor.FileBuffer->DisplayPosition.Column = HEX_POSITION + (Start%0x10)*3;
  129. if (Start%0x10 > 0x07) {
  130. ++MainEditor.FileBuffer->DisplayPosition.Column;
  131. }
  132. MainEditor.StatusBar->SetOffset(Start);
  133. MainEditor.FileBuffer->Offset = Start;
  134. MainEditor.FileBuffer->Refresh();
  135. FileModification();
  136. return EFI_SUCCESS;
  137. }
  138. STATIC
  139. EFI_STATUS
  140. ClipboardCopy (
  141. IN UINTN Start,
  142. IN UINTN End
  143. )
  144. {
  145. ClipboardClear();
  146. ClipboardFill(Start,End);
  147. return EFI_SUCCESS;
  148. }
  149. STATIC
  150. EFI_STATUS
  151. ClipboardPaste()
  152. {
  153. EE_LINE *StartLine;
  154. EE_LINE *BottomHalf;
  155. EE_LINE *Current;
  156. LIST_ENTRY *Link;
  157. LIST_ENTRY *Head;
  158. UINTN NumBytes = 0;
  159. UINTN LinePos;
  160. UINTN ClipPos = 0;
  161. if (Clipboard.NumLines == 0) {
  162. return EFI_SUCCESS;
  163. }
  164. LinePos = MainEditor.FileBuffer->Offset % 0x10;
  165. StartLine = LineCurrent();
  166. BottomHalf = AllocatePool(sizeof(EE_LINE));
  167. BottomHalf->Signature = EE_LINE_LIST;
  168. LineSplit(StartLine,LinePos,BottomHalf);
  169. Head = MainEditor.BufferImage->ListHead;
  170. BottomHalf->Link.Blink = Head->Blink;
  171. BottomHalf->Link.Blink->Flink = &BottomHalf->Link;
  172. BottomHalf->Link.Flink = StartLine->Link.Flink;
  173. BottomHalf->Link.Flink->Blink = &BottomHalf->Link;
  174. Head->Blink = &StartLine->Link;
  175. Head->Blink->Flink = Head;
  176. StartLine->Size = LinePos + 1;
  177. Head = Clipboard.ListHead;
  178. Link = Head->Flink;
  179. while (Link != Head) {
  180. Current = CR(Link,EE_LINE,Link,EE_LINE_LIST);
  181. if (LinePos == 0x10) {
  182. StartLine->Size = 0x10;
  183. StartLine = LineCreateNode(MainEditor.BufferImage->ListHead);
  184. LinePos = 0;
  185. } else if (ClipPos >= Current->Size) {
  186. Link = Link->Flink;
  187. ClipPos = 0;
  188. } else {
  189. StartLine->Buffer[LinePos] = Current->Buffer[ClipPos];
  190. ++LinePos;
  191. ++ClipPos;
  192. ++NumBytes;
  193. }
  194. }
  195. StartLine->Size = LinePos;
  196. MainEditor.FileBuffer->DisplayPosition.Column = LinePos*3 + HEX_POSITION;
  197. if (LinePos > 0x07) {
  198. ++MainEditor.FileBuffer->DisplayPosition.Column;
  199. }
  200. MainEditor.BufferImage->NumBytes += NumBytes;
  201. ClipPos = 0;
  202. Current = BottomHalf;
  203. Link = Head = &Current->Link;
  204. while (Link != Head->Blink && ClipPos <= Current->Size) {
  205. if (LinePos == 0x10) {
  206. StartLine->Size = 0x10;
  207. StartLine = LineCreateNode(MainEditor.BufferImage->ListHead);
  208. LinePos = 0;
  209. } else if (ClipPos >= Current->Size) {
  210. Link = Link->Flink;
  211. Current = CR(Link,EE_LINE,Link,EE_LINE_LIST);
  212. ClipPos = 0;
  213. } else {
  214. StartLine->Buffer[LinePos] = Current->Buffer[ClipPos];
  215. ++LinePos;
  216. ++ClipPos;
  217. }
  218. }
  219. StartLine->Size = LinePos;
  220. Link = Head->Blink;
  221. RemoveEntryList(Link);
  222. InsertTailList(MainEditor.BufferImage->ListHead,Link);
  223. do {
  224. Link = Head->Flink;
  225. RemoveEntryList(Link);
  226. Current = CR(Link,EE_LINE,Link,EE_LINE_LIST);
  227. FreePool(Current);
  228. } while (Link != Head);
  229. LineAdvance(NumBytes/0x10);
  230. NumBytes += MainEditor.FileBuffer->Offset;
  231. MainEditor.FileBuffer->Offset = NumBytes;
  232. if (NumBytes > MainEditor.FileBuffer->HighVisibleOffset) {
  233. MainEditor.FileBuffer->LowVisibleOffset = NumBytes & 0xfffffff0;
  234. MainEditor.FileBuffer->HighVisibleOffset = NumBytes + MainEditor.FileBuffer->MaxVisibleBytes;
  235. }
  236. LinePos = (NumBytes - MainEditor.FileBuffer->LowVisibleOffset);
  237. LinePos /= 0x10;
  238. LinePos += DISP_START_ROW;
  239. MainEditor.FileBuffer->DisplayPosition.Row = LinePos;
  240. MainEditor.StatusBar->SetOffset(NumBytes);
  241. MainEditor.FileBuffer->Refresh();
  242. FileModification();
  243. return EFI_SUCCESS;
  244. }
  245. #endif /* _LIB_CLIPBOARD */