📄 seln_demo.c
字号:
/* compute how much space we need: the length of the selection (size), plus 4 bytes for the terminating null word, plus 0 to 3 bytes to pad the end of the selection to a word boundary */ needed = size + 4; if (size % 4 != 0) needed += 4 - size % 4; if (needed <= length) { /* the entire selection fits */ strcpy(destp, context->context); destp += size; while ((int)destp % 4 != 0) { /* pad to a word boundary */ *destp++ = '\0'; } /* update selection service's pointer so it can determine how much data we are sending */ context->response_pointer = (char **)destp; /* terminate with a NULL word */ *context->response_pointer++ = 0; return(SELN_SUCCESS); } else { /* selection doesn't fit in a single buffer; rest will be put in different buffers on subsequent calls */ strncpy(destp, context->context, length); destp += length; context->response_pointer = (char **)destp; context->context += length; return(SELN_CONTINUED); } case SELN_REQ_YIELD: /* deselect the selection we have (turn off highlight, etc.) */ *context->response_pointer++ = (char *)SELN_SUCCESS; return(SELN_SUCCESS); case SELN_REQ_BYTESIZE: /* send the length of the selection */ if (seln == NULL) return(SELN_DIDNT_HAVE); *context->response_pointer++ = (char *)strlen(seln); return(SELN_SUCCESS); case SELN_REQ_END_REQUEST: /* all attributes have been taken care of; release any internal storage used */ return(SELN_SUCCESS); break; default: /* unrecognized request */ return(SELN_UNRECOGNIZED); } /* NOTREACHED */}/*******************************************************************//* routines involving getting a selection *//*******************************************************************//* * get the value of the selection type specified by the current panel choices * from whichever client is currently holding it */static voidget_button_proc(/* args ignored */){ Seln_holder holder; int len; char context = FIRST_BUFFER; /* context value used when a very long message is received; see procedure comment for read_proc */ if (err) { panel_set(mesg_item, PANEL_LABEL_STRING, mesg_labels[selection_type][selection_source], 0); err = 0; } /* determine who has the selection of the rank we want */ holder = seln_inquire(type_to_rank[selection_type]); if (holder.state == SELN_NONE) { panel_set(mesg_item, PANEL_LABEL_STRING, "You must make a selection first!", 0); err++; return; } /* ask for the length of the selection and then the actual selection; read_proc actually reads it in */ (void) seln_query(&holder, read_proc, &context, SELN_REQ_BYTESIZE, 0, SELN_REQ_CONTENTS_ASCII, 0, 0); /* display the selection in the panel */ len = strlen(selection_bufs[selection_type]); if (len > (int)panel_get(text_item, PANEL_VALUE_STORED_LENGTH)) panel_set(text_item, PANEL_VALUE_STORED_LENGTH, len, 0); panel_set_value(text_item, selection_bufs[selection_type]);}/* * called by seln_query for every buffer of information received; short * messages (under about 2000 bytes) will fit into one buffer; for larger * messages, read_proc will be called with each buffer in turn; the context * pointer passed to seln_query is modified by read_proc so that we will know * if this is the first buffer or not */Seln_resultread_proc(buffer)Seln_request *buffer;{ char *reply; /* pointer to the data in the buffer received */ unsigned len; /* amount of data left in the buffer */ int bytes_to_copy; static int selection_have_bytes; /* number of bytes of the selection which have been read; cumulative over all calls for the same selection (it is reset when the first buffer of a selection is read) */ static int selection_len; /* total number of bytes in the current selection */ if (*buffer->requester.context == FIRST_BUFFER) { /* this is the first buffer */ if (buffer == (Seln_request *)NULL) { panel_set(mesg_item, PANEL_LABEL_STRING, "Error reading selection - NULL buffer", 0); err++; return(SELN_UNRECOGNIZED); } reply = buffer->data; len = buffer->buf_size; /* read in the length of the selection */ if (*((Seln_attribute *)reply) != SELN_REQ_BYTESIZE) { panel_set(mesg_item, PANEL_LABEL_STRING, "Error reading selection - unrecognized request", 0); err++; return(SELN_UNRECOGNIZED); } reply += sizeof(Seln_attribute); len = buffer->buf_size - sizeof(Seln_attribute); selection_len = *(int *)reply; reply += sizeof(int); /* this only works since an int is 4 bytes; all values must be padded to 4-byte word boundaries */ len -= sizeof(int); /* create a buffer to store the selection */ if (selection_bufs[selection_type] != NULL) free(selection_bufs[selection_type]); selection_bufs[selection_type] = malloc(selection_len + 1); if (selection_bufs[selection_type] == NULL) { panel_set(mesg_item, PANEL_LABEL_STRING, "Out of memory!", 0); err++; return(SELN_FAILED); } selection_have_bytes = 0; /* start reading the selection */ if (*(Seln_attribute *)reply != SELN_REQ_CONTENTS_ASCII) { panel_set(mesg_item, PANEL_LABEL_STRING, "Error reading selection - unrecognized request", 0); err++; return(SELN_UNRECOGNIZED); } reply += sizeof(Seln_attribute); len -= sizeof(Seln_attribute); *buffer->requester.context = NOT_FIRST_BUFFER; } else { /* this is not the first buffer, so the contents of the buffer is just more of the selection */ reply = buffer->data; len = buffer->buf_size; } /* copy data from the received buffer to the selection buffer allocated above */ bytes_to_copy = selection_len - selection_have_bytes; if (len < bytes_to_copy) bytes_to_copy = len; strncpy(&selection_bufs[selection_type][selection_have_bytes], reply, bytes_to_copy); selection_have_bytes += bytes_to_copy; if (selection_have_bytes == selection_len) selection_bufs[selection_type][selection_len] = '\0'; return(SELN_SUCCESS);}/***********************************************************//* panel routines *//***********************************************************//* panel initialization routine */init_panel(panel)Panel panel;{ mesg_item = panel_create_item(panel, PANEL_MESSAGE, PANEL_LABEL_STRING, mesg_labels[PRIMARY_CHOICE][ITEM_CHOICE], 0); type_item = panel_create_item(panel, PANEL_CYCLE, PANEL_LABEL_STRING, "Set/Get: ", PANEL_CHOICE_STRINGS, "Primary Selection", "Secondary Selection", "Shelf", 0, PANEL_NOTIFY_PROC, change_label_proc, PANEL_LABEL_X, ATTR_COL(0), PANEL_LABEL_Y, ATTR_ROW(1), 0); source_item = panel_create_item(panel, PANEL_CYCLE, PANEL_LABEL_STRING, "Text item contains:", PANEL_CHOICE_STRINGS, "Selection", "Filename Containing Selection", 0, PANEL_NOTIFY_PROC, change_label_proc, 0); text_item = panel_create_item(panel, PANEL_TEXT, PANEL_LABEL_STRING, text_labels[PRIMARY_CHOICE][ITEM_CHOICE], PANEL_VALUE_DISPLAY_LENGTH, 20, 0); set_item[0] = panel_create_item(panel, PANEL_BUTTON, PANEL_LABEL_IMAGE, panel_button_image(panel, "Set Selection", 15,0), PANEL_NOTIFY_PROC, set_button_proc, PANEL_LABEL_X, ATTR_COL(0), PANEL_LABEL_Y, ATTR_ROW(5), 0); set_item[1] = panel_create_item(panel, PANEL_BUTTON, PANEL_LABEL_IMAGE, panel_button_image(panel, "Set Secondary", 15,0), PANEL_NOTIFY_PROC, set_button_proc, PANEL_LABEL_X, ATTR_COL(0), PANEL_LABEL_Y, ATTR_ROW(5), PANEL_SHOW_ITEM, FALSE, 0); set_item[2] = panel_create_item(panel, PANEL_BUTTON, PANEL_LABEL_IMAGE, panel_button_image(panel, "Set Shelf", 15,0), PANEL_NOTIFY_PROC, set_button_proc, PANEL_LABEL_X, ATTR_COL(0), PANEL_LABEL_Y, ATTR_ROW(5), PANEL_SHOW_ITEM, FALSE, 0); get_item[0] = panel_create_item(panel, PANEL_BUTTON, PANEL_LABEL_IMAGE, panel_button_image(panel, "Get Selection", 15,0), PANEL_NOTIFY_PROC, get_button_proc, PANEL_LABEL_X, ATTR_COL(20), PANEL_LABEL_Y, ATTR_ROW(5), 0); get_item[1] = panel_create_item(panel, PANEL_BUTTON, PANEL_LABEL_IMAGE, panel_button_image(panel, "Get Secondary", 15,0), PANEL_NOTIFY_PROC, get_button_proc, PANEL_SHOW_ITEM, FALSE, PANEL_LABEL_X, ATTR_COL(20), PANEL_LABEL_Y, ATTR_ROW(5), 0); get_item[2] = panel_create_item(panel, PANEL_BUTTON, PANEL_LABEL_IMAGE, panel_button_image(panel, "Get Shelf", 15,0), PANEL_NOTIFY_PROC, get_button_proc, PANEL_SHOW_ITEM, FALSE, PANEL_LABEL_X, ATTR_COL(20), PANEL_LABEL_Y, ATTR_ROW(5), 0);}/* * change the label of the text item to reflect the currently chosen selection * type */static voidchange_label_proc(item, value, event)Panel_item item;int value;Event *event;{ int old_selection_type = selection_type; selection_type = (int)panel_get_value(type_item); selection_source = (int)panel_get_value(source_item); panel_set(text_item, PANEL_LABEL_STRING, text_labels[selection_type][selection_source], 0); panel_set(mesg_item, PANEL_LABEL_STRING, mesg_labels[selection_type][selection_source], 0); if (old_selection_type != selection_type) { panel_set(set_item[old_selection_type], PANEL_SHOW_ITEM, FALSE, 0); panel_set(set_item[selection_type], PANEL_SHOW_ITEM, TRUE, 0); panel_set(get_item[old_selection_type], PANEL_SHOW_ITEM, FALSE, 0); panel_set(get_item[selection_type], PANEL_SHOW_ITEM, TRUE, 0); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -