void draw_thread(void *arg) { struct vfd_ioctl_data *data; struct vfd_ioctl_data draw_data; unsigned char buf[17]; int count = 0; int pos = 0; data = (struct vfd_ioctl_data *)arg; draw_data.length = data->length; memset(draw_data.data, 0, sizeof(draw_data.data)); memcpy(draw_data.data,data->data,data->length); thread_stop = 0; count = utf8_len(&draw_data.data[0], draw_data.length); if(count > mode_digit) { while(pos < draw_data.length) { if(kthread_should_stop()) { thread_stop = 1; return; } clear_display(); memset(buf,0, sizeof(buf)); int countb = utf8_count(&draw_data.data[pos], draw_data.length - pos, 8); memcpy(buf, &draw_data.data[pos], countb); YWPANEL_VFD_ShowString(buf); msleep(200); if (draw_data.data[pos] > 128) { pos += 2; } else { pos += 1; } } } if(count > 0) { clear_display(); memset(buf,0, sizeof(buf)); int countb = utf8_count(&draw_data.data[0], draw_data.length, 8); memcpy(buf, draw_data.data, countb); YWPANEL_VFD_ShowString(buf); } else VFD_clr(); thread_stop = 1; }
static int draw_thread(void *arg) { struct vfd_ioctl_data *data = (struct vfd_ioctl_data *) arg; char buf[sizeof(data->data) + 2 * DISPLAYWIDTH_MAX]; int len = data->length; int off = 0; int doton3 = 0; if (YWPANEL_width == 4 && len == 5 && data->data[2] == '.') doton3 = 1; if (len > YWPANEL_width + doton3) { memset(buf, ' ', sizeof(buf)); off = YWPANEL_width - 1; memcpy(buf + off, data->data, len); len += off; buf[len + YWPANEL_width] = 0; } else { memcpy(buf, data->data, len); buf[len] = 0; } draw_thread_stop = 0; if(len > YWPANEL_width + doton3) { int pos; for(pos = 0; pos < len; pos++) { int i; if(kthread_should_stop()) { draw_thread_stop = 1; return 0; } YWPANEL_VFD_ShowString(buf + pos); // sleep 200 ms for (i = 0; i < 5; i++) { if(kthread_should_stop()) { draw_thread_stop = 1; return 0; } msleep(40); } } } clear_display(); if(len > 0) YWPANEL_VFD_ShowString(buf + off); draw_thread_stop = 1; return 0; }
int run_draw_thread(struct vfd_ioctl_data *draw_data) { if(down_interruptible (&draw_thread_sem)) return -ERESTARTSYS; // return if there's already a draw task running for the same text if(!draw_thread_stop && draw_task && (last_draw_data.length == draw_data->length) && !memcmp(&last_draw_data.data, draw_data->data, draw_data->length)) { up(&draw_thread_sem); return 0; } memcpy(&last_draw_data, draw_data, sizeof(struct vfd_ioctl_data)); // stop existing thread, if any if(!draw_thread_stop && draw_task) { kthread_stop(draw_task); while(!draw_thread_stop) msleep(1); draw_task = 0; } if (draw_data->length < YWPANEL_width) { char buf[DISPLAYWIDTH_MAX + 1]; memset(buf, 0, sizeof(buf)); memset(buf, ' ', sizeof(buf) - 1); if (draw_data->length) memcpy(buf, draw_data->data, draw_data->length); YWPANEL_VFD_ShowString(buf); } else { draw_thread_stop = 2; draw_task = kthread_run(draw_thread,draw_data,"draw_thread"); //wait until thread has copied the argument while(draw_thread_stop == 2) msleep(1); } up(&draw_thread_sem); return 0; }
static int draw_thread(void *arg) { struct vfd_ioctl_data *data = (struct vfd_ioctl_data *) arg; char buf[sizeof(data->data) + 2 * DISPLAYWIDTH_MAX]; char buf2[sizeof(data->data) + 2 * DISPLAYWIDTH_MAX]; int len = data->length; int off = 0; int saved = 0; if (panel_version.DisplayInfo == YWPANEL_FP_DISPTYPE_LED && len > 2 && data->data[2] == '.') saved = 1; if (len - saved > YWPANEL_width) { memset(buf, ' ', sizeof(buf)); off = YWPANEL_width - 1; memcpy(buf + off, data->data, len); len += off; buf[len + YWPANEL_width] = 0; } else { memcpy(buf, data->data, len); buf[len] = 0; } draw_thread_stop = 0; if (saved) { int i; for (i = 0; i < len; i++) buf2[i] = (buf[i] == '.') ? ' ' : buf[i]; buf2[i] = 0; } if(len - saved > YWPANEL_width) { char *b = saved ? buf2 : buf; int pos; for(pos = 0; pos < len; pos++) { int i; if(kthread_should_stop()) { draw_thread_stop = 1; return 0; } YWPANEL_VFD_ShowString(b + pos); // sleep 200 ms for (i = 0; i < 5; i++) { if(kthread_should_stop()) { draw_thread_stop = 1; return 0; } msleep(40); } } } clear_display(); if(len > 0) YWPANEL_VFD_ShowString(buf + off); draw_thread_stop = 1; return 0; }
static void clear_display(void) { YWPANEL_VFD_ShowString(" "); }