Example #1
0
/**
@brief    This function makes a window fullscreen.  It resizes it, but resets the values back to their originals
@return   void
**/
void
change_frame_state (Display *display, struct Frame *frame, enum Window_state state
, struct Separators *seps, const struct Workarea *workarea, struct Themes *themes, struct Atoms *atoms) {

  if(state == fullscreen) {
    int x = frame->x;
    int y = frame->y;
    int w = frame->w;
    int h = frame->h;
    //Make the window look fullscreen and then swap the variables back
    frame->x = 0 - themes->window_type[frame->type][window].x;
    frame->y = 0 - themes->window_type[frame->type][window].y;
    frame->w = workarea->screen_width  + frame->hspace;
    frame->h = workarea->screen_height + frame->vspace;

    frame->state = none;
    resize_frame(display, frame, workarea, themes);
    frame->state = state;
    stack_frame(display,  frame, seps);

    frame->x = x;
    frame->y = y;
    frame->w = w;
    frame->h = h;

    XChangeProperty(display, frame->framed_window, atoms->wm_state, XA_ATOM, 32, PropModeReplace, (unsigned char *)&atoms->wm_state_fullscreen, 1);
    XFlush(display);
    #ifdef SHOW_FRAME_STATE
    printf("Making window fullscreen %s\n", frame->window_name);
    #endif
  }

  if(state == none) {
    frame->state = none;
    //make sure that the property is removed
    XDeleteProperty(display, frame->framed_window, atoms->wm_state);
    stack_frame(display,  frame, seps);
    resize_frame(display, frame, workarea, themes);
    XFlush(display);
    #ifdef SHOW_FRAME_STATE
    printf("Making window state none %s\n", frame->window_name);
    #endif
  }

  if(state == minimized) {
    frame->state = minimized;
    XChangeProperty(display, frame->framed_window, atoms->wm_state, XA_ATOM, 32, PropModeReplace, (unsigned char *)&atoms->wm_state_hidden, 1);
    XFlush(display);
    #ifdef SHOW_FRAME_STATE
    printf("Making window hidden/minimized %s\n", frame->window_name);
    #endif
  }
  return;
}
void dump_trace(struct task_struct *task, struct pt_regs *regs,
		unsigned long *stack, unsigned long bp,
		const struct stacktrace_ops *ops, void *data)
{
	int graph = 0;

	if (!task)
		task = current;

	if (!stack) {
		unsigned long dummy;

		stack = &dummy;
		if (task && task != current)
			stack = (unsigned long *)task->thread.sp;
	}

	if (!bp)
		bp = stack_frame(task, regs);

	for (;;) {
		struct thread_info *context;

		context = (struct thread_info *)
			((unsigned long)stack & (~(THREAD_SIZE - 1)));
		bp = ops->walk_stack(context, stack, bp, ops, data, NULL, &graph);

		stack = (unsigned long *)context->previous_esp;
		if (!stack)
			break;
		if (ops->stack(data, "IRQ") < 0)
			break;
		touch_nmi_watchdog();
	}
}
Example #3
0
/**
@brief  Recover a window chosen from the window menu or in response to a successful _NET_ACTIVE_WINDOW request
@param  frames  workspace the frame is in
@param  i       index of the frame in the workspaces list of frames.
@return void
**/
void
recover_frame(Display *display, struct Workspace *frames, int i /*index*/, struct Separators *seps, const struct Workarea *workarea, struct Themes *themes) {
  //allow desktop windows to be recovered/tiled.  Otherwise the user has no way to recover a desktop window.
  if(frames->list[i]->mode == desktop) {
    if(drop_frame(frames, i, False, workarea))  {
      change_frame_mode(display, frames->list[i], tiling,  workarea, themes);
      resize_frame(display, frames->list[i], workarea, themes);
    }
  }
  else if(frames->list[i]->mode == tiling) {
    if(drop_frame(frames, i, False, workarea))  {
      XMapWindow(display, frames->list[i]->widgets[frame_parent].widget);
      frames->list[i]->state = none;
    }
  }
  else if(frames->list[i]->mode == floating) {
    if(drop_frame(frames, i, True, workarea)) {
      XMapWindow(display, frames->list[i]->widgets[frame_parent].widget);
      frames->list[i]->state = none;
    }
  }
  else {
    XMapWindow(display, frames->list[i]->widgets[frame_parent].widget);
    frames->list[i]->state = none;
  }
  stack_frame(display, frames->list[i], seps);
  reset_frame_titlebar(display, frames->list[i]);
  XFlush(display);
}
Example #4
0
void dump_trace(struct task_struct *task, struct pt_regs *regs,
		unsigned long *stack, unsigned long bp,
		const struct stacktrace_ops *ops, void *data)
{
	int graph = 0;

	if (!task)
		task = current;

	if (!stack) {
		unsigned long dummy;

		stack = &dummy;
		if (task && task != current)
			stack = (unsigned long *)task->thread.sp;
	}

	if (!bp)
		bp = stack_frame(task, regs);

	for (;;) {
		void *stack_start = (void *)((unsigned long)stack & ~(THREAD_SIZE-1));

		bp = ops->walk_stack(task, stack_start, stack, bp, ops, data, NULL, &graph);

		if (stack_start == task_stack_page(task))
			break;
		stack = *(unsigned long **)stack_start;
		if (ops->stack(data, "IRQ") < 0)
			break;
		touch_nmi_watchdog();
	}
}
Example #5
0
/*
 * The architecture-independent dump_stack generator
 */
