Пример #1
0
void remove_icon(TrayWindow *traywin)
{
	if (systray_profile)
		fprintf(stderr,
		        "[%f] %s:%d win = %lu (%s)\n",
		        profiling_get_time(),
		        __FUNCTION__,
		        __LINE__,
		        traywin->win,
		        traywin->name);
	Panel *panel = systray.area.panel;

	// remove from our list
	systray.list_icons = g_slist_remove(systray.list_icons, traywin);
	fprintf(stderr, YELLOW "remove_icon: %lu (%s)" RESET "\n", traywin->win, traywin->name);

	XSelectInput(server.display, traywin->win, NoEventMask);
	if (traywin->damage)
		XDamageDestroy(server.display, traywin->damage);

	// reparent to root
	XSync(server.display, False);
	error = FALSE;
	XErrorHandler old = XSetErrorHandler(window_error_handler);
	XUnmapWindow(server.display, traywin->win);
	XReparentWindow(server.display, traywin->win, server.root_win, 0, 0);
	XDestroyWindow(server.display, traywin->parent);
	XSync(server.display, False);
	XSetErrorHandler(old);
	stop_timeout(traywin->render_timeout);
	stop_timeout(traywin->resize_timeout);
	free(traywin->name);
	if (traywin->image) {
		imlib_context_set_image(traywin->image);
		imlib_free_image_and_decache();
	}
	g_free(traywin);

	// check empty systray
	int count = 0;
	GSList *l;
	for (l = systray.list_icons; l; l = l->next) {
		count++;
	}
	if (count == 0)
		hide(&systray.area);

	// Resize and redraw the systray
	if (systray_profile)
		fprintf(stderr,
				BLUE "[%f] %s:%d trigger resize & redraw" RESET "\n",
				profiling_get_time(),
				__FUNCTION__,
				__LINE__);
	systray.area.resize_needed = TRUE;
	panel->area.resize_needed = TRUE;
	schedule_redraw(&systray.area);
	refresh_systray = TRUE;
}
Пример #2
0
void remove_from_multi_timeout(timeout* t) {
  multi_timeout_handler* mth = g_hash_table_lookup(multi_timeouts, t);
  g_hash_table_remove(multi_timeouts, t);

  mth->timeout_list = g_slist_remove(mth->timeout_list, t);
  free(t->multi_timeout);
  t->multi_timeout = 0;

  if (g_slist_length(mth->timeout_list) == 1) {
    timeout* last_timeout = mth->timeout_list->data;
    mth->timeout_list = g_slist_remove(mth->timeout_list, last_timeout);
    free(last_timeout->multi_timeout);
    last_timeout->multi_timeout = 0;
    g_hash_table_remove(multi_timeouts, last_timeout);
    g_hash_table_remove(multi_timeouts, mth->parent_timeout);
    mth->parent_timeout->multi_timeout = 0;
    stop_timeout(mth->parent_timeout);
    free(mth);

    struct timespec cur_time, diff_time;
    clock_gettime(CLOCK_MONOTONIC, &cur_time);
    timespec_subtract(&diff_time, &t->timeout_expires, &cur_time);
    int msec_to_expiration =
        diff_time.tv_sec * 1000 + diff_time.tv_nsec / 1000000;
    add_timeout_intern(msec_to_expiration, last_timeout->interval_msec,
                       last_timeout->_callback, last_timeout->arg,
                       last_timeout);
  } else
    update_multi_timeout_values(mth);
}
Пример #3
0
void cleanup_clock()
{
	pango_font_description_free(time1_font_desc);
	time1_font_desc = NULL;
	pango_font_description_free(time2_font_desc);
	time2_font_desc = NULL;
	free(time1_format);
	time1_format = NULL;
	free(time2_format);
	time2_format = NULL;
	free(time_tooltip_format);
	time_tooltip_format = NULL;
	free(time1_timezone);
	time1_timezone = NULL;
	free(time2_timezone);
	time2_timezone = NULL;
	free(time_tooltip_timezone);
	time_tooltip_timezone = NULL;
	free(clock_lclick_command);
	clock_lclick_command = NULL;
	free(clock_rclick_command);
	clock_rclick_command = NULL;
	stop_timeout(clock_timeout);
	clock_timeout = NULL;
}
Пример #4
0
void stop_tooltip_timeout()
{
	if (g_tooltip.timeout) {
		stop_timeout(g_tooltip.timeout);
		g_tooltip.timeout = 0;
	}
}
Пример #5
0
Файл: panel.c Проект: asqz/tint2
void stop_autohide_timeout(Panel* p)
{
	if (p->autohide_timeout) {
		stop_timeout(p->autohide_timeout);
		p->autohide_timeout = 0;
	}
}
Пример #6
0
void del_urgent(Task *tsk)
{
	urgent_list = g_slist_remove(urgent_list, tsk);
	if (!urgent_list) {
		stop_timeout(urgent_timeout);
		urgent_timeout = NULL;
	}
}
Пример #7
0
static void cleanup(void)
{
	while (timeout_list)
	{
		struct timeout *t = timeout_list->data;
		gtk_timeout_remove(t->id);
		stop_timeout(t);
	}
	cddb_quit();
}
Пример #8
0
void destroy_execp(void *obj)
{
	Execp *execp = (Execp *)obj;
	if (execp->frontend) {
		// This is a frontend element
		execp->backend->instances = g_list_remove_all(execp->backend->instances, execp);
		free_and_null(execp->frontend);
		remove_area(&execp->area);
		free_area(&execp->area);
		free_and_null(execp);
	} else {
		// This is a backend element
		stop_timeout(execp->backend->timer);
		execp->backend->timer = NULL;

		if (execp->backend->icon) {
			imlib_context_set_image(execp->backend->icon);
			imlib_free_image();
			execp->backend->icon = NULL;
		}
		free_and_null(execp->backend->buf_output);
		free_and_null(execp->backend->text);
		free_and_null(execp->backend->icon_path);
		if (execp->backend->child) {
			kill(-execp->backend->child, SIGHUP);
			execp->backend->child = 0;
		}
		if (execp->backend->child_pipe >= 0) {
			close(execp->backend->child_pipe);
			execp->backend->child_pipe = -1;
		}
		if (execp->backend->cmd_pids) {
			g_tree_destroy(execp->backend->cmd_pids);
			execp->backend->cmd_pids = NULL;
		}

		execp->backend->bg = NULL;
		pango_font_description_free(execp->backend->font_desc);
		execp->backend->font_desc = NULL;
		free_and_null(execp->backend->command);
		free_and_null(execp->backend->tooltip);
		free_and_null(execp->backend->lclick_command);
		free_and_null(execp->backend->mclick_command);
		free_and_null(execp->backend->rclick_command);
		free_and_null(execp->backend->dwheel_command);
		free_and_null(execp->backend->uwheel_command);

		if (execp->backend->instances) {
			fprintf(stderr, "Error: Attempt to destroy backend while there are still frontend instances!\n");
			exit(-1);
		}
		free(execp->backend);
		free(execp);
	}
}
Пример #9
0
static void player_connect(Game * game)
{
	gchar *location;
	gint fd = accept_connection(game->accept_fd, &location);

	if (fd > 0) {
		if (player_new_connection(game, fd, location) != NULL)
			stop_timeout(game);
	}
	g_free(location);
}
Пример #10
0
void execp_force_update(Execp *execp)
{
	if (execp->backend->child_pipe > 0) {
		// Command currently running, nothing to do
	} else {
		if (execp->backend->timer)
			stop_timeout(execp->backend->timer);
		// Run command right away
		execp->backend->timer = add_timeout(10, 0, execp_timer_callback, execp, &execp->backend->timer);
	}
}
Пример #11
0
void cleanup_clock()
{
	if (time1_font_desc) pango_font_description_free(time1_font_desc);
	if (time2_font_desc) pango_font_description_free(time2_font_desc);
	if (time1_format) g_free(time1_format);
	if (time2_format) g_free(time2_format);
	if (time_tooltip_format) g_free(time_tooltip_format);
	if (time1_timezone) g_free(time1_timezone);
	if (time2_timezone) g_free(time2_timezone);
	if (time_tooltip_timezone) g_free(time_tooltip_timezone);
	if (clock_lclick_command) g_free(clock_lclick_command);
	if (clock_rclick_command) g_free(clock_rclick_command);
	if (clock_timeout) stop_timeout(clock_timeout);
}
Пример #12
0
void cleanup_panel()
{
	if (!panels)
		return;

	cleanup_taskbar();

	for (int i = 0; i < num_panels; i++) {
		Panel *p = &panels[i];

		free_area(&p->area);
		if (p->temp_pmap)
			XFreePixmap(server.display, p->temp_pmap);
		p->temp_pmap = 0;
		if (p->hidden_pixmap)
			XFreePixmap(server.display, p->hidden_pixmap);
		p->hidden_pixmap = 0;
		if (p->main_win)
			XDestroyWindow(server.display, p->main_win);
		p->main_win = 0;
		stop_timeout(p->autohide_timeout);
		cleanup_freespace(p);
	}

	free(panel_items_order);
	panel_items_order = NULL;
	free(panel_window_name);
	panel_window_name = NULL;
	free(panels);
	panels = NULL;

	free_area(&panel_config.area);

	if (backgrounds)
		g_array_free(backgrounds, TRUE);
	backgrounds = NULL;
	if (gradients) {
		for (guint i = 0; i < gradients->len; i++)
			cleanup_gradient(&g_array_index(gradients, GradientClass, i));
		g_array_free(gradients, TRUE);
	}
	gradients = NULL;
	pango_font_description_free(panel_config.g_task.font_desc);
	panel_config.g_task.font_desc = NULL;
	pango_font_description_free(panel_config.taskbarname_font_desc);
	panel_config.taskbarname_font_desc = NULL;
}
Пример #13
0
void execp_action(void *obj, int button, int x, int y)
{
	Execp *execp = obj;
	char *command = NULL;
	switch (button) {
	case 1:
		command = execp->backend->lclick_command;
		break;
	case 2:
		command = execp->backend->mclick_command;
		break;
	case 3:
		command = execp->backend->rclick_command;
		break;
	case 4:
		command = execp->backend->uwheel_command;
		break;
	case 5:
		command = execp->backend->dwheel_command;
		break;
	}
	if (command) {
		char *full_cmd = g_strdup_printf("export EXECP_X=%d;"
		                                 "export EXECP_Y=%d;"
		                                 "export EXECP_W=%d;"
		                                 "export EXECP_H=%d; %s",
		                                 x,
		                                 y,
		                                 execp->area.width,
		                                 execp->area.height,
		                                 command);
		tint_exec(full_cmd);
		g_free(full_cmd);
	} else {
		if (execp->backend->child_pipe > 0) {
			// Command currently running, nothing to do
		} else {
			if (execp->backend->timer)
				stop_timeout(execp->backend->timer);
			// Run command right away
			execp->backend->timer = add_timeout(10, 0, execp_timer_callback, execp, &execp->backend->timer);
		}
	}
}
Пример #14
0
void cleanup_panel()
{
	if (!panel1)
		return;

	cleanup_taskbar();

	int i;
	Panel *p;
	for (i = 0; i < nb_panel; i++) {
		p = &panel1[i];

		free_area(&p->area);
		if (p->temp_pmap)
			XFreePixmap(server.dsp, p->temp_pmap);
		p->temp_pmap = 0;
		if (p->hidden_pixmap)
			XFreePixmap(server.dsp, p->hidden_pixmap);
		p->hidden_pixmap = 0;
		if (p->main_win)
			XDestroyWindow(server.dsp, p->main_win);
		p->main_win = 0;
		stop_timeout(p->autohide_timeout);
	}

	free(panel_items_order);
	panel_items_order = NULL;
	free(panel_window_name);
	panel_window_name = NULL;
	free(panel1);
	panel1 = NULL;
	if (backgrounds)
		g_array_free(backgrounds, 1);
	backgrounds = NULL;
	pango_font_description_free(panel_config.g_task.font_desc);
	panel_config.g_task.font_desc = NULL;
}
Пример #15
0
void systray_render_icon_composited(void *t)
{
	// we end up in this function only in real transparency mode or if systray_task_asb != 100 0 0
	// we made also sure, that we always have a 32 bit visual, i.e. we can safely create 32 bit pixmaps here
	TrayWindow *traywin = t;

	if (systray_profile)
		fprintf(stderr,
		        "[%f] %s:%d win = %lu (%s)\n",
		        profiling_get_time(),
		        __FUNCTION__,
		        __LINE__,
		        traywin->win,
		        traywin->name);

	// wine tray icons update whenever mouse is over them, so we limit the updates to 50 ms
	struct timespec now;
	clock_gettime(CLOCK_MONOTONIC, &now);
	struct timespec earliest_render = add_msec_to_timespec(traywin->time_last_render, min_refresh_period);
	if (compare_timespecs(&earliest_render, &now) > 0) {
		traywin->num_fast_renders++;
		if (traywin->num_fast_renders > max_fast_refreshes) {
			traywin->render_timeout =
			    add_timeout(min_refresh_period, 0, systray_render_icon_composited, traywin, &traywin->render_timeout);
			if (systray_profile)
				fprintf(stderr,
				        YELLOW "[%f] %s:%d win = %lu (%s) delaying rendering" RESET "\n",
				        profiling_get_time(),
				        __FUNCTION__,
				        __LINE__,
				        traywin->win,
				        traywin->name);
			return;
		}
	} else {
		traywin->time_last_render.tv_sec = now.tv_sec;
		traywin->time_last_render.tv_nsec = now.tv_nsec;
		traywin->num_fast_renders = 0;
	}

	if (traywin->width == 0 || traywin->height == 0) {
		// reschedule rendering since the geometry information has not yet been processed (can happen on slow cpu)
		traywin->render_timeout =
		    add_timeout(min_refresh_period, 0, systray_render_icon_composited, traywin, &traywin->render_timeout);
		if (systray_profile)
			fprintf(stderr,
			        YELLOW "[%f] %s:%d win = %lu (%s) delaying rendering" RESET "\n",
			        profiling_get_time(),
			        __FUNCTION__,
			        __LINE__,
			        traywin->win,
			        traywin->name);
		return;
	}

	if (traywin->render_timeout) {
		stop_timeout(traywin->render_timeout);
		traywin->render_timeout = NULL;
	}

	// good systray icons support 32 bit depth, but some icons are still 24 bit.
	// We create a heuristic mask for these icons, i.e. we get the rgb value in the top left corner, and
	// mask out all pixel with the same rgb value

	// Very ugly hack, but somehow imlib2 is not able to get the image from the traywindow itself,
	// so we first render the tray window onto a pixmap, and then we tell imlib2 to use this pixmap as
	// drawable. If someone knows why it does not work with the traywindow itself, please tell me ;)
	Pixmap tmp_pmap = XCreatePixmap(server.display, traywin->win, traywin->width, traywin->height, 32);
	if (!tmp_pmap) {
		goto on_systray_error;
	}
	XRenderPictFormat *f;
	if (traywin->depth == 24) {
		f = XRenderFindStandardFormat(server.display, PictStandardRGB24);
	} else if (traywin->depth == 32) {
		f = XRenderFindStandardFormat(server.display, PictStandardARGB32);
	} else {
		fprintf(stderr, RED "Strange tray icon found with depth: %d" RESET "\n", traywin->depth);
		XFreePixmap(server.display, tmp_pmap);
		return;
	}
	XRenderPictFormat *f32 = XRenderFindVisualFormat(server.display, server.visual32);
	if (!f || !f32) {
		XFreePixmap(server.display, tmp_pmap);
		goto on_systray_error;
	}

	XSync(server.display, False);
	error = FALSE;
	XErrorHandler old = XSetErrorHandler(window_error_handler);

	// if (server.real_transparency)
	// Picture pict_image = XRenderCreatePicture(server.display, traywin->parent, f, 0, 0);
	// reverted Rev 407 because here it's breaking alls icon with systray + xcompmgr
	Picture pict_image = XRenderCreatePicture(server.display, traywin->win, f, 0, 0);
	if (!pict_image) {
		XFreePixmap(server.display, tmp_pmap);
		XSetErrorHandler(old);
		goto on_error;
	}
	Picture pict_drawable =
		XRenderCreatePicture(server.display, tmp_pmap, XRenderFindVisualFormat(server.display, server.visual32), 0, 0);
	if (!pict_drawable) {
		XRenderFreePicture(server.display, pict_image);
		XFreePixmap(server.display, tmp_pmap);
		XSetErrorHandler(old);
		goto on_error;
	}
	XRenderComposite(server.display,
	                 PictOpSrc,
	                 pict_image,
	                 None,
	                 pict_drawable,
	                 0,
	                 0,
	                 0,
	                 0,
	                 0,
	                 0,
	                 traywin->width,
	                 traywin->height);
	XRenderFreePicture(server.display, pict_image);
	XRenderFreePicture(server.display, pict_drawable);
	// end of the ugly hack and we can continue as before

	imlib_context_set_visual(server.visual32);
	imlib_context_set_colormap(server.colormap32);
	imlib_context_set_drawable(tmp_pmap);
	Imlib_Image image = imlib_create_image_from_drawable(0, 0, 0, traywin->width, traywin->height, 1);
	imlib_context_set_visual(server.visual);
	imlib_context_set_colormap(server.colormap);
	XFreePixmap(server.display, tmp_pmap);
	if (!image) {
		imlib_context_set_visual(server.visual);
		imlib_context_set_colormap(server.colormap);
		XSetErrorHandler(old);
		goto on_error;
	} else {
		if (traywin->image) {
			imlib_context_set_image(traywin->image);
			imlib_free_image_and_decache();
		}
		traywin->image = image;
	}

	imlib_context_set_image(traywin->image);
	// if (traywin->depth == 24)
	// imlib_save_image("/home/thil77/test.jpg");
	imlib_image_set_has_alpha(1);
	DATA32 *data = imlib_image_get_data();
	if (traywin->depth == 24) {
		create_heuristic_mask(data, traywin->width, traywin->height);
	}

	if (systray.alpha != 100 || systray.brightness != 0 || systray.saturation != 0)
		adjust_asb(data,
		           traywin->width,
		           traywin->height,
		           systray.alpha,
		           (float)systray.saturation / 100,
		           (float)systray.brightness / 100);
	imlib_image_put_back_data(data);

	systray_render_icon_from_image(traywin);

	if (traywin->damage)
		XDamageSubtract(server.display, traywin->damage, None, None);
	XSync(server.display, False);
	XSetErrorHandler(old);

	if (error)
		goto on_error;

	panel_refresh = TRUE;

	if (systray_profile)
		fprintf(stderr,
		        "[%f] %s:%d win = %lu (%s)\n",
		        profiling_get_time(),
		        __FUNCTION__,
		        __LINE__,
		        traywin->win,
		        traywin->name);

	return;

on_error:
	fprintf(stderr,
	        RED "systray %d: rendering error for icon %lu (%s) pid %d" RESET "\n",
	        __LINE__,
	        traywin->win,
	        traywin->name,
	        traywin->pid);
	return;

on_systray_error:
	fprintf(stderr,
	        RED "systray %d: rendering error for icon %lu (%s) pid %d. "
	            "Disabling compositing and restarting systray..." RESET "\n",
	        __LINE__,
	        traywin->win,
	        traywin->name,
	        traywin->pid);
	systray_composited = 0;
	stop_net();
	start_net();
	return;
}
Пример #16
0
void systray_reconfigure_event(TrayWindow *traywin, XEvent *e)
{
	if (systray_profile)
		fprintf(stderr,
		        "XConfigure event: win = %lu (%s), x = %d, y = %d, w = %d, h = %d\n",
		        traywin->win,
		        traywin->name,
		        e->xconfigure.x,
		        e->xconfigure.y,
		        e->xconfigure.width,
		        e->xconfigure.height);

	if (!traywin->reparented)
		return;

	if (e->xconfigure.width != traywin->width || e->xconfigure.height != traywin->height || e->xconfigure.x != 0 ||
	    e->xconfigure.y != 0) {
		if (traywin->bad_size_counter < max_bad_resize_events) {
			struct timespec now;
			clock_gettime(CLOCK_MONOTONIC, &now);
			struct timespec earliest_resize = add_msec_to_timespec(traywin->time_last_resize, resize_period_threshold);
			if (compare_timespecs(&earliest_resize, &now) > 0) {
				// Fast resize, but below the threshold
				traywin->bad_size_counter++;
			} else {
				// Slow resize, reset counter
				traywin->time_last_resize.tv_sec = now.tv_sec;
				traywin->time_last_resize.tv_nsec = now.tv_nsec;
				traywin->bad_size_counter = 0;
			}
			if (traywin->bad_size_counter < min_bad_resize_events) {
				systray_resize_icon(traywin);
			} else {
				if (!traywin->resize_timeout)
					traywin->resize_timeout =
					    add_timeout(fast_resize_period, 0, systray_resize_icon, traywin, &traywin->resize_timeout);
			}
		} else {
			if (traywin->bad_size_counter == max_bad_resize_events) {
				traywin->bad_size_counter++;
				fprintf(stderr,
				        RED "Detected resize loop for tray icon %lu (%s), throttling resize events" RESET "\n",
				        traywin->win,
				        traywin->name);
			}
			// Delayed resize
			// FIXME Normally we should force the icon to resize fill_color to the size we resized it to when we
			// embedded it.
			// However this triggers a resize loop in new versions of GTK, which we must avoid.
			if (!traywin->resize_timeout)
				traywin->resize_timeout =
				    add_timeout(slow_resize_period, 0, systray_resize_icon, traywin, &traywin->resize_timeout);
			return;
		}
	} else {
		// Correct size
		stop_timeout(traywin->resize_timeout);
	}

	// Resize and redraw the systray
	if (systray_profile)
		fprintf(stderr,
				BLUE "[%f] %s:%d trigger resize & redraw" RESET "\n",
				profiling_get_time(),
				__FUNCTION__,
				__LINE__);
	panel_refresh = TRUE;
	refresh_systray = TRUE;
}
Пример #17
0
void stop_tooltip_timeout()
{
	stop_timeout(g_tooltip.timeout);
}
Пример #18
0
static uint32_t bl_evt_handler(bl_evt_t* p_evt)
{
    static bl_cmd_t rsp_cmd;
    bool respond = false;
    switch (p_evt->type)
    {
        case BL_EVT_TYPE_DFU_ABORT:
            bootloader_abort(p_evt->params.dfu.abort.reason);

            /* If bootloader abort returned, it means that the application
             * doesn't work, and we should return to the dfu operation. */
            dfu_mesh_start();
            break;
        case BL_EVT_TYPE_TX_RADIO:
        {
            mesh_packet_t* p_packet = NULL;
            if (!mesh_packet_acquire(&p_packet))
            {
                return NRF_ERROR_NO_MEM;
            }

            mesh_packet_set_local_addr(p_packet);
            p_packet->header.type = BLE_PACKET_TYPE_ADV_NONCONN_IND;
            p_packet->header.length = DFU_PACKET_OVERHEAD + p_evt->params.tx.radio.length;
            ((ble_ad_t*) p_packet->payload)->adv_data_type = MESH_ADV_DATA_TYPE;
            ((ble_ad_t*) p_packet->payload)->data[0] = (MESH_UUID & 0xFF);
            ((ble_ad_t*) p_packet->payload)->data[1] = (MESH_UUID >> 8) & 0xFF;
            ((ble_ad_t*) p_packet->payload)->adv_data_length = DFU_PACKET_ADV_OVERHEAD + p_evt->params.tx.radio.length;
            memcpy(&p_packet->payload[4], p_evt->params.tx.radio.p_dfu_packet, p_evt->params.tx.radio.length);

            bool success = transport_tx(p_packet,
                                        p_evt->params.tx.radio.tx_slot,
                                        p_evt->params.tx.radio.tx_count,
                                        (tx_interval_type_t) p_evt->params.tx.radio.interval_type);
            mesh_packet_ref_count_dec(p_packet);

            if (!success)
            {
                return NRF_ERROR_INTERNAL;
            }
            break;
        }
        case BL_EVT_TYPE_TX_ABORT:
            transport_tx_abort(p_evt->params.tx.abort.tx_slot);
            break;
        case BL_EVT_TYPE_TX_SERIAL:
        {
#ifdef RBC_MESH_SERIAL
            serial_evt_t serial_evt;
            serial_evt.opcode = SERIAL_EVT_OPCODE_DFU;
            memcpy(&serial_evt.params.dfu.packet,
                    p_evt->params.tx.serial.p_dfu_packet,
                    p_evt->params.tx.serial.length);
            serial_evt.length = SERIAL_PACKET_OVERHEAD + p_evt->params.tx.serial.length;
            if (!serial_handler_event_send(&serial_evt))
            {
                return NRF_ERROR_INTERNAL;
            }
            break;
#endif
        }
        case BL_EVT_TYPE_TIMER_SET:
            set_timeout(US_TO_RTC_TICKS(p_evt->params.timer.set.delay_us), TIMEOUT_ACTION_DFU_TIMEOUT);
            break;

        case BL_EVT_TYPE_DFU_NEW_FW:
            {
                stop_timeout();
                __LOG("New FW event\n");
                switch (p_evt->params.dfu.new_fw.fw_type)
                {
                    case DFU_TYPE_APP:
                        __LOG("\tAPP: %08x.%04x:%08x\n",
                                (uint32_t) p_evt->params.dfu.new_fw.fwid.app.company_id,
                                (uint32_t) p_evt->params.dfu.new_fw.fwid.app.app_id,
                                (uint32_t) p_evt->params.dfu.new_fw.fwid.app.app_version);
                        break;
                    case DFU_TYPE_SD:
                        __LOG("\tSD: %04x\n",
                                (uint32_t) p_evt->params.dfu.new_fw.fwid.sd);
                        break;
                    case DFU_TYPE_BOOTLOADER:
                        __LOG("\tBL: %02x:%02x\n",
                                (uint32_t) p_evt->params.dfu.new_fw.fwid.bootloader.id,
                                (uint32_t) p_evt->params.dfu.new_fw.fwid.bootloader.ver);
                        break;
                    default: break;
                }
                /* accept all new firmware, as the bootloader wouldn't run
                   unless there's an actual reason for it. */
                rsp_cmd.type = BL_CMD_TYPE_DFU_START_TARGET;
                rsp_cmd.params.dfu.start.target.p_bank_start = (uint32_t*) 0xFFFFFFFF; /* no banking */
                rsp_cmd.params.dfu.start.target.type = p_evt->params.dfu.new_fw.fw_type;
                rsp_cmd.params.dfu.start.target.fwid = p_evt->params.dfu.new_fw.fwid;
                respond = true;
            }
            break;

        case BL_EVT_TYPE_BANK_AVAILABLE:
            __LOG("Bank:\n");
            switch (p_evt->params.bank_available.bank_dfu_type)
            {
                case DFU_TYPE_APP:
                    __LOG("\tAPP: %08x.%04x:%08x\n",
                            (uint32_t) p_evt->params.bank_available.bank_fwid.app.company_id,
                            (uint32_t) p_evt->params.bank_available.bank_fwid.app.app_id,
                            (uint32_t) p_evt->params.bank_available.bank_fwid.app.app_version);
                    break;
                case DFU_TYPE_SD:
                    __LOG("\tSD: %04x\n",
                            (uint32_t) p_evt->params.bank_available.bank_fwid.sd);
                    break;
                case DFU_TYPE_BOOTLOADER:
                    __LOG("\tBL: %02x:%02x\n",
                            (uint32_t) p_evt->params.bank_available.bank_fwid.bootloader.id,
                            (uint32_t) p_evt->params.bank_available.bank_fwid.bootloader.ver);
                    break;
                default: break;
            }
            __LOG("\tLocation: 0x%x\n", p_evt->params.bank_available.p_bank_addr);
            __LOG("\tLength: 0x%x\n", p_evt->params.bank_available.bank_length);
            if (p_evt->params.bank_available.bank_dfu_type == DFU_TYPE_BOOTLOADER)
            {
                if (!dfu_mesh_app_is_valid())
                {
                    dfu_bank_flash(DFU_TYPE_BOOTLOADER);
                }
            }
            break;

        case BL_EVT_TYPE_DFU_REQ:
            {
                /* Always attempt to relay incoming transfers in BL mode. Will
                   not abort ongoing transfers. */
                if (p_evt->params.dfu.req.role == DFU_ROLE_RELAY)
                {
                    stop_timeout();
                    bl_cmd_t relay_cmd;
                    relay_cmd.type = BL_CMD_TYPE_DFU_START_RELAY;
                    relay_cmd.params.dfu.start.relay.fwid = p_evt->params.dfu.req.fwid;
                    relay_cmd.params.dfu.start.relay.type = p_evt->params.dfu.req.dfu_type;
                    relay_cmd.params.dfu.start.relay.transaction_id = p_evt->params.dfu.req.transaction_id;
                    bootloader_cmd_send(&relay_cmd);
                }
            }
            break;

        case BL_EVT_TYPE_DFU_START:
            set_timeout(TIMER_START_TIMEOUT, TIMEOUT_ACTION_DFU_ABORT);
            break;
        case BL_EVT_TYPE_DFU_DATA_SEGMENT_RX:
            __LOG("RX %u/%u\n",
                    p_evt->params.dfu.data_segment.received_segment,
                    p_evt->params.dfu.data_segment.total_segments);
            set_timeout(TIMER_DATA_TIMEOUT, TIMEOUT_ACTION_DFU_ABORT);
            break;

        case BL_EVT_TYPE_DFU_END:
            if (p_evt->params.dfu.end.dfu_type == DFU_TYPE_APP ||
                p_evt->params.dfu.end.dfu_type == DFU_TYPE_SD)
            {
                /* attempt to reboot to app */
                bootloader_abort(DFU_END_SUCCESS);
            }
            break;

        /* Defer the flash operations to an asynchronous handler. Doing it
           inline causes stack overflow, as the bootloader continues in the
           response callback. */
        case BL_EVT_TYPE_FLASH_WRITE:
            {
                if (!IS_WORD_ALIGNED(p_evt->params.flash.write.start_addr) ||
                    !IS_WORD_ALIGNED(p_evt->params.flash.write.p_data))
                {
                    return NRF_ERROR_INVALID_ADDR;
                }
                if (!IS_WORD_ALIGNED(p_evt->params.flash.write.length))
                {
                    return NRF_ERROR_INVALID_LENGTH;
                }
                if ((p_evt->params.flash.write.start_addr + p_evt->params.flash.write.length) > NRF_UICR->BOOTLOADERADDR &&
                    p_evt->params.flash.write.start_addr < 0x3f800)
                {
                    APP_ERROR_CHECK(NRF_ERROR_INVALID_ADDR);
                }
                flash_queue_entry_t queue_entry;
                queue_entry.type = FLASH_OP_TYPE_WRITE;
                memcpy(&queue_entry.op, &p_evt->params.flash, sizeof(flash_op_t));
                if (fifo_push(&m_flash_fifo, &queue_entry) != NRF_SUCCESS)
                {
                    __LOG(RTT_CTRL_TEXT_RED "FLASH FIFO FULL :( Increase the fifo size.\n");
                    return NRF_ERROR_NO_MEM;
                }
                NVIC_SetPendingIRQ(FLASH_HANDLER_IRQn);
            }
            break;
        case BL_EVT_TYPE_FLASH_ERASE:
            {
                flash_queue_entry_t queue_entry;
                queue_entry.type = FLASH_OP_TYPE_ERASE;
                memcpy(&queue_entry.op, &p_evt->params.flash, sizeof(flash_op_t));
                if (fifo_push(&m_flash_fifo, &queue_entry) != NRF_SUCCESS)
                {
                    __LOG(RTT_CTRL_TEXT_RED "FLASH FIFO FULL :( Increase the fifo size.\n");
                    return NRF_ERROR_NO_MEM;
                }
                NVIC_SetPendingIRQ(FLASH_HANDLER_IRQn);
            }
            break;
        default:
            return NRF_ERROR_NOT_SUPPORTED;
    }
    if (respond)
    {
        /* tail recursion */
        return bl_cmd_handler(&rsp_cmd);
    }
    else
    {
        return NRF_SUCCESS;
    }
}
Пример #19
0
void systray_render_icon(void *t)
{
	TrayWindow *traywin = t;
	if (systray_profile)
		fprintf(stderr,
		        "[%f] %s:%d win = %lu (%s)\n",
		        profiling_get_time(),
		        __FUNCTION__,
		        __LINE__,
		        traywin->win,
		        traywin->name);
	if (!traywin->reparented || !traywin->embedded) {
		if (systray_profile)
			fprintf(stderr,
			        YELLOW "[%f] %s:%d win = %lu (%s) delaying rendering" RESET "\n",
			        profiling_get_time(),
			        __FUNCTION__,
			        __LINE__,
			        traywin->win,
			        traywin->name);
		stop_timeout(traywin->render_timeout);
		traywin->render_timeout =
		    add_timeout(min_refresh_period, 0, systray_render_icon, traywin, &traywin->render_timeout);
		return;
	}

	if (systray_composited) {
		XSync(server.display, False);
		error = FALSE;
		XErrorHandler old = XSetErrorHandler(window_error_handler);

		unsigned int border_width;
		int xpos, ypos;
		unsigned int width, height, depth;
		Window root;
		if (!XGetGeometry(server.display, traywin->win, &root, &xpos, &ypos, &width, &height, &border_width, &depth)) {
			stop_timeout(traywin->render_timeout);
			if (!traywin->resize_timeout)
				traywin->render_timeout =
				    add_timeout(min_refresh_period, 0, systray_render_icon, traywin, &traywin->render_timeout);
			systray_render_icon_from_image(traywin);
			XSetErrorHandler(old);
			return;
		} else {
			if (xpos != 0 || ypos != 0 || width != traywin->width || height != traywin->height) {
				stop_timeout(traywin->render_timeout);
				if (!traywin->resize_timeout)
					traywin->render_timeout =
					    add_timeout(min_refresh_period, 0, systray_render_icon, traywin, &traywin->render_timeout);
				systray_render_icon_from_image(traywin);
				if (systray_profile)
					fprintf(stderr,
					        YELLOW "[%f] %s:%d win = %lu (%s) delaying rendering" RESET "\n",
					        profiling_get_time(),
					        __FUNCTION__,
					        __LINE__,
					        traywin->win,
					        traywin->name);
				XSetErrorHandler(old);
				return;
			}
		}
		XSetErrorHandler(old);
	}

	if (systray_profile)
		fprintf(stderr, "rendering tray icon\n");

	if (systray_composited) {
		systray_render_icon_composited(traywin);
	} else {
		// Trigger window repaint
		if (systray_profile)
			fprintf(stderr,
					"XClearArea(server.display, traywin->parent = %ld, 0, 0, traywin->width, traywin->height, True)\n",
			        traywin->parent);
		XClearArea(server.display, traywin->parent, 0, 0, 0, 0, True);
		if (systray_profile)
			fprintf(stderr,
					"XClearArea(server.display, traywin->win = %ld, 0, 0, traywin->width, traywin->height, True)\n",
			        traywin->win);
		XClearArea(server.display, traywin->win, 0, 0, 0, 0, True);
	}
}
Пример #20
0
void stop_autohide_timeout(Panel *p)
{
	stop_timeout(p->autohide_timeout);
}