Commit 58ec3400b860e0f5527ac6fd2f3dca492b7ef10f
1 parent
30dbf344
Exists in
master
and in
3 other branches
Moving new selection management methods to protocol library.
Showing
2 changed files
with
101 additions
and
4 deletions
Show diff stats
src/include/lib3270/selection.h
| @@ -38,6 +38,35 @@ | @@ -38,6 +38,35 @@ | ||
| 38 | 38 | ||
| 39 | #define LIB3270_SELECTION_H_INCLUDED 1 | 39 | #define LIB3270_SELECTION_H_INCLUDED 1 |
| 40 | 40 | ||
| 41 | + /** | ||
| 42 | + * @brief Selection element | ||
| 43 | + * | ||
| 44 | + */ | ||
| 45 | + typedef struct _lib3270_selection_element { | ||
| 46 | + unsigned char chr; ///< @brief Element character | ||
| 47 | + unsigned short flags; ///< @brief Element colors & visual state. | ||
| 48 | + unsigned char attributes; ///< @brief 3270 attributes. | ||
| 49 | + } lib3270_selection_element; | ||
| 50 | + | ||
| 51 | + /** | ||
| 52 | + * @brief A rectangle containing the selected area. | ||
| 53 | + * | ||
| 54 | + */ | ||
| 55 | + typedef struct _lib3270_selection | ||
| 56 | + { | ||
| 57 | + struct { | ||
| 58 | + unsigned int row; | ||
| 59 | + unsigned int col; | ||
| 60 | + unsigned int width; | ||
| 61 | + unsigned int height; | ||
| 62 | + | ||
| 63 | + } bounds; ///< @brief Clipboard rectangle. | ||
| 64 | + | ||
| 65 | + lib3270_selection_element contents[1]; | ||
| 66 | + | ||
| 67 | + } lib3270_selection; | ||
| 68 | + | ||
| 69 | + | ||
| 41 | LIB3270_EXPORT int lib3270_unselect(H3270 *session); | 70 | LIB3270_EXPORT int lib3270_unselect(H3270 *session); |
| 42 | LIB3270_EXPORT void lib3270_select_to(H3270 *session, int baddr); | 71 | LIB3270_EXPORT void lib3270_select_to(H3270 *session, int baddr); |
| 43 | LIB3270_EXPORT int lib3270_select_word_at(H3270 *session, int baddr); | 72 | LIB3270_EXPORT int lib3270_select_word_at(H3270 *session, int baddr); |
| @@ -48,7 +77,7 @@ | @@ -48,7 +77,7 @@ | ||
| 48 | /** | 77 | /** |
| 49 | * @brief Get selection options. | 78 | * @brief Get selection options. |
| 50 | * | 79 | * |
| 51 | - * @see lib3270_get_selection | 80 | + * @see lib3270_get_selection_as_text |
| 52 | * | 81 | * |
| 53 | */ | 82 | */ |
| 54 | typedef enum _LIB3270_SELECTION_OPTIONS { | 83 | typedef enum _LIB3270_SELECTION_OPTIONS { |
| @@ -148,6 +177,17 @@ | @@ -148,6 +177,17 @@ | ||
| 148 | LIB3270_EXPORT int lib3270_get_selection_rectangle(H3270 *hSession, unsigned int *row, unsigned int *col, unsigned int *width, unsigned int *height); | 177 | LIB3270_EXPORT int lib3270_get_selection_rectangle(H3270 *hSession, unsigned int *row, unsigned int *col, unsigned int *width, unsigned int *height); |
| 149 | 178 | ||
| 150 | /** | 179 | /** |
| 180 | + * @brief Get selection contents. | ||
| 181 | + * | ||
| 182 | + * @param hSession Session handle. | ||
| 183 | + * @param cut Non zero to clear selected contents. | ||
| 184 | + * | ||
| 185 | + * @return NULL on error (sets errno), pointer to a rectangle containing the selected area (release it with lib3270_free). | ||
| 186 | + * | ||
| 187 | + */ | ||
| 188 | + LIB3270_EXPORT lib3270_selection * lib3270_get_selection(H3270 *hSession, int cut); | ||
| 189 | + | ||
| 190 | + /** | ||
| 151 | * @brief Get bitmasked flag for the current selection. | 191 | * @brief Get bitmasked flag for the current selection. |
| 152 | * | 192 | * |
| 153 | * Calculate flags to help drawing of the correct mouse pointer over a selection. | 193 | * Calculate flags to help drawing of the correct mouse pointer over a selection. |
src/lib3270/selection/get.c
| @@ -49,7 +49,7 @@ void clear_chr(H3270 *hSession, int baddr) | @@ -49,7 +49,7 @@ void clear_chr(H3270 *hSession, int baddr) | ||
| 49 | baddr == hSession->cursor_addr ); | 49 | baddr == hSession->cursor_addr ); |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | -LIB3270_EXPORT char * lib3270_get_selection(H3270 *hSession, char tok, LIB3270_SELECTION_OPTIONS options) | 52 | +LIB3270_EXPORT char * lib3270_get_selected_text(H3270 *hSession, char tok, LIB3270_SELECTION_OPTIONS options) |
| 53 | { | 53 | { |
| 54 | int row, col, baddr; | 54 | int row, col, baddr; |
| 55 | char * ret; | 55 | char * ret; |
| @@ -63,7 +63,10 @@ LIB3270_EXPORT char * lib3270_get_selection(H3270 *hSession, char tok, LIB3270_S | @@ -63,7 +63,10 @@ LIB3270_EXPORT char * lib3270_get_selection(H3270 *hSession, char tok, LIB3270_S | ||
| 63 | return NULL; | 63 | return NULL; |
| 64 | 64 | ||
| 65 | if(!hSession->selected || hSession->select.start == hSession->select.end) | 65 | if(!hSession->selected || hSession->select.start == hSession->select.end) |
| 66 | + { | ||
| 67 | + errno = ENOENT; | ||
| 66 | return NULL; | 68 | return NULL; |
| 69 | + } | ||
| 67 | 70 | ||
| 68 | ret = lib3270_malloc(buflen); | 71 | ret = lib3270_malloc(buflen); |
| 69 | 72 | ||
| @@ -133,11 +136,65 @@ LIB3270_EXPORT char * lib3270_get_selection(H3270 *hSession, char tok, LIB3270_S | @@ -133,11 +136,65 @@ LIB3270_EXPORT char * lib3270_get_selection(H3270 *hSession, char tok, LIB3270_S | ||
| 133 | 136 | ||
| 134 | LIB3270_EXPORT char * lib3270_get_selected(H3270 *hSession) | 137 | LIB3270_EXPORT char * lib3270_get_selected(H3270 *hSession) |
| 135 | { | 138 | { |
| 136 | - return lib3270_get_selection(hSession,0,0); | 139 | + return lib3270_get_selected_text(hSession,0,0); |
| 137 | } | 140 | } |
| 138 | 141 | ||
| 139 | LIB3270_EXPORT char * lib3270_cut_selected(H3270 *hSession) | 142 | LIB3270_EXPORT char * lib3270_cut_selected(H3270 *hSession) |
| 140 | { | 143 | { |
| 141 | - return lib3270_get_selection(hSession,0,LIB3270_SELECTION_CUT); | 144 | + return lib3270_get_selected_text(hSession,0,LIB3270_SELECTION_CUT); |
| 142 | } | 145 | } |
| 143 | 146 | ||
| 147 | +LIB3270_EXPORT lib3270_selection * lib3270_get_selection(H3270 *hSession, int cut) | ||
| 148 | +{ | ||
| 149 | + // Get block size | ||
| 150 | + unsigned int row, col, width, height; | ||
| 151 | + if(lib3270_get_selection_rectangle(hSession, &row, &col, &width, &height)) | ||
| 152 | + { | ||
| 153 | + return NULL; | ||
| 154 | + } | ||
| 155 | + | ||
| 156 | + // Get output buffer. | ||
| 157 | + lib3270_selection * selection = lib3270_malloc(sizeof(lib3270_selection) + (sizeof(lib3270_selection_element) * (width*height))); | ||
| 158 | + | ||
| 159 | + selection->bounds.col = col; | ||
| 160 | + selection->bounds.row = row; | ||
| 161 | + selection->bounds.height = height; | ||
| 162 | + selection->bounds.width = width; | ||
| 163 | + | ||
| 164 | + unsigned int dstaddr = 0; | ||
| 165 | + | ||
| 166 | + for(row=0;row < selection->bounds.height; row++) | ||
| 167 | + { | ||
| 168 | + // Get starting address. | ||
| 169 | + int baddr = lib3270_translate_to_address(hSession, selection->bounds.row+row+1, selection->bounds.col+1); | ||
| 170 | + unsigned char fa = get_field_attribute(hSession,baddr); | ||
| 171 | + | ||
| 172 | + if(baddr < 0) | ||
| 173 | + { | ||
| 174 | + errno = EINVAL; | ||
| 175 | + lib3270_free(selection); | ||
| 176 | + return NULL; | ||
| 177 | + } | ||
| 178 | + | ||
| 179 | + for(col=0;col < selection->bounds.width; col++) | ||
| 180 | + { | ||
| 181 | + if(hSession->ea_buf[baddr].fa) { | ||
| 182 | + fa = hSession->ea_buf[baddr].fa; | ||
| 183 | + } | ||
| 184 | + | ||
| 185 | + selection->contents[dstaddr].chr = (hSession->text[baddr].chr ? hSession->text[baddr].chr : ' '); | ||
| 186 | + selection->contents[dstaddr].flags = hSession->text[baddr].attr; | ||
| 187 | + selection->contents[dstaddr].attributes = fa; | ||
| 188 | + | ||
| 189 | + if(cut && !FA_IS_PROTECTED(fa)) { | ||
| 190 | + clear_chr(hSession,baddr); | ||
| 191 | + } | ||
| 192 | + | ||
| 193 | + dstaddr++; | ||
| 194 | + baddr++; | ||
| 195 | + } | ||
| 196 | + | ||
| 197 | + } | ||
| 198 | + | ||
| 199 | + return selection; | ||
| 200 | +} |