Exemplo n.º 1
0
Arquivo: main.c Projeto: xiaq/hlwm
// prints or dumps the layout of an given tag
// first argument tells whether to print or to dump
int print_layout_command(int argc, char** argv, GString* output) {
    HSTag* tag = NULL;
    // an empty argv[1] means current focused tag
    if (argc >= 2 && argv[1][0] != '\0') {
        tag = find_tag(argv[1]);
        if (!tag) {
            g_string_append_printf(output,
                "%s: Tag \"%s\" not found\n", argv[0], argv[1]);
            return HERBST_INVALID_ARGUMENT;
        }
    } else { // use current tag
        HSMonitor* m = get_current_monitor();
        tag = m->tag;
    }
    assert(tag != NULL);

    HSFrame* frame = lookup_frame(tag->frame, argc >= 3 ? argv[2] : "");
    if (argc > 0 && !strcmp(argv[0], "dump")) {
        dump_frame_tree(frame, output);
    } else {
        print_frame_tree(frame, output);
    }
    return 0;
}
Exemplo n.º 2
0
int parse_frame_entry(struct frame *pa)
{
int a, c, i, j, x, y, z;
char *token, *running;
struct frame *pb = 0;
struct object *po = 0;
double da, dx, dy;
double dgx, dgy, dgz;
int frame_nr;
char *cptr, *tptr;
int screen_lines;
int line_height;
char font_dir[4096];
char font_name[4096];
font_desc_t *pfd;
int temp_palette[16][3];
int text_start, max_width, line_len;
struct object *pf = 0;
struct object *pc;
int bg_height, bg_width;

if(debug_flag)
	{
	tc_log_msg(MOD_NAME,
	"subtitler(): parse_frame_entry():\n\
	pa->name=%s pa->type=%d\n\
	pa->end_frame=%d\n\
	pa->data=%lu",
	pa -> name,
	pa -> type,
	pa -> end_frame,
	(unsigned long)pa -> data);
	}

if(pa -> data[0] == '*')
	{
	/* parse the data line */
	running = strsave(pa -> data);
	if(! running)
		{
		tc_log_warn(MOD_NAME, "subtitler(): strsave(pa -> data) failed");

		return -1;
		}

	po = 0;
	while(1)
		{
		token = strsep (&running, " ");
		if(token == NULL) break;

		if(debug_flag)
			{
			tc_log_msg(MOD_NAME, "token=%s", token);
			}

		/* avoid empty string */
		if(token[0] == 0) continue;

		/* check for object reference */
		if(token[0] == '*')
			{
			/* recursive we are in our own list */
			pb = lookup_frame(token);
			if(! pb)
				{
				tc_log_msg(MOD_NAME,
				"subtitler(): undefined object referenced: %s ignoring",
				token);

				return 1;
//				exit(1);
				}

			/* get data for this object */
			if(debug_flag)
				{
//				tc_log_msg(MOD_NAME, "parser(): object %s data=%s", token, pb -> data);
				}

			/*
			add this object to the display list, if it is already there,
			we get a pointer to it.
			*/
			po = install_object_at_end_of_list(token);
			if(! po)
				{
				tc_log_msg(MOD_NAME,
				"subtitler(): parse_frame_entry():\n\
				could not install or find object %s in display list",\
				token);

				exit(1);
				}
			}
		else /* token[0] != 0, must be an argument */
			{
			/* modify arguments for display object */
			/*
			po must have been set in the preceeding argument in this
			line, so '11 *this vpos=5', but '11 vops=5 *this' will NOT work,
			and cause an error exit.
			*/
			if(! po)
				{
				tc_log_msg(MOD_NAME,
		"subtitler(): syntax error (object must be first), line reads:\n\
				%s", pa -> name);

				exit(1);
				}
			/* copy data if not there yet */
			if(! po -> data)
				{
				po -> type = pb -> type;
				po -> data = pb -> data;
				po -> org_xsize = (double) pb -> xsize;
				po -> org_ysize = (double) pb -> ysize;
				po -> org_zsize = (double) pb -> zsize;
				po -> xsize = (double) pb -> xsize;
				po -> ysize = (double) pb -> ysize;
				po -> zsize = (double) pb -> zsize;
				po -> id = pb -> id;

				po -> pfd = pb -> pfd;

				pa -> status = OBJECT_STATUS_NEW;

				/* set some defaults */
				po -> extra_character_space = extra_character_space;

				}

			/* parse line */
			sscanf(token, "de_stripe=%lf", &po -> de_stripe);
			sscanf(token, "show_output=%lf", &po -> show_output);

			sscanf(token, "xpos=%lf", &po -> xpos);
			sscanf(token, "ypos=%lf", &po -> ypos);
			sscanf(token, "zpos=%lf", &po -> zpos);

			sscanf(token, "dxpos=%lf", &po -> dxpos);
			sscanf(token, "dypos=%lf", &po -> dypos);
			sscanf(token, "dzpos=%lf", &po -> dzpos);

			a = sscanf(token, "xdest=%lf", &dgx);
			if(a) po -> status |= OBJECT_STATUS_HAVE_X_DEST;

			a = sscanf(token, "ydest=%lf", &dgy);
			if(a) po -> status |= OBJECT_STATUS_HAVE_Y_DEST;

			a = sscanf(token, "zdest=%lf", &dgz);
			if(a) po -> status |= OBJECT_STATUS_HAVE_Z_DEST;

			if(\
			(po -> status & OBJECT_STATUS_HAVE_X_DEST) ||\
			(po -> status & OBJECT_STATUS_HAVE_Y_DEST) ||\
			(po -> status & OBJECT_STATUS_HAVE_Z_DEST)\
			)
				{
				/* use current position if nothing specified */
				if(po -> status & OBJECT_STATUS_HAVE_X_DEST)
					{
					po -> xdest = dgx;
					}
				else
					{
					po -> xdest = po -> xpos;
					}

				if(po -> status & OBJECT_STATUS_HAVE_Y_DEST)
					{
					po -> ydest = dgy;
					}
				else
					{
					po -> ydest = po -> ypos;
					}

				if(! po -> status & OBJECT_STATUS_HAVE_Z_DEST)
					{
					po -> zdest = dgz;
					}
				else
					{
					po -> zdest = po -> zpos;
					}

				/* calculate a distance */
				/* x distance */
				dx = po -> xdest - po -> xpos;

				/*
				since the 'heading' calculation in object_list.c
				uses aspect correction, we have to to pre-correct here
				the other way around.
				*/
				dx *=\
				(double)image_height / (double)image_width;

				/* y distance */
				dy = po -> ydest - po -> ypos;

				/* true distance */
				po -> distance = sqrt( (dx * dx) + (dy * dy) );

				/* sine */
				da = dx / po -> distance;

				/* calculate a heading angle */
				errno = 0;
				po -> heading = asin(da);
				if(errno == EDOM)
					{
					tc_log_perror(MOD_NAME, "subtitler(): parse_frame_entry():\n\
					asin NOT A NUMBER :-)");

					exit(1);
					}

				/* flip y, x=0, y=0 is top left */
				dy = -1 * dy;

				/* if dy is negative, we move to the other 2 quadrants */
				if(dy < 0) po -> heading = M_PI - po -> heading;

				po -> heading *= 180.0 / M_PI;

				/* indicate we are on our way */
				po -> status |= OBJECT_STATUS_GOTO;

				/*
				in object list we will now each frame substract the
                travelled distance, until po -> distance is 0.
				Then we will reset the mode to NEW.
				*/
				} /* end if some x, y, or z dest */

			sscanf(token, "xrot=%lf", &po -> xrotation);
			sscanf(token, "yrot=%lf", &po -> yrotation);
			sscanf(token, "zrot=%lf", &po -> zrotation);

			sscanf(token, "dxrot=%lf", &po -> dxrotation);
			sscanf(token, "dyrot=%lf", &po -> dyrotation);
			sscanf(token, "dzrot=%lf", &po -> dzrotation);

			sscanf(token, "xshear=%lf", &po -> xshear);
			sscanf(token, "yshear=%lf", &po -> yshear);
			sscanf(token, "zshear=%lf", &po -> zshear);

			sscanf(token, "dxshear=%lf", &po -> dxshear);
			sscanf(token, "dyshear=%lf", &po -> dyshear);
			sscanf(token, "dzshear=%lf", &po -> dzshear);

			sscanf(token, "xsize=%lf", &po -> xsize);
			sscanf(token, "ysize=%lf", &po -> ysize);
			sscanf(token, "zsize=%lf", &po -> zsize);

			sscanf(token, "dxsize=%lf", &po -> dxsize);
			sscanf(token, "dysize=%lf", &po -> dysize);
			sscanf(token, "dzsize=%lf", &po -> dzsize);

			if(strncmp(token, "rsize", 5) == 0)
				{
				po -> xsize = po -> org_xsize;
				po -> ysize = po -> org_ysize;
				po -> zsize = po -> org_zsize;

				po -> dxsize = 0.0;
				po -> dysize = 0.0;
				po -> dzsize = 0.0;
				}

			sscanf(token, "heading=%lf", &po -> heading);
			sscanf(token, "dheading=%lf", &po -> dheading);

			sscanf(token, "speed=%lf", &po -> speed);
			sscanf(token, "dspeed=%lf", &po -> dspeed);
			sscanf(token, "ddspeed=%lf", &po -> ddspeed);

			sscanf(token, "transp=%lf", &po -> transparency);
			sscanf(token, "dtransp=%lf", &po -> dtransparency);

			sscanf(token, "sat=%lf", &po -> saturation);
			sscanf(token, "dsat=%lf", &po -> dsaturation);

			sscanf(token, "hue=%lf", &po -> hue);
			sscanf(token, "dhue=%lf", &po -> dhue);

			sscanf(token, "hue_ldrift=%lf", &po -> hue_line_drift);
			sscanf(token, "dhue_ldrift=%lf", &po -> dhue_line_drift);

			sscanf(token, "contr=%lf", &po -> contrast);
			sscanf(token, "dcontr=%lf", &po -> dcontrast);

			sscanf(token, "u_shift=%lf", &po -> u_shift);
			sscanf(token, "du_shift=%lf", &po -> du_shift);

			sscanf(token, "v_shift=%lf", &po -> v_shift);
			sscanf(token, "dv_shift=%lf", &po -> dv_shift);

			sscanf(token, "slice=%lf", &po -> slice_level);
			sscanf(token, "dslice=%lf", &po -> dslice_level);

			sscanf(token, "mask=%lf", &po -> mask_level);
			sscanf(token, "dmask=%lf", &po -> dmask_level);

			sscanf(token, "bright=%lf", &po -> brightness);
			sscanf(token, "dbright=%lf", &po -> dbrightness);

			sscanf(token, "ck_color=%lf", &po -> chroma_key_color);
			sscanf(token, "dck_color=%lf", &po -> dchroma_key_color);

			sscanf(token, "ck_sat=%lf", &po -> chroma_key_saturation);
			sscanf(token, "dck_sat=%lf", &po -> dchroma_key_saturation);

			sscanf(token, "ck_window=%lf", &po -> chroma_key_window);
			sscanf(token, "dck_window=%lf", &po -> dchroma_key_window);

			sscanf(token, "u=%lf", &po -> u);
			sscanf(token, "du=%lf", &po -> du);

			sscanf(token, "v=%lf", &po -> v);
			sscanf(token, "dv=%lf", &po -> dv);

			sscanf(token, "color=%lf", &po -> color);
			sscanf(token, "dcolor=%lf", &po -> dcolor);

			a = sscanf(token, "center=%lf", &da);
			if(a == 1) center_flag = (int)da;

			sscanf(token, "aspect=%lf", &po -> aspect);

			/* these are globals (double) for subtitles */
			sscanf(token, "hfactor=%lf", &subtitle_h_factor);
			sscanf(token, "vfactor=%lf", &subtitle_v_factor);

			/* font related */

			font_dir[0] = 0;
			a = sscanf(token, "font_dir=%s", font_dir);
			if(a == 1)
				{
				po -> font_dir = strsave(font_dir);
				if(! po -> font_dir)
					{
					tc_log_msg(MOD_NAME,
					"subtitler: parse_frame_entry(): could not allocate space for font_dir, aborting");

					exit(1);
					}
				}

			/* also allow font_path, for compatibility with xste-3.1 */
			a = sscanf(token, "font_path=%s", font_dir);
			if(a == 1)
				{
				po -> font_dir = strsave(font_dir);
				if(! po -> font_dir)
					{
					tc_log_msg(MOD_NAME,
					"subtitler: parse_frame_entry(): could not allocate space for font_dir, aborting");

					exit(1);
					}
				}

			font_name[0] = 0;
			a = sscanf(token, "font_name=%s", font_name);
			if(a == 1)
				{
				po -> font_name = strsave(font_name);
				if(! po -> font_name)
					{
					tc_log_msg(MOD_NAME,
					"subtitler: parse_frame_entry(): could not allocate space for font_name, aborting");

					exit(1);
					}
				}

			a = sscanf(token, "font_size=%d", &po -> font_size);
			a = sscanf(token, "font_iso_extension=%d", &po -> font_iso_extension);
			a = sscanf(token, "font_outline_thickness=%lf", &po -> font_outline_thickness);
			a = sscanf(token, "font_blur_radius=%lf", &po -> font_blur_radius);

			if(debug_flag)
				{
				tc_log_msg(MOD_NAME, "frame=%s font_dir=%s font_name=%s\n\
				font_size=%d font_iso_extension=%d font_outline_thickness=%.2f font_blur_radius=%.2f",\
				pa -> name, po -> font_dir, po -> font_name,\
				po -> font_size, po -> font_iso_extension,\
				po -> font_outline_thickness, po -> font_blur_radius);
				}

			/* also reload font if font_factor changed */
			if( (po -> font_dir) && (po -> font_name) &&\
			(po -> font_size > 0) && (po -> font_iso_extension > 0) &&\
			(po -> font_outline_thickness > 0.0) && (po -> font_blur_radius > 0.0) )
				{
				/*
				IMPORTANT! this sets data in frame_list (pb)!!!!! NOT<<
           	    in object_list (po).
				In fact replaces frame_list pb -> font_dir with the
                new definition.
				Later, when the object is referenced again, a pointer
				is handed to the object list.
				Else the data would be erased when the object was no
           	    longer displayed.
				*/
				po -> font_symbols = default_subtitle_font_symbols;

				/* read in font (also needed for frame counter) */

				pfd = add_font(\
					po -> font_name, po -> font_symbols, po -> font_size, po -> font_iso_extension,\
					po -> font_outline_thickness, po -> font_blur_radius);
				if(! pfd)
					{
					tc_log_msg(MOD_NAME,
					"subtitler(): parser.c: could not load font:\n\
					font_dir=%s font_name=%s symbols=%d size=%d iso extension=%d\n\
					outline_thickness=%.2f  blur_radius=%.2f, aborting",\
					po -> font_dir, po -> font_name, po -> font_symbols, po -> font_size,\
					po -> font_iso_extension,\
					po -> font_outline_thickness, po -> font_blur_radius );

					/* return error */
					exit(1);
					}
Exemplo n.º 3
0
HSClient* manage_client(Window win) {
    if (is_herbstluft_window(g_display, win)) {
        // ignore our own window
        return NULL;
    }
    if (get_client_from_window(win)) {
        return NULL;
    }
    // init client
    HSClient* client = create_client();
    client->pid = window_pid(g_display, win);
    HSMonitor* m = get_current_monitor();
    // set to window properties
    client->window = win;
    client_update_title(client);

    unsigned int border, depth;
    Window root_win;
    int x, y;
    unsigned int w, h;
    XGetGeometry(g_display, win, &root_win, &x, &y, &w, &h, &border, &depth);
    // treat wanted coordinates as floating coords
    client->float_size.x = x;
    client->float_size.y = y;
    client->float_size.width = w;
    client->float_size.height = h;

    // apply rules
    HSClientChanges changes;
    client_changes_init(&changes, client);
    rules_apply(client, &changes);
    if (changes.tag_name) {
        client->tag = find_tag(changes.tag_name->str);
    }

    if (!changes.manage) {
        client_changes_free_members(&changes);
        client_destroy(client);
        // map it... just to be sure
        XMapWindow(g_display, win);
        return NULL;
    }

    // actually manage it
    g_hash_table_insert(g_clients, &(client->window), client);
    client->window_str = g_string_sized_new(10);
    g_string_printf(client->window_str, "0x%lx", win);
    hsobject_link(g_client_object, &client->object, client->window_str->str);
    // insert to layout
    if (!client->tag) {
        client->tag = m->tag;
    }
    // get events from window
    XSelectInput(g_display, win, CLIENT_EVENT_MASK);
    // insert window to the stack
    client->slice = slice_create_client(client);
    stack_insert_slice(client->tag->stack, client->slice);
    // insert window to the tag
    frame_insert_window(lookup_frame(client->tag->frame, changes.tree_index->str), win);
    client_update_wm_hints(client);
    if (changes.focus) {
        // give focus to window if wanted
        // TODO: make this faster!
        // WARNING: this solution needs O(C + exp(D)) time where W is the count
        // of clients on this tag and D is the depth of the binary layout tree
        frame_focus_window(client->tag->frame, win);
    }

    HSAttribute attributes[] = {
        ATTRIBUTE_STRING(   "winid",        client->window_str,     ATTR_READ_ONLY),
        ATTRIBUTE_STRING(   "title",        client->title,          ATTR_READ_ONLY),
        ATTRIBUTE_BOOL(     "fullscreen",   client->fullscreen,     client_attr_fullscreen),
        ATTRIBUTE_BOOL(     "pseudotile",   client->pseudotile,     client_attr_pseudotile),
        ATTRIBUTE_BOOL(     "ewmhrequests", client->ewmhrequests,   ATTR_ACCEPT_ALL),
        ATTRIBUTE_BOOL(     "ewmhnotify",   client->ewmhnotify,     ATTR_ACCEPT_ALL),
        ATTRIBUTE_BOOL(     "sizehints",    client->sizehints,      ATTR_ACCEPT_ALL),
        ATTRIBUTE_BOOL(     "urgent",       client->urgent,         client_attr_urgent),
        ATTRIBUTE_LAST,
    };
    hsobject_set_attributes(&client->object, attributes);

    ewmh_window_update_tag(client->window, client->tag);
    tag_set_flags_dirty();
    client_set_fullscreen(client, changes.fullscreen);
    ewmh_update_window_state(client);
    // add client after setting the correct tag for the new client
    // this ensures a panel can read the tag property correctly at this point
    ewmh_add_client(client->window);

    HSMonitor* monitor = find_monitor_with_tag(client->tag);
    if (monitor) {
        if (monitor != get_current_monitor()
            && changes.focus && changes.switchtag) {
            monitor_set_tag(get_current_monitor(), client->tag);
        }
        // TODO: monitor_apply_layout() maybe is called twice here if it
        // already is called by monitor_set_tag()
        monitor_apply_layout(monitor);
    } else {
        if (changes.focus && changes.switchtag) {
            monitor_set_tag(get_current_monitor(), client->tag);
        }
    }

    client_changes_free_members(&changes);
    grab_client_buttons(client, false);

    return client;
}