void dump_stack(void)
{
	unsigned long bp;
	unsigned long stack;

	bp = stack_frame(current, NULL);
	printk("Pid: %d, comm: %.20s %s %s %.*s\n",
		current->pid, current->comm, print_tainted(),
		init_utsname()->release,
		(int)strcspn(init_utsname()->version, " "),
		init_utsname()->version);
	show_trace(NULL, NULL, &stack, bp);
}
void dump_trace(struct task_struct *task, struct pt_regs *regs,
		unsigned long *stack, unsigned long bp,
		const struct stacktrace_ops *ops, void *data)
{
	const unsigned cpu = get_cpu_light();
	int graph = 0;
	u32 *prev_esp;

	if (!task)
		task = current;

	if (!stack) {
		unsigned long dummy;

		stack = &dummy;
		if (task != current)
			stack = (unsigned long *)task->thread.sp;
	}

	if (!bp)
		bp = stack_frame(task, regs);

	for (;;) {
		struct thread_info *context;
		void *end_stack;

		end_stack = is_hardirq_stack(stack, cpu);
		if (!end_stack)
			end_stack = is_softirq_stack(stack, cpu);

		context = task_thread_info(task);
		bp = ops->walk_stack(context, stack, bp, ops, data,
				     end_stack, &graph);

		/* Stop if not on irq stack */
		if (!end_stack)
			break;

		/* The previous esp is saved on the bottom of the stack */
		prev_esp = (u32 *)(end_stack - THREAD_SIZE);
		stack = (unsigned long *)*prev_esp;
		if (!stack)
			break;

		if (ops->stack(data, "IRQ") < 0)
			break;
		touch_nmi_watchdog();
	}
	put_cpu_light();
}
Example #7
0
void show_stack(struct task_struct *task, unsigned long *sp)
{
	unsigned long bp = 0;
	unsigned long stack;

	/*
	 * Stack frames below this one aren't interesting.  Don't show them
	 * if we're printing for %current.
	 */
	if (!sp && (!task || task == current)) {
		sp = &stack;
		bp = stack_frame(current, NULL);
	}

	show_stack_log_lvl(task, NULL, sp, bp, "");
}
void dump_trace(struct task_struct *task, struct pt_regs *regs,
		unsigned long *stack,
		const struct stacktrace_ops *ops, void *data)
{
	const unsigned cpu = get_cpu();
	unsigned long *irq_stack_end =
		(unsigned long *)per_cpu(irq_stack_ptr, cpu);
	unsigned used = 0;
	struct thread_info *tinfo;
	int graph = 0;
	unsigned long bp;

	if (!task)
		task = current;

	if (!stack) {
		unsigned long dummy;
		stack = &dummy;
		if (task && task != current)
			stack = (unsigned long *)task->thread.sp;
	}

	bp = stack_frame(task, regs);
	/*
	 * Print function call entries in all stacks, starting at the
	 * current stack address. If the stacks consist of nested
	 * exceptions
	 */
	tinfo = task_thread_info(task);
	for (;;) {
		char *id;
		unsigned long *estack_end;
		estack_end = in_exception_stack(cpu, (unsigned long)stack,
						&used, &id);

		if (estack_end) {
			if (ops->stack(data, id) < 0)
				break;

			bp = ops->walk_stack(tinfo, stack, bp, ops,
					     data, estack_end, &graph);
			ops->stack(data, "<EOE>");
			/*
			 * We link to the next stack via the
			 * second-to-last pointer (index -2 to end) in the
			 * exception stack:
			 */
			stack = (unsigned long *) estack_end[-2];
			continue;
		}
		if (irq_stack_end) {
			unsigned long *irq_stack;
			irq_stack = irq_stack_end -
				(IRQ_STACK_SIZE - 64) / sizeof(*irq_stack);

			if (in_irq_stack(stack, irq_stack, irq_stack_end)) {
				if (ops->stack(data, "IRQ") < 0)
					break;
				bp = ops->walk_stack(tinfo, stack, bp,
					ops, data, irq_stack_end, &graph);
				/*
				 * We link to the next stack (which would be
				 * the process stack normally) the last
				 * pointer (index -1 to end) in the IRQ stack:
				 */
				stack = (unsigned long *) (irq_stack_end[-1]);
				bp = fixup_bp_irq_link(bp, stack, irq_stack,
						       irq_stack_end);
				irq_stack_end = NULL;
				ops->stack(data, "EOI");
				continue;
			}
		}
		break;
	}

	/*
	 * This handles the process stack:
	 */
	bp = ops->walk_stack(tinfo, stack, bp, ops, data, NULL, &graph);
	put_cpu();
}
void dump_trace(struct task_struct *task, struct pt_regs *regs,
		unsigned long *stack, unsigned long bp,
		const struct stacktrace_ops *ops, void *data)
{
	const unsigned cpu = get_cpu();
	unsigned long *irq_stack = (unsigned long *)per_cpu(irq_stack_ptr, cpu);
	unsigned long dummy;
	unsigned used = 0;
	int graph = 0;
	int done = 0;
	void *stack_start;

	if (!task)
		task = current;

	if (!stack) {
		if (regs)
			stack = (unsigned long *)regs->sp;
		else if (task != current)
			stack = (unsigned long *)task->thread.sp;
		else
			stack = &dummy;
	}

	if (!bp)
		bp = stack_frame(task, regs);
	/*
	 * Print function call entries in all stacks, starting at the
	 * current stack address. If the stacks consist of nested
	 * exceptions
	 */
	while (!done) {
		unsigned long *stack_end;
		enum stack_type stype;
		char *id;

		stype = analyze_stack(cpu, task, stack, &stack_end,
				      irq_stack, &used, &id);

		/* Default finish unless specified to continue */
		done = 1;

		switch (stype) {

		/* Break out early if we are on the thread stack */
		case STACK_IS_NORMAL:
			break;

		case STACK_IS_EXCEPTION:

			if (ops->stack(data, id) < 0)
				break;

			bp = ops->walk_stack(task, stack_end - EXCEPTION_STKSZ, stack, bp, ops,
					     data, stack_end, &graph);
			ops->stack(data, "<EOE>");
			/*
			 * We link to the next stack via the
			 * second-to-last pointer (index -2 to end) in the
			 * exception stack:
			 */
			if ((u16)stack_end[-1] != __KERNEL_DS)
				goto out;
			stack = (unsigned long *) stack_end[-2];
			done = 0;
			break;

		case STACK_IS_IRQ:

			if (ops->stack(data, "IRQ") < 0)
				break;
			bp = ops->walk_stack(task, irq_stack, stack, bp,
				     ops, data, stack_end, &graph);
			/*
			 * We link to the next stack (which would be
			 * the process stack normally) the last
			 * pointer (index -1 to end) in the IRQ stack:
			 */
			stack = (unsigned long *) (stack_end[-1]);
			irq_stack = NULL;
			ops->stack(data, "EOI");
			done = 0;
			break;

		case STACK_IS_UNKNOWN:
			ops->stack(data, "UNK");
			break;
		}
	}

	/*
	 * This handles the process stack:
	 */
	stack_start = (void *)((unsigned long)stack & ~(THREAD_SIZE-1));
	bp = ops->walk_stack(task, stack_start, stack, bp, ops, data, NULL, &graph);
out:
	put_cpu();
}
Example #10
0
/**
@pre      all parameters intitalized and allocated properly.
@brief    This function changes the user's workspace to the workspace at the specified index.
          If a negative index is passed (This is done when the currently open workspace is removed), it changes to a default workspace which is currently 0.
          If a negative index is passed but no workspace is open nothing happens.
          Generally, it is expected that at least one workspace is open.
          Windows from other workspaces are unmapped.
@post     The user's workspace has visibly changed.
@return   void
**/
void
change_to_workspace(Display *display, struct Workspace_list *workspaces, int *current_workspace, struct Workspace **frames, int index, struct Separators *seps, const struct Workarea *workarea, struct Themes *themes, struct Atoms *atoms) {

  struct Workspace *workspace = &workspaces->list[*current_workspace];
  if(*current_workspace != -1) *frames = workspace;

  struct Saved_frame_state *frame_state;
  if(workspaces->used_workspaces == 0) {
    *frames = NULL;
    *current_workspace = -1;
    return; //don't do anything if no windows are open
  }

  if(*current_workspace < workspaces->used_workspaces /*this function is sometimes called to change from an invalid workspace that has been closed */
  &&  *current_workspace >= 0) {
    for(int i = 0; i < workspace->used; i++) {
      //So we can figure out where to save the frame state we need to calculate the pointer offset.
      int real_frame_index = get_offset_in_array(workspace->list[i], workspaces->frame_list, sizeof(struct Frame));

      if(workspace->list[i]->sticky == False) {
        XUnmapWindow(display, workspace->list[i]->widgets[frame_parent].widget);
        XUnmapWindow(display, workspace->list[i]->menu.item);
      }
      //printf("real_frame_index %d, i = %d, current_workspace %d\n", real_frame_index, i, *current_workspace);
      frame_state = &workspace->states[real_frame_index];
      frame_state->need_to_tile = 0;
      save_frame_state(frame_state, workspace->list[i]);
    }
    free(workspace->list);
    workspace->list = NULL;
    workspace->used = 0;
  }
  XSync(display, False);

  //if index is -1, change to default workspace which is 0
  if(index < 0  &&  workspaces->used_workspaces > 0) index = 0;
  *current_workspace = index;

  workspace = &workspaces->list[*current_workspace];
  *frames = workspace;

  workspace->max = DEFAULT_STARTING_FRAMES;
  workspace->list = malloc(sizeof(struct Frames *) * workspace->max );
  if(!workspace->list) { perror("Couldn't allocate frame list"); return; }

  //Do all the panels because we want them to be tiled first.
  for(int i = 0; i < workspaces->used_frames; i++) {
    if(workspaces->frame_list[i].sticky == True) {
      if(ensure_empty_frame_reference_slots(workspace) == False) { perror("Couldn't allocate frame list"); return; }

      int ref_index = workspace->used;
      struct Frame *frame = workspace->list[ref_index] = &workspaces->frame_list[i];
      if(drop_frame(workspace, ref_index, False, workarea)) { //this should be easy as they should already be non-overlapping
        change_frame_mode(display, frame, tiling, workarea, themes);
      }
      else {
        change_frame_state(display, frame, minimized, seps, workarea, themes, atoms);
        fprintf(stderr, "Couldn't tile panel! It is called %s\n", frame->window_name);
      }
      resize_frame(display, frame, workarea, themes);
      stack_frame(display, frame, seps);
      XMapWindow(display, frame->widgets[frame_parent].widget);  //Actually only needs to be mapped the first time but doesn't matter
      workspace->used++;
    }
  }


  for(int i = 0; i < workspaces->used_frames; i++) {
    frame_state =  &workspace->states[i];
    if(frame_state->available != 0  &&  frame_state->sticky == False) {
      if(ensure_empty_frame_reference_slots(workspace) == False) { perror("Couldn't allocate frame list"); return; }

      int ref_index = workspace->used;
      struct Frame *frame = workspace->list[ref_index] = &workspaces->frame_list[i];

      load_frame_state(display, frame_state, frame, seps, workarea, themes, atoms);
      if(workspace->states[i].need_to_tile) {
        if(drop_frame(workspace, ref_index, False, workarea)) { //this should be easy as they should already be non-overlapping
          change_frame_mode(display, frame, tiling, workarea, themes);
        }
        else {
          change_frame_state(display, frame, minimized, seps, workarea, themes, atoms);
          //TODO set urgency hint
        }
        workspace->states[i].need_to_tile = 0;
      }
      else if(frame->mode == floating) {
        if(!drop_frame(workspace, ref_index, True, workarea)) {
          change_frame_state(display, frame, minimized, seps, workarea, themes, atoms);
          //TODO set urgency hint
        }
      }
      resize_frame(display, frame, workarea, themes);
      stack_frame(display, frame, seps);
      if(frame->state != minimized) XMapWindow(display, frame->widgets[frame_parent].widget);
      XMapWindow(display, workspace->list[ref_index]->menu.item);
      workspace->used++;
    }
  }
  update_client_list(display, workspace, atoms);
  // printf("changing focus to one in new workspace\n");
  recover_focus(display, workspace, atoms);
  XFlush(display);

}
Example #11
0
/**
@brief    Reparents the specified framed_window to a newly created frame.
@return   returns 1 if successful or 0 if no window was created.
@todo     A the moment each pointer is totally valid, in the future it will merely be an alias from another datastructure.
**/
int
create_frame(Display *display, struct Frame* frame
, Window framed_window, struct Popup_menu *window_menu, struct Separators *seps, const struct Workarea *workarea, struct Themes *themes
, struct Cursors *cursors, struct Atoms *atoms) {
  XWindowAttributes get_attributes;

  //printf("Creating frames->list[%d] with window %lu, connection %lu\n"
  //, frames->used, (unsigned long)framed_window, (unsigned long)display);
  //add this window to the save set as soon as possible so that if an error occurs it is still available

  XAddToSaveSet(display, framed_window);
  XSync(display, False);
  XGetWindowAttributes(display, framed_window, &get_attributes);

  /*** Set up defaults ***/
  frame->focussed = False;
  frame->sticky = False;
  frame->window_name = NULL;
  frame->framed_window = framed_window;
  frame->type = unknown;
  frame->theme_type = unknown;
  frame->mode = unset;
  frame->state = none;
  frame->wants_attention = False;
  frame->transient = 0;
  frame->width_inc = 1;
  frame->height_inc = 1;
  frame->menu.item = 0;

  frame->w_inc_offset = 0;
  frame->h_inc_offset = 0;

  frame->w = get_attributes.width;
  frame->h = get_attributes.height;

  get_frame_type_and_mode (display, frame, atoms, themes);

  frame->x = get_attributes.x - themes->window_type[frame->theme_type][window].x;
  frame->y = get_attributes.y - themes->window_type[frame->theme_type][window].y;
  frame->hspace = 0 - themes->window_type[frame->theme_type][window].w;
  frame->vspace = 0 - themes->window_type[frame->theme_type][window].h;


  // This is not set to the something sensive, like the size of the workarea
  // as it may change and we can't tell if it's a default value or a real
  // one set by the client.
  // Instead, always use the MIN of the workarea dimension and these values
  frame->max_width  = INT_MAX;
  frame->max_height = INT_MAX;

  //prevent overly small windows with these sensible defaults
  frame->min_width  = MINWIDTH + frame->hspace;
  frame->min_height = MINHEIGHT + frame->vspace;

  #ifdef ALLOW_OVERSIZE_WINDOWS_WITHOUT_MINIMUM_HINTS
  Screen* screen = DefaultScreenOfDisplay(display);
  /* Ugh Horrible.  */
  /* Many apps that are resizeable ask to be the size of the screen and since windows
     often don't specifiy their minimum size, we have no other way of knowing if they
     really need to be that size or not.  In case they do, this specifies that their
     current width is their minimum size, in the hope that it is overridden by the
     size hints. This kind of behaviour causes problems on small screens like the
     eee pc. */
  if(frame->w > XWidthOfScreen(screen))  frame->min_width = frame->w;
  if(frame->h > XHeightOfScreen(screen)) frame->min_height = frame->h;
  #endif

  /* This requires hspace and vspace to be set as well as the incremental hints */
  get_frame_hints(display, frame);

  frame_type_settings(display, frame, workarea);

  //Don't manage splash screens, they just cause the workspace to be created and instantly destroyed
  if(frame->type == splash) {
    XMapWindow(display, framed_window);
    XFlush(display);
    return 0;
  }


  get_frame_state(display, frame, atoms);
  create_frame_subwindows(display, frame, workarea, themes, cursors);
  create_frame_name(display, window_menu, frame, themes, atoms);

  get_frame_wm_hints(display, frame);  //this might need to change the focus, it's mode (to hidden) and so on
  get_frame_strut_hints_as_normal_hints(display, frame, atoms);

  //_NET_FRAME_EXTENTS, left, right, top, bottom, CARDINAL[4]/32
  int32_t ewmh_frame_extents[4] = { themes->window_type[frame->theme_type][window].x
  , themes->window_type[frame->theme_type][window].y
  , - themes->window_type[frame->theme_type][window].x - themes->window_type[frame->theme_type][window].w
  , - themes->window_type[frame->theme_type][window].y - themes->window_type[frame->theme_type][window].h
  };

  XChangeProperty(display, framed_window, atoms->frame_extents, XA_CARDINAL
  , 32, PropModeReplace, (unsigned char *)ewmh_frame_extents, 4);

  XSetWindowBorderWidth(display, framed_window, 0);

  change_frame_mode(display, frame, unset, workarea, themes);

  #ifdef CRASH_ON_BUG
  XGrabServer(display);
  XSetErrorHandler(supress_xerror);
  #endif

  XSelectInput(display, framed_window,  0);

  //reparent the framed_window to frame->widgets[window].widget
  XReparentWindow(display, framed_window, frame->widgets[window].widget, 0, 0);
  //for some odd reason the reparent only reports an extra unmap event if the window was already unmapped
  XRaiseWindow(display, framed_window);
  XMapWindow(display, frame->widgets[window].widget);

  #ifdef CRASH_ON_BUG
  XSetErrorHandler(NULL);
  XUngrabServer(display);
  #endif

  XSelectInput(display, framed_window,  PropertyChangeMask); //Property notify is used to update titles
  XSelectInput(display, frame->widgets[window].widget
  , SubstructureRedirectMask | SubstructureNotifyMask | ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask);

  //Some windows only send the destroy event (e.g., gimp splash screen)
  XSync(display, False);

  //Intercept clicks so we can set the focus and possibly raise floating windows
  XGrabButton(display, Button1, 0, frame->widgets[window].widget
  , False, ButtonPressMask, GrabModeSync, GrabModeAsync, None, None);

  //do it for numlock as well
  XGrabButton(display, Button1, Mod2Mask, frame->widgets[window].widget
  , False, ButtonPressMask, GrabModeSync, GrabModeAsync, None, None);

  frame->w += frame->hspace;
  frame->h += frame->vspace;

  check_frame_limits(frame, workarea, themes);

  resize_frame(display, frame, workarea, themes);
  stack_frame(display, frame, seps);
  change_frame_state(display, frame, frame->state, seps, workarea, themes, atoms);
  XMoveResizeWindow(display, framed_window, 0, 0, frame->w - frame->hspace, frame->h - frame->vspace);
  XMoveWindow(display, framed_window, 0, 0);
  XMapWindow(display, framed_window);

  XFlush(display);
  save_frame_initial_state(frame);
  return 1;
}